Beispiel #1
0
        /// <summary>
        /// type 7
        ///
        /// called in ADMstate_stoichiometry.cs -> measure_type7
        /// </summary>
        /// <param name="x">ADM state vector - not used</param>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates">not yet used</param>
        /// <param name="mySensors">used to get TS inside digester</param>
        /// <param name="Q">not used</param>
        /// <param name="par">not used</param>
        /// <returns>measured values</returns>
        override protected physValue[] doMeasurement(double[] x, biogas.plant myPlant,
                                                     biogas.substrates mySubstrates,
                                                     biogas.sensors mySensors,
                                                     double[] Q, params double[] par)
        {
            // 1st Pel in kWh/d for mixing digester
            // 2nd Pdissipated in kWh/d for mixing digester, dissipated in digester
            physValue[] values = new physValue[dimension];

            //

            digester myDigester = myPlant.getDigesterByID(id_suffix);

            // calc stirrer(s) power for digester in kWh/d
            values[0] = myDigester.calcStirrerPower(mySensors);

            // calc stirrer(s) power dissipated to digester in kWh/d
            values[1] = myDigester.calcStirrerDissipation(mySensors);

            values[0].Label = "electrical energy of stirrer";
            values[1].Label = "thermal energy dissipated by stirrer";

            //

            return(values);
        }
Beispiel #2
0
        /// <summary>
        /// Calculate thermal/electrical power needed by heating to compensate heat loss in digester.
        /// </summary>
        /// <param name="digester_id">digester id</param>
        /// <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>
        /// <returns>thermal/electrical energy needed by heating in kWh/d</returns>
        /// <exception cref="exception">Unknown digester id</exception>
        /// <exception cref="exception">Q.Length != mySubstrates.Count</exception>
        /// <exception cref="exception">efficiency is zero, division by zero</exception>
        public double calcHeatPower(string digester_id, double[] Q, substrates mySubstrates,
                                    physValue T_ambient, sensors mySensors)
        {
            digester myDigester = get(digester_id);

            return(myDigester.calcHeatPower(Q, mySubstrates, T_ambient, mySensors));
        }
        /// <summary>
        /// write measured variable at time t in given mySubstrate
        /// (mySubstrates.get(substrate_id))
        /// </summary>
        /// <param name="t">current simulation time</param>
        /// <param name="mySensors"></param>
        /// <param name="mySubstrates">changed in this call</param>
        /// <param name="substrate_id">ID of substrate to be set</param>
        public static void set_substrate_params_from_sensor(double t, biogas.sensors mySensors,
                                                            biogas.substrates mySubstrates, string substrate_id)
        {
            biogas.substrate mySubstrate = mySubstrates.get(substrate_id);

            set_substrate_params_from_sensor(t, mySensors, mySubstrate);
        }
Beispiel #4
0
        /// <summary>
        /// Calculates the thermal energy balance of the digester. It compares
        /// thermal sinks (negative) with thermal sources (positive) inside the digester
        /// thermal sinks are:
        /// - heat substrates
        /// - radiation
        /// thermal sources are:
        /// - microbiology
        /// - stirrer dissipation
        /// </summary>
        /// <param name="digester_id">digester id</param>
        /// <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>
        /// <returns>thermal energy balance measured in kWh/d</returns>
        /// <exception cref="exception">Unknown digester id</exception>
        /// <exception cref="exception">Q.Length != mySubstrates.Count</exception>
        public double calcThermalEnergyBalance(string digester_id,
                                               double[] Q, substrates mySubstrates, physValue T_ambient,
                                               sensors mySensors)
        {
            digester myDigester = get(digester_id);

            return(myDigester.calcThermalEnergyBalance(Q, mySubstrates, T_ambient, mySensors));
        }
Beispiel #5
0
        ///// <summary>
        ///// Calculate power needed to comepnsate thermal loss due to
        ///// radiation through the digesters surface.
        ///// </summary>
        ///// <param name="T_ambient">ambient temperature</param>
        ///// <param name="P_radiation_loss_kW">electrical or thermal power</param>
        ///// <param name="P_radiation_loss_kWh_d">electrical or thermal energy per day</param>
        ///// <exception cref="exception">efficiency is zero, division by zero</exception>
        //public void compensateHeatLossDueToRadiation(physValue T_ambient,
        //                                             out physValue P_radiation_loss_kW,
        //                                             out physValue P_radiation_loss_kWh_d)
        //{
        //  physValue P_radiation_loss= calcHeatLossDueToRadiation(T_ambient);

        //  heating.compensateHeatLossDueToRadiation(P_radiation_loss,
        //                                           out P_radiation_loss_kW,
        //                                           out P_radiation_loss_kWh_d);
        //}

        /// <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>
        /// <returns>thermal energy balance mesasured in kWh/d</returns>
        /// <exception cref="exception">Q.Length != mySubstrates.Count</exception>
        public double calcThermalEnergyBalance(double[] Q, substrates mySubstrates,
                                               physValue T_ambient, sensors mySensors)
        {
            physValue Psubsheat, Pradloss, Pmicros, Pstirdiss;

            return(calcThermalEnergyBalance(Q, mySubstrates, T_ambient, mySensors, out Psubsheat,
                                            out Pradloss, out Pmicros, out Pstirdiss));
        }
