/// <summary> /// Returns the ADM params vector, but the substrate dependent parameters /// are returned as normal means, not weighted means /// </summary> /// <param name="mySubstrates"></param> /// <returns></returns> public double[] getParams(substrates mySubstrates) { double[] Q = new double[mySubstrates.getNumSubstrates()]; for (int isubstrate = 0; isubstrate < mySubstrates.getNumSubstrates(); isubstrate++) { Q[isubstrate] = 1; } return(getParams(0, Q, math.sum(Q), mySubstrates)); // , true }
/// <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); }
/// <summary> /// Measure TS content inside a digester /// /// type 7 /// </summary> /// <param name="x">ADM state vector</param> /// <param name="myPlant"></param> /// <param name="mySubstrates">list of substrates</param> /// <param name="mySensors"></param> /// <param name="Q"> /// substrate feed and recirculation sludge going into the digester /// first values are Q for substrates, then pumped sludge going into digester /// dimension: always number of substrates + number of digesters /// </param> /// <param name="par">not used</param> /// <returns></returns> override protected physValue[] doMeasurement(double[] x, biogas.plant myPlant, biogas.substrates mySubstrates, biogas.sensors mySensors, double[] Q, params double[] par) { // TODO // so erweitern, dass auch TS in Fermenter Input gemessen werden kann // evtl. substrate_sensor nutzen, kann aber auch direkt über mySubstrates gemessen werden physValue[] values = new physValue[1]; // number of substrates int n_substrate = mySubstrates.getNumSubstrates(); if (Q.Length < n_substrate) { throw new exception(String.Format( "Q.Length < n_substrate: {0} < {1}!", Q.Length, n_substrate)); } double[] Qsubstrates = new double[n_substrate]; // volumeflow for substrates for (int isubstrate = 0; isubstrate < n_substrate; isubstrate++) { Qsubstrates[isubstrate] = Q[isubstrate]; } // biogas.substrates substrates_or_sludge; // List <double> Q_s_or_s = new List <double>(); // if no substrate is going into the fermenter we have to take the // TS from the digesters sludge going into this digester to calculate a // sludge. If there is substrate going into the digester we ignore // recirculation sludge, because the COD content inside the digester is // already influenced by the recirculated COD, so a high recirculation leads // to a reduction of the COD content inside the digester and then also to a // TS content reduction. if (math.sum(Qsubstrates) == 0) { substrates_or_sludge = new biogas.substrates(); int ifermenter = 0; // for (int iflux = n_substrate; iflux < Q.Length; iflux++) { string digester_id = myPlant.getDigesterID(ifermenter + 1); double TS_digester = 0; try { mySensors.getCurrentMeasurementD("TS_" + digester_id + "_3", out TS_digester); if (TS_digester < double.Epsilon) // vermutlich wurde noch nicht gemessen? { TS_digester = 11; } } catch // TODO: wann passiert das??, sollte eigentlich nicht passieren { TS_digester = 11; } substrates_or_sludge.addSubstrate( new biogas.sludge(mySubstrates, math.ones(n_substrate), TS_digester)); ifermenter = ifermenter + 1; } // for (int isubstrate = n_substrate; isubstrate < Q.Length; isubstrate++) { Q_s_or_s.Add(Q[isubstrate]); } } else { substrates_or_sludge = mySubstrates; for (int isubstrate = 0; isubstrate < Qsubstrates.Length; isubstrate++) { Q_s_or_s.Add(Qsubstrates[isubstrate]); } } if (id.EndsWith("3")) // out sensor { // calc TS inside digester due to the substrates or the sludge if digester is not fed values[0] = biogas.digester.calcTS(x, substrates_or_sludge, Q_s_or_s.ToArray()); } else if (id.EndsWith("2")) // in sensor { // TODO // ändern, da momentan entweder substrate oder sludge genommen wird und nicht beides // selbe Problem wie bei OLR_sensor denke ich substrates_or_sludge.get_weighted_mean_of(Q_s_or_s.ToArray(), "TS", out values[0]); values[0].Symbol = "TS"; } else { throw new exception(String.Format("id of TS sensor not valid: {0}", id)); } // values[0].Label = "total solids"; return(values); }
static void Main(string[] args) { physValue COD = biogas.chemistry.calcTOC("Xch"); //physValueBounded mol_mass= new physValueBounded("Sac"); //double a= 1; //physValueBounded c= a* mol_mass; fitness_params myparams = new fitness_params("fitness_params_geiger.xml"); myparams.set_params_of("manurebonus", true); //double[] state= new double[37]; //physValueBounded fostac= biogas.ADMstate.calcFOSTACOfADMstate(state); //physValue C; //physValue H; //physValue Hh2= biogas.chemistry.Hh2; //biogas.chemistry.get_CHONS_of("Sac_", out C, out H); //physValue ThODch= biogas.chemistry.calcTheoreticalOxygenDemand("Xch"); //biogas.substrate.createMe(); //double[] a= biogas.ADMstate.getDefaultADMstate(33); //double[] b= biogas.ADMstate.getDefaultADMstate(33); //a[33]= 10; //b[33]= 15; //double[,] c= new double[a.Length, 2]; //for (int ii= 0; ii < a.Length; ii++) //{ // c[ii, 0]= a[ii]; // c[ii, 1]= b[ii]; //} //double[] d= biogas.ADMstate.mixADMstreams(c); //biogas.substrate mySubstrate= new biogas.substrate("manure_cattle_1.xml"); //mySubstrate.print(); //mySubstrate= new biogas.substrate("wheat_silage_3.xml"); //mySubstrate.print(); substrates mySubstrates = new biogas.substrates("substrate_geiger.xml"); mySubstrates.print(); //mySubstrates.saveAsXML("test.xml"); plant myPlant = new biogas.plant("plant_geiger.xml"); //myPlant.saveAsXML("test_plant.xml"); //double[] Q= {1,2,3,4,5,6,7}; //myPlant.myDigesters.get("main").AD_Model.getParams(Q, mySubstrates); digester myDigester = myPlant.myDigesters.get(1); myDigester.calcHeatLossDueToRadiation(new physValue(40, "°C")); double[] Q = { 15, 20, 0, 0, 0, 0, 0, 0, 0, 0 }; double QdigesterIn = 35; double[] ADMparams = myDigester.AD_Model.getParams(0, Q, QdigesterIn, mySubstrates); //double[] x= biogas.ADMstate.getDefaultADMstate(); // double[] x= { 0.00890042014469482, //0.00393026902393572, //0.0898975418574202, //0.0105303688871217, //0.0188083338344299, //0.0891872294599488, //4.06518710070508, //1.48197701713060e-06, //0.0463395911897687, //0.0137825768581825, //0.231507824368968, //3.42633334388719, //8.90655977614532, //0.129429796425159, //0.0457772931408461, //0.0271093313710146, //3.81638964565446, //0.988123176978798, //0.410214653254316, //0.633820130695941, //0.537171143510719, //1.81695029971744, //0.992459517922010, //8.07171990003056, //19.9716874568380, //0.000997039324889569, //0.0155655622013352, //0.0104958374141159, //0.0187566838733815, //0.0889172491178123, //4.05462904506225, //0.152623707143880, //0.00590111878589172, //8.13313521280990e-05, //0.465153466604388, //0.506049932143382, //0.971284730099898 ////8.05130545875131e-05, ////0.460473427139200, ////0.500958421870263, ////0.961512362064050 // }; double[] x = { 0.00719913836418267, 0.00322799288019040, 0.0546025712168657, 0.0115793536955362, 0.0229074890746752, 0.0600482037552511, 0.463364086785563, 7.72721521995682e-08, 0.0469910866922296, 0.0479055807768373, 0.154317294840363, -1.35975859128971e-47, 21.5301936374036, 0.750446550594154, 0.161739337648583, 0.0603411370260300, 4.96860324952978, 0.832215069627251, 0.222662822346057, 0.629071151058018, 0.547835241984119, 2.00168204821595, 1.05831074978528, 29.5159593610614, 1.79228974953266, 1.27233772322647e-52, 1.77592375955463e-55, 0.0115411203828431, 0.0228383440861995, 0.0598411508360539, 0.462166407598810, 0.2406363011183078, 0.00374878408176311, 4.31650348109949e-06, 0.476514182736779, 0.487815404290303, 0.964333903530564 }; //biogas.sensors mySensors= // new biogas.sensors(new biogas.VFA_TAC_sensor("1")); //physValue VFA_TAC= mySensors.getCurrentMeasurement("VFA_TAC_1", 2); //VFA_TAC= mySensors.measure(0, "VFA_TAC_1", 1, x); //VFA_TAC= mySensors.measure(2, "VFA_TAC_1", 1, x); biogas.sensors mySensors = new biogas.sensors(new biogas.TS_sensor("postdigester_3")); biogas.sensor_array mySensorArray = new biogas.sensor_array("Q"); for (int isubstrate = 0; isubstrate < mySubstrates.getNumSubstrates(); isubstrate++) { mySensorArray.addSensor(new biogas.Q_sensor(mySubstrates.getID(isubstrate + 1))); } mySensorArray.addSensor(new biogas.Q_sensor("postdigester_digester")); mySensors.addSensorArray(mySensorArray); mySensors.addSensor(new biogas.substrate_sensor("cost")); mySensors.addSensor(new biogas.pumpEnergy_sensor("postdigester_digester")); mySensors.addSensor(new biogas.total_biogas_sensor("", myPlant)); //physValue VFA_TACs= mySensors.measure(0, "VS_1", 1, new double[]{1,2}, mySubstrates); double[,] substrate_network = { { 1, 0 }, { 1, 0 }, { 1, 0 }, { 1, 0 }, { 1, 0 }, { 1, 0 } }; double[,] plant_network = { { 0, 1, 0 }, { 1, 0, 1 } }; double TS; //mySensors.measure(0, "TS_digester_3", 1, x, // myPlant, mySubstrates, mySensors, // substrate_network, plant_network, "digester", out TS); mySensors.measure(0, "substrate_cost", 0, mySubstrates, out TS); mySensors.measure(1, "substrate_cost", 0, mySubstrates, out TS); mySensors.measure(2, "substrate_cost", 0, mySubstrates, out TS); double energy; double[] pump = { 5 }; mySensors.measure(0, "pumpEnergy_postdigester_digester", 0, myPlant, 10, pump, out energy); double[] data; mySensors.getMeasurementStream("substrate_cost", out data); double[] u = new double[6]; u[0] = 10; u[1] = 100; u[2] = 100; u[3] = 20; u[4] = 200; u[5] = 200; mySensors.measureVec(0, "total_biogas_", 0, myPlant, u, "threshold", 5); physValue Qgas_h2; physValue Qgas_ch4; physValue Qgas_co2; physValue T = new physValue("T", 41.4, "°C"); biogas.ADMstate.calcBiogasOfADMstate(x, new physValue(3000, "m^3"), T, out Qgas_h2, out Qgas_ch4, out Qgas_co2); double ph = biogas.ADMstate.calcPHOfADMstate(x); substrate mySubstrate = mySubstrates.get("swinemanure"); biogas.ADMstate.calcADMstream(mySubstrate, 30); double mypH = mySubstrate.get_param_of("pH"); }
/// <summary> /// measures the density of the substrate feed of a given digester /// /// type 7 /// /// TODO: mySensors wird hier eigentlich nicht benötigt /// wenn mySensors gelöscht wird, dann ist das keine type 7 funktion mehr, OK /// /// </summary> /// <param name="x">ADM state 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 /// first values are Q for substrates, then pumped sludge going into digester /// dimension: always number of substrates + number of digesters /// </param> /// <param name="par">not used</param> /// <returns></returns> override protected physValue[] doMeasurement(double[] x, biogas.plant myPlant, biogas.substrates mySubstrates, biogas.sensors mySensors, double[] Q, params double[] par) { physValue[] values = new physValue[1]; // number of substrates int n_substrate = mySubstrates.getNumSubstrates(); double Qsum = math.sum(Q); // das ist feed in fermenter if (Q.Length < n_substrate) { throw new exception(String.Format( "Q.Length < n_substrate: {0} < {1}!", Q.Length, n_substrate)); } double[] Qsubstrates = new double[n_substrate]; // volumeflow for substrates for (int isubstrate = 0; isubstrate < n_substrate; isubstrate++) { Qsubstrates[isubstrate] = Q[isubstrate]; } // physValue rhoSubstrate; // wenn fermenter nicht mit substraten gefüttert wird if (math.sum(Qsubstrates) == 0) { rhoSubstrate = new physValue(0, "kg/d"); } else { mySubstrates.get_weighted_sum_of(Qsubstrates, "rho", out rhoSubstrate); rhoSubstrate = rhoSubstrate.convertUnit("kg/d"); } // physValue rhoSludge = new physValue("rho", 1000, "kg/m^3"); for (int isubstrate = n_substrate; isubstrate < Q.Length; isubstrate++) { rhoSubstrate += rhoSludge * new physValue(Q[isubstrate], "m^3/d"); } // if (Qsum != 0) { values[0] = rhoSubstrate / new physValue(Qsum, "m^3/d"); } else { values[0] = new physValue(0, "kg/m^3"); } // values[0].Symbol = "rho"; // return(values); }
/// <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> /// Measure OLR of a digester /// /// type 7 /// /// TODO: größtenteils identisch mit TS_sensor, man könnte was zusammen legen /// </summary> /// <param name="x">ADM state vector</param> /// <param name="myPlant"></param> /// <param name="mySubstrates">list of substrates</param> /// <param name="mySensors"></param> /// <param name="Q"> /// substrate feed and recirculation sludge going into fermenter in m³/d /// first values are Q for substrates, then pumped sludge going into digester /// dimension: always number of substrates + number of digesters /// </param> /// <param name="par"></param> /// <returns></returns> override protected physValue[] doMeasurement(double[] x, biogas.plant myPlant, biogas.substrates mySubstrates, biogas.sensors mySensors, double[] Q, params double[] par) { physValue[] values = new physValue[1]; // TODO: so abändern, dass die aufgerufene methode calcOLR immer // feed und sludge übergeben werden. nicht oder // number of substrates int n_substrate = mySubstrates.getNumSubstrates(); double Qsum = math.sum(Q); if (Q.Length < n_substrate) { throw new exception(String.Format( "Q.Length < n_substrate: {0} < {1}!", Q.Length, n_substrate)); } double[] Qsubstrates = new double[n_substrate]; // volumeflow for substrates for (int isubstrate = 0; isubstrate < n_substrate; isubstrate++) { Qsubstrates[isubstrate] = Q[isubstrate]; } // biogas.substrates substrates_or_sludge; // List <double> Q_s_or_s = new List <double>(); // if no substrate is going into the fermenter we have to take the // TS from the digesters sludge going into this digester to calculate a // sludge. If there is substrate going into the digester we ignore // recirculation sludge, because the COD content inside the digester is // already influenced by the recirculated COD, so a high recirculation leads // to a reduction of the COD content inside the digester and then also to a // TS content reduction. if (math.sum(Qsubstrates) == 0) { substrates_or_sludge = new biogas.substrates(); int ifermenter = 0; // for (int iflux = n_substrate; iflux < Q.Length; iflux++) { string digester_id = myPlant.getDigesterID(ifermenter + 1); double TS_digester, VS_digester = 0; try { mySensors.getCurrentMeasurementD("TS_" + digester_id + "_3", out TS_digester); mySensors.getCurrentMeasurementD("VS_" + digester_id + "_3", out VS_digester); // TODO - warum 4, wenn Fermenter abgestürzt ist, dann ist TS < 2 // was zu doofen Fehlermeldungen führt mit calcNfE und boundNDF, wenn man // VS unten in biogas.sludge setzt. deshalb hier abfrage if (TS_digester < 4 /*double.Epsilon*/) { TS_digester = 11; } // TODO - herausfinden warum 15 if (VS_digester < 20 /*double.Epsilon*/) { VS_digester = 85; // 85 % TS } } catch { TS_digester = 11; VS_digester = 85; } try { substrates_or_sludge.addSubstrate( new biogas.sludge(mySubstrates, math.ones(n_substrate), TS_digester, VS_digester)); } catch (exception e) { LogError.Log_Err(String.Format("OLR_sensor.doMeasurement, VS: {0}, TS: {1}", VS_digester, TS_digester), e); throw (e); } ifermenter = ifermenter + 1; } // for (int isubstrate = n_substrate; isubstrate < Q.Length; isubstrate++) { Q_s_or_s.Add(Q[isubstrate]); } } else { substrates_or_sludge = mySubstrates; for (int isubstrate = 0; isubstrate < Qsubstrates.Length; isubstrate++) { Q_s_or_s.Add(Qsubstrates[isubstrate]); } } // digester myDigester = myPlant.getDigesterByID(id_suffix); try { values[0] = myDigester.calcOLR(x, substrates_or_sludge, Q_s_or_s.ToArray(), Qsum); } catch (exception e) { LogError.Log_Err("OLR_sensor.doMeasurement2", e); throw (e); } // return(values); }