Skip to content

Commit

Permalink
Modify extra-heat 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 11b2ca4 commit a405503
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 51 deletions.
103 changes: 98 additions & 5 deletions src/HPWH.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,45 @@ bool resampleExtensive(std::vector<double> &values,const std::vector<double> &sa
return false;
}

double expitFunc(double x,double offset) {
double val;
val = 1 / (1 + exp(x - offset));
return val;
}

void normalize(std::vector<double> &distribution) {
size_t N = distribution.size();

bool normalization_needed = true;

// Need to renormalize if negligible elements are zeroed.
while (normalization_needed)
{
normalization_needed = false;
double sum_tmp = 0.;
for(size_t i = 0; i < N; i++) {
sum_tmp += distribution[i];
}
if(sum_tmp > 0.) {
for(size_t i = 0; i < N; i++) {
distribution[i] /= sum_tmp;
//this gives a very slight speed improvement (milliseconds per simulated year)
if(distribution[i] < HPWH::TOL_MINVALUE) {
if (distribution[i] > 0.) {
normalization_needed = true;
}
distribution[i] = 0.;
}
}
}
else {
for(size_t i = 0; i < N; i++) {
distribution[i] = 0.;
}
}
}
}

void HPWH::setMinutesPerStep(const double minutesPerStep_in)
{
minutesPerStep = minutesPerStep_in;
Expand Down Expand Up @@ -2691,23 +2730,77 @@ void HPWH::addExtraHeatAboveNode(double qAdd_kJ,int nodeNum) {
}
}

void HPWH::addExtraHeat(std::vector<double> &nodePowerExtra_W){
void HPWH::modifyHeatDistribution(std::vector<double> &heatDistribution)
{ // Calculate condentropy and ==> shrinkage
double alphaT_C = 1.,betaT_C = 2.; // Mapping from condentropy to shrinkage
double condentropy = 0.;
double totalHeat = 0.;
std::size_t lowestNode = 0;
for(auto &heat: heatDistribution)
totalHeat += heat;

if(totalHeat == 0.)
return;

bool foundLowestNode = false;
for(std::size_t iNode = 0; iNode < heatDistribution.size(); ++iNode) {
double heat = heatDistribution[iNode];
if(heat > 0.) {
if(!foundLowestNode){
lowestNode = iNode;
foundLowestNode = true;
}
double density = heat / totalHeat;
condentropy -= density * log(density);
}
}
// condentropy shifts as ln(# of condensity nodes)
double size_factor = static_cast<double>(heatDistribution.size()) / CONDENSITY_SIZE;
double standard_condentropy = condentropy - log(size_factor);
double shrinkageT_C = alphaT_C + standard_condentropy * betaT_C;

std::vector<double> extTankTemps_C(heatDistribution.size());
resampleIntensive(extTankTemps_C,tankTemps_C);

for(std::size_t iNode = 0; iNode < heatDistribution.size(); ++iNode) {
double dist = 0.;
if(iNode >= lowestNode){
const double Toffset_C = 5.0 / 1.8; // 5 degF
const double offset = Toffset_C / 1.; // should be dimensionless
dist = expitFunc((extTankTemps_C[iNode] - extTankTemps_C[lowestNode]) / shrinkageT_C,offset);
dist *= setpoint_C - extTankTemps_C[iNode];
if(dist < 0.)
dist = 0.;
}
heatDistribution[iNode] = dist;
}
normalize(heatDistribution);

for(auto &heat: heatDistribution)
heat *= totalHeat;
}

std::vector<double> heatDistribution(getNumNodes());
void HPWH::addExtraHeat(std::vector<double> &extraHeatDist_W){

resampleExtensive(heatDistribution,nodePowerExtra_W);
std::vector<double> heatDistribution_W(getNumNodes());
resampleExtensive(heatDistribution_W,extraHeatDist_W);
auto modHeatDistribution_W = heatDistribution_W;
if(true) {
modifyHeatDistribution(modHeatDistribution_W);
}

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.;
if(modHeatDistribution_W[i] != 0) {
double qAdd_kJ = modHeatDistribution_W[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);
}

///////////////////////////////////////////////////////////////////////////////////

void HPWH::turnAllHeatSourcesOff() {
Expand Down
10 changes: 6 additions & 4 deletions src/HPWH.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,8 @@ private:
/// specified node number
void addExtraHeatAboveNode(double qAdd_kJ,int node);

void modifyHeatDistribution(std::vector<double> &heatDistribution);

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

Expand Down Expand Up @@ -1301,10 +1303,6 @@ private:
void sortPerformanceMap();
/**< sorts the Performance Map by increasing external temperatures */

/**< A few helper functions */
double expitFunc(double x,double offset);
void normalize(std::vector<double> &distribution);

}; // end of HeatSource class

#define BTUperKWH 3412.14163312794 // https://www.rapidtables.com/convert/energy/kWh_to_BTU.html
Expand Down Expand Up @@ -1350,4 +1348,8 @@ inline bool resampleIntensive(std::vector<double> &values,const std::vector<doub
}
bool resampleExtensive(std::vector<double> &values,const std::vector<double> &sampleValues);

/// helper functions
double expitFunc(double x,double offset);
void normalize(std::vector<double> &distribution);

#endif
44 changes: 2 additions & 42 deletions src/HPWHHeatSources.cc
Original file line number Diff line number Diff line change
Expand Up @@ -452,45 +452,6 @@ void HPWH::HeatSource::sortPerformanceMap() {
});
}

