Exemplo n.º 1
0
        /// <summary>
        /// Calc mix of substrates for all digesters
        ///
        /// TODO: s. auch in funktion unten
        /// </summary>
        /// <param name="t">current simulation time in days</param>
        /// <param name="mySubstrates"></param>
        /// <param name="myPlant"></param>
        /// <param name="substrate_network"></param>
        /// <param name="mySensors"></param>
        /// <param name="Q">only used if datasource_type == extern</param>
        /// <param name="dilution_rates">double vector with the wanted dilution rates for each digester.
        /// Could be given by a dilution rate control. The size of the vector must
        /// be equal to number of digesters.</param>
        /// <returns>[34dim stream for digester1; 34dim stream for digester2; ...]</returns>
        public static double[] calcADMstreamMix(double t, biogas.substrates mySubstrates,
                                                biogas.plant myPlant, double[,] substrate_network,
                                                biogas.sensors mySensors, double[] Q, //double deltatime,
                                                double[] dilution_rates)
        {
            double[,] myStreams = new double[biogas.ADMstate._dim_stream, myPlant.getNumDigesters()];

            for (int idigester = 0; idigester < myPlant.getNumDigesters(); idigester++)
            {
                double Vliq = myPlant.getDigesterParam(idigester + 1, "Vliq");

                // D ist < 0, wenn Anlage nicht geregelt wird
                double D = dilution_rates[idigester];

                double Q_new = D * Vliq;

                myStreams = math.insertColumn(myStreams,
                                              calcADMstreamMixForDigester(t, mySubstrates, substrate_network, mySensors,
                                                                          idigester, Q, Q_new),
                                              0, idigester);

                // measure energy needed to transport substrates
                biogas.substrate_transport.run(t, mySensors,
                                               "substratemix", myPlant.getDigesterID(idigester + 1), myPlant, mySubstrates,
                                               substrate_network);
            }

            double[] myStream = math.concat(myStreams);

            return(myStream);
        }
Exemplo n.º 2
0
        /// <summary>
        /// calculates ADMstream mix of substrates for each digester
        /// and measures in the mix of all digesters together the COD SS and VS
        /// content.
        /// </summary>
        /// <param name="t">current simulation time in days</param>
        /// <param name="mySubstrates"></param>
        /// <param name="myPlant"></param>
        /// <param name="substrate_network"></param>
        /// <param name="mySensors"></param>
        /// <param name="dilution_rates">double vector with the wanted dilution rates for each digester.
        /// Could be given by a dilution rate control. The size of the vector must
        /// be equal to number of digesters.</param>
        /// <returns></returns>
        public static double[] calc_measureADMstreamMix(double t, biogas.substrates mySubstrates,
                                                        biogas.plant myPlant, double[,] substrate_network,
                                                        biogas.sensors mySensors, //double deltatime,
                                                        double[] dilution_rates)
        {
            double[] mystream = calcADMstreamMix(t, mySubstrates, myPlant, substrate_network,
                                                 mySensors, dilution_rates);

            //

            double[] mixed_stream = mixADMstreams(mystream);

            // measure COD SS and VS of mixed stream

            // TODO : evtl. von total_mix in substratemix umbenennen
            // muss dann auch überall anders gemacht werden. bsp: objectives und
            // sensors: create_sensor_network

            mySensors.measure(t, "SS_COD_total_mix_2", mixed_stream);

            mySensors.measure(t, "VS_COD_total_mix_2", mixed_stream);

            mySensors.measure(t, "Q_total_mix_2", mixed_stream);

            // messe VS in Substratzufuhr
            mySensors.measure(t, "VS_total_mix_2", mixed_stream, mySubstrates);

            return(mystream);
        }
Exemplo n.º 3
0
 /// <summary>
 /// called by TS sensor, OLR sensor, density sensor and heatConsumption_sensor
 ///
 /// type 7
 /// </summary>
 /// <param name="x">stream vector</param>
 /// <param name="myPlant"></param>
 /// <param name="mySubstrates"></param>
 /// <param name="mySensors"></param>
 /// <param name="Q">substrate feed and recirculation sludge going into the digester</param>
 /// <param name="par">some doubles</param>
 /// <returns>measured values</returns>
 /// <exception cref="exception">Not implemented</exception>
 virtual protected physValue[] doMeasurement(double[] x, biogas.plant myPlant,
                                             biogas.substrates mySubstrates,
                                             biogas.sensors mySensors,
                                             double[] Q, params double[] par)
 {
     throw new exception("Not implemented!");
 }