Beispiel #6
0
        // -------------------------------------------------------------------------------------
        //                              !!! PUBLIC GET METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// Returns the ADM params vector, depending on the current substrate feed.
        /// The current substrate feed is taken out of the current substrate feed
        /// measurement in mySensors
        ///
        /// Attention!!! Changes the values of the ADM params!!!
        ///
        /// the following params depend on the substrate feed:
        /// - XC fractions (fCH_XC, fLI_XC, ...]
        /// - disintegration constant: kdis
        /// - hydrolysis constant: khyd_ch, khyd_pr, khyd_li
        /// </summary>
        /// <param name="index">1-based index of digester</param>
        /// <param name="t">current simulation time measured in days</param>
        /// <param name="mySensors"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="substrate_network_digester"></param>
        /// <returns></returns>
        /// <exception cref="exception">Invalid digester index</exception>
        public double[] getADMparams(int index, double t, sensors mySensors,
                                     substrates mySubstrates,
                                     double[] substrate_network_digester /*,
                                                                          * double deltatime*/)
        {
            return(get(index).getADMparams(t, mySensors,
                                           mySubstrates, substrate_network_digester));
        }
Beispiel #7
0
        /// <summary>
        /// ...
        ///
        /// type 9
        /// </summary>
        /// <param name="mySubstrates"></param>
        /// <param name="mySensors"></param>
        /// <param name="par">not used</param>
        /// <returns></returns>
        override protected physValue[] doMeasurement(biogas.substrates mySubstrates,
                                                     biogas.sensors mySensors, params double[] par)
        {
            physValue[] values = new physValue[1];

            //
            bool manurebonus = biogas.eeg2009.check_manurebonus(mySubstrates, mySensors);

            values[0] = new physValue("manurebonus", Convert.ToDouble(manurebonus), "-");

            return(values);
        }
Beispiel #8
0
        /// <summary>
        /// ...
        ///
        /// type 9
        /// </summary>
        /// <param name="mySubstrates"></param>
        /// <param name="mySensors"></param>
        /// <param name="par">not used</param>
        /// <returns></returns>
        override protected physValue[] doMeasurement(biogas.substrates mySubstrates,
                                                     biogas.sensors mySensors, params double[] par)
        {
            physValue[] values = new physValue[1];

            //
            double udot = calcudot(mySensors, mySubstrates);

            values[0] = new physValue("udot", udot, "-");

            return(values);
        }
Beispiel #9
0
        /// <summary>
        /// Calculate electrical power of stirrers inside digester
        /// </summary>
        /// <param name="mySensors"></param>
        /// <returns>electrical power of stirrers inside digester in kWh/d</returns>
        /// <exception cref="exception">calculation of stirrer power failed</exception>
        public physValue calcStirrerPower(sensors mySensors)
        {
            double Tdigester = T.convertUnit("°C").Value;
            double TSdigester;

            // get TS measurement inside this digester
            mySensors.getCurrentMeasurementD("TS_" + id + "_3", out TSdigester);

            // calc electrical power of all mixers in this digester, measure in kWh/d
            double Pel = mixers.calcPelectrical(Tdigester, TSdigester);

            return(new physValue("Pel_mix", Pel, "kWh/d"));
        }
