31constexpr int MONTHS = 12;
32constexpr int LOAD_NUM = 11;
33constexpr int HOURS_IN_YEAR = 8760;
34constexpr int CHILLER_COEFFS_CNT = 7;
50 enum RefrigerantType { R_11, R_123, R_12, R_134a, R_22, R_717 };
52 enum ACSourceLocation { Inside, Outside };
54 enum CoolingSystemType { Water, Air };
56 enum CellFanType { AxialFan, CentrifugalFan };
58 enum TowerSizedBy { Tonnage, Fan_HP, Unknown };
60 enum ChillerCompressorType { Centrifugal, Screw, Reciprocating };
62 enum FanMotorSpeedType { One, Two, Variable };
74 ChillerOutput(vector<vector<double>> efficiency, vector<vector<double>> hours, vector<vector<double>> power,
75 vector<vector<double>> energy)
76 : efficiency(std::move(efficiency)), hours(std::move(hours)), power(std::move(power)),
77 energy(std::move(energy)) {}
79 vector<vector<double>> efficiency;
80 vector<vector<double>> hours;
81 vector<vector<double>> power;
82 vector<vector<double>> energy;
93 : chillerPumpingEnergy(std::move(pumpingEnergy)) {}
95 vector<double> chillerPumpingEnergy;
112 TowerOutput(vector<double> hours, vector<double> energy) : hours(std::move(hours)), energy(std::move(energy)) {}
114 vector<double> tempBins = {35, 45, 55, 65, 75, 75};
115 vector<double> hours;
116 vector<double> energy;
138 bool CWVariableFlow,
double CWFlowRate,
double CWTFollow)
139 : CHWT(CHWT), useFreeCooling(useFreeCooling), HEXApproachTemp(HEXApproachTemp), constantCWT(constantCWT),
140 CWT(CWT), CWVariableFlow(CWVariableFlow), CWFlowRate(CWFlowRate), CWTFollow(CWTFollow) {
141 isWaterCooled =
true;
145 bool useFreeCooling =
false;
146 double HEXApproachTemp = 0;
147 bool constantCWT =
true;
149 bool CWVariableFlow =
true;
150 double CWFlowRate = 3;
151 double CWTFollow = 0;
152 bool isWaterCooled =
false;
171 : CHWT(CHWT), OADT(OADT), ACSource(ACSource), indoorTemp(indoorTemp), CWTFollow(CWTFollow) {
177 ACSourceLocation ACSource = ACSourceLocation::Outside;
178 double indoorTemp = 75;
179 double CWTFollow = 0;
180 bool isAirCooled =
false;
192 PumpInput(
bool variableFlow,
double flowRate,
double efficiency,
double motorSize,
double motorEfficiency)
193 : variableFlow(variableFlow), flowRate(flowRate), efficiency(efficiency * 100), motorSize(motorSize),
194 motorEfficiency(motorEfficiency * 100) {}
200 double motorEfficiency;
223 TowerInput(
int numTower,
int numFanPerTower_Cells, FanMotorSpeedType fanSpeedType, TowerSizedBy towerSizing,
224 CellFanType towerCellFanType,
double cellFanHP,
double tonnage)
225 : numTower(numTower), numFanPerTower_Cells(numFanPerTower_Cells), fanSpeedType(fanSpeedType), towerSizing(towerSizing),
226 towerCellFanType(towerCellFanType), fanHP(cellFanHP), tonnage(tonnage) {}
229 int numFanPerTower_Cells;
230 FanMotorSpeedType fanSpeedType;
231 TowerSizedBy towerSizing;
232 CellFanType towerCellFanType;
253 ChillerInput(ChillerCompressorType chillerType,
double capacity,
bool isFullLoadEffKnown,
double fullLoadEff,
254 double age,
bool installVSD,
bool useARIMonthlyLoadSchedule, vector<vector<double>> monthlyLoads)
255 : chillerType(chillerType), capacity(capacity), isFullLoadEffKnown(isFullLoadEffKnown),
256 fullLoadEff(fullLoadEff), age(age), installVSD(installVSD),
257 useARIMonthlyLoadSchedule(useARIMonthlyLoadSchedule), monthlyLoads(std::move(monthlyLoads)),
258 isCustomChiller(false), loadAtPercent({}), kwPerTonLoads({}), changeRefrig(
false),
259 currentRefrig(RefrigerantType::R_11), proposedRefrig(RefrigerantType::R_11) {
260 InitNonVaryingMonthlyLoad();
282 ChillerInput(ChillerCompressorType chillerType,
double capacity,
bool isFullLoadEffKnown,
double fullLoadEff,
283 double age,
bool installVSD,
bool useARIMonthlyLoadSchedule, vector<vector<double>> monthlyLoads,
284 bool changeRefrig, RefrigerantType currentRefrig, RefrigerantType proposedRefrig)
285 : chillerType(chillerType), capacity(capacity), isFullLoadEffKnown(isFullLoadEffKnown),
286 fullLoadEff(fullLoadEff), age(age), installVSD(installVSD),
287 useARIMonthlyLoadSchedule(useARIMonthlyLoadSchedule), monthlyLoads(std::move(monthlyLoads)),
288 isCustomChiller(false), loadAtPercent({}), kwPerTonLoads({}), changeRefrig(changeRefrig),
289 currentRefrig(currentRefrig), proposedRefrig(proposedRefrig) {
290 InitNonVaryingMonthlyLoad();
311 ChillerInput(ChillerCompressorType chillerType,
double capacity,
bool isFullLoadEffKnown,
double fullLoadEff,
312 double age,
bool installVSD,
bool useARIMonthlyLoadSchedule, vector<vector<double>> monthlyLoads,
313 RefrigerantType currentRefrig, RefrigerantType proposedRefrig)
314 : chillerType(chillerType), capacity(capacity), isFullLoadEffKnown(isFullLoadEffKnown),
315 fullLoadEff(fullLoadEff), age(age), installVSD(installVSD),
316 useARIMonthlyLoadSchedule(useARIMonthlyLoadSchedule), monthlyLoads(std::move(monthlyLoads)),
317 isCustomChiller(false), loadAtPercent({}), kwPerTonLoads({}), changeRefrig(
true),
318 currentRefrig(currentRefrig), proposedRefrig(proposedRefrig) {
319 InitNonVaryingMonthlyLoad();
340 ChillerInput(ChillerCompressorType chillerType,
double capacity,
bool isFullLoadEffKnown,
double fullLoadEff,
341 double age,
bool installVSD,
bool useARIMonthlyLoadSchedule, vector<vector<double>> monthlyLoads,
342 vector<double> loadAtPercent, vector<double> kwPerTonLoads)
343 : chillerType(chillerType), capacity(capacity), isFullLoadEffKnown(isFullLoadEffKnown),
344 fullLoadEff(fullLoadEff), age(age), installVSD(installVSD),
345 useARIMonthlyLoadSchedule(useARIMonthlyLoadSchedule), monthlyLoads(std::move(monthlyLoads)),
346 isCustomChiller(true), loadAtPercent(std::move(loadAtPercent)), kwPerTonLoads(std::move(kwPerTonLoads)),
347 changeRefrig(false), currentRefrig(RefrigerantType::R_11), proposedRefrig(RefrigerantType::R_11) {
348 InitNonVaryingMonthlyLoad();
349 SetCustomCoefficient();
373 ChillerInput(ChillerCompressorType chillerType,
double capacity,
bool isFullLoadEffKnown,
double fullLoadEff,
374 double age,
bool installVSD,
bool useARIMonthlyLoadSchedule, vector<vector<double>> monthlyLoads,
375 vector<double> loadAtPercent, vector<double> kwPerTonLoads, RefrigerantType currentRefrig,
376 RefrigerantType proposedRefrig)
377 : chillerType(chillerType), capacity(capacity), isFullLoadEffKnown(isFullLoadEffKnown),
378 fullLoadEff(fullLoadEff), age(age), installVSD(installVSD),
379 useARIMonthlyLoadSchedule(useARIMonthlyLoadSchedule), monthlyLoads(std::move(monthlyLoads)),
380 isCustomChiller(true), loadAtPercent(std::move(loadAtPercent)), kwPerTonLoads(std::move(kwPerTonLoads)),
381 changeRefrig(true), currentRefrig(currentRefrig), proposedRefrig(proposedRefrig) {
382 InitNonVaryingMonthlyLoad();
383 SetCustomCoefficient();
386 ChillerCompressorType chillerType;
388 bool isFullLoadEffKnown;
392 bool useARIMonthlyLoadSchedule;
393 vector<vector<double>> monthlyLoads;
395 bool isCustomChiller;
396 vector<double> loadAtPercent;
397 vector<double> kwPerTonLoads;
399 bool changeRefrig =
false;
400 RefrigerantType currentRefrig;
401 RefrigerantType proposedRefrig;
403 vector<double> customCoeffs;
404 vector<double> customCoeffs_eff;
407 void InitNonVaryingMonthlyLoad() {
408 if (monthlyLoads.size() == 1) {
409 auto monthlyLoad = monthlyLoads[0];
411 for (
int i = 0; i < 11; i++) {
412 monthlyLoads.push_back(monthlyLoad);
417 void SetCustomCoefficient() {
418 if (loadAtPercent.empty() || kwPerTonLoads.empty() || loadAtPercent.size() != kwPerTonLoads.size()) {
419 throw std::runtime_error(
"Invalid input provided for loadAtPercent or kwPerTonLoads, should be non empty and have same number of elements.");
422 auto size =
static_cast<int>(loadAtPercent.size());
425 if (loadAtPercent[0] > loadAtPercent[size-1]) {
426 std::reverse(loadAtPercent.begin(), loadAtPercent.end());
427 std::reverse(kwPerTonLoads.begin(), kwPerTonLoads.end());
430 vector<double> x(size, 0);
431 vector<double> y(size, 0);
432 const auto kwPerTonLoadAtMaxLoad = kwPerTonLoads[size-1];
434 if (kwPerTonLoadAtMaxLoad == 0) {
435 throw std::runtime_error(
"% loading @ 100 % cannot be zero.");
438 for (
int i = 0; i < size; i++) {
439 x[i] = loadAtPercent[i]/100.0;
440 y[i] = kwPerTonLoads[i] * x[i] / kwPerTonLoadAtMaxLoad;
442 vector<double> coeff = solveForCoefficients(x, y);
443 vector<double> coeff_eff = solveForCoefficients(x, kwPerTonLoads);
445 size =
static_cast<int>(coeff.size());
446 customCoeffs.resize(size, 0);
447 customCoeffs_eff.resize(size, 0);
448 for (
int i = 0; i < size; i++) {
449 customCoeffs[i] = coeff[i];
450 customCoeffs_eff[i] = coeff_eff[i];
454 static vector<double> solveForCoefficients(
const vector<double>& x, vector<double> y) {
455 if (x.empty() || x.size() != y.size())
458 const int n =
static_cast<int>(x.size());
460 vector<vector<double>> a(n, vector<double>(n, 0));
461 for (
int i = 0; i < n; ++i) {
462 for (
int j = 0; j < n; ++j) {
463 a[i][j] = pow(x[i], n - 1 - j);
468 for (
int k = 0; k < n - 1; ++k) {
469 for (
int i = k + 1; i < n; ++i) {
470 double factor = a[i][k] / a[k][k];
471 for (
int j = k + 1; j < n; ++j) {
472 a[i][j] -= factor * a[k][j];
474 y[i] -= factor * y[k];
479 vector<double> coeff(n, 0);
480 coeff[n - 1] = y[n - 1] / a[n - 1][n - 1];
481 for (
int i = n - 2; i >= 0; --i) {
483 for (
int j = i + 1; j < n; ++j) {
484 sum -= a[i][j] * coeff[j];
486 coeff[i] = sum / a[i][i];
509 ProcessCooling(
const vector<int>& systemOperationAnnualHours,
const vector<double>& weatherDryBulbHourlyTemp,
510 const vector<double>& weatherWetBulbHourlyTemp,
const vector<ChillerInput>& chillerInputList,
512 :
ProcessCooling(systemOperationAnnualHours, weatherDryBulbHourlyTemp, weatherWetBulbHourlyTemp,
513 chillerInputList, {}, towerInput, waterCooledSystemInput) {}
526 ProcessCooling(
const vector<int>& systemOperationAnnualHours,
const vector<double>& weatherDryBulbHourlyTemp,
527 const vector<double>& weatherWetBulbHourlyTemp,
const vector<ChillerInput>& chillerInputList,
529 :
ProcessCooling(systemOperationAnnualHours, weatherDryBulbHourlyTemp, weatherWetBulbHourlyTemp,
530 chillerInputList, airCooledSystemInput, {}, {}) {}
562 static vector<int>
getSysOpAnnualHours(
const vector<int>& weeklyOpStartHour,
const vector<int>& weeklyOpStopHour,
const vector<int>& monthlyOpMaxHour);
587 ProcessCooling(
const vector<int>& systemOperationAnnualHours,
const vector<double>& weatherDryBulbHourlyTemp,
588 const vector<double>& weatherWetBulbHourlyTemp,
const vector<ChillerInput>& chillerInputList,
592 vector<int> systemOperationAnnual;
593 vector<double> dryBulbHourlyTemp;
594 vector<double> wetBulbHourlyTemp;
597 WaterCooledSystemInput waterCooledSystem;
598 AirCooledSystemInput airCooledSystem;
599 CoolingSystemType coolingType;
602 vector<double> CWTHourly;
605 vector<ChillerInput> chillers;
606 vector<vector<double>> chillerHourlyLoad;
607 vector<vector<double>> chillerHourlyLoadOperational;
608 vector<vector<double>> chillerEfficiencyCoeffs;
609 vector<vector<double>> chillerHourlyEfficiencyARI;
610 vector<vector<double>> chillerHourlyEfficiency;
611 vector<vector<double>> chillerHourlyPower;
613 int getChillerCapacityIndex(ChillerCompressorType chillerType,
double capacity)
const;
615 void annualChillerLoadProfile();
617 void annualChillerEfficiencyProfileARI();
619 void annualChillerEfficiencyProfile();
621 void annualChillerPowerProfile();
623 void setTowerFanHPTonnage();
625 double getChillerEffAtLoad(
int c,
double load,
bool isFullLoadEffKnown,
bool applyFactoring)
const;
627 double getPercentFanPower(
double wetBulbTemp,
double percentWaterFlow,
double range,
double desiredApproach,
int yearHourIndex);
629 double getPercentWaterFlow(
int yearHourIndex)
const;
631 double getRange(
int yearHourIndex)
const;
633 double getApproach(
double wetBulbTemp)
const;
635 double modifyPercentFanPower(
double percentFanPower)
const;
637 double getWeightedAverageChillerLoad(
int yearHourIndex)
const;
639 double getChillerTonnageTotal()
const;
641 static double getCubeRoot(
double number);
643 static double getPumpHP(
double power);
Calculator estimates energy consumption of operating Chillers, Pumps and Towers in a cooling system (...
TowerOutput calculateTowerEnergy()
ChillerOutput calculateChillerEnergy()
ProcessCooling(const vector< int > &systemOperationAnnualHours, const vector< double > &weatherDryBulbHourlyTemp, const vector< double > &weatherWetBulbHourlyTemp, const vector< ChillerInput > &chillerInputList, const TowerInput &towerInput, const WaterCooledSystemInput &waterCooledSystemInput)
ChillerPumpingEnergyOutput calculatePumpEnergy(PumpInput pump) const
ProcessCooling(const vector< int > &systemOperationAnnualHours, const vector< double > &weatherDryBulbHourlyTemp, const vector< double > &weatherWetBulbHourlyTemp, const vector< ChillerInput > &chillerInputList, const AirCooledSystemInput &airCooledSystemInput)
vector< double > getChillerEfficiencyCoeffs(int chillerIndex) const
static vector< int > getSysOpAnnualHours(const vector< int > &weeklyOpStartHour, const vector< int > &weeklyOpStopHour, const vector< int > &monthlyOpMaxHour)
vector< double > getChillerARIEnergyEfficiency(int chillerIndex, const vector< double > &loadAtPercent, bool applyFactoring) const
ChillerOutput(vector< vector< double > > efficiency, vector< vector< double > > hours, vector< vector< double > > power, vector< vector< double > > energy)
ChillerPumpingEnergyOutput(vector< double > pumpingEnergy)
TowerOutput(vector< double > hours, vector< double > energy)