-
Notifications
You must be signed in to change notification settings - Fork 425
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
Correct VAV maximum air flow fraction during reheat for heating dominated use cases #10763
Changes from all commits
90f2846
73fcfff
d29faa1
3473759
1129a59
9051fe9
83351a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2335,8 +2335,15 @@ void SingleDuctAirTerminal::SizeSys(EnergyPlusData &state) | |
|
||
CheckZoneSizing(state, this->sysType, this->SysName); | ||
|
||
MaxAirVolFlowRateDes = max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolVolFlow, | ||
state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow); | ||
Real64 heatingMaxFlow; | ||
if (this->DamperHeatingAction == Action::ReverseWithLimits && | ||
state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow > | ||
state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlowMax) { | ||
heatingMaxFlow = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlowMax; | ||
} else { | ||
heatingMaxFlow = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow; | ||
} | ||
MaxAirVolFlowRateDes = max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolVolFlow, heatingMaxFlow); | ||
|
||
if (MaxAirVolFlowRateDes < SmallAirVolFlow) { | ||
MaxAirVolFlowRateDes = 0.0; | ||
|
@@ -2385,7 +2392,13 @@ void SingleDuctAirTerminal::SizeSys(EnergyPlusData &state) | |
} | ||
} else { | ||
CheckZoneSizing(state, this->sysType, this->SysName); | ||
MaxHeatAirVolFlowRateDes = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow; | ||
if (this->DamperHeatingAction == Action::ReverseWithLimits && | ||
state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow > | ||
state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlowMax) { | ||
MaxHeatAirVolFlowRateDes = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlowMax; | ||
} else { | ||
MaxHeatAirVolFlowRateDes = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Below at line 3224, ReverseWithLimits uses DesHeatVolFlowMax. That value should also be used here.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed above, these 2 areas of code, above (2937) and below (3231), were changed to use DesHeatVolFlowMax as a limit. |
||
if (MaxHeatAirVolFlowRateDes < SmallAirVolFlow) { | ||
MaxHeatAirVolFlowRateDes = 0.0; | ||
} | ||
|
@@ -2672,7 +2685,13 @@ void SingleDuctAirTerminal::SizeSys(EnergyPlusData &state) | |
if (state.dataSize->ZoneSizingRunDone) { | ||
if (state.dataSize->CurTermUnitSizingNum > 0) { | ||
// if zone sizing run done, set the design max reheat air flow to the value from the design calcs | ||
MaxAirVolFlowRateDuringReheatDes = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlowMax; | ||
if (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow > | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why we need this same (or very similar logic) in multiple places, but not holding up this PR for that. It works as-is. |
||
state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlowMax) { | ||
MaxAirVolFlowRateDuringReheatDes = | ||
state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlowMax; | ||
} else { | ||
MaxAirVolFlowRateDuringReheatDes = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow; | ||
} | ||
} | ||
} else { | ||
// if no design calc use 0.002032 [m3/s-m2] times floor area. That's .40 cfm/ft2 | ||
|
@@ -2868,9 +2887,13 @@ void SingleDuctAirTerminal::SizeSys(EnergyPlusData &state) | |
max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).NonAirSysDesHeatVolFlow, | ||
this->MaxAirVolFlowRate * this->ZoneTurndownMinAirFrac); | ||
} else { | ||
TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow = | ||
max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).NonAirSysDesHeatVolFlow, | ||
this->MaxAirVolFlowRate * this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac); | ||
if (this->SysType_Num == SysType::SingleDuctVAVReheat && this->DamperHeatingAction == Action::ReverseWithLimits) { | ||
TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow = this->MaxAirVolFlowRateDuringReheat; | ||
} else { | ||
TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow = | ||
max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).NonAirSysDesHeatVolFlow, | ||
this->MaxAirVolFlowRate * this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac); | ||
} | ||
} | ||
} else { | ||
if (this->SysType_Num == SysType::SingleDuctVAVReheatVSFan) { | ||
|
@@ -3530,7 +3553,7 @@ void SingleDuctAirTerminal::SimVAV(EnergyPlusData &state, bool const FirstHVACIt | |
this->ControlCompTypeNum, | ||
this->CompErrIndex, | ||
ZoneNodeNum, | ||
SysOutletNode); // why not QZnReq ? | ||
SysOutletNode); | ||
// air flow controller, not on plant, don't pass plant topology info | ||
// reset terminal unit inlet air mass flow to new value. | ||
state.dataLoopNodes->Node(this->OutletNodeNum).MassFlowRateMaxAvail = this->sd_airterminalInlet.AirMassFlowRateMaxAvail; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1294,7 +1294,7 @@ TEST_F(EnergyPlusFixture, SingleDuct_ZeroFloorAreaTest) | |
// zone floor area of zone 1 = 0, zone 2 > 0. Expect TU MaxAirVolFlowRateDuringReheat = 0 only for zone 1. | ||
// this test isn't relevant anymore since defaulting is done differently | ||
Real64 MaxAirVolFlowRateDuringReheatDes = | ||
min(state->dataSize->FinalZoneSizing(1).DesHeatVolFlowMax, state->dataSingleDuct->sd_airterminal(1).MaxAirVolFlowRate); | ||
min(state->dataSize->FinalZoneSizing(1).DesHeatVolFlow, state->dataSingleDuct->sd_airterminal(1).MaxAirVolFlowRate); | ||
// Real64 MaxAirVolFlowRateDuringReheatDes = min( 0.002032 * state->dataSingleDuct->sd_airterminal( 1 ).ZoneFloorArea, | ||
// state->dataSingleDuct->sd_airterminal( 1 ).MaxAirVolFlowRate ); apply limit based on min stop | ||
MaxAirVolFlowRateDuringReheatDes = | ||
|
@@ -1303,7 +1303,7 @@ TEST_F(EnergyPlusFixture, SingleDuct_ZeroFloorAreaTest) | |
|
||
// This isn't relevant any more since the default is calculated differently | ||
Real64 MaxAirVolFractionDuringReheatDes = | ||
min(1.0, (state->dataSize->FinalZoneSizing(1).DesHeatVolFlowMax / state->dataSingleDuct->sd_airterminal(1).MaxAirVolFlowRate)); | ||
min(1.0, (state->dataSize->FinalZoneSizing(1).DesHeatVolFlow / state->dataSingleDuct->sd_airterminal(1).MaxAirVolFlowRate)); | ||
// Real64 MaxAirVolFractionDuringReheatDes = min( 1.0, ( 0.002032 * state->dataSingleDuct->sd_airterminal( 1 ).ZoneFloorArea / | ||
// state->dataSingleDuct->sd_airterminal( 1 ).MaxAirVolFlowRate ) | ||
// ); apply limit based on min stop | ||
|
@@ -1318,12 +1318,12 @@ TEST_F(EnergyPlusFixture, SingleDuct_ZeroFloorAreaTest) | |
EXPECT_NEAR(MaxAirVolFractionDuringReheatDes, state->dataSingleDuct->sd_airterminal(1).MaxAirVolFractionDuringReheat, 0.0000000000001); | ||
|
||
MaxAirVolFlowRateDuringReheatDes = | ||
min(state->dataSize->FinalZoneSizing(2).DesHeatVolFlowMax, state->dataSingleDuct->sd_airterminal(2).MaxAirVolFlowRate); | ||
min(state->dataSize->FinalZoneSizing(2).DesHeatVolFlow, state->dataSingleDuct->sd_airterminal(2).MaxAirVolFlowRate); | ||
MaxAirVolFlowRateDuringReheatDes = | ||
max(MaxAirVolFlowRateDuringReheatDes, | ||
(state->dataSingleDuct->sd_airterminal(2).MaxAirVolFlowRate * state->dataSingleDuct->sd_airterminal(2).ZoneMinAirFrac)); | ||
MaxAirVolFractionDuringReheatDes = | ||
min(1.0, (state->dataSize->FinalZoneSizing(2).DesHeatVolFlowMax / state->dataSingleDuct->sd_airterminal(2).MaxAirVolFlowRate)); | ||
min(1.0, (state->dataSize->FinalZoneSizing(2).DesHeatVolFlow / state->dataSingleDuct->sd_airterminal(2).MaxAirVolFlowRate)); | ||
MaxAirVolFractionDuringReheatDes = max(MaxAirVolFractionDuringReheatDes, state->dataSingleDuct->sd_airterminal(2).ZoneMinAirFrac); | ||
MaxAirVolFlowRateDuringReheatDes = | ||
min(max(MaxAirVolFlowRateDuringReheatDes, MaxAirVolFractionDuringReheatDes * state->dataSingleDuct->sd_airterminal(2).MaxAirVolFlowRate), | ||
|
@@ -2750,23 +2750,69 @@ TEST_F(EnergyPlusFixture, VAVReheatTerminal_SizeMinFrac) | |
EXPECT_TRUE(compare_err_stream("")); | ||
|
||
int SysNum = 1; | ||
auto &thisSys = state->dataSingleDuct->sd_airterminal(SysNum); | ||
|
||
// First test - design min flow < max flow | ||
state->dataSize->ZoneSizingRunDone = true; | ||
state->dataSize->CurZoneEqNum = 1; | ||
state->dataSize->CurTermUnitSizingNum = 1; | ||
state->dataSize->TermUnitFinalZoneSizing(1).DesCoolVolFlowMin = 0.5; | ||
state->dataSingleDuct->sd_airterminal(SysNum).SizeSys(*state); | ||
EXPECT_EQ(0.5, state->dataSingleDuct->sd_airterminal(SysNum).ZoneMinAirFracDes); | ||
thisSys.SizeSys(*state); | ||
EXPECT_EQ(0.5, thisSys.ZoneMinAirFracDes); | ||
|
||
// Second test - design min flow > max flow | ||
state->dataSize->ZoneSizingRunDone = true; | ||
state->dataSize->CurZoneEqNum = 1; | ||
state->dataSize->CurTermUnitSizingNum = 1; | ||
state->dataSingleDuct->sd_airterminal(SysNum).ZoneMinAirFracDes = AutoSize; // need to reset this so it sizes again | ||
thisSys.ZoneMinAirFracDes = AutoSize; // need to reset this so it sizes again | ||
state->dataSize->TermUnitFinalZoneSizing(1).DesCoolVolFlowMin = 1.5; | ||
state->dataSingleDuct->sd_airterminal(SysNum).SizeSys(*state); | ||
EXPECT_EQ(1.0, state->dataSingleDuct->sd_airterminal(SysNum).ZoneMinAirFracDes); | ||
thisSys.SizeSys(*state); | ||
EXPECT_EQ(1.0, thisSys.ZoneMinAirFracDes); | ||
|
||
// test Maximum Flow Fraction During Reheat for heating dominated | ||
thisSys.MaxAirVolFlowRate = DataSizing::AutoSize; | ||
thisSys.ZoneMinAirFracDes = DataSizing::AutoSize; | ||
thisSys.MaxAirVolFlowRateDuringReheat = DataSizing::AutoSize; | ||
thisSys.MaxAirVolFractionDuringReheat = DataSizing::AutoSize; | ||
state->dataSize->TermUnitFinalZoneSizing(1).DesHeatVolFlow = 1.7; | ||
state->dataSize->TermUnitFinalZoneSizing(1).DesHeatVolFlowMax = 1.6; | ||
thisSys.SizeSys(*state); | ||
Real64 expectedZoneMinAirFracDes = std::min(1.0, state->dataSize->TermUnitFinalZoneSizing(1).DesCoolVolFlowMin / thisSys.MaxAirVolFlowRate); | ||
// DesHeatVolFlowMax is limiting flow rate | ||
Real64 expectedMaxAirVolFractionDuringReheat = state->dataSize->TermUnitFinalZoneSizing(1).DesHeatVolFlowMax / thisSys.MaxAirVolFlowRate; | ||
EXPECT_EQ(expectedZoneMinAirFracDes, thisSys.ZoneMinAirFracDes); | ||
EXPECT_EQ(1.0, thisSys.MaxAirVolFractionDuringReheat); | ||
EXPECT_EQ(expectedMaxAirVolFractionDuringReheat, thisSys.MaxAirVolFractionDuringReheat); | ||
|
||
// switch magnitude of DesHeatVolFlow and DesHeatVolFlowMax, still heating dominated | ||
thisSys.MaxAirVolFlowRate = DataSizing::AutoSize; | ||
thisSys.ZoneMinAirFracDes = DataSizing::AutoSize; | ||
thisSys.MaxAirVolFlowRateDuringReheat = DataSizing::AutoSize; | ||
thisSys.MaxAirVolFractionDuringReheat = DataSizing::AutoSize; | ||
state->dataSize->TermUnitFinalZoneSizing(1).DesHeatVolFlow = 1.6; | ||
state->dataSize->TermUnitFinalZoneSizing(1).DesHeatVolFlowMax = 1.7; | ||
thisSys.SizeSys(*state); | ||
expectedZoneMinAirFracDes = std::min(1.0, state->dataSize->TermUnitFinalZoneSizing(1).DesCoolVolFlowMin / thisSys.MaxAirVolFlowRate); | ||
// DesHeatVolFlowMax is NOT limiting flow rate | ||
expectedMaxAirVolFractionDuringReheat = state->dataSize->TermUnitFinalZoneSizing(1).DesHeatVolFlow / thisSys.MaxAirVolFlowRate; | ||
EXPECT_EQ(expectedZoneMinAirFracDes, thisSys.ZoneMinAirFracDes); | ||
EXPECT_EQ(1.0, thisSys.MaxAirVolFractionDuringReheat); | ||
EXPECT_EQ(expectedMaxAirVolFractionDuringReheat, thisSys.MaxAirVolFractionDuringReheat); | ||
|
||
// test Maximum Flow Fraction During Reheat for cooling dominated | ||
thisSys.MaxAirVolFlowRate = DataSizing::AutoSize; | ||
thisSys.ZoneMinAirFracDes = DataSizing::AutoSize; | ||
thisSys.MaxAirVolFlowRateDuringReheat = DataSizing::AutoSize; | ||
thisSys.MaxAirVolFractionDuringReheat = DataSizing::AutoSize; | ||
state->dataSize->TermUnitFinalZoneSizing(1).DesHeatVolFlow = 1.4; | ||
state->dataSize->TermUnitFinalZoneSizing(1).DesHeatVolFlowMax = 1.3; | ||
thisSys.SizeSys(*state); | ||
expectedZoneMinAirFracDes = std::min(1.0, state->dataSize->TermUnitFinalZoneSizing(1).DesCoolVolFlowMin / thisSys.MaxAirVolFlowRate); | ||
// DesHeatVolFlowMax is limiting flow rate | ||
expectedMaxAirVolFractionDuringReheat = state->dataSize->TermUnitFinalZoneSizing(1).DesHeatVolFlowMax / thisSys.MaxAirVolFlowRate; | ||
EXPECT_EQ(expectedZoneMinAirFracDes, thisSys.ZoneMinAirFracDes); | ||
EXPECT_EQ(1.0, thisSys.MaxAirVolFractionDuringReheat); | ||
EXPECT_EQ(expectedMaxAirVolFractionDuringReheat, thisSys.MaxAirVolFractionDuringReheat); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added 3 new tests for maximum air flow fraction during reheat to this unit test. |
||
} | ||
|
||
TEST_F(EnergyPlusFixture, setATMixerSizingProperties_Test) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If ReverseWithLimits uses a different heating air flow rate from the zone design heating air flow rate then that flow rate should be used as the value for the VAV box heating air flow rate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I was expecting DesHeatVolFlowMax to always be less than DesHeatVolFlow. For 5ZoneBoilerOutsideAirReset that's not the case. The diffs show that Zone 5 TU max air flow rate increased, I was only expecting decreases in max air flow rate for heating dominated zones. Zone cooling design air flow is greater than zone heating design air flow, but DesHeatVolFlowMax is larger than both of these.
So is DesHeatVolFlowMax just an upper limit? or is it the expected heating air flow rate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, since DesHeatVolFlowMax looks like a limit and not a flow rate, maybe I should change this line and line 3224 to?:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on this discussion I changed to treat DesHeatVolFlowMax as an upper limit. This should still correct the issue and result in fewer diffs.