Exemplo n.º 4
0
        // -------------------------------------------------------------------------------------
        //                              !!! CONSTRUCTOR METHODS !!!
        // -------------------------------------------------------------------------------------



        // -------------------------------------------------------------------------------------
        //                              !!! PUBLIC METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// simulates all chps of the plant
        /// </summary>
        /// <param name="t"></param>
        /// <param name="u">
        /// number of digesters times n_gases dimensional vector
        /// with the biogas streams for each digester measured in m^3/d</param>
        /// <param name="mySensors"></param>
        /// <param name="myPlant"></param>
        /// <returns>
        /// produced electrical power for each chp in kW and the biogas excess in m³/d
        /// dimension: number of digesters + 1
        /// </returns>
        public static double[] run(double t, double[] u, //double deltatime,
                                   biogas.sensors mySensors, biogas.plant myPlant)
        {
            // TODO - Parameter aus plant bekommen
            string gas2chpsplittype = "threshold";

            return(run(t, u, mySensors, myPlant, gas2chpsplittype));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Do measurements which depend on plant and substrates and other measurements.
        ///
        /// 7th type
        ///
        /// example sensors:
        /// called by TS sensor
        /// OLR_sensor
        /// density_sensor
        /// </summary>
        /// <param name="time">current simulation time</param>
        /// <param name="id">id of sensor</param>
        /// <param name="x">could be statevector</param>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="mySensors"></param>
        /// <param name="Q">
        /// first values are Q for substrates, then pumped sludge going into digester
        /// </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, //double deltatime,
                                      double[] x, biogas.plant myPlant, biogas.substrates mySubstrates,
                                      biogas.sensors mySensors,
                                      double[] Q, params double[] par)
        {
            sensor mySensor = get(id);

            return(mySensor.measure(time, sampling_time, x, myPlant, mySubstrates, mySensors, Q, par));
        }
Exemplo n.º 6
0
        // -------------------------------------------------------------------------------------
        //                              !!! PUBLIC METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// Do measurements which depend on plant and substrates and other measurements.
        ///
        /// 7th type
        ///
        /// example sensors:
        /// called by TS sensor
        /// OLR_sensor
        /// density_sensor
        /// </summary>
        /// <param name="time">current simulation time</param>
        /// <param name="id">id of sensor</param>
        /// <param name="x">could be statevector</param>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="mySensors"></param>
        /// <param name="Q">could be substrate feed</param>
        /// <param name="value">first measured value</param>
        /// <exception cref="exception">Unknown sensor id</exception>
        public void measure(double time, string id, //double deltatime,
                            double[] x, biogas.plant myPlant, biogas.substrates mySubstrates,
                            biogas.sensors mySensors,
                            double[] Q, out double value)
        {
            physValue[] vals = measureVec(time, id, x, myPlant, mySubstrates, mySensors, Q);

            value = vals[0].Value;
        }
