From 90f284668c37bf6f363f27bf2b0f31ab7d51d9b1 Mon Sep 17 00:00:00 2001 From: rraustad Date: Tue, 24 Sep 2024 10:44:18 -0400 Subject: [PATCH 1/3] Correct VAV maximum air flow fraction during reheat --- src/EnergyPlus/SingleDuct.cc | 12 ++++++-- tst/EnergyPlus/unit/SingleDuct.unit.cc | 39 ++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/EnergyPlus/SingleDuct.cc b/src/EnergyPlus/SingleDuct.cc index 69f03474ac6..c5fd062b64b 100644 --- a/src/EnergyPlus/SingleDuct.cc +++ b/src/EnergyPlus/SingleDuct.cc @@ -2877,8 +2877,10 @@ 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 = (this->DamperHeatingAction == Action::ReverseWithLimits) + ? state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlowMax + : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow; + MaxAirVolFlowRateDes = max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolVolFlow, heatingMaxFlow); if (MaxAirVolFlowRateDes < SmallAirVolFlow) { MaxAirVolFlowRateDes = 0.0; @@ -2927,7 +2929,11 @@ 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) { + MaxHeatAirVolFlowRateDes = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlowMax; + } else { + MaxHeatAirVolFlowRateDes = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow; + } if (MaxHeatAirVolFlowRateDes < SmallAirVolFlow) { MaxHeatAirVolFlowRateDes = 0.0; } diff --git a/tst/EnergyPlus/unit/SingleDuct.unit.cc b/tst/EnergyPlus/unit/SingleDuct.unit.cc index 3c448d7b1ee..be75837c77b 100644 --- a/tst/EnergyPlus/unit/SingleDuct.unit.cc +++ b/tst/EnergyPlus/unit/SingleDuct.unit.cc @@ -2737,23 +2737,52 @@ 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); + 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); + + // 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); + expectedMaxAirVolFractionDuringReheat = state->dataSize->TermUnitFinalZoneSizing(1).DesHeatVolFlowMax / thisSys.MaxAirVolFlowRate; + EXPECT_EQ(expectedZoneMinAirFracDes, thisSys.ZoneMinAirFracDes); + EXPECT_EQ(1.0, thisSys.MaxAirVolFractionDuringReheat); + EXPECT_EQ(expectedMaxAirVolFractionDuringReheat, thisSys.MaxAirVolFractionDuringReheat); } TEST_F(EnergyPlusFixture, setATMixerSizingProperties_Test) From 73fcfff756fe6ebbbeab19b6252867557bf797c7 Mon Sep 17 00:00:00 2001 From: rraustad Date: Tue, 24 Sep 2024 13:30:09 -0400 Subject: [PATCH 2/3] Revised based on using DesHeatVolFlowMax as limit --- src/EnergyPlus/SingleDuct.cc | 23 ++++++++++++++++++----- tst/EnergyPlus/unit/SingleDuct.unit.cc | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/EnergyPlus/SingleDuct.cc b/src/EnergyPlus/SingleDuct.cc index c5fd062b64b..59e570811bd 100644 --- a/src/EnergyPlus/SingleDuct.cc +++ b/src/EnergyPlus/SingleDuct.cc @@ -2877,9 +2877,14 @@ void SingleDuctAirTerminal::SizeSys(EnergyPlusData &state) CheckZoneSizing(state, this->sysType, this->SysName); - Real64 heatingMaxFlow = (this->DamperHeatingAction == Action::ReverseWithLimits) - ? state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlowMax - : 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) { @@ -2929,7 +2934,9 @@ void SingleDuctAirTerminal::SizeSys(EnergyPlusData &state) } } else { CheckZoneSizing(state, this->sysType, this->SysName); - if (this->DamperHeatingAction == Action::ReverseWithLimits) { + 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; @@ -3221,7 +3228,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 > + 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 diff --git a/tst/EnergyPlus/unit/SingleDuct.unit.cc b/tst/EnergyPlus/unit/SingleDuct.unit.cc index be75837c77b..cc7c60b35df 100644 --- a/tst/EnergyPlus/unit/SingleDuct.unit.cc +++ b/tst/EnergyPlus/unit/SingleDuct.unit.cc @@ -2765,11 +2765,27 @@ TEST_F(EnergyPlusFixture, VAVReheatTerminal_SizeMinFrac) 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; @@ -2779,6 +2795,7 @@ TEST_F(EnergyPlusFixture, VAVReheatTerminal_SizeMinFrac) 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); From d29faa104bbfd7deae8a462ec916dcf49598f966 Mon Sep 17 00:00:00 2001 From: rraustad Date: Tue, 24 Sep 2024 15:53:05 -0400 Subject: [PATCH 3/3] Update 2 unit tests --- tst/EnergyPlus/unit/SingleDuct.unit.cc | 8 ++++---- tst/EnergyPlus/unit/VAVDefMinMaxFlow.unit.cc | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tst/EnergyPlus/unit/SingleDuct.unit.cc b/tst/EnergyPlus/unit/SingleDuct.unit.cc index cc7c60b35df..be5edc2ff84 100644 --- a/tst/EnergyPlus/unit/SingleDuct.unit.cc +++ b/tst/EnergyPlus/unit/SingleDuct.unit.cc @@ -1282,7 +1282,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 = @@ -1291,7 +1291,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 @@ -1306,12 +1306,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), diff --git a/tst/EnergyPlus/unit/VAVDefMinMaxFlow.unit.cc b/tst/EnergyPlus/unit/VAVDefMinMaxFlow.unit.cc index e4307f6da2d..d7ff4369e02 100644 --- a/tst/EnergyPlus/unit/VAVDefMinMaxFlow.unit.cc +++ b/tst/EnergyPlus/unit/VAVDefMinMaxFlow.unit.cc @@ -490,8 +490,12 @@ TEST_F(EnergyPlusFixture, VAVDefMinMaxFlowTestSizing2) state->dataSingleDuct->sd_airterminal(1).ZoneFloorArea = state->dataHeatBal->Zone(1).FloorArea; UpdateTermUnitFinalZoneSizing(*state); // Fills the TermUnitFinalZoneSizing array state->dataSingleDuct->sd_airterminal(1).SizeSys(*state); + Real64 heatVolFlow = (state->dataSize->FinalZoneSizing(state->dataSize->CurZoneEqNum).DesHeatVolFlow > + state->dataSize->FinalZoneSizing(state->dataSize->CurZoneEqNum).DesHeatVolFlowMax) + ? state->dataSize->FinalZoneSizing(state->dataSize->CurZoneEqNum).DesHeatVolFlowMax + : state->dataSize->FinalZoneSizing(state->dataSize->CurZoneEqNum).DesHeatVolFlow; EXPECT_NEAR(state->dataSingleDuct->sd_airterminal(state->dataSize->CurZoneEqNum).ZoneMinAirFracDes, 0.348739, 0.000001); - EXPECT_NEAR(state->dataSingleDuct->sd_airterminal(state->dataSize->CurZoneEqNum).MaxAirVolFlowRateDuringReheat, 0.196047, 0.000001); + EXPECT_NEAR(state->dataSingleDuct->sd_airterminal(state->dataSize->CurZoneEqNum).MaxAirVolFlowRateDuringReheat, heatVolFlow, 0.000001); state->dataLoopNodes->Node.deallocate(); state->dataZoneEquip->ZoneEquipConfig.deallocate();