/// <summary> /// write measured variable at time t in given mySubstrate /// (mySubstrates.get(substrate_id)) /// </summary> /// <param name="t">current simulation time</param> /// <param name="mySensors"></param> /// <param name="mySubstrates">changed in this call</param> /// <param name="substrate_id">ID of substrate to be set</param> public static void set_substrate_params_from_sensor(double t, biogas.sensors mySensors, biogas.substrates mySubstrates, string substrate_id) { biogas.substrate mySubstrate = mySubstrates.get(substrate_id); set_substrate_params_from_sensor(t, mySensors, mySubstrate); }
/// <summary> /// Calculate g C / kg substrate fresh matter /// </summary> /// <param name="mySubstrate">a substrate</param> /// <returns>g C / kg fresh matter</returns> private static physValue calcC(substrate mySubstrate) { physValue[] values = new physValue[6]; try { mySubstrate.get_params_of(out values, "RF", "RP", "RL", "NfE", "ADL", "TS"); } catch (exception e) { Console.WriteLine(e.Message); return(new physValue("error")); } physValue RF = values[0]; physValue RP = values[1]; physValue RL = values[2]; physValue NfE = values[3]; physValue ADL = values[4]; physValue TS = values[5]; return(calcC(RF, RP, RL, NfE, ADL, TS)); }
/// <summary> /// Returns the variable specified by symbol out of the given substrate as object /// </summary> /// <param name="mySubstrate">a substrate</param> /// <param name="variable">object</param> /// <param name="symbol">"RF"</param> /// <exception cref="exception">Unknown parameter</exception> public static void get_params_of(substrate mySubstrate, out object variable, string symbol) { object[] variables; string[] symbols = { symbol }; mySubstrate.get_params_of(out variables, symbols); variable = variables[0]; }
/// <summary> /// Calculate g S / kg substrate fresh matter /// </summary> /// <param name="mySubstrate">a substrate</param> /// <returns>g S / kg substrate FM</returns> private static physValue calcS(substrate mySubstrate) { physValue[] values = new physValue[6]; mySubstrate.get_params_of(out values, "RF", "RP", "RL", "NfE", "ADL", "TS"); physValue RF = values[0]; physValue RP = values[1]; physValue RL = values[2]; physValue NfE = values[3]; physValue ADL = values[4]; physValue TS = values[5]; return(calcS(RF, RP, RL, NfE, ADL, TS)); }
// ------------------------------------------------------------------------------------- // !!! CONSTRUCTOR METHODS !!! // ------------------------------------------------------------------------------------- /// <summary> /// Returns a copy of the template /// </summary> /// <param name="template">template</param> public substrate(substrate template) { _id = template.id; _name = template.name; Weender.RF = template.Weender.RF.copy(); Weender.RP = template.Weender.RP.copy(); Weender.RL = template.Weender.RL.copy(); Weender.NDF = template.Weender.NDF.copy(); Weender.ADF = template.Weender.ADF.copy(); Weender.ADL = template.Weender.ADL.copy(); //Phys.COD= template.Phys.COD.copy(); Phys.COD_S = template.Phys.COD_S.copy(); //Phys.c_th= template.Phys.c_th.copy(); Phys.pH = template.Phys.pH.copy(); //Phys.rho= template.Phys.rho.copy(); Phys.Sac = template.Phys.Sac.copy(); Phys.Sbu = template.Phys.Sbu.copy(); Phys.Spro = template.Phys.Spro.copy(); Phys.Sva = template.Phys.Sva.copy(); Phys.Snh4 = template.Phys.Snh4.copy(); Phys.TAC = template.Phys.TAC.copy(); //Phys.C= template.Phys.C.copy(); //Phys.N= template.Phys.N.copy(); Phys.T = template.Phys.T.copy(); Phys.TS = template.Phys.TS.copy(); Phys.VS = template.Phys.VS.copy(); Phys.D_VS = template.Phys.D_VS.copy(); AD.kdis = template.AD.kdis.copy(); AD.khyd_ch = template.AD.khyd_ch.copy(); AD.khyd_pr = template.AD.khyd_pr.copy(); AD.khyd_li = template.AD.khyd_li.copy(); AD.km_c4 = template.AD.km_c4.copy(); AD.km_pro = template.AD.km_pro.copy(); AD.km_ac = template.AD.km_ac.copy(); AD.km_h2 = template.AD.km_h2.copy(); cost = template.cost.copy(); substrate_class = template.substrate_class; }
/// <summary> /// Calculates the f-Factor: fPr_Xc, defining the fraction of proteins in /// composites Xc /// </summary> /// <param name="mySubstrate">a substrate</param> /// <returns>fPr_Xc</returns> /// <exception cref="exception">value out of bounds</exception> public static double calcfPr_Xc(substrate mySubstrate) { physValue[] values = new physValue[2]; try { mySubstrate.get_params_of(out values, "RP", "VS"); } catch (exception e) { Console.WriteLine(e.Message); return(-1); } physValue RP = values[0]; physValue VS = values[1]; return(calcfPr_Xc(RP, VS)); }
/// <summary> /// Calculates the f-Factor: fXI_Xc, defining the fraction of particulate inerts in /// composites Xc /// </summary> /// <param name="mySubstrate">a substrate</param> /// <returns>fXI_Xc</returns> public static double calcfXI_Xc(substrate mySubstrate) { physValue[] values = new physValue[4]; try { mySubstrate.get_params_of(out values, "ADL", "NDF", "VS", "D_VS"); } catch (exception e) { Console.WriteLine(e.Message); return(-1); } physValue ADL = values[0]; physValue NDF = values[1]; physValue VS = values[2]; physValue D_VS = values[3]; return(calcfXI_Xc(ADL, NDF, VS, D_VS)); }
/// <summary> /// Calculates the theoretical biochemical methane potential of the substrate /// measured in l per g fresh matter /// </summary> /// <param name="mySubstrate">a substrate</param> /// <returns>BMP</returns> /// <exception cref="exception">Unit of parameters not as specified in method below /// </exception> private static physValue calcBMP(substrate mySubstrate) { physValue[] values = new physValue[7]; try { mySubstrate.get_params_of(out values, "RF", "RP", "RL", "ADL", "VS", "TS", "NDF"); } catch (exception e) { Console.WriteLine(e.Message); return(new physValue("error BMP")); } physValue RF = values[0]; physValue RP = values[1]; physValue RL = values[2]; physValue ADL = values[3]; physValue VS = values[4]; physValue TS = values[5]; physValue NDF = values[6]; double d; try { d = calc_d(mySubstrate); } catch (exception e) { Console.WriteLine(e.Message); return(new physValue("error2")); } return(calcBMP(RF, RP, RL, ADL, VS, TS, d, NDF)); }
// ------------------------------------------------------------------------------------- // !!! PUBLIC SET METHODS !!! // ------------------------------------------------------------------------------------- /// <summary> /// Set a double value, static method. /// Used to set the value of physValues as well, so make sure that /// the value you want to set is measured in the unit in which the /// physValue is saved in the object. /// Therefore see: init_params_of(params double[] values) /// </summary> /// <param name="mySubstrate">a substrate</param> /// <param name="symbol">"RF"</param> /// <param name="value">double value</param> /// <exception cref="exception">Unknown parameter</exception> public static void set_params_of(substrate mySubstrate, string symbol, double value) { object[] values = { symbol, value }; mySubstrate.set_params_of(values); }
/// <summary> /// TODO - die ganze funktion ist noch nicht ausgegoren /// /// write measured variable at time t in given mySubstrate /// /// </summary> /// <param name="t">current simulation time</param> /// <param name="mySensors"></param> /// <param name="mySubstrate">changed in this call</param> public static void set_substrate_params_from_sensor(double t, biogas.sensors mySensors, biogas.substrate mySubstrate) { string substrate_id = mySubstrate.id; substrateparams_sensor substrate_param_sensor = (substrateparams_sensor)mySensors.get("substrateparams_" + substrate_id); if (!substrate_param_sensor.isEmpty()) { physValue[] measVec = substrate_param_sensor.getMeasurementVectorAt(t); // hier werden nur TS und VS geändert mySubstrate.set_params_of("TS", measVec[0], // umrechung in % TS wird in c# bib gemacht (substrateparams_sensor) // s.unten in doMeasurement methode // this value measVec[1] is measured in % TS, this OK "VS", measVec[1], "pH", measVec[2] //, /*"Sac", measVec[3], * // umrechnung von g/l in mmol/l * // g/l / 50 g/mol * 1000 m = 1000 / 50 mmol/l * // TODO convertTo nutzen * "TAC", measVec[4] * 1000 / 50, */ /*"Snh4", measVec[5]*/); //'COD', measVec.Get(6)); //mySubstrate.calc //if (mySubstrate.ismanure) //{ // mySubstrate.set_params_of("RF", measVec[6]); // // TODO outcomment // // measured in gCOD/l // //mySubstrate.set_params_of("COD", measVec[7]); // //mySubstrate.set_params_of("COD_S", 0.3 * measVec[7].Value); //} //else //{ // // TODO - delete // //if (substrate_id == "bullmanure") // // throw new exception("AAAAAAAAAAAA"); // mySubstrate.set_params_of("RL", measVec[6], "RP", measVec[7], // "RF", measVec[8]); // // measured in kgCOD/m^3, same as gCOD/l // //physValue COD_c= biogas.substrate.calcXc(mySubstrate);//.convertUnit("gCOD/l"); // //// TODO // //// 0.3 // //double COD_c2 = 0; // //// TODO delete // //if (substrate_id == "maize") // für geiger kalibrierung // // COD_c2= COD_c.Value * 1.1;//5; // //else // // COD_c2= COD_c.Value; // //mySubstrate.set_params_of("COD", COD_c2); // //mySubstrate.set_params_of("COD_S", 0.3 * COD_c2); //} } }
/// <summary> /// Check whether given substrate feed Q qualifies for the manure bonus /// /// Güllebonus wird ab jetzt immer während simulation geprüft, wird von manurebonus_sensor /// aufgezeichnet. eine überprüfung vor einer simulation wäre auch möglich, sollte aber /// nicht mehr durch geführt werden. zumindest sollte ein negatives ergebnis für den /// güllebonus nicht daran hindern eine simulaion durchzuführen. /// wenn sich substratzufuhr über prädiktionshorizont verändert, müsste aktuell diese /// methode für jeden neuen substratmix einzeln aufgerufen werden. d.h. Q enthält immer nur /// ein element je substrat und nicht mehrere elemente zu verschiedenen zeitpunkten /// </summary> /// <param name="mySubstrates"></param> /// <param name="Q">substrate feed on plant in m³/d</param> /// <param name="A">linear constraint vector of A * Q <= b</param> /// <param name="b">right side of cosntraint</param> /// <param name="dist_bonus">distance of given feed Q to bonus, must be negative such that /// bonus is satisfied</param> /// <returns></returns> public static bool check_manurebonus(biogas.substrates mySubstrates, double[] Q, out double[] A, out double b, out double dist_bonus) { // // linear inequality constraints for the substrate flow // Gülle Bonus // // Erklärung zum Gülle Bonus: // // Für Strom aus Biogasanlagen kann nach den Vorschriften des "EEG // 2009" ein erhöhter NaWaRo Bonus gewährt werden, wenn der Anlage ein // Mindestanteil an Gülle zugeführt wird. Gemäß Anlage 2, Ziffer VI // des EEG 2009 besteht der Anspruch nur dann, wenn der Anteil von // Gülle (dazu zählt auch Festmist) JEDERZEIT (stimmt das WIRKLICH???) mindestens 30 // Masseprozent beträgt. // // Quelle: // // http://www.dlr.rlp.de/internet/global/themen.nsf/ALL/26C1BE11D99FE329C12575270048A024?OpenDocument // // // Summe über Gülle [kg/d] >= 0,3 * ( Summe aller Substrate [kg/d] ) // // -0.7 * ( Summe über Gülle [kg/d] ) + 0.3 ( Summe restlicher // Substrate [kg/d] ) <= 0 // // -0.7 * ( Summe über Gülle [m³/d] * rho_gülle [kg/m³] ) + 0.3 ( // Summe restlicher Substrate [m³/d] * rho_substrat [kg/m³] ) <= 0 // // In der Form Ax <= b // // b= 0; // // A= -0.7 * rho_gülle für alle Gülleformen und 0.3 * rho_substrat für // den Rest, hier ein liegender Vektor // int n_substrates = mySubstrates.getNumSubstrates(); // substrate_ineq= [A, b] double[] substrate_ineq = new double[n_substrates + 1]; // for (int isubstrate = 0; isubstrate < n_substrates; isubstrate++) { substrate mySubstrate = mySubstrates.get(isubstrate + 1); double rho = mySubstrate.get_param_of("rho"); // get density of substrate in kg/m^3 if (mySubstrate.ismanure) { substrate_ineq[isubstrate] = -0.7 * rho; } else { substrate_ineq[isubstrate] = 0.3 * rho; } } // bool is_manure_bonus = false; // linear constraint: A * Q <= b A * Q - b <= 0 A = math.getrows(substrate_ineq, 0, n_substrates - 1); b = substrate_ineq[n_substrates]; // MATLAB syntax: if (substrate_ineq(1:end-1) * Q <= substrate_ineq(end)) // this is the distance of the given feed Q to the manure bonus hyperplane dist_bonus = math.mtimes(A, Q) - b; // MATLAB syntax: if (substrate_ineq(1:end-1) * Q <= substrate_ineq(end)) if (dist_bonus <= 0) { is_manure_bonus = true; } else { is_manure_bonus = false; } // return(is_manure_bonus); }