Exemplo n.º 7
0
        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="t">current simulation time in days</param>
        /// <param name="mySensors"></param>
        /// <param name="u">stream going into the pump measured in m^3/d</param>
        /// <param name="Q_pump">to be pumped amount in m^3/d</param>
        /// <param name="unit_start"></param>
        /// <param name="unit_destiny"></param>
        /// <param name="myPlant"></param>
        /// <returns></returns>
        public static double run(double t, //double deltatime,
                                 biogas.sensors mySensors, double u, double Q_pump,
                                 string unit_start, string unit_destiny,
                                 biogas.plant myPlant /*, biogas.substrates mySubstrates,
                                                       * double[,] substrate_network*/)
        {
            string pump_id = getid(unit_start, unit_destiny);

            // determine rho - default value for digester or storagetank
            //physValue density = new physValue("rho", 1000, "kg/m^3", "density");

            if (unit_start == "substratemix")
            {
                throw new exception("pumps may not pump the substratemix");

                // get mean rho out of substrates and double[] Q
                // nutze hier getSubstrateMixFlowForFermenter

                //double[] Q;

                // TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                // id_in_array einführen und durch "Q" ersetzen
                // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                //mySensors.getCurrentMeasurements("Q", "Q", mySubstrates, out Q);
                //getMeasurementsAt("Q", "Q", time, mySubstrates, out Q);

                // unit_destiny here must be a digester_id, because you cannot
                // pump substratemix directly into final storage tank
                //physValue[] Q_digester =
                //  sensors.getSubstrateMixFlowForFermenter(t, mySubstrates, myPlant,
                //                          mySensors, substrate_network, unit_destiny);

                //// values are Q for all substrates
                //double[] Q = physValue.getValues(Q_digester);

                //mySubstrates.get_weighted_mean_of(Q, "rho", out density);
            }


            // measure energy needed to pump stuff

            double P_kWh_d;

            // es ist wichtig, dass hier rho nicht mit übergeben wird
            // wird genutzt als erkennungsmerkmal in pumpEnergy_sensor
            // im unterschied zu substrate_transport
            double[] parvec = { Q_pump };//, density.Value };

            mySensors.measure(t, "pumpEnergy_" + pump_id,
                              myPlant, u, parvec, out P_kWh_d);

            // TODO - DEFINE WHAT SHOULD be returned
            //double[] retvals = { P_kWh_d, Q_pump };

            return(P_kWh_d);// retvals;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Do measurements which depend on plant and substrates and other measurements.
        ///
        /// 7th type
        ///
        /// example sensors:
        /// called by TS sensor
        /// OLR_sensor
        /// density_sensor
        /// </summary>
        /// <param name="time">current simulation time</param>
        /// <param name="id">id of sensor</param>
        /// <param name="x">could be statevector</param>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="mySensors"></param>
        /// <param name="Q">
        /// first values are Q for substrates, then pumped sludge going into digester
        /// dimension: always number of substrates + number of digesters
        /// </param>
        /// <returns>measured values</returns>
        /// <exception cref="exception">Unknown sensor id</exception>
        public physValue[] measureVec(double time, string id, //double deltatime,
                                      double[] x, biogas.plant myPlant, biogas.substrates mySubstrates,
                                      biogas.sensors mySensors,
                                      double[] Q)
        {
            double[] par = new double[1];

            return(measureVec(time, id, x, myPlant, mySubstrates, mySensors,
                              Q, par));
        }
Exemplo n.º 9
0
        // -------------------------------------------------------------------------------------
        //                              !!! PUBLIC METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// Check whether current substrate feed saved in sensors qualifies for the manure bonus
        ///
        /// </summary>
        /// <param name="mySubstrates"></param>
        /// <param name="mySensors"></param>
        /// <returns></returns>
        public static bool check_manurebonus(biogas.substrates mySubstrates, biogas.sensors mySensors)
        {
            double t = mySensors.getCurrentTime(); // get current time

            // get recorded substrate feeds in m³/d
            physValue[] Q = mySensors.getMeasurementsAt("Q", "Q", t, mySubstrates);

            double[] Qdbl = physValue.getValues(Q);

            return(check_manurebonus(mySubstrates, Qdbl));
        }
Exemplo n.º 10
0
        // -------------------------------------------------------------------------------------
        //                              !!! PUBLIC METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="t">current simulation time in days</param>
        /// <param name="mySensors"></param>
        /// <param name="unit_start"></param>
        /// <param name="unit_destiny"></param>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="substrate_network"></param>
        /// <returns></returns>
        public static double run(double t, //double deltatime,
                                 biogas.sensors mySensors,
                                 string unit_start, string unit_destiny,
                                 biogas.plant myPlant, biogas.substrates mySubstrates,
                                 double[,] substrate_network)
        {
            double Q_pump, Q_solids;

            return(run(t, mySensors, unit_start, unit_destiny,
                       myPlant, mySubstrates, substrate_network, out Q_pump, out Q_solids));
        }
Exemplo n.º 11
0
        /// <summary>
        /// Calc mix of substrates for all digesters
        ///
        /// Q is gotten out of sensor
        /// </summary>
        /// <param name="t">current simulation time in days</param>
        /// <param name="mySubstrates"></param>
        /// <param name="myPlant"></param>
        /// <param name="substrate_network"></param>
        /// <param name="mySensors"></param>
        /// <param name="dilution_rates">double vector with the wanted dilution rates for each digester.
        /// Could be given by a dilution rate control. The size of the vector must
        /// be equal to number of digesters.</param>
        /// <returns>a column vector with dimension equal to dim_stream * n_digester</returns>
        public static double[] calcADMstreamMix(double t, biogas.substrates mySubstrates,
                                                biogas.plant myPlant, double[,] substrate_network,
                                                biogas.sensors mySensors, //double deltatime,
                                                double[] dilution_rates)
        {
            double[] Q;

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

            return(calcADMstreamMix(t, mySubstrates, myPlant, substrate_network, mySensors,
                                    Q, dilution_rates));
        }
Exemplo n.º 12
0
        /// <summary>
        /// Do measurements which depend on plant and substrates and other measurements.
        ///
        /// 7th type
        ///
        /// example sensors:
        /// called by TS sensor
        /// OLR_sensor
        /// density_sensor
        /// </summary>
        /// <param name="time">current simulation time</param>
        /// <param name="id">id of sensor</param>
        /// <param name="x">could be statevector</param>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="mySensors"></param>
        /// <param name="substrate_network"></param>
        /// <param name="plant_network"></param>
        /// <param name="digester_id">digester ID</param>
        /// <param name="value">first measured value</param>
        /// <exception cref="exception">Unknown sensor id</exception>
        public void measure(double time, string id, //double deltatime,
                            double[] x, biogas.plant myPlant, biogas.substrates mySubstrates,
                            biogas.sensors mySensors,
                            double[,] substrate_network, double[,] plant_network,
                            string digester_id, out double value)
        {
            physValue[] vals = measureVec(time, id, x, myPlant,
                                          mySubstrates, mySensors,
                                          substrate_network, plant_network, digester_id);

            value = vals[0].Value;
        }
        /// <summary>
        /// Calculation of total thermal energy consumption
        ///
        /// returns thermal energy consumption of
        /// - heating
        /// - microbiology (production)
        /// - mixer (production)
        ///
        /// in kWh/d
        /// </summary>
        /// <param name="myPlant"></param>
        /// <param name="mySensors"></param>
        /// <param name="energyConsumptionHeat">thermal energy consumption of heat losses [kWh/d]</param>
        /// <param name="energyProdMixer">th. energy prod. of stirrer [kWh/d]</param>
        /// <param name="energyProdMicro">th. energy prod. by micros [kWh/d]</param>
        /// <returns></returns>
        private static double getThermalEnergyConsumption(biogas.plant myPlant, biogas.sensors mySensors,
                                                          out double energyConsumptionHeat,
                                                          out double energyProdMixer, out double energyProdMicro)
        {
            double energyConsumption = 0;

            energyConsumptionHeat = 0;
            energyProdMixer       = 0; // heat energy dissipated to digester in kWh/d
            energyProdMicro       = 0;

            //

            int n_digester = myPlant.getNumDigesters();

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

                biogas.digester myDigester = myPlant.getDigester(idigester + 1);

                // heating

                physValue[] heat_v = mySensors.getCurrentMeasurementVector("heatConsumption_" + digester_id);

                // inflow heating
                // thermal Energie welche benötigt wird um das Substrat aufzuheizen
                // \frac{kWh}{d}
                energyConsumptionHeat += heat_v[0].Value;

                // radiation loss energy
                // thermal Energie, welche die Heizungen benötigen um die
                // Wärmeverluste auszugleichen
                // \frac{kWh}{d}
                energyConsumptionHeat += heat_v[1].Value;

                // produced heat by bacteria in digester [kWh/d]
                // das ist eine thermische, keine elektrische energie
                energyProdMicro += heat_v[2].Value;

                // thermal energy production by stirrer through dissipation
                // \frac{kWh}{d}
                energyProdMixer += heat_v[3].Value;
            }

            // sum in kWh/d
            // Vorsicht: energy von bakterien wird als produktion nicht als verbrauch
            // angesehen, deshalb hier neg. VZ
            energyConsumption = energyConsumptionHeat - energyProdMicro - energyProdMixer;

            return(energyConsumption);
        }
