// ------------------------------------------------------------------------------------- // !!! PRIVATE METHODS !!! // ------------------------------------------------------------------------------------- /// <summary> /// returns a value between 0 and 1. if the pH value is lower or upper /// some constraints, then the value is greater 0, else 0. /// /// TODO: diese methode überdenken /// </summary> /// <param name="mySensors"></param> /// <param name="myPlant"></param> /// <param name="myFitnessParams"></param> /// <returns></returns> private static double getpHvalue_fitness(biogas.sensors mySensors, biogas.plant myPlant, biooptim.fitness_params myFitnessParams) { double pH_Punishment = 0; double pH_value; int n_digester = myPlant.getNumDigesters(); for (int idigester = 0; idigester < n_digester; idigester++) { string digester_id = myPlant.getDigesterID(idigester + 1); mySensors.getCurrentMeasurementD("pH_" + digester_id + "_3", out pH_value); // punish values bigger than 8 or smaller than 7 // Der Faktor gibt die Steilheit der Strafe an, bei max. 2, dann ist // schon bei 8 bzw. 7 der Ausdruck ( 2.0 .* (pH(ifermenter,1) - 7.5) ) // == 1 // TODO - maybe use tukey function here instead // macht es überhaupt sinn mit optimal values zu arbeiten? // oder einfacher die calcFitnessDigester_min_max() methode nutzen double pH_punish_digester = Math.Min(1 / (10 ^ 4) * ( Math.Pow(1.8 * (pH_value - myFitnessParams.get_param_of("pH_optimum", idigester)), 12)), Math.Abs(pH_value - myFitnessParams.get_param_of("pH_optimum", idigester))); pH_punish_digester = Math.Max(pH_punish_digester, Convert.ToDouble(pH_value < myFitnessParams.get_param_of("pH_min", idigester))); pH_punish_digester = Math.Max(pH_punish_digester, Convert.ToDouble(pH_value > myFitnessParams.get_param_of("pH_max", idigester))); // diese zeile begrenzt pH Strafe zwischen 0 und 1 pH_Punishment = pH_Punishment + Math.Min(pH_punish_digester, 1); } if (n_digester > 0) { pH_Punishment = pH_Punishment / n_digester; } // values between 0 and 1, can be hard constraints return(pH_Punishment); }
/// <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> /// /// </summary> /// <param name="myPlant"></param> /// <param name="u">contains (h2, ch4, co2)_digester_1, (h2, ch4, co2)_digester_2</param> /// <param name="gas2bhkwsplittype">fiftyfifty, one2one, threshold</param> /// <param name="par"></param> /// <returns></returns> override protected physValue[] doMeasurement(biogas.plant myPlant, double[] u, string gas2bhkwsplittype, params double[] par) { // contains: // total biogas production [m³/d] // total biogas production splitted into components [m³d] // biogas for each chp splitted into components // biogas excess [m³/d] physValue[] values = new physValue[dimension]; // TODO //Console.WriteLine(dimension); int n_digester = myPlant.getNumDigesters(); int n_chp = myPlant.getNumCHPs(); int n_gases = (int)BioGas.n_gases; // u contains (h2, ch4, co2)_digester_1, (h2, ch4, co2)_digester_2, ... // TODO - scheint mir ok zu sein, kann das nicht erkennen. // ch4 must be the second element due to implementation below // // ch4 is the second element int index_ch4 = BioGas.pos_ch4 - 1; // total biogas in m^3/d (h2, ch4, co2) double[] biogas_total = BioGas.merge_streams(u, n_digester); // total biogas production in m³/d, sum of biogas_total double total_biogas_total; // percentual biogas prdocution on the plant (h2 %, ch4 %, co2 %) double[] biogas_total_perc = BioGas.calcRelContent(biogas_total, out total_biogas_total); // double[] gas_out = new double[n_gases * n_chp]; // switch (gas2bhkwsplittype) { case "fiftyfifty": gas_out = math.repmat(math.rdivide(biogas_total, n_chp), n_chp); break; case "one2one": if (n_chp == n_digester) { gas_out = u; } else { throw new exception(String.Format("n_chp != n_digester: {0} != {1}!", n_chp, n_digester)); } break; case "threshold": double gas_max; for (int ichp = 0; ichp < n_chp; ichp++) { if (biogas_total[index_ch4] > 0) { // in gas_max is the maximal amount of methane in m^3/d which // can be handled by the indexed bhkw myPlant.getCHP(ichp + 1).getMaxMethaneConsumption(out gas_max); // available methane content double methan = Math.Min(biogas_total[index_ch4], gas_max); for (int igas = 0; igas < n_gases; igas++) { // get the fraction out of the biogas gas_out[igas + ichp * n_gases] = methan / biogas_total[index_ch4] * biogas_total[igas]; } // decrease biogas amount for (int igas = 0; igas < n_gases; igas++) { biogas_total[igas] -= gas_out[igas + ichp * n_gases]; } } else { break; } } // break; default: throw new exception(String.Format( "Unknown gas2bhkwsplittype: {0}!", id_suffix)); } // too much biogas produced [m^3/d], sum of the three parts double gas_excess = Math.Max(total_biogas_total - math.sum(gas_out), 0); // values[0] = new physValue("biogas_t", total_biogas_total, "m^3/d", "total biogas"); // physValue[] values_rel = BioGas.convert(biogas_total_perc); for (int igas = 0; igas < n_gases; igas++) { values[igas + 1] = values_rel[igas]; } // for (int igas = 0; igas < n_gases; igas++) { for (int ichp = 0; ichp < n_chp; ichp++) { values[igas + ichp * n_gases + 1 + n_gases] = new physValue(BioGas.symGases[igas] + "_" + myPlant.getCHPID(ichp + 1), gas_out[igas + ichp * n_gases], "m^3/d", BioGas.labelGases[igas]); } } values[values.Length - 1] = new physValue("biogas_excess", gas_excess, "m^3/d", "excess biogas"); // return(values); }