Beispiel #10
0
        /// <summary>
        /// Calculate dissipated power of stirrers inside digester, dissipated to digester
        /// in kWh/d
        /// </summary>
        /// <param name="mySensors"></param>
        /// <returns>dissipated power of stirrers inside digester in kWh/d</returns>
        /// <exception cref="exception">calculation of stirrer power failed</exception>
        public physValue calcStirrerDissipation(sensors mySensors)
        {
            double Tdigester = T.convertUnit("°C").Value;
            double TSdigester;

            // get TS measurement inside this digester
            mySensors.getCurrentMeasurementD("TS_" + id + "_3", out TSdigester);

            // calc dissipated power of all mixers in this digester, measure in kWh/d
            double Pdiss = mixers.calcPdissipation(Tdigester, TSdigester);

            return(new physValue("Pdiss_mix", Pdiss, "kWh/d"));
        }
        /// <summary>
        /// calculates fitness values that have to do with biogas production
        /// at the moment two fitness values are calculated:
        /// - methane concentration smaller 50 %
        /// - biogas excess
        ///
        /// TODO: erweitern um H2_fitness? use a H2_max boundary
        /// / da simulation für h2 bisher teilweise recht ungenau, macht
        /// die nutzun einer upper boundary momentan nicht so viel sinn
        /// </summary>
        /// <param name="mySensors"></param>
        /// <param name="CH4_fitness">1 if CH4 concentration is smaller 50 %</param>
        private static void getBiogas_fitness(biogas.sensors mySensors, out double CH4_fitness)
        {
            // Calculation of methane amount in Biogas

            physValue[] biogas_v = mySensors.getCurrentMeasurementVector("total_biogas_");

            double methaneConcentration = biogas_v[2].Value;


            CH4_fitness = Convert.ToDouble(methaneConcentration < 50) *
                          (0 * 1 + math.tukeybiweight(methaneConcentration - 50));

            //CH4_fitness = Convert.ToDouble(methaneConcentration < 50);
        }
        /// <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);
        }
        // -------------------------------------------------------------------------------------
        //                              !!! PRIVATE METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// Calculates sum of setpoint control errors
        /// </summary>
        /// <param name="mySensors">sensors object with all measurements</param>
        /// <param name="myPlant">plant object</param>
        /// <param name="myFitnessParams">fitness params</param>
        /// <param name="noisy">if true then noisy measurements are used</param>
        /// <returns></returns>
        private static double calc_setpoint_errors(sensors mySensors, plant myPlant,
                                                   biooptim.fitness_params myFitnessParams, bool noisy)
        {
            double diff_setpoints = 0; // to be returned value: control setpoint error

            double[] sim_t = mySensors.getTimeStream();

            double t = mySensors.getCurrentTime();

            double sim_val, ref_val; // last simulated value and reference value at time t

            //

            if (sim_t.Length > 3)
            {
                foreach (biooptim.setpoint mySetpoint in myFitnessParams.mySetpoints)
                {
                    if (mySetpoint.s_operator == "") // then compare measurement of one sensor
                    {
                        string sensor_id = mySetpoint.sensor_id + "_" + mySetpoint.location;

                        // get reference values always not noisy
                        ref_val = mySensors.getMeasurementDAt(String.Format("ref_{0}_{1}", sensor_id, mySetpoint.index),
                                                              "", t, 0, false);

                        sim_val = mySensors.getCurrentMeasurementDind(sensor_id, mySetpoint.index, noisy);
                    }
                    else // compare measurement of a group of sensors, energy of all chps, gas of all digesters, ...
                    {
                        string s_operator = mySetpoint.location + "_" + mySetpoint.s_operator;

                        // get reference values always not noisy
                        ref_val = mySensors.getMeasurementDAt(
                            String.Format("ref_{0}_{1}", mySetpoint.sensor_id, mySetpoint.index),
                            "", t, 0, false);

                        sim_val = mySensors.getCurrentMeasurementDind(myPlant, mySetpoint.sensor_id, s_operator,
                                                                      mySetpoint.index, noisy);
                    }

                    diff_setpoints += mySetpoint.scalefac * Math.Pow(ref_val - sim_val, 2);
                }
            }

            return(diff_setpoints);
        }
        // -------------------------------------------------------------------------------------
        //                            !!! PRIVATE METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// returns a value between 0 and 1. if the pH value is lower or upper
        /// some constraints, then the value is greater 0, else 0.
        ///
        /// TODO: diese methode überdenken
        /// </summary>
        /// <param name="mySensors"></param>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <returns></returns>
        private static double getpHvalue_fitness(biogas.sensors mySensors, biogas.plant myPlant,
                                                 biooptim.fitness_params myFitnessParams)
        {
            double pH_Punishment = 0;
            double pH_value;

            int n_digester = myPlant.getNumDigesters();

            for (int idigester = 0; idigester < n_digester; idigester++)
            {
                string digester_id = myPlant.getDigesterID(idigester + 1);

                mySensors.getCurrentMeasurementD("pH_" + digester_id + "_3", out pH_value);

                // punish values bigger than 8 or smaller than 7
                // Der Faktor gibt die Steilheit der Strafe an, bei max. 2, dann ist
                // schon bei 8 bzw. 7 der Ausdruck ( 2.0 .* (pH(ifermenter,1) - 7.5) )
                // == 1

                // TODO - maybe use tukey function here instead
                // macht es überhaupt sinn mit optimal values zu arbeiten?
                // oder einfacher die calcFitnessDigester_min_max() methode nutzen

                double pH_punish_digester = Math.Min(1 / (10 ^ 4) * (
                                                         Math.Pow(1.8 * (pH_value -
                                                                         myFitnessParams.get_param_of("pH_optimum", idigester)), 12)),
                                                     Math.Abs(pH_value - myFitnessParams.get_param_of("pH_optimum", idigester)));

                pH_punish_digester = Math.Max(pH_punish_digester,
                                              Convert.ToDouble(pH_value < myFitnessParams.get_param_of("pH_min", idigester)));
                pH_punish_digester = Math.Max(pH_punish_digester,
                                              Convert.ToDouble(pH_value > myFitnessParams.get_param_of("pH_max", idigester)));

                // diese zeile begrenzt pH Strafe zwischen 0 und 1
                pH_Punishment = pH_Punishment + Math.Min(pH_punish_digester, 1);
            }

            if (n_digester > 0)
            {
                pH_Punishment = pH_Punishment / n_digester;
            }

            // values between 0 and 1, can be hard constraints
            return(pH_Punishment);
        }