Exemplo n.º 14
0
        /// <summary>
        /// run (emulate) the final storage tank
        /// just measures concentration of SS and VS COD in output
        /// stream as well as Q.
        /// </summary>
        /// <param name="t">current simulation time in days</param>
        /// <param name="x">ADM stream vector</param>
        /// <param name="mySensors"></param>
        public static void run(double t, double[] x, biogas.sensors mySensors /*,
                                                                               * double deltatime*/)
        {
            // measure COD SS and VS and Q of outlet stream

            mySensors.measure(t, "SS_COD_finalstorage_2", x);

            mySensors.measure(t, "VS_COD_finalstorage_2", x);

            mySensors.measure(t, "Q_finalstorage_2", x);

            // TODO - messen von volatile solids
            // TODO - substrate müsste noch als parameter übergeben werden
        }
Exemplo n.º 15
0
        /// <summary>
        /// Do measurements which depend on plant and substrates and other measurements.
        ///
        /// 7th type
        ///
        /// example sensors:
        /// called by TS sensor
        /// OLR_sensor
        /// density_sensor
        /// </summary>
        /// <param name="time">current simulation time</param>
        /// <param name="id">id of sensor</param>
        /// <param name="x">could be statevector</param>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="mySensors"></param>
        /// <param name="substrate_network"></param>
        /// <param name="plant_network"></param>
        /// <param name="digester_id">ID of digester</param>
        /// <returns>measured values</returns>
        /// <exception cref="exception">Unknown sensor id</exception>
        public physValue[] measureVec(double time, string id, //double deltatime,
                                      double[] x, biogas.plant myPlant, biogas.substrates mySubstrates,
                                      biogas.sensors mySensors,
                                      double[,] substrate_network, double[,] plant_network,
                                      string digester_id)
        {
            physValue[] pQ = getInputVolumeflowForFermenter(time, mySubstrates, myPlant, mySensors,
                                                            substrate_network, plant_network, digester_id);

            // first values are Q for substrates, then pumped sludge going into digester
            double[] Q = physValue.getValues(pQ);

            return(measureVec(time, id, x, myPlant, mySubstrates, mySensors, Q));
        }
