32constexpr int MONTHS = 12;
33constexpr int LOAD_NUM = 11;
34constexpr int HOURS_IN_YEAR = 8760;
35constexpr int CHILLER_COEFFS_CNT = 7;
51 enum RefrigerantType { R_11, R_123, R_12, R_134a, R_22, R_717 };
53 enum ACSourceLocation { Inside, Outside };
55 enum CoolingSystemType { Water, Air };
57 enum CellFanType { AxialFan, CentrifugalFan };
59 enum TowerSizedBy { Tonnage, Fan_HP, Unknown };
61 enum ChillerCompressorType { Centrifugal, Screw, Reciprocating };
63 enum FanMotorSpeedType { One, Two, Variable };
75 ChillerOutput(vector<vector<double>> efficiency, vector<vector<double>> hours, vector<vector<double>> power,
76 vector<vector<double>> energy)
77 : efficiency(std::move(efficiency)), hours(std::move(hours)), power(std::move(power)),
78 energy(std::move(energy)) {}
80 vector<vector<double>> efficiency;
81 vector<vector<double>> hours;
82 vector<vector<double>> power;
83 vector<vector<double>> energy;
94 : chillerPumpingEnergy(std::move(pumpingEnergy)) {}
96 vector<double> chillerPumpingEnergy;
113 TowerOutput(vector<double> hours, vector<double> energy) : hours(std::move(hours)), energy(std::move(energy)) {}
115 vector<double> tempBins = {35, 45, 55, 65, 75, 75};
116 vector<double> hours;
117 vector<double> energy;
139 bool CWVariableFlow,
double CWFlowRate,
double CWTFollow)
140 : CHWT(CHWT), useFreeCooling(useFreeCooling), HEXApproachTemp(HEXApproachTemp), constantCWT(constantCWT),
141 CWT(CWT), CWVariableFlow(CWVariableFlow), CWFlowRate(CWFlowRate), CWTFollow(CWTFollow) {
142 isWaterCooled =
true;
146 bool useFreeCooling =
false;
147 double HEXApproachTemp = 0;
148 bool constantCWT =
true;
150 bool CWVariableFlow =
true;
151 double CWFlowRate = 3;
152 double CWTFollow = 0;
153 bool isWaterCooled =
false;
172 : CHWT(CHWT), OADT(OADT), ACSource(ACSource), indoorTemp(indoorTemp), CWTFollow(CWTFollow) {
178 ACSourceLocation ACSource = ACSourceLocation::Outside;
179 double indoorTemp = 75;
180 double CWTFollow = 0;
181 bool isAirCooled =
false;
193 PumpInput(
bool variableFlow,
double flowRate,
double efficiency,
double motorSize,
double motorEfficiency)
194 : variableFlow(variableFlow), flowRate(flowRate), efficiency(efficiency * 100), motorSize(motorSize),
195 motorEfficiency(motorEfficiency * 100) {}
201 double motorEfficiency;
224 TowerInput(
int numTower,
int numFanPerTower_Cells, FanMotorSpeedType fanSpeedType, TowerSizedBy towerSizing,
225 CellFanType towerCellFanType,
double cellFanHP,
double tonnage)
226 : numTower(numTower), numFanPerTower_Cells(numFanPerTower_Cells), fanSpeedType(fanSpeedType), towerSizing(towerSizing),
227 towerCellFanType(towerCellFanType), fanHP(cellFanHP), tonnage(tonnage) {}
230 int numFanPerTower_Cells;
231 FanMotorSpeedType fanSpeedType;
232 TowerSizedBy towerSizing;
233 CellFanType towerCellFanType;
254 ChillerInput(ChillerCompressorType chillerType,
double capacity,
bool isFullLoadEffKnown,
double fullLoadEff,
255 double age,
bool installVSD,
bool useARIMonthlyLoadSchedule, vector<vector<double>> monthlyLoads)
256 : chillerType(chillerType), capacity(capacity), isFullLoadEffKnown(isFullLoadEffKnown),
257 fullLoadEff(fullLoadEff), age(age), installVSD(installVSD),
258 useARIMonthlyLoadSchedule(useARIMonthlyLoadSchedule), monthlyLoads(std::move(monthlyLoads)),
259 isCustomChiller(false), loadAtPercent({}), kwPerTonLoads({}), changeRefrig(
false),
260 currentRefrig(RefrigerantType::R_11), proposedRefrig(RefrigerantType::R_11) {
261 InitNonVaryingMonthlyLoad();
283 ChillerInput(ChillerCompressorType chillerType,
double capacity,
bool isFullLoadEffKnown,
double fullLoadEff,
284 double age,
bool installVSD,
bool useARIMonthlyLoadSchedule, vector<vector<double>> monthlyLoads,
285 bool changeRefrig, RefrigerantType currentRefrig, RefrigerantType proposedRefrig)
286 : chillerType(chillerType), capacity(capacity), isFullLoadEffKnown(isFullLoadEffKnown),
287 fullLoadEff(fullLoadEff), age(age), installVSD(installVSD),
288 useARIMonthlyLoadSchedule(useARIMonthlyLoadSchedule), monthlyLoads(std::move(monthlyLoads)),
289 isCustomChiller(false), loadAtPercent({}), kwPerTonLoads({}), changeRefrig(changeRefrig),
290 currentRefrig(currentRefrig), proposedRefrig(proposedRefrig) {
291 InitNonVaryingMonthlyLoad();
312 ChillerInput(ChillerCompressorType chillerType,
double capacity,
bool isFullLoadEffKnown,
double fullLoadEff,
313 double age,
bool installVSD,
bool useARIMonthlyLoadSchedule, vector<vector<double>> monthlyLoads,
314 RefrigerantType currentRefrig, RefrigerantType proposedRefrig)
315 : chillerType(chillerType), capacity(capacity), isFullLoadEffKnown(isFullLoadEffKnown),
316 fullLoadEff(fullLoadEff), age(age), installVSD(installVSD),
317 useARIMonthlyLoadSchedule(useARIMonthlyLoadSchedule), monthlyLoads(std::move(monthlyLoads)),
318 isCustomChiller(false), loadAtPercent({}), kwPerTonLoads({}), changeRefrig(
true),
319 currentRefrig(currentRefrig), proposedRefrig(proposedRefrig) {
320 InitNonVaryingMonthlyLoad();
341 ChillerInput(ChillerCompressorType chillerType,
double capacity,
bool isFullLoadEffKnown,
double fullLoadEff,
342 double age,
bool installVSD,
bool useARIMonthlyLoadSchedule, vector<vector<double>> monthlyLoads,
343 vector<double> loadAtPercent, vector<double> kwPerTonLoads)
344 : chillerType(chillerType), capacity(capacity), isFullLoadEffKnown(isFullLoadEffKnown),
345 fullLoadEff(fullLoadEff), age(age), installVSD(installVSD),
346 useARIMonthlyLoadSchedule(useARIMonthlyLoadSchedule), monthlyLoads(std::move(monthlyLoads)),
347 isCustomChiller(true), loadAtPercent(std::move(loadAtPercent)), kwPerTonLoads(std::move(kwPerTonLoads)),
348 changeRefrig(false), currentRefrig(RefrigerantType::R_11), proposedRefrig(RefrigerantType::R_11) {
349 InitNonVaryingMonthlyLoad();
350 SetCustomCoefficient();
374 ChillerInput(ChillerCompressorType chillerType,
double capacity,
bool isFullLoadEffKnown,
double fullLoadEff,
375 double age,
bool installVSD,
bool useARIMonthlyLoadSchedule, vector<vector<double>> monthlyLoads,
376 vector<double> loadAtPercent, vector<double> kwPerTonLoads, RefrigerantType currentRefrig,
377 RefrigerantType proposedRefrig)
378 : chillerType(chillerType), capacity(capacity), isFullLoadEffKnown(isFullLoadEffKnown),
379 fullLoadEff(fullLoadEff), age(age), installVSD(installVSD),
380 useARIMonthlyLoadSchedule(useARIMonthlyLoadSchedule), monthlyLoads(std::move(monthlyLoads)),
381 isCustomChiller(true), loadAtPercent(std::move(loadAtPercent)), kwPerTonLoads(std::move(kwPerTonLoads)),
382 changeRefrig(true), currentRefrig(currentRefrig), proposedRefrig(proposedRefrig) {
383 InitNonVaryingMonthlyLoad();
384 SetCustomCoefficient();
387 ChillerCompressorType chillerType;
389 bool isFullLoadEffKnown;
393 bool useARIMonthlyLoadSchedule;
394 vector<vector<double>> monthlyLoads;
396 bool isCustomChiller;
397 vector<double> loadAtPercent;
398 vector<double> kwPerTonLoads;
400 bool changeRefrig =
false;
401 RefrigerantType currentRefrig;
402 RefrigerantType proposedRefrig;
404 vector<double> customCoeffs;
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);
444 size =
static_cast<int>(coeff.size());
445 customCoeffs.resize(size, 0);
446 for (
int i = 0; i < size; i++) {
447 customCoeffs[i] = coeff[i];
451 static vector<double> solveForCoefficients(
const vector<double>& x, vector<double> y) {
452 if (x.empty() || x.size() != y.size())
455 const int n =
static_cast<int>(x.size());
457 vector<vector<double>> a(n, vector<double>(n, 0));
458 for (
int i = 0; i < n; ++i) {
459 for (
int j = 0; j < n; ++j) {
460 a[i][j] = pow(x[i], n - 1 - j);
465 for (
int k = 0; k < n - 1; ++k) {
466 for (
int i = k + 1; i < n; ++i) {
467 double factor = a[i][k] / a[k][k];
468 for (
int j = k + 1; j < n; ++j) {
469 a[i][j] -= factor * a[k][j];
471 y[i] -= factor * y[k];
476 vector<double> coeff(n, 0);
477 coeff[n - 1] = y[n - 1] / a[n - 1][n - 1];
478 for (
int i = n - 2; i >= 0; --i) {
480 for (
int j = i + 1; j < n; ++j) {
481 sum -= a[i][j] * coeff[j];
483 coeff[i] = sum / a[i][i];
506 ProcessCooling(
const vector<int>& systemOperationAnnualHours,
const vector<double>& weatherDryBulbHourlyTemp,
507 const vector<double>& weatherWetBulbHourlyTemp,
const vector<ChillerInput>& chillerInputList,
509 :
ProcessCooling(systemOperationAnnualHours, weatherDryBulbHourlyTemp, weatherWetBulbHourlyTemp,
510 chillerInputList, {}, towerInput, waterCooledSystemInput) {}
523 ProcessCooling(
const vector<int>& systemOperationAnnualHours,
const vector<double>& weatherDryBulbHourlyTemp,
524 const vector<double>& weatherWetBulbHourlyTemp,
const vector<ChillerInput>& chillerInputList,
526 :
ProcessCooling(systemOperationAnnualHours, weatherDryBulbHourlyTemp, weatherWetBulbHourlyTemp,
527 chillerInputList, airCooledSystemInput, {}, {}) {}
559 static vector<int>
getSysOpAnnualHours(
const vector<int>& weeklyOpStartHour,
const vector<int>& weeklyOpStopHour,
const vector<int>& monthlyOpMaxHour);
581 ProcessCooling(
const vector<int>& systemOperationAnnualHours,
const vector<double>& weatherDryBulbHourlyTemp,
582 const vector<double>& weatherWetBulbHourlyTemp,
const vector<ChillerInput>& chillerInputList,
586 vector<int> systemOperationAnnual;
587 vector<double> dryBulbHourlyTemp;
588 vector<double> wetBulbHourlyTemp;
591 WaterCooledSystemInput waterCooledSystem;
592 AirCooledSystemInput airCooledSystem;
593 CoolingSystemType coolingType;
596 vector<double> CWTHourly;
599 vector<ChillerInput> chillers;
600 vector<vector<double>> chillerHourlyLoad;
601 vector<vector<double>> chillerHourlyLoadOperational;
602 vector<vector<double>> chillerEfficiencyCoeffs;
603 vector<vector<double>> chillerHourlyEfficiencyARI;
604 vector<vector<double>> chillerHourlyEfficiency;
605 vector<vector<double>> chillerHourlyPower;
607 int getChillerCapacityIndex(ChillerCompressorType chillerType,
double capacity)
const;
609 double getChillerEffAtLoad(
int c,
double load,
bool isFullLoadEffKnown)
const;
611 void annualChillerLoadProfile();
613 void annualChillerEfficiencyProfileARI();
615 void annualChillerEfficiencyProfile();
617 void annualChillerPowerProfile();
619 void setTowerFanHPTonnage();
621 double getPercentFanPower(
double wetBulbTemp,
double percentWaterFlow,
double range,
double desiredApproach,
624 double getPercentWaterFlow(
int yearHourIndex)
const;
626 double getRange(
int yearHourIndex)
const;
628 double getApproach(
double wetBulbTemp)
const;
630 double modifyPercentFanPower(
double percentFanPower)
const;
632 double getWeightedAverageChillerLoad(
int yearHourIndex)
const;
634 double getChillerTonnageTotal()
const;
636 static double getCubeRoot(
double number);
638 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
vector< double > getChillerEnergyEfficiency(int chillerIndex, const vector< double > &loadAtPercent) const
static vector< int > getSysOpAnnualHours(const vector< int > &weeklyOpStartHour, const vector< int > &weeklyOpStopHour, const vector< int > &monthlyOpMaxHour)
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)