Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heat exchange models #183

Merged
merged 34 commits into from
Dec 19, 2023
Merged
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
99efbed
Restart heat exchange model.
Nov 1, 2023
8618861
Add heat exchange params.
Nov 1, 2023
508b544
AquaThermAire fails file and regression tests.
Nov 1, 2023
6e78b76
Fails villara test.
Nov 1, 2023
4681954
Adjust villara time.
Nov 1, 2023
7a6b418
Aquatherm added.
Nov 2, 2023
ad7efa0
Merge branch 'master' into heat-exchange-models
spahrenk Nov 6, 2023
539ef53
Merge branch 'master' into heat-exchange-models
Nov 9, 2023
638a51e
Merge branch 'master' into heat-exchange-models
Nov 13, 2023
ccdc7d2
accept master
Nov 13, 2023
098874d
Remove specific AquaTerm refs.
Nov 13, 2023
9bb19c7
No AquaTherm refs.
Nov 13, 2023
2fa7021
AquaTherm back in.
Nov 13, 2023
3611502
Review changes; unlock condenser.
Nov 20, 2023
92d5edf
Merge branch 'master' into heat-exchange-models
Nov 20, 2023
19ae202
Merge branch 'master' into heat-exchange-models
Nov 29, 2023
63b453a
Use 800 C storage tank to pass solar test.
Dec 6, 2023
e7bb180
Merge master.
Dec 11, 2023
592b89e
Fix heating logic issues.
Dec 11, 2023
e2d006f
Set AquaTherm to 12 tank nodes.
Dec 11, 2023
b8e569c
Use whole-tank logic.
Dec 11, 2023
9348872
Merge branch 'master' into heat-exchange-models
Dec 11, 2023
5043494
Improve unit conversion.
Dec 12, 2023
0dcc923
Conform case.
Dec 12, 2023
7553fdd
Merge branch 'master' into heat-exchange-models
Dec 12, 2023
4f64c7a
Merge branch 'master' into heat-exchange-models
Dec 13, 2023
533ec62
Change heat-exch-eff coeff.
Dec 14, 2023
4de5ef1
Define node-heat-exch-effec.
Dec 14, 2023
c5e0c99
Check validity.
Dec 14, 2023
e3f4a7c
Add 2nd third function.
Dec 14, 2023
2e25a71
Review comments; remove outletT space.
Dec 15, 2023
4a3e3f9
Remove unused fnc.
Dec 18, 2023
31cec6c
Change coil config.
Dec 18, 2023
ad4f931
Merge branch 'heat-exchange-models' of https://github.com/bigladder/H…
Dec 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Restart heat exchange model.
Phil Ahrenkiel authored and Phil Ahrenkiel committed Nov 1, 2023
commit 99efbed7e81f26eac30df8ffd9b126b72881106d
115 changes: 57 additions & 58 deletions src/HPWH.cc
Original file line number Diff line number Diff line change
@@ -194,6 +194,7 @@ void HPWH::setAllDefaults() {
usesSoCLogic = false;
setMinutesPerStep(1.0);
hpwhVerbosity = VRB_minuteOut;
waterIsDrawnFromTank = true;
}