Exemplo n.º 16
0
        // -------------------------------------------------------------------------------------
        //                              !!! PUBLIC METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="t">current simulation time in days</param>
        /// <param name="mySensors"></param>
        /// <param name="u">stream going into the pump measured in m^3/d</param>
        /// <param name="unit_start"></param>
        /// <param name="unit_destiny"></param>
        /// <param name="myPlant"></param>
        /// <param name="Q_pump">to be pumped amount in m^3/d</param>
        /// <returns></returns>
        public static double run(double t, //double deltatime,
                                 biogas.sensors mySensors, double u,
                                 string unit_start, string unit_destiny,
                                 biogas.plant myPlant, /*biogas.substrates mySubstrates,
                                                        * double[,] substrate_network,*/out double Q_pump)
        {
            string pump_id = getid(unit_start, unit_destiny);

            // determine Q
            //double Q_pump;      // to be pumped amount

            mySensors.getMeasurementAt("Q", "Q_" + pump_id, t, out Q_pump);

            return(run(t, mySensors, u, Q_pump, unit_start, unit_destiny,
                       myPlant));//, mySubstrates, substrate_network);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Do measurements which depend on substrate and sensors.
        ///
        /// 9th type
        ///
        /// example sensor:
        /// used by manurebonus sensor
        /// </summary>
        /// <param name="time">current simulation time [days]</param>
        /// <param name="deltatime">sample time of the sensor [days]</param>
        /// <param name="mySubstrates"></param>
        /// <param name="mySensors"></param>
        /// <param name="par">some doubles</param>
        /// <returns>measured values</returns>
        public physValue[] measure(double time, double deltatime,
                                   biogas.substrates mySubstrates,
                                   biogas.sensors mySensors, params double[] par)
        {
            physValue[] values;

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

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

            return(values);
        }
Exemplo n.º 18
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.º 19
0
        /// <summary>
        /// Call measure of all type 7 sensors
        ///
        /// type 7
        ///
        /// used by OLR, TS and density sensor
        /// </summary>
        /// <param name="time">current simulation time in days</param>
        /// <param name="x">stream vector usually 34 dim.</param>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="mySensors"></param>
        /// <param name="substrate_network"></param>
        /// <param name="plant_network"></param>
        /// <param name="digester_id">ID of digester</param>
        public void measure_type7(double time, //double deltatime,
                                  double[] x, biogas.plant myPlant, biogas.substrates mySubstrates,
                                  biogas.sensors mySensors,
                                  double[,] substrate_network, double[,] plant_network,
                                  string digester_id)
        {
            double value;

            foreach (string id in ids_type7)
            {
                // TODO weiterhin ein Problem, wenn 1. Dig: dig1 und zweiter digester
                // dummy_dig1 heißt, hatten wir nicht ohnehin definiert, dass digester
                // ID keinen Unterstrich haben darf? s. gui_plant??? dann wäre das hier ok.
                if (id.Contains("_" + digester_id))
                {
                    measure(time, id, x, myPlant, mySubstrates, mySensors,
                            substrate_network, plant_network, digester_id, out value);
                }
            }
        }
Exemplo n.º 20
0
        /// <summary>
        /// Calculates Ash content in digester
        /// </summary>
        /// <param name="x"></param>
        /// <param name="digester_id"></param>
        /// <param name="mySensors"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="Q"></param>
        /// <param name="myPlant"></param>
        /// <returns></returns>
        public static physValue calcAsh(double[] x, string digester_id, biogas.sensors mySensors, substrates mySubstrates, double[] Q,
                                        plant myPlant)
        {
            physValue ash_digester, ash_substrate;

            try
            {
                ash_digester = mySensors.getCurrentMeasurement("Ash_" + digester_id + "_3");
            }
            catch (exception e)
            {
                Console.WriteLine(e.Message);
                ash_digester = new physValue("ash_digester", 11, "% TS");
            }

            try
            {
                mySubstrates.get_weighted_mean_of(Q, "Ash", out ash_substrate);
            }
            catch (exception e)
            {
                ash_substrate = new physValue("ash_substrate", 0, "% FM");

                return(ash_digester);
            }

            double volume_substrate = math.sum(Q);              // m^3/d

            double volume_dig = myPlant.get_param_of_d("Vliq"); // m^3

            // TODO - achtung mit einheiten, mix von % TS und % FM
            ash_digester = ash_digester + volume_substrate / volume_dig * ash_substrate;

            ash_digester        = ash_digester.convertUnit("% TS");
            ash_digester.Symbol = "Ash";

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

        /// <summary>
        /// Calculation of total electrical energy consumption
        ///
        /// returns energy consumption of
        /// - pumps
        /// - mixer
        ///
        /// in kWh/d
        /// </summary>
        /// <param name="myPlant"></param>
        /// <param name="mySensors"></param>
        /// <param name="energyConsumptionPump">el. energy consumption of pumps [kWh/d]</param>
        /// <param name="energyConsumptionMixer">el. energy consumption of stirrer [kWh/d]</param>
        /// <returns></returns>
        private static double getElEnergyConsumption(biogas.plant myPlant, biogas.sensors mySensors,
                                                     out double energyConsumptionPump, out double energyConsumptionMixer)
        {
            double energyConsumption = 0;

            energyConsumptionPump  = 0;
            energyConsumptionMixer = 0;

            //

            int n_digester = myPlant.getNumDigesters();

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

                // Idee: zu energieverbrauch gehören auch Rührwerke, Rührwerksleistung soll
                // von TS im Fermenter abhängig sein.
                // folgende Formel:
                // Energieverbrauch [kWh/d] = V_fermenter * 1 kWh/(d * 100 m³) * TS [%]
                //
                // frei nach der Quelle:
                // Empfehlung für die Auswahl von Rührwerken...


                // mixer

                //double V_digester= myPlant.getDigesterParam(digester_id, "Vliq");

                //double TS= mySensors.getCurrentMeasurement("TS" + "_" + digester_id + "_3").Value;

                double Pel_mixer;

                physValue[] e_mixer = mySensors.getCurrentMeasurementVector("stirrer_" + digester_id);

                Pel_mixer = e_mixer[0].Value;

                energyConsumptionMixer += Pel_mixer;//V_digester / 100 * TS;
            }


            // pumps

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

                double pump_energy;

                mySensors.getCurrentMeasurementD("pumpEnergy_" + pump_id, out pump_energy);

                // pump energy per day
                // P(t) [kWh/d]
                energyConsumptionPump += pump_energy;
            }

            // substrate_transport

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

                double pump_energy;

                mySensors.getCurrentMeasurementD("pumpEnergy_" + substrate_transport_id, out pump_energy);

                // pump energy per day
                // P(t) [kWh/d]
                energyConsumptionPump += pump_energy;

                mySensors.getCurrentMeasurementD("transportEnergy_" + substrate_transport_id, out pump_energy);

                // pump energy per day
                // P(t) [kWh/d]
                energyConsumptionPump += pump_energy;
            }


            // sum in kWh/d
            // Vorsicht: energy von bakterien wird als produktion nicht als verbrauch
            // angesehen, deshalb hier neg. VZ
            energyConsumption = energyConsumptionPump + energyConsumptionMixer;

            return(energyConsumption);
        }