Beispiel #15
0
        /// <summary>
        /// calc electrical or thermal power needed to heat the digester
        /// using the heating, in kWh/d
        /// </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>
        /// <returns>thermal/electrical energy needed by heating in kWh/d</returns>
        /// <exception cref="exception">Q.Length != mySubstrates.Count</exception>
        /// <exception cref="exception">efficiency is zero, division by zero</exception>
        public double calcHeatPower(double[] Q, substrates mySubstrates,
                                    physValue T_ambient, sensors mySensors)
        {
            // thermal energy balance in kWh/d
            double balance = calcThermalEnergyBalance(Q, mySubstrates, T_ambient, mySensors);

            physValue P_loss_kW, P_loss_kWh_d;

            if (balance < 0)
            {
                heating.compensateHeatLoss(new physValue(-balance, "kWh/d"), out P_loss_kW, out P_loss_kWh_d);

                return(P_loss_kWh_d.Value);
            }
            else
            {
                return(0);
            }
        }
        /// <summary>
        /// type 7
        ///
        /// called in ADMstate_stoichiometry.cs
        ///
        /// unterschied zu typ 7 ist, dass Q hier nur aus Substraten besteht und nicht
        /// aus zusätzlichem sludge, da sludge nicht aufgewärmt werden muss,
        /// nein ist jetzt ein Typ 7 sensor, sludge wird ignoriert
        /// </summary>
        /// <param name="x">not used</param>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="mySensors"></param>
        /// <param name="Q">zufuhr aller substrate in fermenter (nicht in Anlage),
        /// da heatConsumption_sensor am fermenter angebracht ist</param>
        /// <param name="par">not used</param>
        /// <returns>measured values</returns>
        override protected physValue[] doMeasurement(double[] x, biogas.plant myPlant,
                                                     biogas.substrates mySubstrates,
                                                     biogas.sensors mySensors,
                                                     double[] Q, params double[] par)
        {
            // wegen 4 siehe oben
            // 1. Ptherm kWh/d for heating substrates
            // 2. Ptherm kWh/d loss due to radiation
            // 3. Ptherm kWh/d produced by microbiology
            // 4. Ptherm kWh/d produced by stirrer dissipation
            physValue[] values = new physValue[dimension];

            // TODO - rufe hier calcThermalEnergyBalance auf von digester_energy.cs
            // benötigt als weiteren Parameter allerdings mySensors

            digester myDigester = myPlant.getDigesterByID(id_suffix);

            // Q ist nur das was in fermenter rein geht
            // bspw. gäbe es bei einem nicht gefütterten aber beheiztem fermenter
            // keine substrate welche aufgeheizt werden müssten
            //myDigester.heatInputSubstrates(Q, mySubstrates, out values[0]);

            myDigester.calcThermalEnergyBalance(Q, mySubstrates, myPlant.Tout, mySensors,
                                                out values[0], out values[1], out values[2], out values[3]);

            //

            values[0].Label = "thermal energy to heat substrates";
            values[1].Label = "thermal energy loss due to radiation";
            values[2].Label = "thermal energy produced by microorganisms";
            values[3].Label = "thermal energy dissipated by stirrer";

            //physValue P_radiation_loss_kW;
            // because in heating first power in kW is calculated, it does not
            // make the code faster to not have power in kW as parameter
            //myPlant.compensateHeatLossDueToRadiation(id_suffix,
            //        out P_radiation_loss_kW, out values[1]);

            //

            return(values);
        }
        /// <summary>
        /// Returns a vector of volumeflows for the given digester digester_id.
        /// first elements are the feeds for each substrate followed by the flows
        /// going over each incoming connection to the digester.
        /// </summary>
        /// <param name="t">current simulation time</param>
        /// <param name="mySubstrates"></param>
        /// <param name="myPlant"></param>
        /// <param name="mySensors"></param>
        /// <param name="substrate_network"></param>
        /// <param name="plant_network"></param>
        /// <param name="digester_id"></param>
        /// <returns></returns>
        private physValue[] getInputVolumeflowForFermenter(double t, biogas.substrates mySubstrates,
                                                           biogas.plant myPlant, sensors mySensors,
                                                           double[,] substrate_network, double[,] plant_network,
                                                           string digester_id)
        {
            // get volumeflow of substrates into fermenter as column vector

            physValue[] Q_digester = getSubstrateMixFlowForFermenter(t, mySubstrates, myPlant,
                                                                     mySensors, substrate_network, digester_id);


            // get recirculated volumflow of other fermenters into this fermenter as
            // column vector

            physValue[] Q_pumped = getPumpedInputFlowForFermenter(t, mySubstrates,
                                                                  myPlant, mySensors,
                                                                  substrate_network, plant_network, digester_id);

            // concatenate both vectors vertically

            return(physValue.concat(Q_digester, Q_pumped));
        }
Beispiel #18
0
        /// <summary>
        /// Calc u prime for substrate feed of all substrates saved in sensors at the
        /// current time
        /// </summary>
        /// <param name="mySensors"></param>
        /// <param name="mySubstrates"></param>
        /// <returns>|| u'(t) ||_2^2, where u is the vector of substrate feeds</returns>
        private double calcudot(biogas.sensors mySensors, biogas.substrates mySubstrates)
        {
            double t2 = mySensors.getCurrentTime();

            if (t2 < 0) // no recorded value yet in no sensor
            {
                return(0);
            }

            double t1 = mySensors.getPreviousTime();

            double[] Q1, Q2;

            // TODO
            // wenn init substrate feed nicht gegeben ist, dann ist am anfang der simulation
            // Q2 = Q1
            // aktuell berechne ich in MATLAb noch init_substrate feed und addiere das am ende
            // zu udot hinzu, sollte erstmal ok sein
            mySensors.getMeasurementsAt("Q", "Q", t1, mySubstrates, out Q1);

            mySensors.getMeasurementsAt("Q", "Q", t2, mySubstrates, out Q2);

            //

            double udot = 0;

            for (int isubstrate = 0; isubstrate < mySubstrates.getNumSubstrates(); isubstrate++)
            {
                double u1 = Q1[isubstrate];
                double u2 = Q2[isubstrate];

                double udot1 = calcudot(t1, t2, u1, u2);

                udot += udot1 * udot1;
            }

            return(udot);
        }