double HPWH::HeatSource::expitFunc(double x,double offset) {
double val;
val = 1 / (1 + exp(x - offset));
return val;
}

void HPWH::HeatSource::normalize(std::vector<double> &distribution) {
size_t N = distribution.size();

bool normalization_needed = true;

// Need to renormalize if negligible elements are zeroed.
while (normalization_needed)
{
normalization_needed = false;
double sum_tmp = 0.;
for(size_t i = 0; i < N; i++) {
sum_tmp += distribution[i];
}
if(sum_tmp > 0.) {
for(size_t i = 0; i < N; i++) {
distribution[i] /= sum_tmp;
//this gives a very slight speed improvement (milliseconds per simulated year)
if(distribution[i] < TOL_MINVALUE) {
if (distribution[i] > 0.) {
normalization_needed = true;
}
distribution[i] = 0.;
}
}
}
else {
for(size_t i = 0; i < N; i++) {
distribution[i] = 0.;
}
}
}
}

double HPWH::HeatSource::getTankTemp() const{

std::vector<double> resampledTankTemps(getCondensitySize());
Expand Down Expand Up @@ -779,7 +740,6 @@ double HPWH::HeatSource::addHeatAboveNode(double cap_kJ,int node) {
double Q_kJ,deltaT_C,targetTemp_C;
int setPointNodeNum;

double volumePerNode_L = hpwh->tankVolume_L / hpwh->getNumNodes();
double maxTargetTemp_C = std::min(maxSetpoint_C,hpwh->setpoint_C);

if(hpwh->hpwhVerbosity >= VRB_emetic) {
Expand Down Expand Up @@ -815,12 +775,12 @@ double HPWH::HeatSource::addHeatAboveNode(double cap_kJ,int node) {
deltaT_C = targetTemp_C - hpwh->tankTemps_C[setPointNodeNum];

//heat needed to bring all equal temp. nodes up to the temp of the next node. kJ
Q_kJ = CPWATER_kJperkgC * volumePerNode_L * DENSITYWATER_kgperL * (setPointNodeNum + 1 - node) * deltaT_C;
Q_kJ = CPWATER_kJperkgC * hpwh->nodeVolume_L * DENSITYWATER_kgperL * (setPointNodeNum + 1 - node) * deltaT_C;

//Running the rest of the time won't recover
if(Q_kJ > cap_kJ) {
for(int j = node; j <= setPointNodeNum; j++) {
hpwh->tankTemps_C[j] += cap_kJ / CPWATER_kJperkgC / volumePerNode_L / DENSITYWATER_kgperL / (setPointNodeNum + 1 - node);
hpwh->tankTemps_C[j] += cap_kJ / CPWATER_kJperkgC / hpwh->nodeVolume_L / DENSITYWATER_kgperL / (setPointNodeNum + 1 - node);
}
cap_kJ = 0;
}
Expand Down

0 comments on commit a405503

Please sign in to comment.