/// <summary>
        /// Calculates the organic loading rate of the digester.
        /// Assumption that Q and Qsum is measured in m^3/d.
        ///
        /// As a reference see:
        ///
        /// Handreichung Biogasgewinnung und -nutzung: Grundlagen der anaeroben
        /// Fermentation, S. 29.
        ///
        /// </summary>
        /// <param name="x">digester state vector</param>
        /// <param name="mySubstrates">
        /// substrates or sludge but not both!!! Because TS content is calculated
        /// out of COD in digester. If there is a mixture of substrate and sludge going
        /// into the digester, then the COD is aleardy decreased by the sludge, so no need
        /// to account for the lower TS of the sludge here.
        /// TODO: hier sollten es beide sein!
        /// </param>
        /// <param name="Q">
        /// Q of the substrates or sludge, but not both!
        /// TODO: hier sollten es beide sein!
        /// </param>
        /// <param name="Qsum">
        /// if there is sludge and substrate going into the digester, then Qsum will be
        /// bigger then math.sum(Q). Qsum is needed to account for full volumeflow
        /// going into the digester no matter if substrate or sludge.
        /// TODO: nach Änderung, dass Q alle feed enthält, ist Qsum= sum(Q)
        /// kann also als Parameter entfernt werden
        /// </param>
        /// <returns></returns>
        public physValue calcOLR(double[] x, substrates mySubstrates, double[] Q, double Qsum)
        {
            physValue Vliq = this.Vliq;

            physValue TS;

            // TODO
            // was mache ich hier!!!! ???????????????????
            // warum nehme ich nicht einfach VS aus den Substraten???
            physValue VS;//= calcVS(x, mySubstrates, Q, out TS);

            mySubstrates.get_weighted_mean_of(Q, "VS", out VS);
            mySubstrates.get_weighted_mean_of(Q, "TS", out TS);

            VS = biogas.substrate.convertFrom_TS_To_FM(VS, TS);
            VS = VS.convertUnit("100 %");

            physValue rho;

            mySubstrates.get_weighted_mean_of(Q, "rho", out rho);

            // hier wird die Annahme gemacht, dass rho von schlamm gleich ist
            // wie rho der substrate, aber egal (TODO)
            // evtl. wäre es besser gemessenes rho aus density_sensor zu nehmen
            // das ist dichte des inputs in den fermenter (Gemisch aus substrate und rezischlamm)
            physValue OLR = new physValue(Qsum, "m^3/d") * rho * VS / Vliq;

            OLR.Symbol = "OLR";

            return(OLR);
        }
        // -------------------------------------------------------------------------------------
        //                              !!! PUBLIC METHODS !!!
        // -------------------------------------------------------------------------------------

        /// <summary>
        /// Calculates TS content inside the digester. Therefore we calculate the COD
        /// inside the digester using the state vector x. Furthermore we calculate out
        /// of the substrates going into the digester the ash and TS content. If
        /// no substrate is going into the digester we take the sludge and pass it to
        /// this method. But never mix substrates and sludge!!!
        ///
        /// Basic formula is:
        ///
        /// Xc,digester= rho_substrate * TS_digester [100 % FM] *
        ///              VS_digester [% TS] / VS_substrate [% TS] * ( ... )
        ///
        ///
        /// !!!!!!!!!!!!!!!!!!!! ATTENTION !!!!!!!!!!!!!!!!!!!!!
        /// this function only calculates the total solids in steady state!!!
        /// because the ash content in the digester is not taken into account, just the ash of the substrate, which is only
        /// a small part of volume compared with ash in digester. in steady state we assume that ash content in digester is
        /// the same as the one of the substrate, but in dynamic simulation this is not true at all
        ///
        /// As a reference see:
        ///
        /// Koch, K., Lübken, M., Gehring, T., Wichern, M., and Horn, H.:
        /// Biogas from grass silage – Measurements and modeling with ADM1,
        /// Bioresource Technology 101, pp. 8158-8165, 2010.
        ///
        /// </summary>
        /// <param name="x">digester state vector</param>
        /// <param name="mySubstrates">
        /// substrates or sludge but not both!!! Because TS content is calculated
        /// out of COD in digester. If there is a mixture of substrate and sludge going
        /// into the digester, then the COD is already decreased by the sludge, so no need
        /// to account for the lower TS of the sludge here.
        /// </param>
        /// <param name="Q">
        /// array of substrate mix stream or recirculations in m³/d
        /// wie soll das mit recirculations funktionieren?
        /// Q welches an get_weighted_mean_of übergeben wird, muss mindestens
        /// anzahl der substrate beinhalten. das funktioniert, weil
        /// mySubstrates einmal eine liste von schlamm ist, und einmal
        /// eine liste der substrate
        /// </param>
        /// <returns>TS in % FM</returns>
        /// <exception cref="exception">Q.Length &lt; mySubstrates.Count</exception>
        /// <exception cref="exception">TS value out of bounds</exception>
        public static physValue calcTS(double[] x, substrates mySubstrates, double[] Q)
        {
            physValue RF;
            physValue RP;
            physValue RL;
            physValue ADL;
            physValue VS;
            physValue rho;
            physValue ash;

            //physValue TS_substrate;

            mySubstrates.get_weighted_mean_of(Q, "RF", out RF);
            mySubstrates.get_weighted_mean_of(Q, "RP", out RP);
            mySubstrates.get_weighted_mean_of(Q, "RL", out RL);
            mySubstrates.get_weighted_mean_of(Q, "ADL", out ADL);
            mySubstrates.get_weighted_mean_of(Q, "VS", out VS);
            mySubstrates.get_weighted_mean_of(Q, "rho", out rho);

            mySubstrates.get_weighted_mean_of(Q, "Ash", out ash);
            //mySubstrates.get_weighted_mean_of(Q, "TS",  out TS_substrate);

            // particulate COD inside the digester
            physValue COD = biogas.ADMstate.calcVSOfADMstate(x, "kgCOD/m^3");

            VS = VS.convertUnit("% TS");

            ash = ash.convertUnit("% FM"); // ash of the substrates

            physValue TS;

            // we assume that the COD inside the digester is composed as is the substrate mix
            TS = biogas.substrate.calcTS(RF, RP, RL, ADL,
                                         VS, COD, rho);//.convertUnit("100 %");

            //VS= biogas.substrate.convertFrom_TS_To_FM(VS, TS_substrate);
            VS = VS.convertUnit("100 %"); // VS of substrate mix, weiterhin gemessen in 100 % TS

            // TS_digester [% FM] * VS_substrates [100 % TS] + ash_substrate [% FM]
            // we know that the ash content of the substrates does not change inisde the digester
            // TODO: explain a bit better
            // wenn COD oben 0 wäre, dann wäre TS ebenfalls 0, durch die nächste Zeile
            // wird TS auf ash content angehoben.
            TS = TS * VS + ash;

            TS.Symbol = "TS";

            return(TS);
        }