Beispiel #19
0
        /// <summary>
        /// Returns the ADM params vector, depending on the current substrate feed.
        /// The current substrate feed is taken out of the current substrate feed
        /// measurement in mySensors
        ///
        /// Attention!!! Changes the values of the ADM params!!!
        ///
        /// the following params depend on the substrate feed:
        /// - XC fractions (fCH_XC, fLI_XC, ...]
        /// - disintegration constant: kdis
        /// - hydrolysis constant: khyd_ch, khyd_pr, khyd_li
        /// </summary>
        /// <param name="t">current simulation time measured in days</param>
        /// <param name="mySensors"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="substrate_network_digester"></param>
        /// <param name="digesterID">digester id</param>
        /// <returns></returns>
        public double[] getParams(double t, sensors mySensors, substrates mySubstrates,
                                  double[] substrate_network_digester, String digesterID /*,
                                                                                          * double deltatime*/)
        {
            double[] Q;

            mySensors.getMeasurementsAt("Q", "Q", t, mySubstrates, out Q);

            // multiply the two vectors with the vector product
            // two column vector are multiplied therefore a column vector is returned
            Q = math.times(substrate_network_digester, Q);

            double QdigesterIn;

            mySensors.getCurrentMeasurementD(String.Format("Q_{0}_2", digesterID), out QdigesterIn);

            double[] ADMparams = getParams(t, Q, QdigesterIn, mySubstrates); // , mySensors.isEmpty()

            // measurement of ADM1 params to sensors
            mySensors.measure(t, "ADMparams_" + digesterID, ADMparams);

            return(ADMparams);
        }
        /// <summary>
        /// ...
        ///
        /// type 8
        /// </summary>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="mySensors"></param>
        /// <param name="par">not used</param>
        /// <returns></returns>
        override protected physValue[] doMeasurement(biogas.plant myPlant,
                                                     biooptim.fitness_params myFitnessParams, biogas.sensors mySensors, params double[] par)
        {
            physValue[] values = new physValue[1];

            // this is the fitness of the VS_COD in the digester
            double VS_COD_degradationRate;
            double VS_COD_fitness = getVS_COD_fitness(mySensors, out VS_COD_degradationRate);

            values[0] = new physValue("VS_COD_fitness", VS_COD_fitness, "-");

            return(values);
        }
        /// <summary>
        /// ...
        ///
        /// type 8
        /// </summary>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="mySensors"></param>
        /// <param name="par">not used</param>
        /// <returns></returns>
        override protected physValue[] doMeasurement(biogas.plant myPlant,
                                                     biooptim.fitness_params myFitnessParams, biogas.sensors mySensors, params double[] par)
        {
            physValue[] values = new physValue[1];

            // da mit tukey gearbeitet wird, kann der term auch etwas größer als 1 sein
            double VFA_TAC_fitness = sensors.calcFitnessDigester_min_max(myPlant, mySensors, "VFA_TAC",
                                                                         "min_max", myFitnessParams, "_3", true);

            values[0] = new physValue("VFA_TAC_fitness", VFA_TAC_fitness, "-");

            return(values);
        }
Beispiel #22
0
        /// <summary>
        /// Measure TS content inside a digester
        ///
        /// type 7
        /// </summary>
        /// <param name="x">ADM state vector</param>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates">list of substrates</param>
        /// <param name="mySensors"></param>
        /// <param name="Q">
        /// substrate feed and recirculation sludge going into the digester
        /// first values are Q for substrates, then pumped sludge going into digester
        /// dimension: always number of substrates + number of digesters
        /// </param>
        /// <param name="par">not used</param>
        /// <returns></returns>
        override protected physValue[] doMeasurement(double[] x, biogas.plant myPlant,
                                                     biogas.substrates mySubstrates, biogas.sensors mySensors,
                                                     double[] Q, params double[] par)
        {
            // TODO
            // so erweitern, dass auch TS in Fermenter Input gemessen werden kann
            // evtl. substrate_sensor nutzen, kann aber auch direkt über mySubstrates gemessen werden

            physValue[] values = new physValue[1];

            // number of substrates
            int n_substrate = mySubstrates.getNumSubstrates();

            if (Q.Length < n_substrate)
            {
                throw new exception(String.Format(
                                        "Q.Length < n_substrate: {0} < {1}!", Q.Length, n_substrate));
            }

            double[] Qsubstrates = new double[n_substrate];

            // volumeflow for substrates
            for (int isubstrate = 0; isubstrate < n_substrate; isubstrate++)
            {
                Qsubstrates[isubstrate] = Q[isubstrate];
            }

            //

            biogas.substrates substrates_or_sludge;

            //
            List <double> Q_s_or_s = new List <double>();

            // if no substrate is going into the fermenter we have to take the
            // TS from the digesters sludge going into this digester to calculate a
            // sludge. If there is substrate going into the digester we ignore
            // recirculation sludge, because the COD content inside the digester is
            // already influenced by the recirculated COD, so a high recirculation leads
            // to a reduction of the COD content inside the digester and then also to a
            // TS content reduction.
            if (math.sum(Qsubstrates) == 0)
            {
                substrates_or_sludge = new biogas.substrates();

                int ifermenter = 0;

                //

                for (int iflux = n_substrate; iflux < Q.Length; iflux++)
                {
                    string digester_id = myPlant.getDigesterID(ifermenter + 1);

                    double TS_digester = 0;

                    try
                    {
                        mySensors.getCurrentMeasurementD("TS_" + digester_id + "_3", out TS_digester);

                        if (TS_digester < double.Epsilon) // vermutlich wurde noch nicht gemessen?
                        {
                            TS_digester = 11;
                        }
                    }
                    catch // TODO: wann passiert das??, sollte eigentlich nicht passieren
                    {
                        TS_digester = 11;
                    }

                    substrates_or_sludge.addSubstrate(
                        new biogas.sludge(mySubstrates, math.ones(n_substrate), TS_digester));

                    ifermenter = ifermenter + 1;
                }

                //

                for (int isubstrate = n_substrate; isubstrate < Q.Length; isubstrate++)
                {
                    Q_s_or_s.Add(Q[isubstrate]);
                }
            }
            else
            {
                substrates_or_sludge = mySubstrates;

                for (int isubstrate = 0; isubstrate < Qsubstrates.Length; isubstrate++)
                {
                    Q_s_or_s.Add(Qsubstrates[isubstrate]);
                }
            }



            if (id.EndsWith("3")) // out sensor
            {
                // calc TS inside digester due to the substrates or the sludge if digester is not fed
                values[0] = biogas.digester.calcTS(x, substrates_or_sludge, Q_s_or_s.ToArray());
            }
            else if (id.EndsWith("2")) // in sensor
            {
                // TODO
                // ändern, da momentan entweder substrate oder sludge genommen wird und nicht beides
                // selbe Problem wie bei OLR_sensor denke ich
                substrates_or_sludge.get_weighted_mean_of(Q_s_or_s.ToArray(), "TS", out values[0]);

                values[0].Symbol = "TS";
            }
            else
            {
                throw new exception(String.Format("id of TS sensor not valid: {0}", id));
            }

            //

            values[0].Label = "total solids";

            return(values);
        }
