// -------------------------------------------------------------------------------------
        //                              !!! PRIVATE METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// Calculates the volumeflow of each substrate going into the given digester digester_id.
        /// The substrate flows are returned as a vector.
        ///
        /// TODO: ist nicht mehr private
        /// </summary>
        /// <param name="t">current simulation time</param>
        /// <param name="mySubstrates"></param>
        /// <param name="myPlant"></param>
        /// <param name="mySensors"></param>
        /// <param name="substrate_network"></param>
        /// <param name="digester_id">id of the digester which is fed</param>
        /// <returns>
        /// always a vector with as many elements as there are substrates on the plant
        /// </returns>
        public static physValue[] getSubstrateMixFlowForFermenter(double t, biogas.substrates mySubstrates,
                                                                  biogas.plant myPlant, sensors mySensors, double[,] substrate_network,
                                                                  string digester_id)
        {
            int digester_index = myPlant.getDigesterIndex(digester_id) - 1;

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

            // make the sum over the 2nd dimension, the digesters
            double[] norm_vec = math.sum(substrate_network, 1);

            double[] substrate_digester = new double[substrate_network.GetLength(0)];

            for (int isubstrate = 0; isubstrate < substrate_network.GetLength(0); isubstrate++)
            {
                // what is if norm_vec is 0 for an element
                // then we have 0/0.
                if (norm_vec[isubstrate] != 0)
                {
                    substrate_digester[isubstrate] =
                        substrate_network[isubstrate, digester_index] /
                        norm_vec[isubstrate];
                }
                else
                {
                    substrate_digester[isubstrate] = 0;
                }
            }

            // this is the amount of each substrate going into the given digester
            Q = physValue.times(Q, substrate_digester);

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

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

            double t1 = mySensors.getPreviousTime();

            double[] Q1, Q2;

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

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

            //

            double udot = 0;

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

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

                udot += udot1 * udot1;
            }

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

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

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

            double QdigesterIn;

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

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

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

            return(ADMparams);
        }