Exemplo n.º 22
0
        /// <summary>
        /// Calculates the ADM input mix for the given digester
        ///
        /// OK, s. oben: diese Funktion noch überladen, ohne Q, aber mit sensors
        /// dann wird Q aus sensor geholt, mit übergabe von t
        ///
        /// OK, ist drin: was ist mit substrate parameter, müsste auch hier rein, oder?
        /// </summary>
        /// <param name="t">current simulation time in days</param>
        /// <param name="mySubstrates"></param>
        /// <param name="substrate_network"></param>
        /// <param name="mySensors"></param>
        /// <param name="digester_index">0-based</param>
        /// <param name="Q">Q for each substrate for total plant</param>
        /// <param name="Q_new">wanted total substrate feed into digester, in m^3/d</param>
        public static double[] calcADMstreamMixForDigester(double t, biogas.substrates mySubstrates,
                                                           double[,] substrate_network, biogas.sensors mySensors, int digester_index, double[] Q,
                                                           double Q_new)
        {
            int isubstrate = 0;

            // normalize substrate_network
            double[,] norm_substrate_network = math.normalize(substrate_network, 1);

            //

            double[] substrate_network_digester =
                science.math.getcol(norm_substrate_network, digester_index);

            //
            // total feed into digester
            double myQ    = science.math.mtimes(substrate_network_digester, Q);
            double myQnew = myQ;

            //
            if (Q_new >= 0) // wenn es < 0 wäre, dann wäre der Fermenter nicht geregelt
            {
                myQnew = Q_new;
            }

            //

            double[,] myStreams = new double[biogas.ADMstate._dim_stream, mySubstrates.getNumSubstrates()];

            foreach (biogas.substrate mySubstrate in mySubstrates)
            {
                // change params of substrate
                biogas.substrateparams_sensor.set_substrate_params_from_sensor(t, mySensors,
                                                                               mySubstrate);

                // Q of substrate
                double Q_subs = Q[isubstrate] * substrate_network_digester[isubstrate];

                if (myQ > 0)
                {
                    Q_subs = Q_subs * myQnew / myQ;
                }

                // calc ADM stream out of substrate
                myStreams = math.insertColumn(myStreams, calcADMstream(mySubstrate, Q_subs), 0, isubstrate);

                isubstrate++;
            }

            return(mixADMstreams(myStreams));



            //if strcmp(substrate_name, 'futterkalk')

            //  % CO2 auf - Hco3/2 setzen
            //  % da durch zugabe von CaCO3 Co2 abgebaut wird und reagiert zu zweifacher
            //  % menge von Hco3 und Ca2+
            //  y_adm1xp(10)= -y_adm1xp(32) / 2;
            //  %y_adm1xp(26)= 0;

            //end
        }
Exemplo n.º 23
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!");
 }