Beispiel #23
0
        static void Main(string[] args)
        {
            physValue COD = biogas.chemistry.calcTOC("Xch");

            //physValueBounded mol_mass= new physValueBounded("Sac");

            //double a= 1;

            //physValueBounded c= a* mol_mass;

            fitness_params myparams = new fitness_params("fitness_params_geiger.xml");

            myparams.set_params_of("manurebonus", true);

            //double[] state= new double[37];

            //physValueBounded fostac= biogas.ADMstate.calcFOSTACOfADMstate(state);

            //physValue C;
            //physValue H;

            //physValue Hh2= biogas.chemistry.Hh2;

            //biogas.chemistry.get_CHONS_of("Sac_", out C, out H);

            //physValue ThODch= biogas.chemistry.calcTheoreticalOxygenDemand("Xch");

            //biogas.substrate.createMe();

            //double[] a= biogas.ADMstate.getDefaultADMstate(33);

            //double[] b= biogas.ADMstate.getDefaultADMstate(33);

            //a[33]= 10;
            //b[33]= 15;

            //double[,] c= new double[a.Length, 2];

            //for (int ii= 0; ii < a.Length; ii++)
            //{
            //  c[ii, 0]= a[ii];
            //  c[ii, 1]= b[ii];
            //}

            //double[] d= biogas.ADMstate.mixADMstreams(c);

            //biogas.substrate mySubstrate= new biogas.substrate("manure_cattle_1.xml");

            //mySubstrate.print();

            //mySubstrate= new biogas.substrate("wheat_silage_3.xml");

            //mySubstrate.print();

            substrates mySubstrates = new biogas.substrates("substrate_geiger.xml");

            mySubstrates.print();
            //mySubstrates.saveAsXML("test.xml");

            plant myPlant = new biogas.plant("plant_geiger.xml");
            //myPlant.saveAsXML("test_plant.xml");

            //double[] Q= {1,2,3,4,5,6,7};

            //myPlant.myDigesters.get("main").AD_Model.getParams(Q, mySubstrates);

            digester myDigester = myPlant.myDigesters.get(1);

            myDigester.calcHeatLossDueToRadiation(new physValue(40, "°C"));

            double[] Q           = { 15, 20, 0, 0, 0, 0, 0, 0, 0, 0 };
            double   QdigesterIn = 35;

            double[] ADMparams = myDigester.AD_Model.getParams(0, Q, QdigesterIn, mySubstrates);

            //double[] x= biogas.ADMstate.getDefaultADMstate();

//      double[] x= { 0.00890042014469482,
//0.00393026902393572,
//0.0898975418574202,
//0.0105303688871217,
//0.0188083338344299,
//0.0891872294599488,
//4.06518710070508,
//1.48197701713060e-06,
//0.0463395911897687,
//0.0137825768581825,
//0.231507824368968,
//3.42633334388719,
//8.90655977614532,
//0.129429796425159,
//0.0457772931408461,
//0.0271093313710146,
//3.81638964565446,
//0.988123176978798,
//0.410214653254316,
//0.633820130695941,
//0.537171143510719,
//1.81695029971744,
//0.992459517922010,
//8.07171990003056,
//19.9716874568380,
//0.000997039324889569,
//0.0155655622013352,
//0.0104958374141159,
//0.0187566838733815,
//0.0889172491178123,
//4.05462904506225,
//0.152623707143880,
//0.00590111878589172,
//8.13313521280990e-05,
//0.465153466604388,
//0.506049932143382,
//0.971284730099898
////8.05130545875131e-05,
////0.460473427139200,
////0.500958421870263,
////0.961512362064050
// };

            double[] x = { 0.00719913836418267,
                           0.00322799288019040,
                           0.0546025712168657,
                           0.0115793536955362,
                           0.0229074890746752,
                           0.0600482037552511,
                           0.463364086785563,
                           7.72721521995682e-08,
                           0.0469910866922296,
                           0.0479055807768373,
                           0.154317294840363,
                           -1.35975859128971e-47,
                           21.5301936374036,
                           0.750446550594154,
                           0.161739337648583,
                           0.0603411370260300,
                           4.96860324952978,
                           0.832215069627251,
                           0.222662822346057,
                           0.629071151058018,
                           0.547835241984119,
                           2.00168204821595,
                           1.05831074978528,
                           29.5159593610614,
                           1.79228974953266,
                           1.27233772322647e-52,
                           1.77592375955463e-55,
                           0.0115411203828431,
                           0.0228383440861995,
                           0.0598411508360539,
                           0.462166407598810,
                           0.2406363011183078,
                           0.00374878408176311,
                           4.31650348109949e-06,
                           0.476514182736779,
                           0.487815404290303,
                           0.964333903530564 };



            //biogas.sensors mySensors=
            //  new biogas.sensors(new biogas.VFA_TAC_sensor("1"));

            //physValue VFA_TAC= mySensors.getCurrentMeasurement("VFA_TAC_1", 2);

            //VFA_TAC= mySensors.measure(0, "VFA_TAC_1", 1, x);

            //VFA_TAC= mySensors.measure(2, "VFA_TAC_1", 1, x);

            biogas.sensors mySensors =
                new biogas.sensors(new biogas.TS_sensor("postdigester_3"));

            biogas.sensor_array mySensorArray = new biogas.sensor_array("Q");

            for (int isubstrate = 0; isubstrate < mySubstrates.getNumSubstrates(); isubstrate++)
            {
                mySensorArray.addSensor(new biogas.Q_sensor(mySubstrates.getID(isubstrate + 1)));
            }

            mySensorArray.addSensor(new biogas.Q_sensor("postdigester_digester"));

            mySensors.addSensorArray(mySensorArray);

            mySensors.addSensor(new biogas.substrate_sensor("cost"));

            mySensors.addSensor(new biogas.pumpEnergy_sensor("postdigester_digester"));

            mySensors.addSensor(new biogas.total_biogas_sensor("", myPlant));

            //physValue VFA_TACs= mySensors.measure(0, "VS_1", 1, new double[]{1,2}, mySubstrates);

            double[,] substrate_network = { { 1, 0 }, { 1, 0 }, { 1, 0 }, { 1, 0 }, { 1, 0 }, { 1, 0 } };

            double[,] plant_network = { { 0, 1, 0 }, { 1, 0, 1 } };

            double TS;

            //mySensors.measure(0, "TS_digester_3", 1, x,
            //          myPlant, mySubstrates, mySensors,
            //          substrate_network, plant_network, "digester", out TS);


            mySensors.measure(0, "substrate_cost", 0, mySubstrates, out TS);
            mySensors.measure(1, "substrate_cost", 0, mySubstrates, out TS);
            mySensors.measure(2, "substrate_cost", 0, mySubstrates, out TS);

            double energy;

            double[] pump = { 5 };

            mySensors.measure(0, "pumpEnergy_postdigester_digester", 0, myPlant, 10, pump, out energy);

            double[] data;

            mySensors.getMeasurementStream("substrate_cost", out data);

            double[] u = new double[6];
            u[0] = 10;
            u[1] = 100;
            u[2] = 100;
            u[3] = 20;
            u[4] = 200;
            u[5] = 200;

            mySensors.measureVec(0, "total_biogas_", 0, myPlant, u, "threshold", 5);

            physValue Qgas_h2;
            physValue Qgas_ch4;
            physValue Qgas_co2;

            physValue T = new physValue("T", 41.4, "°C");

            biogas.ADMstate.calcBiogasOfADMstate(x, new physValue(3000, "m^3"),
                                                 T, out Qgas_h2, out Qgas_ch4, out Qgas_co2);

            double ph = biogas.ADMstate.calcPHOfADMstate(x);

            substrate mySubstrate = mySubstrates.get("swinemanure");

            biogas.ADMstate.calcADMstream(mySubstrate, 30);

            double mypH = mySubstrate.get_param_of("pH");
        }
        /// <summary>
        /// ...
        ///
        /// type 8
        /// </summary>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="mySensors"></param>
        /// <param name="par">not used</param>
        /// <returns></returns>
        override protected physValue[] doMeasurement(biogas.plant myPlant,
                                                     biooptim.fitness_params myFitnessParams, biogas.sensors mySensors, params double[] par)
        {
            physValue[] values = new physValue[1];

            // Grenzwerte, welche ich mal auf einer Konferenz (vermutlich VDI Tagung) aufgeschnappt habe
            //
            // TAC &lt; 50 mmol/l              gefährlich
            // 50 &lt; TAC &lt; 100 mmol/l     gering Warnung
            // 100 &lt; TAC &lt; 250 mmol/l    OK

            // da mit tukey gearbeitet wird, kann der term auch etwas größer als 1 sein
            double TAC_fitness = sensors.calcFitnessDigester_min_max(myPlant, mySensors, "TAC",
                                                                     "min", myFitnessParams, "_3", true);

            values[0] = new physValue("TAC_fitness", TAC_fitness, "-");

            return(values);
        }
