diff --git a/src/HPWH.cc b/src/HPWH.cc index 6e2ead4e..85b3ed58 100644 --- a/src/HPWH.cc +++ b/src/HPWH.cc @@ -2670,6 +2670,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/HPWH.hh b/src/HPWH.hh index 69898a8b..415e7686 100644 --- a/src/HPWH.hh +++ b/src/HPWH.hh @@ -1017,6 +1017,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 348ab49a..430b707b 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); @@ -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()) { // Avoid using empty perfMap + 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 @@ -737,6 +741,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); } @@ -988,43 +993,31 @@ void HPWH::HeatSource::setupAsResistiveElement(int node,double Watts,int condens typeOfHeatSource = TYPE_resistance; } -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]; - } - normalize(extraCondensity); - - // set condensity - setCondensity(extraCondensity); - if(hpwh->hpwhVerbosity >= VRB_emetic){ - hpwh->msg("extra heat condensity: "); - for(int i = 0; i < getCondensitySize(); i++) { - hpwh->msg("C[%d]: %f",i,condensity[i]); - } - hpwh->msg("\n "); - } +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) { 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); diff --git a/test/testHeatingLogics.cc b/test/testHeatingLogics.cc index b166bada..47d620a4 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. BTU->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