Exemplo n.º 24
0
        /// <summary>
        /// Calculate fitness value of digester measurements which must be between min and/or max
        /// </summary>
        /// <param name="myPlant"></param>
        /// <param name="mySensors"></param>
        /// <param name="var_id">"pH", "TS", ...</param>
        /// <param name="min_max">"min", "max" or "min_max"</param>
        /// <param name="myFitnessParams"></param>
        /// <param name="append_var_id">"_2" or "_3"</param>
        /// <param name="use_tukey">if true, then tukey function is used, leads to
        /// that returned value can be > 1. if false, then the fitness value
        /// is between 0 and 1.</param>
        /// <returns></returns>
        public static double calcFitnessDigester_min_max(biogas.plant myPlant, biogas.sensors mySensors,
                                                         string var_id, string min_max, fitness_params myFitnessParams,
                                                         string append_var_id, bool use_tukey)
        {
            double fitness = 0;

            int n_digester = myPlant.getNumDigesters();

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

                double variable;

                mySensors.getCurrentMeasurementD(var_id + "_" + digester_id + append_var_id, out variable);

                //

                double punish_digester = 0;

                if ((min_max == "min") || (min_max == "min_max"))
                {
                    double min_bound = myFitnessParams.get_param_of(var_id + "_min", idigester);

                    if (!use_tukey)
                    {
                        punish_digester = Convert.ToDouble(variable < min_bound);
                    }
                    else
                    {
                        // if a boundary is violated then the penalty is at least 1, and bounded
                        // by tukey biweight rho function
                        // TODO : warum wollte ich das 1 + ... haben??? das macht die sache
                        // nicht stetig, was sehr schlecht ist für skalierung und auch
                        // für kriging
                        punish_digester = Convert.ToDouble(variable < min_bound) *
                                          (0 * 1 + math.tukeybiweight(variable - min_bound));
                    }
                }

                if ((min_max == "max") || (min_max == "min_max"))
                {
                    double max_bound = myFitnessParams.get_param_of(var_id + "_max", idigester);

                    if (!use_tukey)
                    {
                        punish_digester = Math.Max(punish_digester, Convert.ToDouble(variable > max_bound));
                    }
                    else
                    {
                        // if a boundary is violated then the penalty is at least 1, and bounded
                        // by tukey biweight rho function
                        // TODO : warum wollte ich das 1 + ... haben??? das macht die sache
                        // nicht stetig, was sehr schlecht ist für skalierung und auch
                        // für kriging
                        punish_digester = Math.Max(punish_digester, Convert.ToDouble(variable > max_bound) *
                                                   (0 * 1 + math.tukeybiweight(variable - max_bound)));
                    }
                }

                fitness += punish_digester;
            }

            // values between 0 and 1, but if tukey function used, then may also be > 1
            fitness = fitness / n_digester;

            return(fitness);
        }
Exemplo n.º 25
0
        /// <summary>
        /// simulates all chps of the plant
        /// </summary>
        /// <param name="t"></param>
        /// <param name="u">
        /// number of digesters times n_gases dimensional vector
        /// with the biogas streams for each digester measured in m^3/d</param>
        /// <param name="mySensors"></param>
        /// <param name="myPlant"></param>
        /// <param name="gas2chpsplittype">"threshold", "one2one", "fiftyfifty"</param>
        /// <returns>
        /// produced electrical power for each chp in kW and the biogas excess in m³/d
        /// dimension: number of chps + 1
        /// </returns>
        public static double[] run(double t, double[] u, //double deltatime,
                                   biogas.sensors mySensors, biogas.plant myPlant, string gas2chpsplittype)
        {
            //
            // total biogas production [m³/d]
            // total biogas production splitted into components [m³d]
            // biogas for each chp splitted into components
            // biogas excess [m³/d]
            double[] biogas_vec;

            try
            {
                // split biogas upon available chps
                mySensors.measureVec(t, "total_biogas_",
                                     myPlant, u, gas2chpsplittype, out biogas_vec);
            }
            catch (exception e)
            {
                biogas_vec = math.zeros(11);
                //throw(e);
            }

            //

            int num_chps = myPlant.getNumCHPs(); // number of digesters

            // 2dim vector, 1st value, produced electrical energy / day
            // 2nd value: produced thermal energy / day
            double[] P_kWh_d;

            // returned vector by this method
            // produced electrical power for each chp in kW and the biogas excess in m³/d
            // dimension: number of chps + 1
            double[] outvec = new double[num_chps + 1];

            //

            double[] Psum_el_th = new double[2];
            Psum_el_th[0] = 0;
            Psum_el_th[1] = 0;

            //

            for (int ichp = 0; ichp < num_chps; ichp++)
            {
                // biogas which is burned by chp ichp
                double[] biogas_chp;

                try
                {
                    // biogas which is burned by chp ichp
                    biogas_chp = math.getrows(biogas_vec,
                                              1 + (1 + ichp) * (int)biogas.BioGas.n_gases,
                                              1 + (2 + ichp) * (int)biogas.BioGas.n_gases - 1);
                }
                catch (exception e)
                {
                    biogas_chp = math.zeros(3);
                    //throw (e);
                }

                try
                {
                    // burn biogas in chp ichp
                    mySensors.measureVec(t, "energyProduction_" + myPlant.getCHPID(ichp + 1),
                                         myPlant, biogas_chp, out P_kWh_d);
                }
                catch (exception e)
                {
                    P_kWh_d = math.zeros(2);
                    //throw (e);
                }

                // electrical energy in kW
                outvec[ichp] = P_kWh_d[0] / 24; // convert from kWh/d -> kW

                Psum_el_th[0] += P_kWh_d[0];
                Psum_el_th[1] += P_kWh_d[1];
            }

            // insert biogas excess in m^3/d
            outvec[num_chps] = biogas_vec[biogas_vec.Length - 1];

            try
            {
                //
                // measure total energy production of plant in kWh/d
                mySensors.measureVec(t, "energyProdSum", Psum_el_th);
            }
            catch (exception e)
            {
                //throw(e);
            }

            //

            return(outvec);
        }