Beispiel #25
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);
        }
Beispiel #26
0
        /// <summary>
        /// ...
        ///
        /// type 8
        /// </summary>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="mySensors"></param>
        /// <param name="par">not used</param>
        /// <returns></returns>
        override protected physValue[] doMeasurement(biogas.plant myPlant,
                                                     biooptim.fitness_params myFitnessParams, biogas.sensors mySensors, params double[] par)
        {
            physValue[] values = new physValue[1];

            //

            // <param name="biogasExcess_fitness">lost money due to biogas excess [1000 €/d]</param>
            // <param name="biogasExcess">in excess produced biogas [m^3/d]</param>
            // <param name="lossBiogasExcess">lost money due to biogas excess [€/d]</param>

            physValue[] biogas_v = mySensors.getCurrentMeasurementVector("total_biogas_");

            //
            // excess biogas in [m^3/d]
            double biogasExcess;// = biogas_v[biogas_v.Length - 1].Value;

            //
            // Calculation of costs of substrate inflow
            // € / d
            double substrate_costs;

            mySensors.getCurrentMeasurementD("substrate_cost", out substrate_costs);


            // loss of excess methane prod. in €/d
            // if there is a loss, then positive value
            // if there is a gain, then negative value, should not be the case
            double lossBiogasExcess = calcLossDueToBiogasExcess(biogas_v, substrate_costs, myPlant,
                                                                myFitnessParams, out biogasExcess);

            // tausend € / d
            double biogasExcess_fitness = lossBiogasExcess / 1000;

            //

            values[0] = new physValue("biogasExcess_fitness", biogasExcess_fitness, "-");

            return(values);
        }
