/// <summary>
        /// Calculates VS_COD degradation rate and return its normalized
        /// value as VS_COD_fitness
        /// </summary>
        /// <param name="mySensors"></param>
        /// <param name="VS_COD_degradationRate"></param>
        /// <returns>VS_COD_fitness: normalized between 0 and 1</returns>
        private static double getVS_COD_fitness(biogas.sensors mySensors,
                                                out double VS_COD_degradationRate)
        {
            // Volatile Solids COD degradation
            // volatile COD in the final storage tank

            // TODO stimmt so nicht, masseabgang durch biogas
            // da der FLuss welcher in das Endlager rein geht immer identisch mit
            // dem Fluss der Eingangssubstrate ist, kürzen sich die beiden werte
            // immer raus, also hier nicht benötigt

            physValue Q_final_storage = mySensors.getCurrentMeasurement("Q_finalstorage_2");

            // gCOD/l
            physValue VS_COD_final_storage = mySensors.getCurrentMeasurement("VS_COD_finalstorage_2");

            // gCOD/l * m^3 == also eine Menge, keine Konzentration
            double VS_COD_amount_final = VS_COD_final_storage.Value * Q_final_storage.Value;

            // volatile COD in the substrate feed

            // TODO
            // measure Q_total_mix_2
            physValue Q_total_mix = mySensors.getCurrentMeasurement("Q_total_mix_2");

            // gCOD/l
            physValue VS_COD_substrate = mySensors.getCurrentMeasurement("VS_COD_total_mix_2");

            // gCOD/l * m^3 == also eine Menge, keine Konzentration
            double VS_COD_amount_total = VS_COD_substrate.Value * Q_total_mix.Value;

            //

            // a value between 0 and 100
            VS_COD_degradationRate =
                (1 - Math.Max(VS_COD_amount_final, 0) / Math.Max(VS_COD_amount_total, double.Epsilon)) * 100;

            //

            double VS_COD_degradationMin = 0;
            double VS_COD_degradationMax = 100;

            // values between 0 and 1
            double VS_COD_fitness = Math.Abs((1 - math.normalize(VS_COD_degradationRate,
                                                                 VS_COD_degradationMin, VS_COD_degradationMax)));

            return(VS_COD_fitness);
        }
Exemple #2
0
        /// <summary>
        /// Calculates the thermal energy balance of the digester. It compares
        /// thermal sinks (negative) with thermal sources (positive) inside the digester
        ///
        /// At the moment the following processes are reflected:
        ///
        /// thermal sinks are:
        ///
        /// 1) heat energy needed to heat the substrates up to the digesters temperature
        /// (heat substrates)
        /// 2) heat energy loss due to radiation through the surface of the fermenter
        /// (radiation)
        ///
        /// thermal sources are:
        ///
        /// 1) microbiology
        /// 2) stirrer dissipation
        ///
        /// For further effects see
        ///
        /// 1) Lübken, M., Wichern, M., Schlattmann, M., Gronauer, A., and Horn, H.:
        ///    Modelling the energy balance of an anaerobic digester fed with cattle manure
        ///    and renewable energy crops, Water Research 41, pp. 4085-4096, 2007
        /// 2) Lindorfer, H., Kirchmayr, R., Braun, R.:
        ///    Self-heating of anaerobic digesters using energy crops, 2005
        ///
        ///
        /// </summary>
        /// <param name="Q">substrate feed measured in m^3/d</param>
        /// <param name="mySubstrates"></param>
        /// <param name="T_ambient">ambient temperature</param>
        /// <param name="mySensors"></param>
        /// <param name="Psubsheat">thermal energy needed to heat substrates in kWh/d</param>
        /// <param name="Pradloss">thermal energy loss due to radiation in kWh/d</param>
        /// <param name="Pmicros">Wärme produziert durch Bakterien in kWh/d</param>
        /// <param name="Pstirdiss">thermal energy created by stirrer in kWh/d</param>
        /// <returns>thermal energy balance mesasured in kWh/d</returns>
        /// <exception cref="exception">Q.Length &lt; mySubstrates.Count</exception>
        /// <exception cref="exception">energy calculations failed</exception>
        public double calcThermalEnergyBalance(double[] Q, substrates mySubstrates,
                                               physValue T_ambient, sensors mySensors, out physValue Psubsheat, out physValue Pradloss,
                                               out physValue Pmicros, out physValue Pstirdiss)
        {
            //physValue Pel_kWh_d;
            //physValue Pel_kW;

            // thermal energy needed to heat substrates in kWh/d
            try
            {
                Psubsheat = mySubstrates.calcSumQuantityOfHeatPerDay(Q, T).convertUnit("kWh/d");
            }
            catch (exception e)
            {
                Console.WriteLine(e.Message);
                throw new exception("calcThermalEnergyBalance: heat substrates failed!");
            }

            //physValue P_radiation_loss_kW;
            //physValue P_radiation_loss_kWh_d;

            // energy needed to compensate loss due to radiation
            //compensateHeatLossDueToRadiation(T_ambient, out P_radiation_loss_kW, out P_radiation_loss_kWh_d);

            // thermal energy loss due to radiation in kWh/d
            try
            {
                Pradloss = calcHeatLossDueToRadiation(T_ambient).convertUnit("kWh/d");
            }
            catch (exception e)
            {
                Console.WriteLine(e.Message);
                throw new exception("calcThermalEnergyBalance: heat loss calculation failed!");
            }

            // Wärme produziert durch Bakterien
            // in kWh/d
            try
            {
                Pmicros = mySensors.getCurrentMeasurement("energyProdMicro_" + id);

                // wenn noch nichts aufgezeichnet wurde, dann ist der Wert 0
                if (Pmicros.Value != 0)
                {
                    Pmicros = Pmicros.convertUnit("kWh/d");
                }
                else // setzte zu 0 kWh/d, da einheit sonst nicht stimmt
                {
                    Pmicros = new physValue(0, "kWh/d");
                }
            }
            catch (exception e)
            {
                Console.WriteLine(e.Message);
                throw new exception("calcThermalEnergyBalance: microorganisms failed!");
            }

            // Wärme welche das Rühwerk erzeugt ist eine Wärmequelle, muss hier addiert werden
            // In Ganzheitliche stoffliche und energetische Modellierung S. 65
            // Dissipation Rührwerk - ist identisch mit der aufgebrachten Leistung des
            // rührwerks. dafür muss erstmal rührwerksleistung berechnet werden, s. ebenfalls
            // In Ganzheitliche stoffliche und energetische Modellierung S. 45 ff.
            // für rührwerksleitung muss auch viskosität berechnet werden s. S. 81 für verschiedene
            // TS im fermenter

            // thermal energy created by stirrer in kWh/d
            try
            {
                Pstirdiss = calcStirrerDissipation(mySensors).convertUnit("kWh/d");
            }
            catch (exception e)
            {
                Console.WriteLine(e.Message);
                throw new exception("calcThermalEnergyBalance: stirrer dissipation failed!");
            }

            // sinks are negative, themal sources are positive
            physValue balance = -Psubsheat - Pradloss +
                                Pstirdiss + Pmicros; // + produzierteWärme im Fermenter



            return(balance.Value);
        }