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
fan203.h
Go to the documentation of this file.
1
7#pragma once
8
9#include <cmath>
10#include <functional>
11#include <stdexcept>
12#include <vector>
13
14#include "motorDriven/fans/Planar.h"
15#include "motorDriven/pumpFan/FanShaftPower.h"
16
51
57 public:
62 enum class GasType { AIR, STANDARDAIR, OTHERGAS };
67 enum class InputType { DewPoint, RelativeHumidity, WetBulbTemp };
68
76 // used for method 1
77 BaseGasDensity(const double dryBulbTemp, const double staticPressure, const double barometricPressure,
78 const double gasDensity, const GasType gasType)
79 : tdo(dryBulbTemp), pso(staticPressure), pbo(barometricPressure), gasDensity(gasDensity), gasType(gasType) {}
99 // TODO ensure correctness
100 BaseGasDensity(double const dryBulbTemp, double const staticPressure, double const barometricPressure,
101 double const relativeHumidityOrDewPoint, GasType const gasType, InputType const inputType,
102 double const specificGravity)
103 : tdo(dryBulbTemp), pso(staticPressure), pbo(barometricPressure), g(specificGravity), gasType(gasType) {
104 saturationPressure = calculateSaturationPressure(tdo);
105 relativeHumidity = 0;
106 if (inputType == InputType::RelativeHumidity) {
107 relativeHumidity = relativeHumidityOrDewPoint / 100;
108 }
109 else if (inputType == InputType::DewPoint) {
110 relativeHumidity = calculateSaturationPressure(relativeHumidityOrDewPoint) / saturationPressure;
111 }
112 else if (inputType == InputType::WetBulbTemp) {
113 throw std::runtime_error(
114 "The wrong constructor for BaseGasDensity was called here - check inputType field");
115 }
116
117 calculateFanAttributes(inputType, relativeHumidityOrDewPoint);
118
119 /*
120 std::ofstream fout;
121 fout.open("debug.txt", std::ios::app);
122 fout << "gasDensity: " << gasDensity << std::endl;
123 fout << "absolutePressure: " << absolutePressure << std::endl;
124 fout << "saturatedHumidity: " << saturatedHumidity << std::endl;
125 fout << "saturationDegree: " << saturationDegree << std::endl;
126 fout << "humidityRatio: " << humidityRatio << std::endl;
127 fout << "specificVolume: " << specificVolume << std::endl;
128 fout << "enthalpy: " << enthalpy << std::endl;
129 fout << "dewPoint: " << dewPoint << std::endl;
130 fout << "relativeHumidity: " << relativeHumidity << std::endl;
131 fout << "saturationPressure: " << saturationPressure << std::endl;
132 fout << "------------------------------" << std::endl << std::endl;
133 fout.close();
134 */
135 }
136
137 BaseGasDensity(double const dryBulbTemp, double const staticPressure, double const barometricPressure,
138 double const wetBulbTemp, GasType const gasType, InputType const inputType,
139 double const specificGravity, const double cpGas)
140 : tdo(dryBulbTemp), pso(staticPressure), pbo(barometricPressure), wetBulbTemp(wetBulbTemp), g(specificGravity),
141 gasType(gasType) {
142 if (inputType != InputType::WetBulbTemp)
143 throw std::runtime_error("The wrong constructor for BaseGasDensity was called - check inputType field");
144 saturationPressure = calculateSaturationPressure(tdo);
145 relativeHumidity = calculateRelativeHumidityFromWetBulb(tdo, wetBulbTemp, cpGas);
146
147 calculateFanAttributes(inputType);
148
149 /*
150 std::ofstream fout;
151 fout.open("debug.txt", std::ios::app);
152 fout << "Wet Bulb" << std::endl;
153 fout << "gasDensity: " << gasDensity << std::endl;
154 fout << "absolutePressure: " << absolutePressure << std::endl;
155 fout << "saturatedHumidity: " << saturatedHumidity << std::endl;
156 fout << "saturationDegree: " << saturationDegree << std::endl;
157 fout << "humidityRatio: " << humidityRatio << std::endl;
158 fout << "specificVolume: " << specificVolume << std::endl;
159 fout << "enthalpy: " << enthalpy << std::endl;
160 fout << "dewPoint: " << dewPoint << std::endl;
161 fout << "relativeHumidity: " << relativeHumidity << std::endl;
162 fout << "saturationPressure: " << saturationPressure << std::endl;
163 fout << "------------------------------" << std::endl << std::endl;
164 fout.close();
165 */
166 }
167
168 double getGasDensity() const {
169 return gasDensity; // po
170 }
171 double getAbsolutePressureIn() const {
172 return absolutePressure; // pIn
173 }
174 double getSaturatedHumidityRatio() const {
175 return saturatedHumidity; // satW
176 }
177 double getDegreeOfSaturation() const {
178 return saturationDegree; // satDeg
179 }
180 double getHumidityRatio() const {
181 return humidityRatio; // humW
182 }
183 double getSpecificVolume() const {
184 return specificVolume; // specVol
185 }
186 double getEnthalpy() const { return enthalpy; }
187 double getDewPoint() const { return dewPoint; }
188 double getRelativeHumidity() const {
189 return relativeHumidity; // rh
190 }
191 double getSaturationPressure() const {
192 return saturationPressure; // satPress
193 }
194 double getWetBulbTemp() const {
195 return wetBulbTemp; // Tdb
196 }
197
198 private:
207 double calculateWetBulbTemperature(double dryBulbTemp, double relativeHumidity, double absolutePressure) const {
208 // Newton-Raphson iteration (solve to within 0.001% accuracy)
209
210 double humidityRatioNormal = calculateRatioRH(dryBulbTemp, relativeHumidity, absolutePressure, 1);
211 double wetBulbTemp = dryBulbTemp; // set initial guess
212 double humidityRatioNew = calculateHumidityRatioFromWetBulb(dryBulbTemp, wetBulbTemp, 0.24);
213 if (humidityRatioNormal > 0) {
214 while (fabs((humidityRatioNew - humidityRatioNormal) / humidityRatioNormal) > 0.00001) {
215 double humidityRatioNew2 = calculateHumidityRatioFromWetBulb(dryBulbTemp, wetBulbTemp - 0.001, 0.24);
216 double dw_dtwb = (humidityRatioNew - humidityRatioNew2) / 0.001;
217 wetBulbTemp = wetBulbTemp - (humidityRatioNew - humidityRatioNormal) / dw_dtwb;
218 humidityRatioNew = calculateHumidityRatioFromWetBulb(dryBulbTemp, wetBulbTemp, 0.24);
219 }
220 }
221 else {
222 while (fabs(humidityRatioNew) > 0.00001) {
223 double humidityRatioNew2 = calculateHumidityRatioFromWetBulb(dryBulbTemp, wetBulbTemp - 0.001, 0.24);
224 double dw_dtwb = (humidityRatioNew - humidityRatioNew2) / 0.001;
225 wetBulbTemp = wetBulbTemp - (humidityRatioNew - humidityRatioNormal) / dw_dtwb;
226 humidityRatioNew = calculateHumidityRatioFromWetBulb(dryBulbTemp, wetBulbTemp, 0.24);
227 }
228 }
229 return wetBulbTemp;
230 }
237 double calculateSaturationPressure(double dryBulbTemp) const {
238 double const C1 = -5674.5359;
239 double const C2 = 6.3925247;
240 double const C3 = -0.009677843;
241 double const C4 = 0.00000062215701;
242 double const C5 = 2.0747825 * std::pow(10, -9);
243 double const C6 = -9.484024 * std::pow(10, -13);
244 double const C7 = 4.1635019;
245 double const C8 = -5800.2206;
246 double const C9 = 1.3914993;
247 double const C10 = -0.048640239;
248 double const C11 = 0.000041764768;
249 double const C12 = -0.000000014452093;
250 double const C13 = 6.5459673;
251
252 double const tKelvin = (dryBulbTemp + 459.67) * 0.555556;
253
254 if (tKelvin < 273.15) {
255 double const p =
256 std::exp(C1 / tKelvin + C2 + tKelvin * C3 + tKelvin * tKelvin * (C4 + tKelvin * (C5 + C6 * tKelvin)) +
257 C7 * std::log(tKelvin));
258 return p * (29.9216 / 101325);
259 }
260 double const p =
261 std::exp(C8 / tKelvin + C9 + tKelvin * (C10 + tKelvin * (C11 + tKelvin * C12)) + C13 * std::log(tKelvin));
262
263 return p * (29.9216 / 101325);
264 }
274 double calculateRatioRH(const double dryBulbTemp, const double relativeHumidity, const double barometricPressure,
275 const double specificGravity) const {
276 auto const pw = (calculateSaturationPressure(dryBulbTemp) * relativeHumidity);
277 return (18.02 / (specificGravity * 28.98)) * pw / (barometricPressure - pw);
278 }
286 double calculateRelativeHumidityFromWetBulb(const double dryBulbTemp, const double wetBulbTemp,
287 const double cpGas) const {
288 double const nMol = 0.62198;
289 double const local_pIn = pbo + (pso / 13.608703);
290 // double const pAtm = 29.9213 / pbo, nMol = 18.02 / (g * 28.98);
291 double const pumpDb = calculateSaturationPressure(dryBulbTemp);
292 // double const wSat = nMol * pumpDb / (pAtm - pumpDb);
293 double const pumpWb = calculateSaturationPressure(wetBulbTemp);
294 double const wStar = nMol * pumpWb / (local_pIn - pumpWb);
295 double const w = ((1093 - (1 - 0.444) * wetBulbTemp) * wStar - cpGas * (dryBulbTemp - wetBulbTemp)) /
296 (1093 + (0.444 * dryBulbTemp) - wetBulbTemp);
297
298 double const pV = local_pIn * w / (nMol + w);
299
300 return pV / pumpDb;
301 }
310 double calculateHumidityRatioFromWetBulb(const double dryBulbTemp, const double wetBulbTemp,
311 const double cpGas) const {
312 double const nMol = 0.62198;
313 double const local_pIn = pbo + (pso / 13.608703);
314
315 double const pumpWb = calculateSaturationPressure(wetBulbTemp);
316 double const wStar = nMol * pumpWb / (local_pIn - pumpWb);
317 double const w = ((1093 - (1 - 0.444) * wetBulbTemp) * wStar - cpGas * (dryBulbTemp - wetBulbTemp)) /
318 (1093 + (0.444 * dryBulbTemp) - wetBulbTemp);
319
320 return w;
321 }
329 void calculateFanAttributes(InputType const inputType, double const relativeHumidityOrDewPoint = -1) {
330 double const nMol = 0.62198;
331
332 absolutePressure = pbo + (pso / 13.608703);
333 saturatedHumidity = nMol * saturationPressure / (absolutePressure - saturationPressure);
334 saturationDegree = relativeHumidity / (1 + (1 - relativeHumidity) * saturatedHumidity / nMol);
335 humidityRatio = saturationDegree * saturatedHumidity;
336 specificVolume =
337 (10.731557 * (tdo + 459.67) * (1 + 1.6078 * humidityRatio)) / (28.9645 * absolutePressure * 0.4911541);
338 gasDensity = (1 / specificVolume) * (1 + humidityRatio);
339 enthalpy = (0.247 * tdo) + (humidityRatio * (1061 + 0.444 * tdo));
340
341 if (inputType != InputType::DewPoint) {
342 double const alpha = std::log(absolutePressure * 0.4911541 * humidityRatio / (nMol + humidityRatio));
343
344 if (tdo < 32) {
345 dewPoint = 90.12 + 26.412 * alpha + 0.8927 * alpha * alpha;
346 }
347 else {
348 dewPoint =
349 100.45 + 33.193 * alpha + 2.319 * alpha * alpha + 0.17074 * alpha * alpha * alpha +
350 1.2063 *
351 (std::pow((absolutePressure * 0.4911541 * humidityRatio / (0.62196 + humidityRatio)), 0.1984));
352 }
353 }
354 else {
355 dewPoint = relativeHumidityOrDewPoint;
356 }
357
358 if (inputType !=
359 InputType::WetBulbTemp) // If not given as an input, calculateThermalResistance wet bulb temperature
360 {
361 wetBulbTemp = calculateWetBulbTemperature(tdo, relativeHumidity, absolutePressure);
362 }
363 }
364
365 // dry bulb temp, reference static pressure, reference barometric pressure, gas density respectively
366 const double tdo, pso, pbo;
367 double wetBulbTemp = 0;
368
369 // gasDensity, specificGravity
374 double gasDensity = 0, g = 0;
375 const GasType gasType;
376
389 double absolutePressure = 0, saturatedHumidity = 0, saturationDegree = 0, humidityRatio = 0, specificVolume = 0,
390 enthalpy = 0, dewPoint = 0, relativeHumidity = 0, saturationPressure = 0;
391
392 friend class PlaneData;
393 friend class Fan203;
394};
395
402 public:
403 // used to access private stuff from the nan bindings
411 struct NodeBinding {
412 struct Data {
413 Data(const double density, const double velocity, const double volumeFlowRate,
414 const double velocityPressure, const double totalPressure)
415 : gasDensity(density), gasVelocity(velocity), gasVolumeFlowRate(volumeFlowRate),
416 gasVelocityPressure(velocityPressure), gasTotalPressure(totalPressure) {}
417
418 double gasDensity = 0, gasVelocity = 0, gasVolumeFlowRate = 0, gasVelocityPressure = 0,
419 gasTotalPressure = 0;
420 };
429 struct DataFlange : Data {
430 DataFlange(const double density, const double velocity, const double volumeFlowRate,
431 const double velocityPressure, const double totalPressure, const double staticPressure)
432 : Data(density, velocity, volumeFlowRate, velocityPressure, totalPressure),
433 staticPressure(staticPressure) {}
434
435 double staticPressure = 0;
436 };
437 struct Output {
438 explicit Output(PlaneData const& planeData)
439 : fanInletFlange(getDataFlange(planeData.fanInletFlange)),
440 fanOrEvaseOutletFlange(getDataFlange(planeData.fanOrEvaseOutletFlange)),
441 flowTraverse(getData(planeData.flowTraverse)), inletMstPlane(getData(planeData.inletMstPlane)),
442 outletMstPlane(getData(planeData.outletMstPlane)),
443 addlTravPlanes(getDataTrav(planeData.addlTravPlanes)) {}
444 DataFlange fanInletFlange, fanOrEvaseOutletFlange;
445 Data flowTraverse, inletMstPlane, outletMstPlane;
446 std::vector<Data> addlTravPlanes;
447 };
448 static Output calculate(PlaneData& planeData, BaseGasDensity const& baseGasDensity) {
449 planeData.calculate(baseGasDensity);
450 return Output(planeData);
451 }
452
453 private:
454 static Data getData(Planar const& plane) {
455 return {plane.gasDensity, plane.gasVelocity, plane.gasVolumeFlowRate, plane.gasVelocityPressure,
456 plane.gasTotalPressure};
457 }
458 static DataFlange getDataFlange(Planar const& plane) {
459 return {plane.gasDensity, plane.gasVelocity, plane.gasVolumeFlowRate,
460 plane.gasVelocityPressure, plane.gasTotalPressure, plane.staticPressure};
461 }
462 static std::vector<Data> getDataTrav(std::vector<TraversePlane> const& addlPlanes) {
463 std::vector<Data> data;
464 for (auto const& plane : addlPlanes) {
465 data.push_back({plane.gasDensity, plane.gasVelocity, plane.gasVolumeFlowRate, plane.gasVelocityPressure,
466 plane.gasTotalPressure});
467 }
468 return data;
469 }
470 };
471
472 PlaneData(FlangePlane fanInletFlange, FlangePlane fanOrEvaseOutletFlange, TraversePlane flowTraverse,
473 std::vector<TraversePlane> addlTravPlanes, MstPlane inletMstPlane, MstPlane outletMstPlane,
474 const double totalPressureLossBtwnPlanes1and4, const double totalPressureLossBtwnPlanes2and5,
475 bool const plane5upstreamOfPlane2)
476 : fanInletFlange(std::move(fanInletFlange)), fanOrEvaseOutletFlange(std::move(fanOrEvaseOutletFlange)),
477 flowTraverse(std::move(flowTraverse)), addlTravPlanes(std::move(addlTravPlanes)),
478 inletMstPlane(std::move(inletMstPlane)), outletMstPlane(std::move(outletMstPlane)),
479 plane5upstreamOfPlane2(plane5upstreamOfPlane2),
480 totalPressureLossBtwnPlanes1and4(totalPressureLossBtwnPlanes1and4),
481 totalPressureLossBtwnPlanes2and5(totalPressureLossBtwnPlanes2and5) {}
482
483 private:
484 void establishFanInletOrOutletDensity(Planar& plane,
485 std::function<double(Planar const&, const double)> const& calcDensity,
486 double const mTotal, double const assumedDensity) {
487 double calculatedDensity = assumedDensity;
488 for (auto i = 0; i < 50; i++) {
489 plane.gasDensity = calculatedDensity;
490 plane.gasVolumeFlowRate = mTotal / plane.gasDensity;
491 plane.gasVelocity = plane.gasVolumeFlowRate / plane.area;
492 plane.gasVelocityPressure = plane.gasDensity * std::pow(plane.gasVelocity / 1096, 2);
493 double fanInletOrOutletStaticPressure = plane.gasTotalPressure - plane.gasVelocityPressure;
494 double fanInletOrOutletGasDensity = calcDensity(plane, fanInletOrOutletStaticPressure);
495
496 calculatedDensity = fanInletOrOutletGasDensity;
497 if (fabs(fanInletOrOutletGasDensity - plane.gasDensity) < 0.0001) {
498 plane.gasDensity = fanInletOrOutletGasDensity;
499 plane.staticPressure = fanInletOrOutletStaticPressure;
500 return;
501 }
502 }
503 throw std::runtime_error("In PlaneData::establishFanInletOrOutletDensity - density iteration did not converge");
504 }
505
506 void calculate(BaseGasDensity const& bgd) {
507 /*
508 If using custom density or the fields for dry bulb temperature, static pressure and barometric pressure are
509 blank in "Base Gas Density", then the desktop is sending the values entered for Plane 3a (the first traverse
510 plane).
511 */
512 auto const calcDensity = [&bgd](Planar const& plane, const double psx) {
513 return bgd.gasDensity * (bgd.tdo + 460) * (psx + 13.63 * plane.barometricPressure) /
514 ((plane.dryBulbTemperature + 460) * (bgd.pso + 13.63 * bgd.pbo));
515 };
516
517 flowTraverse.gasDensity = calcDensity(flowTraverse, flowTraverse.staticPressure);
518 for (auto& p : addlTravPlanes) {
519 p.gasDensity = calcDensity(p, p.staticPressure);
520 }
521 inletMstPlane.gasDensity = calcDensity(inletMstPlane, inletMstPlane.staticPressure);
522 outletMstPlane.gasDensity = calcDensity(outletMstPlane, outletMstPlane.staticPressure);
523
524 flowTraverse.gasVelocity = 1096 * std::sqrt(flowTraverse.pv3 / flowTraverse.gasDensity);
525 flowTraverse.gasVolumeFlowRate = flowTraverse.gasVelocity * flowTraverse.area;
526 // MARK ADDITION FOR issue 259
527 flowTraverse.gasVelocityPressure = flowTraverse.gasDensity * std::pow((flowTraverse.gasVelocity / 1096), 2);
528 flowTraverse.gasTotalPressure = flowTraverse.staticPressure + flowTraverse.gasVelocityPressure;
529
530 double mTotal = flowTraverse.gasDensity * flowTraverse.gasVolumeFlowRate;
531 for (auto& plane : addlTravPlanes) {
532 plane.gasVelocity = 1096 * std::sqrt(plane.pv3 / plane.gasDensity);
533 plane.gasVolumeFlowRate = plane.gasVelocity * plane.area;
534 // MARK ADDITION FOR issue 259
535 plane.gasVelocityPressure = plane.gasDensity * std::pow((plane.gasVelocity / 1096), 2);
536 plane.gasTotalPressure = plane.staticPressure + plane.gasVelocityPressure;
537 mTotal += plane.gasDensity * plane.gasVolumeFlowRate;
538 }
539
540 inletMstPlane.gasVolumeFlowRate = mTotal / inletMstPlane.gasDensity;
541 inletMstPlane.gasVelocity = inletMstPlane.gasVolumeFlowRate / inletMstPlane.area;
542 inletMstPlane.gasVelocityPressure = inletMstPlane.gasDensity * std::pow((inletMstPlane.gasVelocity / 1096), 2);
543 inletMstPlane.gasTotalPressure = inletMstPlane.staticPressure + inletMstPlane.gasVelocityPressure;
544
545 // step 7
546 fanInletFlange.gasTotalPressure = inletMstPlane.gasTotalPressure - totalPressureLossBtwnPlanes1and4;
547
548 // steps 8 - 13
549 establishFanInletOrOutletDensity(fanInletFlange, calcDensity, mTotal, inletMstPlane.gasDensity);
550
551 // calculating plane 2 inlet density and pressure
552 outletMstPlane.gasVolumeFlowRate = mTotal / outletMstPlane.gasDensity;
553 outletMstPlane.gasVelocity = outletMstPlane.gasVolumeFlowRate / outletMstPlane.area;
554 outletMstPlane.gasVelocityPressure = outletMstPlane.gasDensity * std::pow(outletMstPlane.gasVelocity / 1096, 2);
555 outletMstPlane.gasTotalPressure = outletMstPlane.staticPressure + outletMstPlane.gasVelocityPressure;
556
557 // step 7
558 fanOrEvaseOutletFlange.gasTotalPressure = outletMstPlane.gasTotalPressure;
559 fanOrEvaseOutletFlange.gasTotalPressure +=
560 (plane5upstreamOfPlane2) ? -totalPressureLossBtwnPlanes2and5 : totalPressureLossBtwnPlanes2and5;
561
562 // step 8 - iteration
563 establishFanInletOrOutletDensity(fanOrEvaseOutletFlange, calcDensity, mTotal, outletMstPlane.gasDensity);
564 }
565
566 FlangePlane fanInletFlange, fanOrEvaseOutletFlange;
567 TraversePlane flowTraverse;
568 std::vector<TraversePlane> addlTravPlanes;
569 MstPlane inletMstPlane;
570 MstPlane outletMstPlane;
571
572 bool const plane5upstreamOfPlane2;
573 const double totalPressureLossBtwnPlanes1and4, totalPressureLossBtwnPlanes2and5;
574
575 friend class Fan203;
576 friend struct NodeBinding;
577};
578
584class Fan203 {
585 public:
586 Fan203(FanRatedInfo fanRatedInfo, PlaneData planeData, BaseGasDensity baseGasDensity, FanShaftPower fanShaftPower)
587 : fanRatedInfo(fanRatedInfo), planeData(std::move(planeData)), baseGasDensity(baseGasDensity),
588 fanShaftPower(fanShaftPower) {
589 this->planeData.calculate(this->baseGasDensity);
590 };
591
592 struct Results {
593 Results(const double kpc, const double power, const double flow, const double pressureTotal,
594 const double pressureStatic, const double staticPressureRise)
595 : kpc(kpc), power(power), flow(flow), pressureTotal(pressureTotal), pressureStatic(pressureStatic),
596 staticPressureRise(staticPressureRise) {}
597 const double kpc, power, flow, pressureTotal;
598 const double pressureStatic, staticPressureRise;
599 };
600
601 struct Output {
602 Output(const double fanEfficiencyTotalPressure, const double fanEfficiencyStaticPressure,
603 const double fanEfficiencyStaticPressureRise, const Results asTested, const Results converted)
604 : fanEfficiencyTotalPressure(fanEfficiencyTotalPressure),
605 fanEfficiencyStaticPressure(fanEfficiencyStaticPressure),
606 fanEfficiencyStaticPressureRise(fanEfficiencyStaticPressureRise), asTested(asTested),
607 converted(converted) {}
608
609 const double fanEfficiencyTotalPressure, fanEfficiencyStaticPressure, fanEfficiencyStaticPressureRise;
610 const Results asTested, converted;
611 };
612
613 Output calculate() {
614 // TODO barometricPressure = barometric pressure, what to do if barometric pressure does vary between planes ?
615 // pg
616 double const x =
617 (planeData.fanOrEvaseOutletFlange.gasTotalPressure - planeData.fanInletFlange.gasTotalPressure) /
618 (planeData.fanInletFlange.gasTotalPressure + 13.63 * planeData.fanInletFlange.barometricPressure);
619
620 double isentropicExponent = 1.4; // TODO what value to use for GasTypes other than Air ?
621 if (baseGasDensity.gasType == BaseGasDensity::GasType::AIR)
622 isentropicExponent = 1.4;
623
624 // TODO barometricPressure = barometric pressure, what to do if barometric pressure does vary between planes ?
625 // pg 61
626 double const z =
627 ((isentropicExponent - 1) / isentropicExponent) *
628 ((6362 * fanShaftPower.getFanPowerInput() / planeData.fanInletFlange.gasVolumeFlowRate) /
629 (planeData.fanInletFlange.gasTotalPressure + 13.63 * planeData.fanInletFlange.barometricPressure));
630
631 double const kp = (std::log(1 + x) / x) * (z / (std::log(1 + z)));
632
633 planeData.flowTraverse.gasTotalPressure =
634 planeData.flowTraverse.staticPressure + planeData.flowTraverse.gasVelocityPressure;
635 for (auto& p : planeData.addlTravPlanes) {
636 p.gasTotalPressure = p.staticPressure + p.gasVelocityPressure;
637 }
638
639 double const fanTotalPressure = planeData.fanOrEvaseOutletFlange.gasTotalPressure -
640 planeData.fanInletFlange.gasTotalPressure + fanShaftPower.getSEF();
641
642 double const fanStaticPressure = planeData.fanOrEvaseOutletFlange.staticPressure -
643 planeData.fanInletFlange.gasTotalPressure + fanShaftPower.getSEF();
644
645 double const staticPressureRise = planeData.fanOrEvaseOutletFlange.staticPressure -
646 planeData.fanInletFlange.staticPressure + fanShaftPower.getSEF();
647
648 double const kpFactorRatio = calculateCompressibilityFactor(x, z, isentropicExponent);
649
650 // // corrected variables
651 // double const qc = planeData.fanInletFlange.gasVolumeFlowRate *
652 // (fanRatedInfo.fanSpeedCorrected / fanRatedInfo.fanSpeed) * kpFactorRatio;
653
654 // double const ptc = fanTotalPressure * kpFactorRatio *
655 // std::pow(fanRatedInfo.fanSpeedCorrected / fanRatedInfo.fanSpeed, 2) *
656 // (fanRatedInfo.densityCorrected / planeData.fanInletFlange.gasDensity);
657
658 // double const psc = fanStaticPressure * kpFactorRatio *
659 // std::pow(fanRatedInfo.fanSpeedCorrected / fanRatedInfo.fanSpeed, 2) *
660 // (fanRatedInfo.densityCorrected / planeData.fanInletFlange.gasDensity);
661
662 // double const sprc = staticPressureRise * kpFactorRatio *
663 // std::pow(fanRatedInfo.fanSpeedCorrected / fanRatedInfo.fanSpeed, 2) *
664 // (fanRatedInfo.densityCorrected / planeData.fanInletFlange.gasDensity);
665
666 // double const hc = fanShaftPower.getFanPowerInput() * kpFactorRatio *
667 // std::pow(fanRatedInfo.fanSpeedCorrected / fanRatedInfo.fanSpeed, 3) *
668 // (fanRatedInfo.densityCorrected / planeData.fanInletFlange.gasDensity);
669
670 double const qc = planeData.fanInletFlange.gasVolumeFlowRate *
671 (fanRatedInfo.fan_speed_corrected / fanRatedInfo.fan_speed) * kpFactorRatio;
672
673 double const ptc = fanTotalPressure * kpFactorRatio *
674 std::pow(fanRatedInfo.fan_speed_corrected / fanRatedInfo.fan_speed, 2) *
675 (fanRatedInfo.density_corrected / planeData.fanInletFlange.gasDensity);
676
677 double const psc = fanStaticPressure * kpFactorRatio *
678 std::pow(fanRatedInfo.fan_speed_corrected / fanRatedInfo.fan_speed, 2) *
679 (fanRatedInfo.density_corrected / planeData.fanInletFlange.gasDensity);
680
681 double const sprc = staticPressureRise * kpFactorRatio *
682 std::pow(fanRatedInfo.fan_speed_corrected / fanRatedInfo.fan_speed, 2) *
683 (fanRatedInfo.density_corrected / planeData.fanInletFlange.gasDensity);
684
685 double const hc = fanShaftPower.getFanPowerInput() * kpFactorRatio *
686 std::pow(fanRatedInfo.fan_speed_corrected / fanRatedInfo.fan_speed, 3) *
687 (fanRatedInfo.density_corrected / planeData.fanInletFlange.gasDensity);
688
689 double const kpc = kp / kpFactorRatio;
690
691 double const efficiency =
692 planeData.fanInletFlange.gasVolumeFlowRate * kp / (6362 * fanShaftPower.getFanPowerInput());
693
694 return {fanTotalPressure * efficiency * 100,
695 fanStaticPressure * efficiency * 100,
696 staticPressureRise * efficiency * 100,
697 {kpFactorRatio, fanShaftPower.getFanPowerInput(), planeData.fanInletFlange.gasVolumeFlowRate,
698 fanTotalPressure, fanStaticPressure, staticPressureRise},
699 {kpc, hc, qc, ptc, psc, sprc}};
700 }
701
702 private:
703 double calculateCompressibilityFactor(const double x, const double z, const double isentropic) {
704 double assumedKpOverKpc = 1.0;
705 auto const& p1 = planeData.fanInletFlange;
706 for (auto i = 0; i < 50; i++) {
707 double const pt1c = p1.gasTotalPressure *
708 std::pow(fanRatedInfo.fan_speed_corrected / fanRatedInfo.fan_speed, 2) *
709 (fanRatedInfo.density_corrected / p1.gasDensity) * assumedKpOverKpc;
710
711 // TODO how to get isentropic exponent for gas at converted conditions? section 9.4.1 step 2
712 double const zOverZc = ((pt1c + 13.63 * fanRatedInfo.pressure_barometric_corrected) /
713 (p1.gasTotalPressure + 13.63 * p1.barometricPressure)) *
714 (p1.gasDensity / fanRatedInfo.density_corrected) *
715 std::pow(fanRatedInfo.fan_speed / fanRatedInfo.fan_speed_corrected, 2) *
716 ((isentropic - 1) / isentropic) * (isentropic / (isentropic - 1));
717
718 double const zc = z / zOverZc;
719
720 double const ln1xc = std::log(1 + x) * ((std::log(1 + zc) / std::log(1 + z))) *
721 ((isentropic - 1) / isentropic) * (isentropic / (isentropic - 1));
722
723 double const xc = std::exp(ln1xc) - 1;
724
725 double const kpOverKpc =
726 (z / zc) * (xc / x) * (isentropic / (isentropic - 1)) * ((isentropic - 1) / isentropic);
727 if (fabs(kpOverKpc - assumedKpOverKpc) < 0.0000001) {
728 return kpOverKpc;
729 }
730 assumedKpOverKpc = kpOverKpc;
731 }
732 throw std::runtime_error("compressibility factor ratio iteration did not converge");
733 }
734
735 FanRatedInfo const fanRatedInfo;
736 PlaneData planeData;
737 BaseGasDensity const baseGasDensity;
738 FanShaftPower const fanShaftPower;
739};
BaseGasDensity(double const dryBulbTemp, double const staticPressure, double const barometricPressure, double const relativeHumidityOrDewPoint, GasType const gasType, InputType const inputType, double const specificGravity)
Definition fan203.h:100
double absolutePressure
Definition fan203.h:389
double calculateSaturationPressure(double dryBulbTemp) const
Calculates Saturation Pressure.
Definition fan203.h:237
void calculateFanAttributes(InputType const inputType, double const relativeHumidityOrDewPoint=-1)
Calculates numerous fan attributes. Note: This function assumes that the member variables pbo,...
Definition fan203.h:329
double gasDensity
Definition fan203.h:374
BaseGasDensity(const double dryBulbTemp, const double staticPressure, const double barometricPressure, const double gasDensity, const GasType gasType)
Definition fan203.h:77
double calculateRelativeHumidityFromWetBulb(const double dryBulbTemp, const double wetBulbTemp, const double cpGas) const
Calculates Relative Humidity from Wet Bulb Temperature.
Definition fan203.h:286
double calculateWetBulbTemperature(double dryBulbTemp, double relativeHumidity, double absolutePressure) const
Calculates Wet Bulb Temperature.
Definition fan203.h:207
double calculateRatioRH(const double dryBulbTemp, const double relativeHumidity, const double barometricPressure, const double specificGravity) const
Calculates Relative Humidity Ratio.
Definition fan203.h:274
double calculateHumidityRatioFromWetBulb(const double dryBulbTemp, const double wetBulbTemp, const double cpGas) const
Calculates Relative Humidity Ratio from Wet Bulb Temperature.
Definition fan203.h:310
double getFanPowerInput() const
double getSEF() const
double dryBulbTemperature
Definition Planar.h:73
Stores measured and reference-corrected fan and motor operating data for AMCA 203 calculations.
Definition fan203.h:26
double density_corrected
Gas density corrected to reference conditions .
Definition fan203.h:30
double fan_speed_corrected
Fan speed corrected to reference conditions .
Definition fan203.h:29
double motor_speed
Motor speed
Definition fan203.h:28
double pressure_barometric_corrected
Barometric pressure corrected to reference conditions .
Definition fan203.h:32
double fan_speed
Fan speed .
Definition fan203.h:27
FanRatedInfo(double fan_speed, double motor_speed, double fan_speed_corrected, double density_corrected, double pressure_barometric_corrected)
Constructor for FanRatedInfo.
Definition fan203.h:44