Beispiel #27
0
        /// <summary>
        /// ...
        ///
        /// type 8
        /// </summary>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="mySensors"></param>
        /// <param name="par">not used</param>
        /// <returns></returns>
        override protected physValue[] doMeasurement(biogas.plant myPlant,
                                                     biooptim.fitness_params myFitnessParams, biogas.sensors mySensors, params double[] par)
        {
            physValue[] values = new physValue[1];

            // TODO - was muss ich hier machen, damit sensor daten noisy aufzeichnet???
            bool noisy = false;

            // calc setpoint control error - errors of setpoint controls
            double diff_setpoints = calc_setpoint_errors(mySensors, myPlant, myFitnessParams, noisy);

            // wende tukey biweight an

            diff_setpoints = math.tukeybiweight(diff_setpoints);

            values[0] = new physValue("diff_setpoints", diff_setpoints, "-");

            return(values);
        }
        /// <summary>
        /// TODO - die ganze funktion ist noch nicht ausgegoren
        ///
        /// write measured variable at time t in given mySubstrate
        ///
        /// </summary>
        /// <param name="t">current simulation time</param>
        /// <param name="mySensors"></param>
        /// <param name="mySubstrate">changed in this call</param>
        public static void set_substrate_params_from_sensor(double t, biogas.sensors mySensors,
                                                            biogas.substrate mySubstrate)
        {
            string substrate_id = mySubstrate.id;

            substrateparams_sensor substrate_param_sensor =
                (substrateparams_sensor)mySensors.get("substrateparams_" + substrate_id);

            if (!substrate_param_sensor.isEmpty())
            {
                physValue[] measVec = substrate_param_sensor.getMeasurementVectorAt(t);

                // hier werden nur TS und VS geändert
                mySubstrate.set_params_of("TS", measVec[0],
                                                           // umrechung in % TS wird in c# bib gemacht (substrateparams_sensor)
                                                           // s.unten in doMeasurement methode
                                                           // this value measVec[1] is measured in % TS, this OK
                                          "VS", measVec[1],
                                          "pH", measVec[2] //,

                                                           /*"Sac", measVec[3],
                                                            * // umrechnung von g/l in mmol/l
                                                            * // g/l / 50 g/mol * 1000 m = 1000 / 50 mmol/l
                                                            * // TODO convertTo nutzen
                                                            * "TAC", measVec[4] * 1000 / 50, */
                                          /*"Snh4", measVec[5]*/);
                //'COD', measVec.Get(6));

                //mySubstrate.calc

                //if (mySubstrate.ismanure)
                //{
                //  mySubstrate.set_params_of("RF", measVec[6]);

                //  // TODO outcomment
                //  // measured in gCOD/l
                //  //mySubstrate.set_params_of("COD", measVec[7]);
                //  //mySubstrate.set_params_of("COD_S", 0.3 * measVec[7].Value);
                //}
                //else
                //{
                //  // TODO - delete
                //  //if (substrate_id == "bullmanure")
                //  //  throw new exception("AAAAAAAAAAAA");

                //  mySubstrate.set_params_of("RL", measVec[6], "RP", measVec[7],
                //                            "RF", measVec[8]);

                //  // measured in kgCOD/m^3, same as gCOD/l
                //  //physValue COD_c= biogas.substrate.calcXc(mySubstrate);//.convertUnit("gCOD/l");

                //  //// TODO
                //  //// 0.3

                //  //double COD_c2 = 0;

                //  //// TODO delete
                //  //if (substrate_id == "maize")    // für geiger kalibrierung
                //  //  COD_c2= COD_c.Value * 1.1;//5;
                //  //else
                //  //  COD_c2= COD_c.Value;

                //  //mySubstrate.set_params_of("COD", COD_c2);
                //  //mySubstrate.set_params_of("COD_S", 0.3 * COD_c2);

                //}
            }
        }
Beispiel #29
0
 /// <summary>
 /// Calculates the thermal energy balance of the digester. It compares
 /// thermal sinks (negative) with thermal sources (positive) inside the digester
 /// thermal sinks are:
 /// - heat substrates
 /// - radiation
 /// thermal sources are:
 /// - microbiology
 /// - stirrer dissipation
 /// </summary>
 /// <param name="digester_id">digester id</param>
 /// <param name="Q">substrate feed measured in m^3/d</param>
 /// <param name="mySubstrates"></param>
 /// <param name="mySensors"></param>
 /// <returns>thermal energy balance mesasured in kWh/d</returns>
 public double calcThermalEnergyBalance(string digester_id,
                                        double[] Q, substrates mySubstrates, sensors mySensors)
 {
     return(myDigesters.calcThermalEnergyBalance(digester_id, Q, mySubstrates, Tout, mySensors));
 }
        /// <summary>
        /// ...
        ///
        /// type 8
        /// </summary>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="mySensors"></param>
        /// <param name="par">not used</param>
        /// <returns></returns>
        override protected physValue[] doMeasurement(biogas.plant myPlant,
                                                     biooptim.fitness_params myFitnessParams, biogas.sensors mySensors, params double[] par)
        {
            physValue[] values = new physValue[1];

            // this is the fitness of the CH4 in the digester
            // da mit tukey gearbeitet wird, kann der term auch etwas größer als 1 sein
            double CH4_fitness;

            getBiogas_fitness(mySensors, out CH4_fitness);

            values[0] = new physValue("CH4_fitness", CH4_fitness, "-");

            return(values);
        }