Skip to content

Commit

Permalink
Extra heat added as distribution.
Browse files Browse the repository at this point in the history
  • Loading branch information
Phil Ahrenkiel authored and Phil Ahrenkiel committed Dec 1, 2023
1 parent a336249 commit ef04896
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 57 deletions.
84 changes: 67 additions & 17 deletions src/HPWH.cc
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ int HPWH::runOneStep(double drawVolume_L,
double tankAmbientT_C,double heatSourceAmbientT_C,
DRMODES DRstatus,
double inletVol2_L,double inletT2_C,
std::vector<double>* nodePowerExtra_W) {
std::vector<double>* extraHeatDist_W) {
//returns 0 on successful completion, HPWH_ABORT on failure

//check for errors
Expand Down Expand Up @@ -313,6 +313,7 @@ int HPWH::runOneStep(double drawVolume_L,
heatSources[i].energyInput_kWh = 0.;
heatSources[i].energyOutput_kWh = 0.;
}
extraEnergyInput_kWh = 0.;

// if you are doing temp. depression, set tank and heatSource ambient temps
// to the tracked locationTemperature
Expand Down Expand Up @@ -504,8 +505,8 @@ int HPWH::runOneStep(double drawVolume_L,
isHeating = false;
}
//If there's extra user defined heat to add -> Add extra heat!
if(nodePowerExtra_W != NULL && (*nodePowerExtra_W).size() != 0) {
addExtraHeat(*nodePowerExtra_W,tankAmbientT_C);
if((extraHeatDist_W != NULL) && (extraHeatDist_W->size()) != 0) {
addExtraHeat(*extraHeatDist_W);
updateSoCIfNecessary();
}

Expand Down Expand Up @@ -2652,28 +2653,77 @@ void HPWH::mixTankInversions() {
}
}

void HPWH::addExtraHeat(std::vector<double> &nodePowerExtra_W,double tankAmbientT_C){
//-----------------------------------------------------------------------------
/// @brief Adds a heat amount qAdd_kJ at and above the node with index nodeNum.
/// @note addExtraHeat
/// @param[in] qAdd_kJ Amount of heat to add
/// @param[in] nodeNum Lowest node at which to add heat
//-----------------------------------------------------------------------------
void HPWH::addExtraHeatAboveNode(double qAdd_kJ,int nodeNum) {

while(qAdd_kJ > 0.) {
// Find the first node above the specified node that has a higher temperature than the one above it.
// double prevHeatContent_kJ = getTankHeatContent_kJ();
bool uniformT = true;
int nodesToHeat = 1;
double heatToTemp_C = tankTemps_C[nodeNum];
for(int i = nodeNum; i < getNumNodes() - 1; ++i) {
if(tankTemps_C[i + 1] > tankTemps_C[i]) {
heatToTemp_C = tankTemps_C[i + 1];
uniformT = false;
break;
} else {
++nodesToHeat;
}
}

for(int i = 0; i < getNumHeatSources(); i++){
if(heatSources[i].typeOfHeatSource == TYPE_extra) {
double incQ_kJ = 0.;
if(uniformT) {
heatToTemp_C = tankTemps_C[nodeNum] + qAdd_kJ / nodeCp_kJperC / nodesToHeat;
incQ_kJ = qAdd_kJ;
}
else {
for(int i = nodeNum; i < nodeNum + nodesToHeat; ++i) {
double qNode_kJ = nodeCp_kJperC * ((heatToTemp_C > tankTemps_C[i]) ? (heatToTemp_C - tankTemps_C[i]) : 0.);
incQ_kJ += qNode_kJ;
}

if (incQ_kJ > qAdd_kJ) {
heatToTemp_C = tankTemps_C[nodeNum] + (qAdd_kJ / incQ_kJ) * (heatToTemp_C - tankTemps_C[nodeNum]);
incQ_kJ = qAdd_kJ;
}
}

// Set up the extra heat source
heatSources[i].setupExtraHeat(nodePowerExtra_W);
for(int i = nodeNum; i < nodeNum + nodesToHeat; ++i) {
double qNode_kJ = nodeCp_kJperC * ((heatToTemp_C > tankTemps_C[i]) ? (heatToTemp_C - tankTemps_C[i]) : 0.);
tankTemps_C[i] += qNode_kJ / nodeCp_kJperC;
}
qAdd_kJ -= incQ_kJ;
/*
double heatContent_kJ = getTankHeatContent_kJ();
double dHeat_kJ = heatContent_kJ - prevHeatContent_kJ;
std::cout <<std::setprecision(12) << std::setw(12)
<< dHeat_kJ << ", " << incQ_kJ<<"\n";
*/
}
}

// condentropy/shrinkage and lowestNode are now in calcDerivedHeatingValues()
calcDerivedHeatingValues();
void HPWH::addExtraHeat(std::vector<double> &nodePowerExtra_W){

// add heat
heatSources[i].addHeat(tankAmbientT_C,minutesPerStep);
std::vector<double> heatDistribution(getNumNodes());

// 0 out to ignore features
heatSources[i].perfMap.clear();
heatSources[i].energyInput_kWh = 0.0;
heatSources[i].energyOutput_kWh = 0.0;
resampleExtensive(heatDistribution,nodePowerExtra_W);

break; // Only add extra heat to the first "extra" heat source found.
double tot_qAdded_kJ = 0.;
for(int i = getNumNodes() - 1; i >= 0; i--) {
if(heatDistribution[i] != 0) {
double qAdd_kJ = heatDistribution[i] / 1000. * minutesPerStep * 60.;
addExtraHeatAboveNode(qAdd_kJ,i);
tot_qAdded_kJ += qAdd_kJ;
}
}
// Write the input & output energy
extraEnergyInput_kWh = KJ_TO_KWH(tot_qAdded_kJ);
}
///////////////////////////////////////////////////////////////////////////////////

Expand Down
19 changes: 9 additions & 10 deletions src/HPWH.hh
Original file line number Diff line number Diff line change
Expand Up @@ -815,9 +815,8 @@ private:

void addHeatParent(HeatSource *heatSourcePtr,double heatSourceAmbientT_C,double minutesToRun);

void addExtraHeat(std::vector<double> &nodePowerExtra_W,double tankAmbientT_C);
/**< adds extra heat defined by the user, where nodeExtraHeat[] is a vector of heat quantities to be added during the step.
nodeExtraHeat[ 0] would go to bottom node, 1 to next etc. */
/// adds an extra-heat distribution extraHeatDist_W[] during a simulation step.
void addExtraHeat(std::vector<double> &extraHeatDist_W);

double tankAvg_C(const std::vector<NodeWeight> nodeWeights) const;
/**< functions to calculate what the temperature in a portion of the tank is */
Expand Down Expand Up @@ -1000,6 +999,13 @@ private:
/// Generates a vector of logical nodes
std::vector<HPWH::NodeWeight> getNodeWeightRange(double bottomFraction,double topFraction);

/// adds extra heat to the set of nodes that are at the same temperature, above the
/// specified node number
void addExtraHeatAboveNode(double qAdd_kJ,int node);

/// "extra" heat added during a simulation step
double extraEnergyInput_kWh;

}; //end of HPWH class

class HPWH::HeatSource {
Expand All @@ -1018,13 +1024,6 @@ public:
/**< 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<double> &nodePowerExtra_W);
/**< Configure a user-defined heat source added as extra, based off using
nodePowerExtra_W as the total watt input and the condensity*/

bool isEngaged() const;
/**< return whether or not the heat source is engaged */
void engageHeatSource(DRMODES DRstatus = DR_ALLOW);
Expand Down
27 changes: 0 additions & 27 deletions src/HPWHHeatSources.cc
Original file line number Diff line number Diff line change
Expand Up @@ -993,33 +993,6 @@ void HPWH::HeatSource::setupAsResistiveElement(int node,double Watts,int condens
typeOfHeatSource = TYPE_resistance;
}

void HPWH::HeatSource::setupExtraHeat(const double extraPower_W) {

perfMap.clear();
perfMap.reserve(2);

perfMap.push_back({
50, // Temperature (T_F)
{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)
{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<double> &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<HeatingLogic> logic) {
this->turnOnLogicSet.push_back(logic);
}
Expand Down
6 changes: 3 additions & 3 deletions test/testHeatingLogics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,8 @@ void testExtraHeat() {
const double inletVol2_L = 0.;
const double inletT2_C = 0.;

double extraPower_W = 1000.;
std::vector<double> nodePowerExtra_W = {extraPower_W};
const double extraPower_W = 1000.;
std::vector<double> nodePowerExtra_W = {extraPower_W, 0., 0., 0.};

//
hpwh.setUA(0.);
Expand All @@ -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. BTU->kJ conversion.
double dQ_actual_kJ = (Q_final - Q_init);

double dQ_expected_kJ = extraPower_W * 60. / 1.e3; // 1 min

Expand Down

0 comments on commit ef04896

Please sign in to comment.