/// <summary> /// type 7 /// /// called in ADMstate_stoichiometry.cs -> measure_type7 /// </summary> /// <param name="x">ADM state vector - not used</param> /// <param name="myPlant"></param> /// <param name="mySubstrates">not yet used</param> /// <param name="mySensors">used to get TS inside digester</param> /// <param name="Q">not used</param> /// <param name="par">not used</param> /// <returns>measured values</returns> override protected physValue[] doMeasurement(double[] x, biogas.plant myPlant, biogas.substrates mySubstrates, biogas.sensors mySensors, double[] Q, params double[] par) { // 1st Pel in kWh/d for mixing digester // 2nd Pdissipated in kWh/d for mixing digester, dissipated in digester physValue[] values = new physValue[dimension]; // digester myDigester = myPlant.getDigesterByID(id_suffix); // calc stirrer(s) power for digester in kWh/d values[0] = myDigester.calcStirrerPower(mySensors); // calc stirrer(s) power dissipated to digester in kWh/d values[1] = myDigester.calcStirrerDissipation(mySensors); values[0].Label = "electrical energy of stirrer"; values[1].Label = "thermal energy dissipated by stirrer"; // return(values); }
/// <summary> /// Adds the digester myDigester to the list. /// </summary> /// <param name="myDigester"></param> public void addDigester(digester myDigester) { myDigesters.addDigester(myDigester); substrate_transport mySubstrateTransport = new substrate_transport("substratemix", myDigester.id); myTransportation.addSubstrateTransport(mySubstrateTransport); }
/// <summary> /// Deletes the by 1-based index specified digester from the list. /// </summary> /// <param name="index">digester index</param> /// <exception cref="exception">Invalid digester index</exception> public void deleteDigester(int index) { digester myDigester = getDigester(index); myTransportation.deleteSubstrateTransport("substratemix_" + myDigester.id); myDigesters.deleteDigester(index); }
/// <summary> /// type 7 /// /// called in ADMstate_stoichiometry.cs /// /// unterschied zu typ 7 ist, dass Q hier nur aus Substraten besteht und nicht /// aus zusätzlichem sludge, da sludge nicht aufgewärmt werden muss, /// nein ist jetzt ein Typ 7 sensor, sludge wird ignoriert /// </summary> /// <param name="x">not used</param> /// <param name="myPlant"></param> /// <param name="mySubstrates"></param> /// <param name="mySensors"></param> /// <param name="Q">zufuhr aller substrate in fermenter (nicht in Anlage), /// da heatConsumption_sensor am fermenter angebracht ist</param> /// <param name="par">not used</param> /// <returns>measured values</returns> override protected physValue[] doMeasurement(double[] x, biogas.plant myPlant, biogas.substrates mySubstrates, biogas.sensors mySensors, double[] Q, params double[] par) { // wegen 4 siehe oben // 1. Ptherm kWh/d for heating substrates // 2. Ptherm kWh/d loss due to radiation // 3. Ptherm kWh/d produced by microbiology // 4. Ptherm kWh/d produced by stirrer dissipation physValue[] values = new physValue[dimension]; // TODO - rufe hier calcThermalEnergyBalance auf von digester_energy.cs // benötigt als weiteren Parameter allerdings mySensors digester myDigester = myPlant.getDigesterByID(id_suffix); // Q ist nur das was in fermenter rein geht // bspw. gäbe es bei einem nicht gefütterten aber beheiztem fermenter // keine substrate welche aufgeheizt werden müssten //myDigester.heatInputSubstrates(Q, mySubstrates, out values[0]); myDigester.calcThermalEnergyBalance(Q, mySubstrates, myPlant.Tout, mySensors, out values[0], out values[1], out values[2], out values[3]); // values[0].Label = "thermal energy to heat substrates"; values[1].Label = "thermal energy loss due to radiation"; values[2].Label = "thermal energy produced by microorganisms"; values[3].Label = "thermal energy dissipated by stirrer"; //physValue P_radiation_loss_kW; // because in heating first power in kW is calculated, it does not // make the code faster to not have power in kW as parameter //myPlant.compensateHeatLossDueToRadiation(id_suffix, // out P_radiation_loss_kW, out values[1]); // return(values); }
/// <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); }