HPWH::HPWH(const HPWH &hpwh) {
@@ -2412,11 +2413,8 @@ int HPWH::getResistancePosition(int elementIndex) const {
//the privates
void HPWH::updateTankTemps(double drawVolume_L,double inletT_C,double tankAmbientT_C,
double inletVol2_L,double inletT2_C) {
//set up some useful variables for calculations
double drawFraction;
this->outletTemp_C = 0.;
double nodeInletFraction,cumInletFraction,drawVolume_N;
double nodeInletTV = 0.;

outletTemp_C = 0.;

if(drawVolume_L > 0.) {

@@ -2449,75 +2447,77 @@ void HPWH::updateTankTemps(double drawVolume_L,double inletT_C,double tankAmbien
lowInletT = inletT_C;
lowInletV = drawVolume_L - inletVol2_L;
}
//calculate how many nodes to draw (drawVolume_N)
drawVolume_N = drawVolume_L / nodeVolume_L;
if(drawVolume_L > tankVolume_L) {
//if (hpwhVerbosity >= VRB_reluctant) {
// //msg("WARNING: Drawing more than the tank volume in one step is undefined behavior. Terminating simulation. \n");
// msg("WARNING: Drawing more than the tank volume in one step is undefined behavior. Continuing simulation at your own risk. \n");
//}
//simHasFailed = true;
//return;
for(int i = 0; i < getNumNodes(); i++){
outletTemp_C += tankTemps_C[i];
tankTemps_C[i] = (inletT_C * (drawVolume_L - inletVol2_L) + inletT2_C * inletVol2_L) / drawVolume_L;
}
outletTemp_C = (outletTemp_C / getNumNodes() * tankVolume_L + tankTemps_C[0] * (drawVolume_L - tankVolume_L))
/ drawVolume_L * drawVolume_N;

drawVolume_N = 0.;
}

/////////////////////////////////////////////////////////////////////////////////////////////////
if (waterIsDrawnFromTank) {
//calculate how many nodes to draw (drawVolume_N)
double drawVolume_N = drawVolume_L / nodeVolume_L;
if(drawVolume_L > tankVolume_L) {
//if (hpwhVerbosity >= VRB_reluctant) {
// //msg("WARNING: Drawing more than the tank volume in one step is undefined behavior. Terminating simulation. \n");
// msg("WARNING: Drawing more than the tank volume in one step is undefined behavior. Continuing simulation at your own risk. \n");
//}
//simHasFailed = true;
//return;
for(int i = 0; i < getNumNodes(); i++){
outletTemp_C += tankTemps_C[i];
tankTemps_C[i] = (inletT_C * (drawVolume_L - inletVol2_L) + inletT2_C * inletVol2_L) / drawVolume_L;
}
outletTemp_C = (outletTemp_C / getNumNodes() * tankVolume_L + tankTemps_C[0] * (drawVolume_L - tankVolume_L))
/ drawVolume_L * drawVolume_N;

while(drawVolume_N > 0) {
drawVolume_N = 0.;
}

// Draw one node at a time
drawFraction = drawVolume_N > 1. ? 1. : drawVolume_N;
/////////////////////////////////////////////////////////////////////////////////////////////////

//add temperature for outletT average
outletTemp_C += drawFraction * tankTemps_C[getNumNodes() - 1];
while(drawVolume_N > 0) {

cumInletFraction = 0.;
for(int i = getNumNodes() - 1; i >= lowInletH; i--) {
// Draw one node at a time
double drawFraction = drawVolume_N > 1. ? 1. : drawVolume_N;
double nodeInletTV = 0.;

// Reset inlet inputs at this node.
nodeInletFraction = 0.;
nodeInletTV = 0.;
//add temperature for outletT average
outletTemp_C += drawFraction * tankTemps_C[getNumNodes() - 1];

// Sum of all inlets Vi*Ti at this node
if(i == highInletH) {
nodeInletTV += highInletV * drawFraction / drawVolume_L * highInletT;
nodeInletFraction += highInletV * drawFraction / drawVolume_L;
}
if(i == lowInletH) {
nodeInletTV += lowInletV * drawFraction / drawVolume_L * lowInletT;
nodeInletFraction += lowInletV * drawFraction / drawVolume_L;
double cumInletFraction = 0.;
for(int i = getNumNodes() - 1; i >= lowInletH; i--) {

break; // if this is the bottom inlet break out of the four loop and use the boundary condition equation.
}
// Reset inlet inputs at this node.
double nodeInletFraction = 0.;
nodeInletTV = 0.;

// Look at the volume and temperature fluxes into this node
tankTemps_C[i] = (1. - (drawFraction - cumInletFraction)) * tankTemps_C[i] +
nodeInletTV +
(drawFraction - (cumInletFraction + nodeInletFraction)) * tankTemps_C[i - 1];
// Sum of all inlets Vi*Ti at this node
if(i == highInletH) {
nodeInletTV += highInletV * drawFraction / drawVolume_L * highInletT;
nodeInletFraction += highInletV * drawFraction / drawVolume_L;
}
if(i == lowInletH) {
nodeInletTV += lowInletV * drawFraction / drawVolume_L * lowInletT;
nodeInletFraction += lowInletV * drawFraction / drawVolume_L;

cumInletFraction += nodeInletFraction;
break; // if this is the bottom inlet break out of the four loop and use the boundary condition equation.
}

}
// Look at the volume and temperature fluxes into this node
tankTemps_C[i] = (1. - (drawFraction - cumInletFraction)) * tankTemps_C[i] +
nodeInletTV +
(drawFraction - (cumInletFraction + nodeInletFraction)) * tankTemps_C[i - 1];

// Boundary condition equation because it shouldn't take anything from tankTemps_C[i - 1] but it also might not exist.
tankTemps_C[lowInletH] = (1. - (drawFraction - cumInletFraction)) * tankTemps_C[lowInletH] + nodeInletTV;
cumInletFraction += nodeInletFraction;

drawVolume_N -= drawFraction;
}

mixTankInversions();
}
// Boundary condition equation because it shouldn't take anything from tankTemps_C[i - 1] but it also might not exist.
tankTemps_C[lowInletH] = (1. - (drawFraction - cumInletFraction)) * tankTemps_C[lowInletH] + nodeInletTV;

drawVolume_N -= drawFraction;

//fill in average outlet T - it is a weighted averaged, with weights == nodes drawn
this->outletTemp_C /= (drawVolume_L / nodeVolume_L);
mixTankInversions();
}

//fill in average outlet T - it is a weighted averaged, with weights == nodes drawn
outletTemp_C /= (drawVolume_L / nodeVolume_L);
}
/////////////////////////////////////////////////////////////////////////////////////////////////

//Account for mixing at the bottom of the tank
@@ -2528,7 +2528,6 @@ void HPWH::updateTankTemps(double drawVolume_L,double inletT_C,double tankAmbien

} //end if(draw_volume_L > 0)


if(doConduction) {

// Get the "constant" tau for the stability condition and the conduction calculation
9 changes: 6 additions & 3 deletions src/HPWH.in.hh
Original file line number Diff line number Diff line change
@@ -219,7 +219,9 @@ public:
MODELS_RHEEM_HPHD60HNU_201_MP = 350,
MODELS_RHEEM_HPHD60VNU_201_MP = 351,
MODELS_RHEEM_HPHD135HNU_483_MP = 352, // really bad fit to data due to inconsistency in data
MODELS_RHEEM_HPHD135VNU_483_MP = 353 // really bad fit to data due to inconsistency in data
MODELS_RHEEM_HPHD135VNU_483_MP = 353, // really bad fit to data due to inconsistency in data

MODELS_AQUATHERMAIRE = 400 // heat exchanger model
};

///specifies the modes for writing output
@@ -1002,9 +1004,10 @@ private:
/// Generates a vector of logical nodes
std::vector<HPWH::NodeWeight> getNodeWeightRange(double bottomFraction,double topFraction);

}; //end of HPWH class

/// True: water is drawn from the tank itself; False: tank provides heat exchange only
bool waterIsDrawnFromTank;

}; //end of HPWH class


class HPWH::HeatSource {
53 changes: 52 additions & 1 deletion src/HPWHpresets.cc
Original file line number Diff line number Diff line change
@@ -3819,8 +3819,59 @@ int HPWH::HPWHinit_presets(MODELS presetNum) {
heatSources[1].followedByHeatSource = &heatSources[2];

heatSources[0].companionHeatSource = &heatSources[2];
}
}
else if (presetNum == MODELS_AQUATHERMAIRE) { // AquaThermAire
setNumNodes(1);
setpoint_C = F_TO_C(120.);

tankVolume_L = 50.;
tankUA_kJperHrC = 7.31;

doTempDepression = false;
tankMixesOnDraw = true;

HeatSource compressor(this);

//compressor values
compressor.isOn = false;
compressor.isVIP = false;
compressor.typeOfHeatSource = TYPE_compressor;

compressor.setCondensity({1.});

//voltex60 tier 1 values
compressor.perfMap.reserve(2);

compressor.perfMap.push_back({
47, // Temperature (T_F)
{0.467 * 1000, 0.00281 * 1000, 0.0000072 * 1000}, // Input Power Coefficients (inputPower_coeffs)
{4.86, -0.0222, -0.00001} // COP Coefficients (COP_coeffs)
});

compressor.perfMap.push_back({
67, // Temperature (T_F)
{0.541 * 1000, 0.00147 * 1000, 0.0000176 * 1000}, // Input Power Coefficients (inputPower_coeffs)
{6.58, -0.0392, 0.0000407} // COP Coefficients (COP_coeffs)
});

compressor.minT = F_TO_C(45.0);
compressor.maxT = F_TO_C(120.);
compressor.hysteresis_dC = dF_TO_dC(4);
compressor.configuration = HeatSource::CONFIG_WRAPPED;
compressor.maxSetpoint_C = MAXOUTLET_R134A;

//logic conditions
double compStart = dF_TO_dC(43.6);
double standbyT = dF_TO_dC(23.8);
compressor.addTurnOnLogic(HPWH::bottomThird(compStart));
compressor.addTurnOnLogic(HPWH::standby(standbyT));

//set everything in its places
heatSources.resize(1);
heatSources[0] = compressor;

waterIsDrawnFromTank = false;
}
else {
if (hpwhVerbosity >= VRB_reluctant) {
msg("You have tried to select a preset model which does not exist. \n");
39 changes: 39 additions & 0 deletions test/AquaThermAire.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
verbosity silent
numNodes 1 #number of nodes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to 12?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

setpoint 120 F
volume 50 gal
UA 7.31 kJperHrC
depressTemp false
mixOnDraw true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be false, the draw doesn't go into the tank at all, and it shouldn't cause any mixing of the water.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

waterIsDrawnFromTank false

#a test comment
numHeatSources 1

heatsource 0 isVIP false
heatsource 0 isOn false
heatsource 0 type compressor
heatsource 0 condensity 1
heatsource 0 nTemps 2
heatsource 0 T1 47 F
heatsource 0 T2 67 F
heatsource 0 inPowT1const 280
heatsource 0 inPowT1lin 4.97342
heatsource 0 inPowT1quad 0
heatsource 0 inPowT2const 280
heatsource 0 inPowT2lin 5.35992
heatsource 0 inPowT2quad 0
heatsource 0 copT1const 5.634009
heatsource 0 copT1lin -0.029485
heatsource 0 copT1quad 0.0
heatsource 0 copT2const 6.3
heatsource 0 copT2lin -0.03
heatsource 0 copT2quad 0.0
heatsource 0 minT 40 F
heatsource 0 maxT 120 F
heatsource 0 hysteresis 1 F
heatsource 0 coilConfig wrapped
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be "submerged" based on conversations with Ben. What impact will this have on the simulation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrapped and submerged use different heat distributions. Simulation results are slightly altered.


heatsource 0 onlogic bottomThird 43.6 F
heatsource 0 onlogic standby 23.8 F