/// <summary>
        /// Call measure of all type 8 sensors
        ///
        /// type 8
        ///
        /// used by fitness sensors
        /// </summary>
        /// <param name="time">current simulation time in days</param>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="par"></param>
        public void measure_type8(double time, //double deltatime,
                                  biogas.plant myPlant, biooptim.fitness_params myFitnessParams, double par)
        {
            double value;

            foreach (string id in ids_type8)
            {
                measure(time, id, myPlant, myFitnessParams, par, out value);
            }
        }
Exemplo n.º 2
0
        // -------------------------------------------------------------------------------------
        //                              !!! PRIVATE METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// Calc loss in €/d due to in excess produced biogas
        /// </summary>
        /// <param name="biogas_v">measured biogas vector gotten out of sensors</param>
        /// <param name="substrate_costs">costs for substrates in [€/d]</param>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="biogasExcess">in excess produced biogas [m^3/d]</param>
        /// <returns></returns>
        private static double calcLossDueToBiogasExcess(physValue[] biogas_v, double substrate_costs,
                                                        biogas.plant myPlant, biooptim.fitness_params myFitnessParams, out double biogasExcess)
        {
            double H2Concentration      = biogas_v[1].Value; // ppm
            double methaneConcentration = biogas_v[2].Value; // %
            double CO2Concentration     = biogas_v[3].Value; // %

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

            //

            double[] u = new double[3];

            // biogas excess in m³/d
            u[0] = biogasExcess * H2Concentration / 1000000;
            u[1] = biogasExcess * methaneConcentration / 100;
            u[2] = biogasExcess * CO2Concentration / 100;


            // €/d : get monetary value of in excess produced biogas. which amount of
            // money would we earn when we had sell the energy produced by the in excess
            // produced biogas?
            double valueMethaneExcess = calcValueOfMethaneExcess(u, myPlant, myFitnessParams);


            // m³/d : total biogas production
            double total_biogas_prod = biogas_v[0].Value;


            // costs of substrates needed to produce the excess methane amount in €/d
            double substrateCostsMethaneExcess =
                calcSubstrateCostsForMethaneExcess(biogasExcess, methaneConcentration,
                                                   substrate_costs, total_biogas_prod);


            // since complete substrate costs are already included in fitness function.
            // therefore we only may add the difference of the value of the methane and
            // the substrate costs needed to produce it. this value is always positive,
            // because methane is more worse then the substates needed to produce it.
            double lossBiogasExcess = valueMethaneExcess - substrateCostsMethaneExcess;

            //

            if (lossBiogasExcess < 0)
            {
                // TODO - throw error
                //error('loss: %f < 0, value: %f, costs: %f', ...
                //lossBiogasExcess, valueMethaneExcess, substrateCostsMethaneExcess);
                //throw new toolbox.exception(String.Format("lossBiogasExcess < 0: {0}", lossBiogasExcess));
            }

            return(lossBiogasExcess);
        }
Exemplo n.º 3
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];

            // fitness > 0 if pH value under or over boundaries
            double pHvalue_fitness = getpHvalue_fitness(mySensors, myPlant, myFitnessParams);

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

            return(values);
        }
Exemplo n.º 4
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];

            // 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);
        }
Exemplo n.º 5
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];

            // 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);
        }
Exemplo n.º 6
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];

            // 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);
        }
Exemplo n.º 7
0
        // -------------------------------------------------------------------------------------
        //                              !!! PUBLIC METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// Sell produced electrical and thermal energy.
        /// returns money we make by selling the energy in [€/d]
        /// </summary>
        /// <param name="energyProduction">electrical energy production in kWh/d</param>
        /// <param name="energyThermProduction">thermal energy production in kWh/d</param>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <returns></returns>
        public static double sellEnergy(double energyProduction, double energyThermProduction,
                                        biogas.plant myPlant, biooptim.fitness_params myFitnessParams)
        {
            // how much is paid for electrical energy production in €/kWh
            // sellCurrent measured in €/kWh
            double sellCurrent = myPlant.getVerguetung(energyProduction / 24, myFitnessParams.manurebonus);

            // energyProduction : produced electrical energy (power) [kWh/d]
            // energyThermProduction : produced thermal energy (power) [kWh/d]
            //
            // moneyEnergy is the money you get by selling electrical and thermal power
            // €/d = kWh/d * €/kWh
            double moneyEnergy = energyProduction * sellCurrent +
                                 energyThermProduction * myPlant.myFinances.revenueTherm.Value;

            return(moneyEnergy);
        }
        // -------------------------------------------------------------------------------------
        //                              !!! 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);
        }
Exemplo n.º 9
0
        // -------------------------------------------------------------------------------------
        //                            !!! 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);
        }
Exemplo n.º 10
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 [days]</param>
        /// <param name="deltatime">sample time of the sensor [days]</param>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <param name="mySensors"></param>
        /// <param name="par">some doubles</param>
        /// <returns>measured values</returns>
        public physValue[] measure(double time, double deltatime,
                                   biogas.plant myPlant, biooptim.fitness_params myFitnessParams,
                                   biogas.sensors mySensors, params double[] par)
        {
            physValue[] values;

            if (time - getCurrentTime() >= deltatime)
            {
                values = doMeasurement(myPlant, myFitnessParams, mySensors, par);

                addMeasurement(time, values);
            }
            else
            {
                values = getCurrentMeasurementVector();
            }

            return(values);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Calc monetary value of in excess produced methane in €/d
        /// </summary>
        /// <param name="u">u - 3dim vector of in excess produced biogas in m³/d
        /// h2, ch4, co2</param>
        /// <param name="myPlant"></param>
        /// <param name="myFitnessParams"></param>
        /// <returns></returns>
        private static double calcValueOfMethaneExcess(double[] u, biogas.plant myPlant,
                                                       biooptim.fitness_params myFitnessParams)
        {
            string bhkw_id = myPlant.getCHPID(1);

            // electrical and thermal energy produced by in excess produced biogas
            // measured in kWh/d
            double Pel_kWh_d, Ptherm_kWh_d;

            myPlant.burnBiogas(bhkw_id, u, out Pel_kWh_d, out Ptherm_kWh_d);

            //

            // €/d : get money that we would get by selling produced energy
            double valueMethaneExcess = sellEnergy(Pel_kWh_d, Ptherm_kWh_d,
                                                   myPlant, myFitnessParams);

            return(valueMethaneExcess);
        }
Exemplo n.º 12
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);
        }
Exemplo n.º 13
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];

            // 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);
        }
Exemplo n.º 14
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);
        }
Exemplo n.º 15
0
 /// <summary>
 /// used by all fitness sensors
 ///
 /// type 8
 /// </summary>
 /// <param name="myPlant"></param>
 /// <param name="myFitnessParams"></param>
 /// <param name="mySensors"></param>
 /// <param name="par">some doubles</param>
 /// <returns>measured values</returns>
 /// <exception cref="exception">Not implemented</exception>
 virtual protected physValue[] doMeasurement(biogas.plant myPlant,
                                             biooptim.fitness_params myFitnessParams, biogas.sensors mySensors, params double[] par)
 {
     throw new exception("Not implemented!");
 }