Exemplo n.º 26
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);
        }
Exemplo n.º 27
0
        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="t">current simulation time in days</param>
        /// <param name="mySensors"></param>
        /// <param name="unit_start"></param>
        /// <param name="unit_destiny"></param>
        /// <param name="myPlant"></param>
        /// <param name="mySubstrates"></param>
        /// <param name="substrate_network"></param>
        /// <param name="Q_pump">to be pumped amount in m^3/d</param>
        /// <param name="Q_solids">
        /// amount that can not be pumped because TS content is too high
        /// </param>
        /// <returns></returns>
        public static double run(double t, //double deltatime,
                                 biogas.sensors mySensors,
                                 string unit_start, string unit_destiny,
                                 biogas.plant myPlant, biogas.substrates mySubstrates,
                                 double[,] substrate_network, out double Q_pump, out double Q_solids)
        {
            string substrate_transport_id = getid(unit_start, unit_destiny);

            // determine rho - default value for digester or storagetank
            physValue density_liq = new physValue("rho", 1000, "kg/m^3", "density");
            physValue density_sol = new physValue("rho", 1000, "kg/m^3", "density");

            Q_pump   = 0;
            Q_solids = 0;

            //

            if (unit_start == "substratemix")
            {
                // get mean rho out of substrates and double[] Q
                // nutze hier getSubstrateMixFlowForFermenter

                //double[] Q;

                // TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                // id_in_array einführen und durch "Q" ersetzen
                // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                //mySensors.getCurrentMeasurements("Q", "Q", mySubstrates, out Q);
                //getMeasurementsAt("Q", "Q", time, mySubstrates, out Q);

                // unit_destiny here must be a digester_id, because you cannot
                // pump substratemix directly into final storage tank
                physValue[] Q_digester =
                    sensors.getSubstrateMixFlowForFermenter(t, mySubstrates, myPlant,
                                                            mySensors, substrate_network, unit_destiny);

                // values are Q for all substrates
                double[] Q = physValue.getValues(Q_digester);

                // an dieser Stelle muss man heraus finden, welche Elemente
                // von Q flüssig und welche fest sind, an Hand TS Gehalt bestimmen < 11 % FM

                biogas.substrates mySubsSol = new biogas.substrates();
                biogas.substrates mySubsLiq = new biogas.substrates();

                List <double> Q_liq_subs = new List <double>();
                List <double> Q_sol_subs = new List <double>();

                //

                for (int iel = 0; iel < Q.Length; iel++)
                {
                    double TS = mySubstrates.get_param_of(iel + 1, "TS");

                    if (TS < 11) // liquid substrate (pumpable)
                    {
                        mySubsLiq.addSubstrate(mySubstrates.get(iel + 1));
                        Q_liq_subs.Add(Q[iel]);
                    }
                    else
                    {
                        mySubsSol.addSubstrate(mySubstrates.get(iel + 1));
                        Q_sol_subs.Add(Q[iel]);
                    }
                }

                if (Q_liq_subs.Count > 0)
                {
                    double[] Q_liq_s_a = Q_liq_subs.ToArray();

                    Q_pump = math.sum(Q_liq_s_a);

                    //
                    mySubsLiq.get_weighted_mean_of(Q_liq_s_a, "rho", out density_liq);
                }

                if (Q_sol_subs.Count > 0)
                {
                    double[] Q_sol_s_a = Q_sol_subs.ToArray();

                    Q_solids = math.sum(Q_sol_s_a);

                    //
                    mySubsSol.get_weighted_mean_of(Q_sol_s_a, "rho", out density_sol);
                }
            }
            else
            {
                throw new exception("substrate_transport may only pump the substratemix");
            }


            // measure energy needed to pump stuff

            // dann als summe raus geben (solids + liquids)
            double P_kWh_d;

            // its important that we pass two arguments here
            // is used in energyPump_sensor to ditinguish between this call
            // the one from pump.cs
            double[] parvec = { Q_pump, density_liq.Value };

            mySensors.measure(t, "pumpEnergy_" + substrate_transport_id,
                              myPlant, Q_pump, parvec, out P_kWh_d);

            //

            double[] parv = { density_sol.Value };
            double   P_solids;

            mySensors.measure(t, "transportEnergy_" + substrate_transport_id,
                              myPlant, Q_solids, parv, out P_solids);

            P_kWh_d += P_solids;

            // TODO - DEFINE WHAT SHOULD be returned
            //double[] retvals = { P_kWh_d, Q_pump };

            return(P_kWh_d);// retvals;
        }