Ejemplo n.º 1
0
        /// <summary>
        /// Do measurements which depend on fitness_params.
        ///
        /// 8th type
        ///
        /// example sensor:
        /// used by all fitness sensors
        /// </summary>
        /// <param name="time">current simulation time</param>
        /// <param name="id">id of sensor</param>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="par">some doubles</param>
        /// <param name="value">first measured value</param>
        /// <exception cref="exception">Unknown sensor id</exception>
        public void measure(double time, string id, biogas.plant myPlant, //double deltatime,
                            biooptim.fitness_params myFitnessParams, double[] par, out double value)
        {
            physValue[] vals = measureVec(time, id, myPlant, myFitnessParams, par);

            value = vals[0].Value;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Do measurements which depend on fitness_params.
        ///
        /// 8th type
        ///
        /// example sensor:
        /// used by all fitness sensors
        /// </summary>
        /// <param name="time">current simulation time</param>
        /// <param name="id">id of sensor</param>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="par">some doubles</param>
        /// <returns>measured values</returns>
        /// <exception cref="exception">Unknown sensor id</exception>
        public physValue[] measureVec(double time, string id, biogas.plant myPlant, //double deltatime,
                                      biooptim.fitness_params myFitnessParams, params double[] par)
        {
            sensor mySensor = get(id);

            return(mySensor.measure(time, sampling_time, myPlant, myFitnessParams, this, par));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// calculate finale fitness vector, for so-optimization this is a vector with
        /// one element only
        /// </summary>
        /// <param name="myFitnessParams"></param>
        /// <param name="energyBalance"></param>
        /// <param name="fitness_constraints"></param>
        /// <param name="udot"></param>
        /// <returns>fitness vector</returns>
        private static double[] calcFitnessVector(fitness_params myFitnessParams,
                                                  double energyBalance, double fitness_constraints, double udot)
        {
            double[] fitness = new double[myFitnessParams.nObjectives];

            if (myFitnessParams.nObjectives == 1)
            {
                // TODO - der vorfaktor vor udot muss immer identisch sein zu dem
                // welcher in matlab genutzt wird
                fitness[0] = myFitnessParams.myWeights.w_money * energyBalance +
                             fitness_constraints + myFitnessParams.myWeights.w_udot * udot;
            }
            else if (myFitnessParams.nObjectives == 2)
            {
                fitness[0] = energyBalance; // 1000 €/d
                // TODO - der vorfaktor vor udot muss immer identisch sein zu dem
                // welcher in matlab genutzt wird
                fitness[1] = fitness_constraints + myFitnessParams.myWeights.w_udot * udot;
            }
            else if (myFitnessParams.nObjectives == 3)
            {
                fitness[0] = energyBalance; // 1000 €/d
                // TODO - der vorfaktor vor udot muss immer identisch sein zu dem
                // welcher in matlab genutzt wird
                fitness[1] = fitness_constraints;
                fitness[2] = myFitnessParams.myWeights.w_udot * udot;
            }
            else
            {
                throw new exception(String.Format("myFitnessParams.nObjectives == {0}", myFitnessParams.nObjectives));
            }

            return(fitness);
        }
Ejemplo n.º 4
0
        // -------------------------------------------------------------------------------------
        //                              !!! PRIVATE METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// Calc weighted sum of fitness values
        /// </summary>
        /// <param name="myFitnessParams"></param>
        /// <param name="SS_COD_fitness"></param>
        /// <param name="VS_COD_fitness"></param>
        /// <param name="pHvalue_fitness"></param>
        /// <param name="VFA_TAC_fitness"></param>
        /// <param name="TS_fitness"></param>
        /// <param name="VFA_fitness"></param>
        /// <param name="AcVsPro_fitness"></param>
        /// <param name="TAC_fitness"></param>
        /// <param name="OLR_fitness"></param>
        /// <param name="HRT_fitness"></param>
        /// <param name="N_fitness">NH3 and NH4 boundaries</param>
        /// <param name="CH4_fitness"></param>
        /// <param name="biogasExcess_fitness">wird in 1000 €/d Verlust gerechnet</param>
        /// <param name="Stability_punishment"></param>
        /// <param name="energyProd_fitness">is produced energy near max. producable energy</param>
        /// <param name="fitness_etaIE">
        /// fitness of removal capacity of intestinal enterococci: 0, ..., 1
        /// </param>
        /// <param name="fitness_etaFC">
        /// fitness of removal capacity of faecal coliforms: 0, ..., 1
        /// </param>
        /// <param name="diff_setpoints"></param>
        /// <returns></returns>
        private static double calcFitnessConstraints(fitness_params myFitnessParams,
                                                     double SS_COD_fitness, double VS_COD_fitness,
                                                     //double VS_COD_degradationRate,
                                                     double pHvalue_fitness, double VFA_TAC_fitness, double TS_fitness,
                                                     double VFA_fitness, double AcVsPro_fitness, double TAC_fitness, double OLR_fitness,
                                                     double HRT_fitness, double N_fitness, double CH4_fitness,
                                                     double biogasExcess_fitness, double Stability_punishment,
                                                     double energyProd_fitness, double fitness_etaIE, double fitness_etaFC,
                                                     double diff_setpoints)
        {
            // TODO
            // anstatt biogasExcess / 20000
            // prüfen ob biogasExcess > 10 % der max. zu verarbietenden Biogasmenge,
            // d.h. > 110 % produzierte biogasmenge isngesamt, dann mit 1 * gewicht
            // bestrafen

            double fitness_constraints =
                myFitnessParams.myWeights.w_CSB * (SS_COD_fitness + VS_COD_fitness) +
                // TODO macht der term sinn?
                //myFitnessParams.myWeights.w_CSB * 1 / 3 * Convert.ToDouble(VS_COD_degradationRate < 65) +
                myFitnessParams.myWeights.w_pH * pHvalue_fitness +
                myFitnessParams.myWeights.w_TS * TS_fitness +
                // TODO - falls einfluss zu stark, dann noch mit w_money multiplizieren
                myFitnessParams.myWeights.w_gasexc * biogasExcess_fitness +  // wegen finanziellem Verlust
                // und wegen Umweltbelastung, falls Biogas nicht ideal verbrennt, so oder so
                // es wird CO2 erzeugt, was vorher mit energieaufwand angebaut wurde
                // dieser term ist für umweltbelastung, einfach eine konstante -> 1
                // linearer anstieg mit biogasExcess_fitness ist ja schon oben, muss nicht doppelt
                // nicht > 0 machen, da matlab berechnung von excess gas komischerweise werte
                // ganz knapp über 0 zurück gibt auch wenn sie 0 sind. wo da der fehler
                // ist muss ich mal prüfen
                // TODO - da ich keine Sprünge mag habe ich das auskommentiert!!!
                //myFitnessParams.myWeights.w_gasexc * 1 / 2 * Convert.ToDouble(biogasExcess_fitness > 0.001) +
                myFitnessParams.myWeights.w_CH4 * CH4_fitness +
                myFitnessParams.myWeights.w_FOS_TAC * VFA_TAC_fitness +
                myFitnessParams.myWeights.w_VFA * VFA_fitness +
                myFitnessParams.myWeights.w_AcVsPro * AcVsPro_fitness +
                myFitnessParams.myWeights.w_TAC * TAC_fitness +
                myFitnessParams.myWeights.w_OLR * OLR_fitness +
                myFitnessParams.myWeights.w_HRT * HRT_fitness +
                myFitnessParams.myWeights.w_N * N_fitness +
                myFitnessParams.myWeights.w_energy * energyProd_fitness +
                Stability_punishment +
                myFitnessParams.myWeights.w_faecal * (fitness_etaIE + fitness_etaFC) +
                myFitnessParams.myWeights.w_setpoint * diff_setpoints;

            return(fitness_constraints);
        }
Ejemplo n.º 5
0
        // -------------------------------------------------------------------------------------
        //                              !!! PUBLIC METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// called by fitness_sensor in MATLAB
        /// </summary>
        /// <param name="time">current simulation time in days</param>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="par"></param>
        public void measure_optim_params(double time, biogas.plant myPlant,
                                         biooptim.fitness_params myFitnessParams, biogas.substrates mySubstrates, double par)
        {
            // measure substrate costs
            // Calculation of costs of substrate inflow
            // € / d
            double substrate_costs, manurebonus, udot;

            measure(time, "substrate_cost", mySubstrates, out substrate_costs);

            // measure whether current substrate feed qualifies for EEG2009 manure bonus
            measure(time, "manurebonus", mySubstrates, 0, out manurebonus);

            measure(time, "udot", mySubstrates, 0, out udot);

            // measure all other fitness sensors
            measure_type8(time, myPlant, myFitnessParams, par);
        }
Ejemplo n.º 6
0
        // -------------------------------------------------------------------------------------
        //                              !!! PUBLIC METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// get all objectives
        /// </summary>
        /// <param name="mySensors"></param>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="Stability_punishment"></param>
        /// <param name="energyBalance">cost - benefit [1000 €/d]</param>
        /// <param name="energyProd_fitness"></param>
        /// <param name="energyConsumption">total el. energy consumption [kWh/d]</param>
        /// <param name="energyThConsumptionHeat">thermal energy consumption [kWh/d]</param>
        /// <param name="energyConsumptionPump">el. energy consumption for pumps [kWh/d]</param>
        /// <param name="energyConsumptionMixer">el. energy consumption for mixer [kWh/d]</param>
        /// <param name="energyProdMicro">thermal energy prod. microbiology [kWh/d]</param>
        /// <param name="moneyEnergy">
        /// money I get for selling the produced total energy (el. + therm.) in €/d
        /// </param>
        /// <param name="fitness_constraints">sum of fitness functions</param>
        /// <param name="fitness">fitness vector</param>
        public static void getObjectives(biogas.sensors mySensors, biogas.plant myPlant,
                                         biogas.substrates mySubstrates, fitness_params myFitnessParams,
                                         /*out double SS_COD_fitness, out double VS_COD_fitness,*/
                                         /*out double SS_COD_degradationRate, out double VS_COD_degradationRate, */
                                         /*out double CH4_fitness, */ out double Stability_punishment,
                                         out double energyBalance, out double energyProd_fitness,
                                         out double energyConsumption, out double energyThConsumptionHeat,
                                         out double energyConsumptionPump, out double energyConsumptionMixer,
                                         out double energyProdMicro, /*out double energyThermProduction,
                                                                      * out double energyProduction,*/out double moneyEnergy,
                                         out double fitness_constraints, out double[] fitness)
        {
            double pHvalue_fitness, VFA_TAC_fitness, TS_fitness,
           VFA_fitness, AcVsPro_fitness, TAC_fitness, OLR_fitness, HRT_fitness, N_fitness,
           biogasExcess_fitness, diff_setpoints, CH4_fitness, SS_COD_fitness, VS_COD_fitness;

            //
            // normalized between 0 and 1
            mySensors.getCurrentMeasurementD("SS_COD_fit", out SS_COD_fitness);
            // normalized between 0 and 1
            mySensors.getCurrentMeasurementD("VS_COD_fit", out VS_COD_fitness);

            // fitness > 0 if pH value under or over boundaries
            // normalized between 0 and 1
            mySensors.getCurrentMeasurementD("pH_fit", out pHvalue_fitness);

            // da mit tukey gearbeitet wird, kann der term auch etwas größer als 1 sein
            mySensors.getCurrentMeasurementD("VFA_TAC_fit", out VFA_TAC_fitness);

            // this is the fitness of the TS in the digester
            // da mit tukey gearbeitet wird, kann der term auch etwas größer als 1 sein
            mySensors.getCurrentMeasurementD("TS_fit", out TS_fitness);

            // TODO
            // Calculation of TS concentration in inflow

            // gibt es auch schon in Individuum Überprüfung: nonlcon_substrate
            // braucht hier dann eigentlich nicht mehr gemacht werden

            // verhältnis von propionic acid to acetic acid
            // max. grenze bei 1.4, s. PhD für Quellen
            // hier ist der Kehrwert, also min grenze, hier wird mit tukey gearbeitet
            mySensors.getCurrentMeasurementD("AcVsPro_fit", out AcVsPro_fitness);


            // da mit tukey gearbeitet wird, kann der term auch etwas größer als 1 sein
            mySensors.getCurrentMeasurementD("VFA_fit", out VFA_fitness);

            // tukey
            mySensors.getCurrentMeasurementD("TAC_fit", out TAC_fitness);
            // tukey
            mySensors.getCurrentMeasurementD("OLR_fit", out OLR_fitness);

            // da mit tukey gearbeitet wird, kann der term auch etwas größer als 1 sein
            mySensors.getCurrentMeasurementD("HRT_fit", out HRT_fitness);

            // sum of Snh4 + Snh3, mit tukey
            mySensors.getCurrentMeasurementD("N_fit", out N_fitness);


            // CH4 > 50 % als tukey implementiert
            mySensors.getCurrentMeasurementD("CH4_fit", out CH4_fitness);

            // biogasExcess_fitness is lossbiogasExcess / 1000
            // measured in tausend € / d
            mySensors.getCurrentMeasurementD("gasexcess_fit", out biogasExcess_fitness);


            // TODO
            //
            // calculate OLR and HRT of plant



            // TODO - ich könnte auch faecal_fit_sensor schreiben
            // faecal bacteria removal capacity
            // intestinal enterococci
            // faecal coliforms
            double etaIE = 0, etaFC = 0;

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

                etaIE += mySensors.getCurrentMeasurementDind("faecal_" + digesterID, 0);
                etaFC += mySensors.getCurrentMeasurementDind("faecal_" + digesterID, 1);
            }

            if (myPlant.getNumDigesters() > 0)
            {
                etaIE /= myPlant.getNumDigesters();
                etaFC /= myPlant.getNumDigesters();
            }

            // TODO - als ausgabeargumente definieren - nö
            double fitness_etaIE, fitness_etaFC;

            // wird in 100 % gemessen
            fitness_etaIE = 1.0f - etaIE / 100.0f;
            fitness_etaFC = 1.0f - etaFC / 100.0f;



            // TODO
            // stability

            //stateIsStable(1:n_fermenter,1)= 0;

            //for ifermenter= 1:n_fermenter

            //  %digester_id= char( plant.getDigesterID(ifermenter) );

            //  %% TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

            //  stateIsStable(ifermenter,1)= 1;%...
            //      %getStateIsStable(measurements, digester_id, plant);

            //end

            //% d.h instabil?
            //if any(stateIsStable == 0)
            //    Stability_punishment= 1;
            //else
            //    Stability_punishment= 0;
            //end


            Stability_punishment = 0; // TODO


            //
            double mbonus;

            mySensors.getCurrentMeasurementD("manurebonus", out mbonus);
            myFitnessParams.manurebonus = Convert.ToBoolean(mbonus);

            //

            energyConsumption = getElEnergyConsumption(myPlant, mySensors,
                                                       out energyConsumptionPump, out energyConsumptionMixer);

            //
            double energyThProdMixer;

            double energyThConsumption = getThermalEnergyConsumption(myPlant, mySensors,
                                                                     out energyThConsumptionHeat, out energyThProdMixer, out energyProdMicro);

            // TODO: einheiten nicht sauber
            // costs for heating in €/d
            //
            // kosten für heizung werden direkt in geld umgerechnet
            // wenn thermisch produzierte wärme zum heizen des fermenters benutzt wird,
            // dann werden hier virtuelle kosten berechnet mit kosten revenueTherm,
            // welche unten bei sellEnergy wieder als erlös mit dem gleichen Wert
            // berechnet werden, d.h. +/- das gleiche.
            //
            double costs_heating       = myPlant.calcCostsForHeating_Total(
                new physValue(energyThConsumption, "kWh/d"),
                myPlant.myFinances.revenueTherm.Value, myPlant.myFinances.priceElEnergy.Value);

            //

            // total el. energy production in kWh/d
            double energyProduction = mySensors.getCurrentMeasurementDind("energyProdSum", 0);
            // total thermal energy production in kWh/d
            double energyThermProduction = mySensors.getCurrentMeasurementDind("energyProdSum", 1);

            //energyProduction= getEnergyProduction(myPlant, mySensors, out energyThermProduction);

            //

            double energyProductionMax = getMaxElEnergyProduction(myPlant);

            // measured in 100 %
            energyProd_fitness = (1 - energyProduction / energyProductionMax);

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

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


            //

            double udot;

            mySensors.getCurrentMeasurementD("udot", out udot);

            //

            // TODO
            // was ist wenn wir weniger thermische energie im BHKW erzeugen als wir verbrauchen?
            // dann ist costs_heating (virt. kosten) > moneyEnergy thermisch (verkauf von thermischer Energie)
            // die differenz muss dann elektrisch erzeugt werden, wird allerdings nicht gemacht.
            // die differenz wird aktuell alas virtuelle Kosten verbucht (Verlust den man hat da man nicht wärme verkauft)
            // und nicht als reale kosten (erzeugungskosten: thermische energie erzeugt durch heizung)
            // um das zu lösen, warum ruft man nicht berechnung von costs_heating nach berechnung
            // von energyThermProduction auf und übergibt dann differenz zw. energyThConsumption und
            // energyThermProduction?

            //
            // TODO - was ist wenn die produzierte elektrische energie von niemanden abgenommen wird
            // das ist der fall, wenn nach sollwert gefahren wird, dann wird nur so viel energie bezahlt
            // wie nach sollwert verlangt wurde, das geht so ab eeg 2012 - direktvermarktung

            // must be in kWh/d
            double energyElSold = 0; // electrical energy that would be sold

            // dann gibt es eine referenz kurve welche angibt wieviel energie verkauft würde wenn sie produziert
            // würde, hier nur elektrische energie
            if (mySensors.exist("ref_energy_sold"))
            {
                // wichtig, dass man sich die messung zur aktuellen zeit holt, da
                // ref_energy_sold eine referenz vorgibt
                double time = mySensors.getCurrentTime();

                energyElSold = mySensors.getMeasurementDAt("ref_energy_sold", "", time, 0, false);

                energyElSold = Math.Min(energyElSold, energyProduction);
            }
            else
            {
                energyElSold = energyProduction;
            }

            // moneyEnergy : €/d
            moneyEnergy = biogas.gasexcess_fit_sensor.sellEnergy(energyElSold, energyThermProduction,
                                                                 myPlant, myFitnessParams);

            // € / d
            // is negative when we make more money as we have to pay
            energyBalance = energyConsumption * myPlant.myFinances.priceElEnergy.Value
                            + costs_heating - moneyEnergy + substrate_costs;

            // tausend € / d
            energyBalance = energyBalance / 1000;

            //
            // TODO
            bool noisy = false;

            // calc setpoint control error
            //diff_setpoints = calc_setpoint_errors(mySensors, myPlant, myFitnessParams, noisy);
            mySensors.getCurrentMeasurementD("setpoint_fit", noisy, out diff_setpoints);

            // calc total fitness of all the constraints

            fitness_constraints = calcFitnessConstraints(myFitnessParams, SS_COD_fitness,
                                                         VS_COD_fitness, /*VS_COD_degradationRate,*/ pHvalue_fitness, VFA_TAC_fitness,
                                                         TS_fitness, VFA_fitness, AcVsPro_fitness, TAC_fitness, OLR_fitness, HRT_fitness, N_fitness,
                                                         CH4_fitness, biogasExcess_fitness, Stability_punishment, energyProd_fitness,
                                                         fitness_etaIE, fitness_etaFC, diff_setpoints);


            // calc fitness vector
            fitness = calcFitnessVector(myFitnessParams, energyBalance, fitness_constraints, udot);
        }
Ejemplo n.º 7
0
        // -------------------------------------------------------------------------------------
        //                              !!! PUBLIC METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// Do measurements which depend on fitness_params.
        ///
        /// 8th type
        ///
        /// example sensor:
        /// used by all fitness sensors
        /// </summary>
        /// <param name="time">current simulation time</param>
        /// <param name="id">id of sensor</param>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="par">some double</param>
        /// <param name="value">first measured value</param>
        /// <exception cref="exception">Unknown sensor id</exception>
        public void measure(double time, string id, biogas.plant myPlant, //double deltatime,
                            biooptim.fitness_params myFitnessParams, double par, out double value)
        {
            double[] parvec = { par };
            measure(time, id, myPlant, myFitnessParams, parvec, out value);
        }