Esempio n. 1
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);
        }
Esempio n. 2
0
        /// <summary>
        /// Create network of sensors, which are inside the simulation model
        /// </summary>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="plant_network"></param>
        /// <param name="plant_network_max"></param>
        /// <returns>
        /// sensors object containing all sensor and sensor_array objects inside the simulation model
        /// </returns>
        /// <exception cref="exception">Unknown sensor array id</exception>
        public static sensors create_sensor_network(plant myPlant, substrates mySubstrates,
                                                    double[,] plant_network, double[,] plant_network_max)
        {
            sensors mySensors = new sensors();

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

                //

                mySensors.addSensor(new biogas.VFA_TAC_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.aceto_hydro_sensor(digester_id));

                mySensors.addSensor(new biogas.AcVsPro_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.HRT_sensor(digester_id));

                mySensors.addSensor(new biogas.faecal_sensor(digester_id));

                mySensors.addSensor(new biogas.inhibition_sensor(digester_id));

                mySensors.addSensor(new biogas.energyProdMicro_sensor(digester_id));

                mySensors.addSensor(new biogas.biogas_sensor(digester_id));

                mySensors.addSensor(new biogas.VFA_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.VFA_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.VFAmatrix_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.VFAmatrix_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.Sva_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.Sva_sensor(digester_id + "_3"));
                mySensors.addSensor(new biogas.Sbu_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.Sbu_sensor(digester_id + "_3"));
                mySensors.addSensor(new biogas.Spro_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.Spro_sensor(digester_id + "_3"));
                mySensors.addSensor(new biogas.Sac_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.Sac_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.VS_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.VS_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.Q_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.Q_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.NH3_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.NH3_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.NH4_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.NH4_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.Norg_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.Norg_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.TKN_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.TKN_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.Ntot_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.Ntot_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.pH_stream_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.pH_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.biomassAciAce_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.biomassMeth_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.TAC_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.TAC_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.SS_COD_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.SS_COD_sensor(digester_id + "_3"));

                mySensors.addSensor(new biogas.VS_COD_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.VS_COD_sensor(digester_id + "_3"));

                // heating
                mySensors.addSensor(new biogas.heatConsumption_sensor(digester_id));

                // stirrers - all stirrer in the digester
                mySensors.addSensor(new biogas.stirrer_sensor(digester_id));

                //

                mySensors.addSensor(new biogas.TS_sensor(digester_id + "_2")); // TS messung des Fermenterinputs
                mySensors.addSensor(new biogas.TS_sensor(digester_id + "_3")); // TS im fermenter

                mySensors.addSensor(new biogas.OLR_sensor(digester_id));

                // measures density of sludge inside the digester
                mySensors.addSensor(new biogas.density_sensor(digester_id));

                //

                mySensors.addSensor(new biogas.ADMstate_sensor(digester_id));

                mySensors.addSensor(new biogas.ADMstream_sensor(digester_id + "_2"));
                mySensors.addSensor(new biogas.ADMstream_sensor(digester_id + "_3"));

                //

                mySensors.addSensor(new biogas.ADMintvars_sensor(digester_id));

                mySensors.addSensor(new biogas.ADMparams_sensor(digester_id));
            }

            //

            mySensors.addSensor(new biogas.SS_COD_sensor("finalstorage_2"));
            mySensors.addSensor(new biogas.VS_COD_sensor("finalstorage_2"));
            mySensors.addSensor(new biogas.Q_sensor("finalstorage_2"));

            mySensors.addSensor(new biogas.SS_COD_sensor("total_mix_2"));
            mySensors.addSensor(new biogas.VS_COD_sensor("total_mix_2"));
            mySensors.addSensor(new biogas.Q_sensor("total_mix_2"));
            mySensors.addSensor(new biogas.VS_sensor("total_mix_2"));

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

            // fitness sensors

            mySensors.addSensor(new biogas.fitness_sensor());

            mySensors.addSensor(new biogas.AcVsPro_fit_sensor());
            mySensors.addSensor(new biogas.VFA_fit_sensor());
            mySensors.addSensor(new biogas.VFA_TAC_fit_sensor());
            mySensors.addSensor(new biogas.TS_fit_sensor());
            mySensors.addSensor(new biogas.pH_fit_sensor());
            mySensors.addSensor(new biogas.OLR_fit_sensor());
            mySensors.addSensor(new biogas.TAC_fit_sensor());
            mySensors.addSensor(new biogas.HRT_fit_sensor());
            mySensors.addSensor(new biogas.N_fit_sensor());
            mySensors.addSensor(new biogas.CH4_fit_sensor());
            mySensors.addSensor(new biogas.SS_COD_fit_sensor());
            mySensors.addSensor(new biogas.VS_COD_fit_sensor());
            mySensors.addSensor(new biogas.gasexcess_fit_sensor());
            mySensors.addSensor(new biogas.setpoint_fit_sensor());
            mySensors.addSensor(new biogas.manurebonus_sensor());
            mySensors.addSensor(new biogas.udot_sensor());

            //

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

            //

            mySensors.addSensorArray(new biogas.sensor_array("Q"));

            for (int isubstrate = 0; isubstrate < mySubstrates.getNumSubstrates(); isubstrate++)
            {
                try
                {
                    mySensors.getArray("Q").addSensor(new biogas.Q_sensor(mySubstrates.getID(isubstrate + 1)));
                }
                catch (exception e)
                {
                    Console.WriteLine("Could not add Q_sensor to substrate array!");
                    throw (e);
                }

                mySensors.addSensor(new biogas.substrateparams_sensor(mySubstrates.getID(isubstrate + 1)));
            }

            //


            // nº of Columms -> Inputs to the fermenter
            for (int ifermenterIn = 0; ifermenterIn < myPlant.getNumDigesters() + 1; ifermenterIn++)
            {
                // nº of Rows -> Outputs to the fermenter
                for (int ifermenterOut = 0; ifermenterOut < myPlant.getNumDigesters(); ifermenterOut++)
                {
                    // TODO - es gibt bestimmt auch eine funktion in matlab, welche diese schleife
                    // schon implementiert hat als funktion
                    // Connection condition within fermenters
                    if ((plant_network[ifermenterOut, ifermenterIn] > 0) &&
                        (plant_network_max[ifermenterOut, ifermenterIn] < Double.PositiveInfinity))
                    {
                        //
                        // Fermenter Name for Input
                        String fermenter_id_in = myPlant.getDigesterID(ifermenterIn + 1);
                        // Fermenter Name for Output
                        String fermenter_id_out = myPlant.getDigesterID(ifermenterOut + 1);

                        //

                        mySensors.getArray("Q").addSensor(
                            new biogas.Q_sensor(fermenter_id_out + "_" + fermenter_id_in));
                    }
                }
            }

            //

            for (int ibhkw = 0; ibhkw < myPlant.getNumCHPs(); ibhkw++)
            {
                String bhkw_id = myPlant.getCHPID(ibhkw + 1);

                mySensors.addSensor(new biogas.energyProduction_sensor(bhkw_id));
            }

            //

            mySensors.addSensor(new biogas.energyProdSum_sensor());

            //

            // TODO - könnte man evtl. auch in transportation rein schieben

            for (int ipump = 0; ipump < myPlant.getNumPumps(); ipump++)
            {
                String pump_id = myPlant.getPumpID(ipump + 1);

                mySensors.addSensor(new biogas.pumpEnergy_sensor(pump_id));
            }

            //

            for (int isubstrate_transport = 0;
                 isubstrate_transport < myPlant.getNumSubstrateTransports();
                 isubstrate_transport++)
            {
                String substrate_transport_id = myPlant.getSubstrateTransportID(isubstrate_transport + 1);

                // for liquid substrates
                mySensors.addSensor(new biogas.pumpEnergy_sensor(substrate_transport_id));

                // for non-liquid substrates
                mySensors.addSensor(new biogas.transportEnergy_sensor(substrate_transport_id));
            }

            //



            //

            return(mySensors);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="myPlant"></param>
        /// <param name="u">contains (h2, ch4, co2)_digester_1, (h2, ch4, co2)_digester_2</param>
        /// <param name="gas2bhkwsplittype">fiftyfifty, one2one, threshold</param>
        /// <param name="par"></param>
        /// <returns></returns>
        override protected physValue[] doMeasurement(biogas.plant myPlant,
                                                     double[] u, string gas2bhkwsplittype,
                                                     params double[] par)
        {
            // contains:
            // total biogas production [m³/d]
            // total biogas production splitted into components [m³d]
            // biogas for each chp splitted into components
            // biogas excess [m³/d]
            physValue[] values = new physValue[dimension];

            // TODO
            //Console.WriteLine(dimension);

            int n_digester = myPlant.getNumDigesters();
            int n_chp      = myPlant.getNumCHPs();
            int n_gases    = (int)BioGas.n_gases;

            // u contains (h2, ch4, co2)_digester_1, (h2, ch4, co2)_digester_2, ...

            // TODO - scheint mir ok zu sein, kann das nicht erkennen.
            // ch4 must be the second element due to implementation below
            //
            // ch4 is the second element
            int index_ch4 = BioGas.pos_ch4 - 1;

            // total biogas in m^3/d (h2, ch4, co2)
            double[] biogas_total = BioGas.merge_streams(u, n_digester);

            // total biogas production in m³/d, sum of biogas_total
            double total_biogas_total;

            // percentual biogas prdocution on the plant (h2 %, ch4 %, co2 %)
            double[] biogas_total_perc = BioGas.calcRelContent(biogas_total, out total_biogas_total);

            //

            double[] gas_out = new double[n_gases * n_chp];

            //

            switch (gas2bhkwsplittype)
            {
            case "fiftyfifty":

                gas_out = math.repmat(math.rdivide(biogas_total, n_chp), n_chp);

                break;

            case "one2one":

                if (n_chp == n_digester)
                {
                    gas_out = u;
                }
                else
                {
                    throw new exception(String.Format("n_chp != n_digester: {0} != {1}!",
                                                      n_chp, n_digester));
                }

                break;

            case "threshold":

                double gas_max;

                for (int ichp = 0; ichp < n_chp; ichp++)
                {
                    if (biogas_total[index_ch4] > 0)
                    {
                        // in gas_max is the maximal amount of methane in m^3/d which
                        // can be handled by the indexed bhkw
                        myPlant.getCHP(ichp + 1).getMaxMethaneConsumption(out gas_max);

                        // available methane content
                        double methan = Math.Min(biogas_total[index_ch4], gas_max);

                        for (int igas = 0; igas < n_gases; igas++)
                        {
                            // get the fraction out of the biogas
                            gas_out[igas + ichp * n_gases] =
                                methan / biogas_total[index_ch4] * biogas_total[igas];
                        }

                        // decrease biogas amount
                        for (int igas = 0; igas < n_gases; igas++)
                        {
                            biogas_total[igas] -= gas_out[igas + ichp * n_gases];
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                //

                break;

            default:
                throw new exception(String.Format(
                                        "Unknown gas2bhkwsplittype: {0}!", id_suffix));
            }

            // too much biogas produced [m^3/d], sum of the three parts
            double gas_excess = Math.Max(total_biogas_total - math.sum(gas_out), 0);

            //

            values[0] = new physValue("biogas_t", total_biogas_total, "m^3/d", "total biogas");

            //

            physValue[] values_rel = BioGas.convert(biogas_total_perc);

            for (int igas = 0; igas < n_gases; igas++)
            {
                values[igas + 1] = values_rel[igas];
            }

            //

            for (int igas = 0; igas < n_gases; igas++)
            {
                for (int ichp = 0; ichp < n_chp; ichp++)
                {
                    values[igas + ichp * n_gases + 1 + n_gases] =
                        new physValue(BioGas.symGases[igas] + "_" + myPlant.getCHPID(ichp + 1),
                                      gas_out[igas + ichp * n_gases], "m^3/d",
                                      BioGas.labelGases[igas]);
                }
            }

            values[values.Length - 1] = new physValue("biogas_excess", gas_excess, "m^3/d", "excess biogas");

            //

            return(values);
        }