/// <summary> /// Calculates VS_COD degradation rate and return its normalized /// value as VS_COD_fitness /// </summary> /// <param name="mySensors"></param> /// <param name="VS_COD_degradationRate"></param> /// <returns>VS_COD_fitness: normalized between 0 and 1</returns> private static double getVS_COD_fitness(biogas.sensors mySensors, out double VS_COD_degradationRate) { // Volatile Solids COD degradation // volatile COD in the final storage tank // TODO stimmt so nicht, masseabgang durch biogas // da der FLuss welcher in das Endlager rein geht immer identisch mit // dem Fluss der Eingangssubstrate ist, kürzen sich die beiden werte // immer raus, also hier nicht benötigt physValue Q_final_storage = mySensors.getCurrentMeasurement("Q_finalstorage_2"); // gCOD/l physValue VS_COD_final_storage = mySensors.getCurrentMeasurement("VS_COD_finalstorage_2"); // gCOD/l * m^3 == also eine Menge, keine Konzentration double VS_COD_amount_final = VS_COD_final_storage.Value * Q_final_storage.Value; // volatile COD in the substrate feed // TODO // measure Q_total_mix_2 physValue Q_total_mix = mySensors.getCurrentMeasurement("Q_total_mix_2"); // gCOD/l physValue VS_COD_substrate = mySensors.getCurrentMeasurement("VS_COD_total_mix_2"); // gCOD/l * m^3 == also eine Menge, keine Konzentration double VS_COD_amount_total = VS_COD_substrate.Value * Q_total_mix.Value; // // a value between 0 and 100 VS_COD_degradationRate = (1 - Math.Max(VS_COD_amount_final, 0) / Math.Max(VS_COD_amount_total, double.Epsilon)) * 100; // double VS_COD_degradationMin = 0; double VS_COD_degradationMax = 100; // values between 0 and 1 double VS_COD_fitness = Math.Abs((1 - math.normalize(VS_COD_degradationRate, VS_COD_degradationMin, VS_COD_degradationMax))); return(VS_COD_fitness); }
/// <summary> /// Calculates the thermal energy balance of the digester. It compares /// thermal sinks (negative) with thermal sources (positive) inside the digester /// /// At the moment the following processes are reflected: /// /// thermal sinks are: /// /// 1) heat energy needed to heat the substrates up to the digesters temperature /// (heat substrates) /// 2) heat energy loss due to radiation through the surface of the fermenter /// (radiation) /// /// thermal sources are: /// /// 1) microbiology /// 2) stirrer dissipation /// /// For further effects see /// /// 1) Lübken, M., Wichern, M., Schlattmann, M., Gronauer, A., and Horn, H.: /// Modelling the energy balance of an anaerobic digester fed with cattle manure /// and renewable energy crops, Water Research 41, pp. 4085-4096, 2007 /// 2) Lindorfer, H., Kirchmayr, R., Braun, R.: /// Self-heating of anaerobic digesters using energy crops, 2005 /// /// /// </summary> /// <param name="Q">substrate feed measured in m^3/d</param> /// <param name="mySubstrates"></param> /// <param name="T_ambient">ambient temperature</param> /// <param name="mySensors"></param> /// <param name="Psubsheat">thermal energy needed to heat substrates in kWh/d</param> /// <param name="Pradloss">thermal energy loss due to radiation in kWh/d</param> /// <param name="Pmicros">Wärme produziert durch Bakterien in kWh/d</param> /// <param name="Pstirdiss">thermal energy created by stirrer in kWh/d</param> /// <returns>thermal energy balance mesasured in kWh/d</returns> /// <exception cref="exception">Q.Length < mySubstrates.Count</exception> /// <exception cref="exception">energy calculations failed</exception> public double calcThermalEnergyBalance(double[] Q, substrates mySubstrates, physValue T_ambient, sensors mySensors, out physValue Psubsheat, out physValue Pradloss, out physValue Pmicros, out physValue Pstirdiss) { //physValue Pel_kWh_d; //physValue Pel_kW; // thermal energy needed to heat substrates in kWh/d try { Psubsheat = mySubstrates.calcSumQuantityOfHeatPerDay(Q, T).convertUnit("kWh/d"); } catch (exception e) { Console.WriteLine(e.Message); throw new exception("calcThermalEnergyBalance: heat substrates failed!"); } //physValue P_radiation_loss_kW; //physValue P_radiation_loss_kWh_d; // energy needed to compensate loss due to radiation //compensateHeatLossDueToRadiation(T_ambient, out P_radiation_loss_kW, out P_radiation_loss_kWh_d); // thermal energy loss due to radiation in kWh/d try { Pradloss = calcHeatLossDueToRadiation(T_ambient).convertUnit("kWh/d"); } catch (exception e) { Console.WriteLine(e.Message); throw new exception("calcThermalEnergyBalance: heat loss calculation failed!"); } // Wärme produziert durch Bakterien // in kWh/d try { Pmicros = mySensors.getCurrentMeasurement("energyProdMicro_" + id); // wenn noch nichts aufgezeichnet wurde, dann ist der Wert 0 if (Pmicros.Value != 0) { Pmicros = Pmicros.convertUnit("kWh/d"); } else // setzte zu 0 kWh/d, da einheit sonst nicht stimmt { Pmicros = new physValue(0, "kWh/d"); } } catch (exception e) { Console.WriteLine(e.Message); throw new exception("calcThermalEnergyBalance: microorganisms failed!"); } // Wärme welche das Rühwerk erzeugt ist eine Wärmequelle, muss hier addiert werden // In Ganzheitliche stoffliche und energetische Modellierung S. 65 // Dissipation Rührwerk - ist identisch mit der aufgebrachten Leistung des // rührwerks. dafür muss erstmal rührwerksleistung berechnet werden, s. ebenfalls // In Ganzheitliche stoffliche und energetische Modellierung S. 45 ff. // für rührwerksleitung muss auch viskosität berechnet werden s. S. 81 für verschiedene // TS im fermenter // thermal energy created by stirrer in kWh/d try { Pstirdiss = calcStirrerDissipation(mySensors).convertUnit("kWh/d"); } catch (exception e) { Console.WriteLine(e.Message); throw new exception("calcThermalEnergyBalance: stirrer dissipation failed!"); } // sinks are negative, themal sources are positive physValue balance = -Psubsheat - Pradloss + Pstirdiss + Pmicros; // + produzierteWärme im Fermenter return(balance.Value); }