MEASUR-Tools-Suite v1.0.11
The MEASUR Tools Suite is a collection of industrial efficiency calculations written in C++ and with bindings for compilation to WebAssembly.
Loading...
Searching...
No Matches
gas_flue_gas_material.h
Go to the documentation of this file.
1
12#ifndef TOOLS_SUITE_GASFLUEGASMATERIAL_H
13#define TOOLS_SUITE_GASFLUEGASMATERIAL_H
14
15#include <cmath>
16#include <functional>
17#include <memory>
18#include <stdexcept>
19#include <string>
20#include <unordered_map>
21
27 public:
42 GasProperties(std::function<double(double t)> specificHeat, const double molecularWeight,
43 const double specificWeight, const double compPercent, const double compByVol, const int o2Generated,
44 const int heatingValue, const int heatingValueVolume, const double h2oGenerated,
45 const double co2Generated)
46 : specificHeat(std::move(specificHeat)), molecularWeight(molecularWeight), specificWeight(specificWeight),
47 compByVol(compPercent), compAdjByVol(compByVol), h2oGenerated(h2oGenerated), co2Generated(co2Generated),
48 o2Generated(o2Generated), heatingValue(heatingValue), heatingValueVolume(heatingValueVolume) {};
49
50 private:
51 friend class GasCompositions;
52 const std::function<double(double t)> specificHeat;
53 // compByWeight == X double bar, compAdjByVol == X bar in document
54 double compByWeight = 0;
55 const double molecularWeight, specificWeight, compByVol, compAdjByVol, h2oGenerated, co2Generated;
56
57 // TODO so2Generated is always 0 according to the one table, are these all the gas types we deal with or not?
58 const int so2Generated = 0, o2Generated, heatingValue, heatingValueVolume;
59};
60
61// TODO should be a private class but unit tests need access to this
62
68 public:
70 ProcessHeatPropertiesResults(double stoichAir, double excessAir, double availableHeat, double specificHeat,
71 double density, double heatValueFuel, double flueGasO2)
72 : stoichAir(stoichAir), excessAir(excessAir), availableHeat(availableHeat), specificHeat(specificHeat),
73 density(density), heatValueFuel(heatValueFuel), flueGasO2(flueGasO2) {}
74
76 double stoichAir = 0, excessAir = 0, availableHeat = 0, specificHeat = 0, density = 0, heatValueFuel = 0,
77 flueGasO2 = 0;
78 };
79
98 GasCompositions(std::string substance, const double CH4, const double C2H6, const double N2, const double H2,
99 const double C3H8, const double C4H10_CnH2n, const double H2O, const double CO, const double CO2,
100 const double SO2, const double O2)
101 : substance(std::move(substance)),
102 totalPercent(CH4 + C2H6 + N2 + H2 + C3H8 + C4H10_CnH2n + H2O + CO + CO2 + SO2 + O2),
103 CH4(std::make_shared<GasProperties>([](double t) { return 4.23 + 0.01177 * t; }, 16.042, 0.042417, CH4,
104 CH4 / totalPercent, 64, 23875, 1012, 36.032, 44.01)),
105 C2H6(std::make_shared<GasProperties>([](double t) { return 4.04 + 0.01636 * t; }, 30.068, 0.079503, C2H6,
106 C2H6 / totalPercent, 112, 22323, 1773, 54.048, 88.02)),
107 N2(std::make_shared<GasProperties>([](double t) { return 9.47 - 3.47 * 1000 / t + 1.07 * 1000000 / (t * t); },
108 28.016, 0.074077, N2, N2 / totalPercent, 0, 0, 0, 0, 0)),
109 H2(std::make_shared<GasProperties>([](double t) { return 5.76 + 0.578 * t / 1000 + 20 / pow(t, 0.5); }, 2.016,
110 0.005331, H2, H2 / totalPercent, 16, 61095, 325, 18.016, 0)),
111 C3H8(std::make_shared<GasProperties>(
112 [](double t) {
113 (void)t;
114 return 17.108;
115 },
116 44.094, 0.116589, C3H8, C3H8 / totalPercent, 160, 21669, 2523, 72.064, 132.03)),
117 C4H10_CnH2n(std::make_shared<GasProperties>(
118 [](double t) {
119 (void)t;
120 return 22.202;
121 },
122 58.12, 0.153675, C4H10_CnH2n, C4H10_CnH2n / totalPercent, 208, 21321, 3270, 90.08, 176.04)),
123 H2O(std::make_shared<GasProperties>([](double t) { return 19.86 - 597 / pow(t, 0.5) + 7500 / t; }, 18.016,
124 0.047636, H2O, H2O / totalPercent, 0, 0, 0, 18.016, 0)),
125 CO(std::make_shared<GasProperties>([](double t) { return 9.46 - 3.29 * 1000 / t + 1.07 * 1000000 / (t * t); },
126 28.01, 0.074061, CO, CO / totalPercent, 16, 4347, 321, 0, 44.01)),
127 CO2(std::make_shared<GasProperties>(
128 [](double t) { return 16.2 - 6.53 * 1000 / t + 1.41 * 1000000 / (t * t); }, 44.01, 0.116367, CO2,
129 CO2 / totalPercent, 0, 0, 0, 0, 44.01)),
130 SO2(std::make_shared<GasProperties>(
131 [](double t) {
132 (void)t;
133 return 17.472;
134 },
135 64.06, 0.169381, SO2, SO2 * 100 / totalPercent, 0, 0, 0, 0, 0)),
136 O2(std::make_shared<GasProperties>([](double t) { return 11.515 - 172 / pow(t, 0.5) + 1530 / t; }, 32.00,
137 0.084611, O2, O2 / totalPercent, -32, 0, 0, 0, 0)) {
138 gasses = {{"CH4", this->CH4}, {"C2H6", this->C2H6}, {"N2", this->N2},
139 {"H2", this->H2}, {"C3H8", this->C3H8}, {"C4H10_CnH2n", this->C4H10_CnH2n},
140 {"H2O", this->H2O}, {"CO", this->CO}, {"CO2", this->CO2},
141 {"SO2", this->SO2}, {"O2", this->O2}};
142
143 calculateCompByWeight();
144 heatingValue = calculateHeatingValueFuel();
145 heatingValueVolume = calculateHeatingValueFuelVolume();
146 specificGravity = calculateSpecificGravity();
147 stoichometricAir = calculateStoichometricAir();
148 }
149
155 double getGasByVol(const std::string& gasName) const {
156 auto const gas = gasses.find(gasName);
157 if (gas == gasses.end()) {
158 throw std::runtime_error("Cannot find " + gasName + " in gasses");
159 }
160 return gas->second->compByVol;
161 }
162
163 double getHeatingValue() const { return heatingValue; };
164 double getHeatingValueVolume() const { return heatingValueVolume; };
165 double getSpecificGravity() const { return specificGravity; };
166 double getStoichometricAir() const { return stoichometricAir; };
167
173 double getSaturationTemperature(const double ppH2O) const;
174
180 double getEnthalpyAtSaturation(const double ppH2O) const;
181
203 ProcessHeatPropertiesResults getProcessHeatProperties(const double flueGasTempF, const double flueGasO2,
204 const double combAirTemperatureF, const double fuelTempF = 60,
205 const double ambientAirTempF = 60,
206 const double combAirMoisturePerc = 0,
207 const double excessAir = 0);
208
209 double calculateExcessAir(double flueGasO2);
210 double calculateO2(double excessAir);
211
216 std::string getSubstance() const;
217
222 int getID() const { return this->id; }
223
228 void setID(const int id) { this->id = id; }
229
230 private:
231 friend class GasFlueGasMaterial;
232 friend class DefaultData;
233
234 double calculateSpecificGravity();
235 double calculateStoichometricAir();
236
237 void calculateCompByWeight();
238 double calculateSensibleHeat(double combustionAirTemp);
239 double calculateHeatCombustionAir(double combustionAirTemp, double excessAir);
240 void calculateMassFlueGasComponents(double excessAir);
241 double calculateHeatingValueFuel();
242 double calculateHeatingValueFuelVolume();
243 void calculateEnthalpy();
244 double calculateTotalHeatContentFlueGas(double flueGasTemperature);
245
246 GasCompositions(std::string substance, const double CH4, const double C2H6, const double N2, const double H2,
247 const double C3H8, const double C4H10_CnH2n, const double H2O, const double CO, const double CO2,
248 const double SO2, const double O2, const double heatingValue, const double heatingValueVolume,
249 const double specificGravity, const double stoichometricAir = 0)
250 : substance(std::move(substance)),
251 totalPercent(CH4 + C2H6 + N2 + H2 + C3H8 + C4H10_CnH2n + H2O + CO + CO2 + SO2 + O2),
252 CH4(std::make_shared<GasProperties>([](double t) { return 4.23 + 0.01177 * t; }, 16.042, 0.042417, CH4,
253 CH4 / totalPercent, 64, 23875, 1012, 36.032, 44.01)),
254 C2H6(std::make_shared<GasProperties>([](double t) { return 4.04 + 0.01636 * t; }, 30.068, 0.079503, C2H6,
255 C2H6 / totalPercent, 112, 22323, 1773, 54.048, 88.02)),
256 N2(std::make_shared<GasProperties>([](double t) { return 9.47 - 3.47 * 1000 / t + 1.07 * 1000000 / (t * t); },
257 28.016, 0.074077, N2, N2 / totalPercent, 0, 0, 0, 0, 0)),
258 H2(std::make_shared<GasProperties>([](double t) { return 5.76 + 0.578 * t / 1000 + 20 / pow(t, 0.5); }, 2.016,
259 0.005331, H2, H2 / totalPercent, 16, 61095, 325, 18.016, 0)),
260 C3H8(std::make_shared<GasProperties>(
261 [](double t) {
262 (void)t;
263 return 17.108;
264 },
265 44.094, 0.116589, C3H8, C3H8 / totalPercent, 160, 21669, 2523, 72.064, 132.03)),
266 C4H10_CnH2n(std::make_shared<GasProperties>(
267 [](double t) {
268 (void)t;
269 return 22.202;
270 },
271 58.12, 0.153675, C4H10_CnH2n, C4H10_CnH2n / totalPercent, 208, 21321, 3270, 90.08, 176.04)),
272 H2O(std::make_shared<GasProperties>([](double t) { return 19.86 - 597 / pow(t, 0.5) + 7500 / t; }, 18.016,
273 0.047636, H2O, H2O / totalPercent, 0, 0, 0, 18.016, 0)),
274 CO(std::make_shared<GasProperties>([](double t) { return 9.46 - 3.29 * 1000 / t + 1.07 * 1000000 / (t * t); },
275 28.01, 0.074061, CO, CO / totalPercent, 16, 4347, 321, 0, 44.01)),
276 CO2(std::make_shared<GasProperties>(
277 [](double t) { return 16.2 - 6.53 * 1000 / t + 1.41 * 1000000 / (t * t); }, 44.01, 0.116367, CO2,
278 CO2 / totalPercent, 0, 0, 0, 0, 44.01)),
279 SO2(std::make_shared<GasProperties>(
280 [](double t) {
281 (void)t;
282 return 17.472;
283 },
284 64.06, 0.169381, SO2, SO2 * 100 / totalPercent, 0, 0, 0, 0, 0)),
285 O2(std::make_shared<GasProperties>([](double t) { return 11.515 - 172 / pow(t, 0.5) + 1530 / t; }, 32.00,
286 0.084611, O2, O2 / totalPercent, -32, 0, 0, 0, 0)),
287 heatingValue(heatingValue), specificGravity(specificGravity), heatingValueVolume(heatingValueVolume),
288 stoichometricAir(stoichometricAir) {
289 gasses = {{"CH4", this->CH4}, {"C2H6", this->C2H6}, {"N2", this->N2},
290 {"H2", this->H2}, {"C3H8", this->C3H8}, {"C4H10_CnH2n", this->C4H10_CnH2n},
291 {"H2O", this->H2O}, {"CO", this->CO}, {"CO2", this->CO2},
292 {"SO2", this->SO2}, {"O2", this->O2}};
293 }
294
295 // the hash map holds a reference to the GasProperties below for easier iterable summations
296 std::unordered_map<std::string, std::shared_ptr<GasProperties>> gasses;
297 int id = 0;
298 std::string substance;
299 double totalPercent;
300 double hH2Osat = 0, tH2Osat = 0;
301 double mH2O = 0, mCO2 = 0, mO2 = 0, mN2 = 0, mSO2 = 0;
302 std::shared_ptr<GasProperties> CH4, C2H6, N2, H2, C3H8, C4H10_CnH2n, H2O, CO, CO2, SO2, O2;
303 double heatingValue = 0, specificGravity = 0, heatingValueVolume = 0, stoichometricAir = 0;
304
310 double getExcessAir(const double flueGasO2) const;
311
312 void flueGasO2AdjustForCalcError(const double excessAir, double& flueO2) const;
313};
314
325 public:
336 GasFlueGasMaterial(const double flueGasTemperature, const double excessAirPercentage,
337 const double combustionAirTemperature, GasCompositions compositions,
338 const double fuelTemperature)
339 : flueGasTemperature(flueGasTemperature), excessAirPercentage(excessAirPercentage / 100.0),
340 combustionAirTemperature(combustionAirTemperature), fuelTemperature(fuelTemperature),
341 compositions(std::move(compositions)) {}
342
351 double getHeatLoss();
352
353 private:
354 const double flueGasTemperature, excessAirPercentage, combustionAirTemperature, fuelTemperature;
355 GasCompositions compositions;
356};
357#endif // TOOLS_SUITE_GASFLUEGASMATERIAL_H
ProcessHeatPropertiesResults getProcessHeatProperties(const double flueGasTempF, const double flueGasO2, const double combAirTemperatureF, const double fuelTempF=60, const double ambientAirTempF=60, const double combAirMoisturePerc=0, const double excessAir=0)
double getGasByVol(const std::string &gasName) const
void setID(const int id)
std::string getSubstance() const
GasCompositions(std::string substance, const double CH4, const double C2H6, const double N2, const double H2, const double C3H8, const double C4H10_CnH2n, const double H2O, const double CO, const double CO2, const double SO2, const double O2)
double getExcessAir(const double flueGasO2) const
double getEnthalpyAtSaturation(const double ppH2O) const
double getSaturationTemperature(const double ppH2O) const
GasFlueGasMaterial(const double flueGasTemperature, const double excessAirPercentage, const double combustionAirTemperature, GasCompositions compositions, const double fuelTemperature)
GasProperties(std::function< double(double t)> specificHeat, const double molecularWeight, const double specificWeight, const double compPercent, const double compByVol, const int o2Generated, const int heatingValue, const int heatingValueVolume, const double h2oGenerated, const double co2Generated)