From f29bb13249927dd17eca63d6791b31eb74188261 Mon Sep 17 00:00:00 2001 From: Phil Ahrenkiel Date: Wed, 15 Nov 2023 17:42:17 -0700 Subject: [PATCH 1/5] Correct extra-heat assignment. --- src/HPWHHeatSources.cc | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/HPWHHeatSources.cc b/src/HPWHHeatSources.cc index 348ab49a..3c3d3121 100644 --- a/src/HPWHHeatSources.cc +++ b/src/HPWHHeatSources.cc @@ -383,7 +383,7 @@ void HPWH::HeatSource::addHeat(double externalT_C,double minutesToRun) { case CONFIG_SUBMERGED: case CONFIG_WRAPPED: { - std::vector heatDistribution(hpwh->getNumNodes()); + std::vector heatDistribution; //calcHeatDist takes care of the swooping for wrapped configurations calcHeatDist(heatDistribution); @@ -737,6 +737,7 @@ void HPWH::HeatSource::btwxtInterp(double& input_BTUperHr,double& cop,std::vecto void HPWH::HeatSource::calcHeatDist(std::vector &heatDistribution) { // Populate the vector of heat distribution + heatDistribution.resize(hpwh->getNumNodes()); if(configuration == CONFIG_SUBMERGED) { resampleExtensive(heatDistribution, condensity); } @@ -989,22 +990,21 @@ void HPWH::HeatSource::setupAsResistiveElement(int node,double Watts,int condens } void HPWH::HeatSource::setupExtraHeat(std::vector &nodePowerExtra_W) { - - // retain original condensity size for this heat source - std::vector extraCondensity(getCondensitySize()); - resampleExtensive(extraCondensity, nodePowerExtra_W); - double watts = 0.0; - for(int i = 0; i < getCondensitySize(); ++i) { - //get sum of vector - watts += extraCondensity[i]; + // The elements of nodePowerExtra_W are assigned to the condensity nodes for + // this heat source. If condensity.size() is larger than nodePowerExtra_W.size, + // the additional elements of condensity are set to zero. If condensity.size() is smaller than nodePowerExtra_W.size, + // the additional elements of nodePowerExtra_W are omitted. + // Suggest specifying nodePowerExtra_W as the full condensity distribution (scaled by power) instead. + for(unsigned int i = 0; i < condensity.size(); ++i) { + + //put into vector for normalization + condensity[i] = (i < nodePowerExtra_W.size()) ? nodePowerExtra_W[i] : 0.; } - normalize(extraCondensity); + normalize(condensity); - // set condensity - setCondensity(extraCondensity); if(hpwh->hpwhVerbosity >= VRB_emetic){ hpwh->msg("extra heat condensity: "); - for(int i = 0; i < getCondensitySize(); i++) { + for(unsigned int i = 0; i < condensity.size(); i++) { hpwh->msg("C[%d]: %f",i,condensity[i]); } hpwh->msg("\n "); @@ -1013,6 +1013,11 @@ void HPWH::HeatSource::setupExtraHeat(std::vector &nodePowerExtra_W) { perfMap.clear(); perfMap.reserve(2); + double watts = 0.; + for(unsigned int i = 0; i < nodePowerExtra_W.size(); ++i) { + watts += nodePowerExtra_W[i]; + } + perfMap.push_back({ 50, // Temperature (T_F) {watts,0.0,0.0}, // Input Power Coefficients (inputPower_coeffs) From 877d3e6067ad36f98a4603c444dd2a1a07b46b46 Mon Sep 17 00:00:00 2001 From: Phil Ahrenkiel Date: Thu, 16 Nov 2023 09:19:52 -0700 Subject: [PATCH 2/5] Distribute extra power across existing condensity. --- src/HPWHHeatSources.cc | 28 ++++------------------------ src/HPWHpresets.cc | 2 +- 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/src/HPWHHeatSources.cc b/src/HPWHHeatSources.cc index 3c3d3121..d6c7ceeb 100644 --- a/src/HPWHHeatSources.cc +++ b/src/HPWHHeatSources.cc @@ -990,34 +990,15 @@ void HPWH::HeatSource::setupAsResistiveElement(int node,double Watts,int condens } void HPWH::HeatSource::setupExtraHeat(std::vector &nodePowerExtra_W) { - // The elements of nodePowerExtra_W are assigned to the condensity nodes for - // this heat source. If condensity.size() is larger than nodePowerExtra_W.size, - // the additional elements of condensity are set to zero. If condensity.size() is smaller than nodePowerExtra_W.size, - // the additional elements of nodePowerExtra_W are omitted. - // Suggest specifying nodePowerExtra_W as the full condensity distribution (scaled by power) instead. - for(unsigned int i = 0; i < condensity.size(); ++i) { - - //put into vector for normalization - condensity[i] = (i < nodePowerExtra_W.size()) ? nodePowerExtra_W[i] : 0.; - } - normalize(condensity); - - if(hpwh->hpwhVerbosity >= VRB_emetic){ - hpwh->msg("extra heat condensity: "); - for(unsigned int i = 0; i < condensity.size(); i++) { - hpwh->msg("C[%d]: %f",i,condensity[i]); - } - hpwh->msg("\n "); - } - - perfMap.clear(); - perfMap.reserve(2); - + // The total power in nodePowerExtra_W is applied, using the existing condensity. double watts = 0.; for(unsigned int i = 0; i < nodePowerExtra_W.size(); ++i) { watts += nodePowerExtra_W[i]; } + perfMap.clear(); + perfMap.reserve(2); + perfMap.push_back({ 50, // Temperature (T_F) {watts,0.0,0.0}, // Input Power Coefficients (inputPower_coeffs) @@ -1029,7 +1010,6 @@ void HPWH::HeatSource::setupExtraHeat(std::vector &nodePowerExtra_W) { {watts,0.0,0.0}, // Input Power Coefficients (inputPower_coeffs) {1.0,0.0,0.0} // COP Coefficients (COP_coeffs) }); - } void HPWH::HeatSource::addTurnOnLogic(std::shared_ptr logic) { diff --git a/src/HPWHpresets.cc b/src/HPWHpresets.cc index c5ae25f9..582fabe4 100644 --- a/src/HPWHpresets.cc +++ b/src/HPWHpresets.cc @@ -537,7 +537,7 @@ int HPWH::HPWHinit_presets(MODELS presetNum) { extra.addTurnOnLogic(HPWH::topThird_absolute(1)); //initial guess, will get reset based on the input heat vector - extra.setCondensity({1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}); + extra.setCondensity({1., 0., 0., 0.}); //set everything in its places heatSources.resize(1); From ea16e7714e270523893a8a075ce601c94d590263 Mon Sep 17 00:00:00 2001 From: Phil Ahrenkiel Date: Thu, 16 Nov 2023 10:14:38 -0700 Subject: [PATCH 3/5] Add simplified setupExtraHeat fnc. --- src/HPWH.in.hh | 4 ++++ src/HPWHHeatSources.cc | 20 ++++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/HPWH.in.hh b/src/HPWH.in.hh index a13723c7..0aa5fd9f 100644 --- a/src/HPWH.in.hh +++ b/src/HPWH.in.hh @@ -1020,6 +1020,10 @@ public: void setupAsResistiveElement(int node,double Watts,int condensitySize = CONDENSITY_SIZE); /**< configure the heat source to be a resisive element, positioned at the specified node, with the specified power in watts */ + + void setupExtraHeat(const double extraPower_W); + /**< Sets the power provided by this heat source to extraPower_W*/ + void setupExtraHeat(std::vector &nodePowerExtra_W); /**< Configure a user-defined heat source added as extra, based off using nodePowerExtra_W as the total watt input and the condensity*/ diff --git a/src/HPWHHeatSources.cc b/src/HPWHHeatSources.cc index d6c7ceeb..6730168c 100644 --- a/src/HPWHHeatSources.cc +++ b/src/HPWHHeatSources.cc @@ -989,29 +989,33 @@ void HPWH::HeatSource::setupAsResistiveElement(int node,double Watts,int condens typeOfHeatSource = TYPE_resistance; } -void HPWH::HeatSource::setupExtraHeat(std::vector &nodePowerExtra_W) { - // The total power in nodePowerExtra_W is applied, using the existing condensity. - double watts = 0.; - for(unsigned int i = 0; i < nodePowerExtra_W.size(); ++i) { - watts += nodePowerExtra_W[i]; - } +void HPWH::HeatSource::setupExtraHeat(const double extraPower_W) { perfMap.clear(); perfMap.reserve(2); perfMap.push_back({ 50, // Temperature (T_F) - {watts,0.0,0.0}, // Input Power Coefficients (inputPower_coeffs) + {extraPower_W,0.0,0.0}, // Input Power Coefficients (inputPower_coeffs) {1.0,0.0,0.0} // COP Coefficients (COP_coeffs) }); perfMap.push_back({ 67, // Temperature (T_F) - {watts,0.0,0.0}, // Input Power Coefficients (inputPower_coeffs) + {extraPower_W,0.0,0.0}, // Input Power Coefficients (inputPower_coeffs) {1.0,0.0,0.0} // COP Coefficients (COP_coeffs) }); } +void HPWH::HeatSource::setupExtraHeat(std::vector &nodePowerExtra_W) { + // Only the total power in nodePowerExtra_W is used. + double extraPower_W = 0.; + for(unsigned int i = 0; i < nodePowerExtra_W.size(); ++i) { + extraPower_W += nodePowerExtra_W[i]; + } + setupExtraHeat(extraPower_W); +} + void HPWH::HeatSource::addTurnOnLogic(std::shared_ptr logic) { this->turnOnLogicSet.push_back(logic); } From c356e71620e9e0f61de6e9071cb9d4ef55d5f0e5 Mon Sep 17 00:00:00 2001 From: Phil Ahrenkiel Date: Thu, 16 Nov 2023 15:13:55 -0700 Subject: [PATCH 4/5] Add extra-heat test. --- src/HPWH.cc | 2 ++ src/HPWHHeatSources.cc | 8 ++++++-- test/testHeatingLogics.cc | 30 ++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/HPWH.cc b/src/HPWH.cc index 3a709c34..cfda079f 100644 --- a/src/HPWH.cc +++ b/src/HPWH.cc @@ -2681,6 +2681,8 @@ void HPWH::addExtraHeat(std::vector &nodePowerExtra_W,double tankAmbient heatSources[i].perfMap.clear(); heatSources[i].energyInput_kWh = 0.0; heatSources[i].energyOutput_kWh = 0.0; + + break; // Only add extra heat to the first "extra" heat source found. } } } diff --git a/src/HPWHHeatSources.cc b/src/HPWHHeatSources.cc index 6730168c..6773b53c 100644 --- a/src/HPWHHeatSources.cc +++ b/src/HPWHHeatSources.cc @@ -433,7 +433,8 @@ void HPWH::HeatSource::addHeat(double externalT_C,double minutesToRun) { case CONFIG_EXTERNAL: //Else the heat source is external. SANCO2 system is only current example - //capacity is calculated internal to this function, and cap/input_BTUperHr, cop are outputs + //capacity is calculated internal to this functio + // n, and cap/input_BTUperHr, cop are outputs this->runtime_min = addHeatExternal(externalT_C,minutesToRun,cap_BTUperHr,input_BTUperHr,cop); break; } @@ -513,7 +514,10 @@ void HPWH::HeatSource::getCapacity(double externalT_C,double condenserTemp_C,dou std::vector target{externalT_F,Tout_F,condenserTemp_F}; btwxtInterp(input_BTUperHr,cop,target); } else { - if(perfMap.size() > 1) { + if(perfMap.empty()) { + input_BTUperHr = 0.; + cop = 0.; + } else if(perfMap.size() > 1) { double COP_T1,COP_T2; //cop at ambient temperatures T1 and T2 double inputPower_T1_Watts,inputPower_T2_Watts; //input power at ambient temperatures T1 and T2 diff --git a/test/testHeatingLogics.cc b/test/testHeatingLogics.cc index b166bada..cc8f0a20 100644 --- a/test/testHeatingLogics.cc +++ b/test/testHeatingLogics.cc @@ -20,6 +20,7 @@ void testChangeToStateofChargeControlled(string& input); void testSetStateOfCharge(string& input); void testSetStateOfCharge(string& input, double coldWater_F, double minTUse_F, double tankTAt76SoC); +void testExtraHeat(); const std::vector hasHighShuttOffVectSP = { "Sanden80", "QAHV_N136TAU_HPB_SP", \ "ColmacCxA_20_SP", "ColmacCxV_5_SP", "NyleC60A_SP", "NyleC60A_C_SP", "NyleC185A_C_SP", "TamScalable_SP" }; @@ -62,6 +63,7 @@ int main(int, char*) { testCanNotSetEnteringWaterShutOff(hpwhStr); } + testExtraHeat(); return 0; } @@ -264,3 +266,31 @@ void testSetStateOfCharge(string& input, double coldWater_F, double minTUse_F, d hpwh.runOneStep(0, externalT_C, externalT_C, HPWH::DR_ALLOW); ASSERTFALSE(compressorIsRunning(hpwh)); } + +/*Test adding extra heat to a tank for one minute*/ +void testExtraHeat() { + HPWH hpwh; + getHPWHObject(hpwh, "StorageTank"); + + const double ambientT_C = 20.; + const double externalT_C = 20.; + const double inletVol2_L = 0.; + const double inletT2_C = 0.; + + double extraPower_W = 1000.; + std::vector nodePowerExtra_W = {extraPower_W}; + + // + hpwh.setUA(0.); + hpwh.setTankToTemperature(20.); + + double Q_init = hpwh.getTankHeatContent_kJ(); + hpwh.runOneStep(0, ambientT_C, externalT_C, HPWH::DR_LOC, inletVol2_L, inletT2_C, &nodePowerExtra_W); + double Q_final = hpwh.getTankHeatContent_kJ(); + + double dQ_actual_kJ = (Q_final - Q_init) * 1.055055853 / 1.055; // Correct for approx. BU->kJ conversion. + + double dQ_expected_kJ = extraPower_W * 60. / 1.e3; // 1 min + + ASSERTTRUE(cmpd(dQ_actual_kJ, dQ_expected_kJ)); +} \ No newline at end of file From 4881d3a053c87cf4658cc4a4004765d498c84fc3 Mon Sep 17 00:00:00 2001 From: Phil Ahrenkiel Date: Thu, 16 Nov 2023 15:26:28 -0700 Subject: [PATCH 5/5] Improve comments. --- src/HPWHHeatSources.cc | 2 +- test/testHeatingLogics.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/HPWHHeatSources.cc b/src/HPWHHeatSources.cc index 6773b53c..430b707b 100644 --- a/src/HPWHHeatSources.cc +++ b/src/HPWHHeatSources.cc @@ -514,7 +514,7 @@ void HPWH::HeatSource::getCapacity(double externalT_C,double condenserTemp_C,dou std::vector target{externalT_F,Tout_F,condenserTemp_F}; btwxtInterp(input_BTUperHr,cop,target); } else { - if(perfMap.empty()) { + if(perfMap.empty()) { // Avoid using empty perfMap input_BTUperHr = 0.; cop = 0.; } else if(perfMap.size() > 1) { diff --git a/test/testHeatingLogics.cc b/test/testHeatingLogics.cc index cc8f0a20..47d620a4 100644 --- a/test/testHeatingLogics.cc +++ b/test/testHeatingLogics.cc @@ -288,7 +288,7 @@ void testExtraHeat() { hpwh.runOneStep(0, ambientT_C, externalT_C, HPWH::DR_LOC, inletVol2_L, inletT2_C, &nodePowerExtra_W); double Q_final = hpwh.getTankHeatContent_kJ(); - double dQ_actual_kJ = (Q_final - Q_init) * 1.055055853 / 1.055; // Correct for approx. BU->kJ conversion. + double dQ_actual_kJ = (Q_final - Q_init) * 1.055055853 / 1.055; // Correct for approx. BTU->kJ conversion. double dQ_expected_kJ = extraPower_W * 60. / 1.e3; // 1 min