diff --git a/src/EnergyPlus/SZVAVModel.cc b/src/EnergyPlus/SZVAVModel.cc index 1222e303314..a625f1a1ae1 100644 --- a/src/EnergyPlus/SZVAVModel.cc +++ b/src/EnergyPlus/SZVAVModel.cc @@ -579,8 +579,6 @@ namespace SZVAVModel { HVAC::CompressorOp const CompressorONFlag) { - UnitarySystems::UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[SysIndex]; - int constexpr MaxIter(100); // maximum number of iterations int SolFlag(0); // return flag from RegulaFalsi for sensible load std::string MessagePrefix; // label for warning reporting @@ -603,6 +601,7 @@ namespace SZVAVModel { int coilAirOutletNode(0); Real64 HeatCoilLoad(0.0); Real64 SupHeaterLoad(0.0); + Real64 iterWaterAirOrNot(0.0); Real64 TempSensOutput; // iterative sensible capacity [W] Real64 TempLatOutput; // iterative latent capacity [W] @@ -722,34 +721,34 @@ namespace SZVAVModel { if (SZVAVModel.MaxCoolCoilFluidFlow > 0.0) { SZVAVModel.CoolCoilWaterFlowRatio = maxCoilFluidFlow / SZVAVModel.MaxCoolCoilFluidFlow; } - thisSys.calcUnitarySystemToLoad(state, - AirLoopNum, - FirstHVACIteration, - PartLoadRatio, - 0.0, - OnOffAirFlowRatio, - TempSensOutput, - TempLatOutput, - HXUnitOn, - HeatCoilLoad, - SupHeaterLoad, - CompressorONFlag); + SZVAVModel.calcUnitarySystemToLoad(state, + AirLoopNum, + FirstHVACIteration, + PartLoadRatio, + 0.0, + OnOffAirFlowRatio, + TempSensOutput, + TempLatOutput, + HXUnitOn, + HeatCoilLoad, + SupHeaterLoad, + CompressorONFlag); } else { if (SZVAVModel.MaxHeatCoilFluidFlow > 0.0) { SZVAVModel.HeatCoilWaterFlowRatio = maxCoilFluidFlow / SZVAVModel.MaxHeatCoilFluidFlow; } - thisSys.calcUnitarySystemToLoad(state, - AirLoopNum, - FirstHVACIteration, - 0.0, - PartLoadRatio, - OnOffAirFlowRatio, - TempSensOutput, - TempLatOutput, - HXUnitOn, - ZoneLoad, - SupHeaterLoad, - CompressorONFlag); + SZVAVModel.calcUnitarySystemToLoad(state, + AirLoopNum, + FirstHVACIteration, + 0.0, + PartLoadRatio, + OnOffAirFlowRatio, + TempSensOutput, + TempLatOutput, + HXUnitOn, + ZoneLoad, + SupHeaterLoad, + CompressorONFlag); } coilActive = std::abs(state.dataLoopNodes->Node(coilAirInletNode).Temp - state.dataLoopNodes->Node(coilAirOutletNode).Temp) > 0; @@ -764,6 +763,7 @@ namespace SZVAVModel { } if ((CoolingLoad && TempSensOutput < ZoneLoad) || (HeatingLoad && TempSensOutput > ZoneLoad)) { // low speed fan can meet load + // don't iterate on air flow in region 1 using iterWaterAirOrNot = 0.0 as default auto fR1 = [&state, SysIndex, FirstHVACIteration, @@ -776,6 +776,7 @@ namespace SZVAVModel { maxCoilFluidFlow, minAirMassFlow, maxAirMassFlow, + iterWaterAirOrNot, CoolingLoad](Real64 const PartLoadRatio) { return UnitarySystems::UnitarySys::calcUnitarySystemWaterFlowResidual(state, PartLoadRatio, // coil part load ratio @@ -792,7 +793,7 @@ namespace SZVAVModel { 0.0, maxAirMassFlow, CoolingLoad, - 1.0); + iterWaterAirOrNot); }; General::SolveRoot(state, 0.001, MaxIter, SolFlag, PartLoadRatio, fR1, 0.0, 1.0); if (SolFlag < 0) { @@ -814,6 +815,7 @@ namespace SZVAVModel { if ((CoolingLoad && boundaryLoadMet < ZoneLoad) || (HeatingLoad && boundaryLoadMet > ZoneLoad)) { // in Region 2 of figure + iterWaterAirOrNot = 1.0; // iterate on air and/or water flow in region 2 outletTemp = state.dataLoopNodes->Node(OutletNode).Temp; minHumRat = state.dataLoopNodes->Node(SZVAVModel.NodeNumOfControlledZone).HumRat; if (outletTemp < ZoneTemp) { @@ -836,6 +838,7 @@ namespace SZVAVModel { lowSpeedFanRatio, AirMassFlow, maxAirMassFlow, + iterWaterAirOrNot, CoolingLoad, maxCoilFluidFlow](Real64 const PartLoadRatio) { return UnitarySystems::UnitarySys::calcUnitarySystemWaterFlowResidual(state, @@ -853,7 +856,7 @@ namespace SZVAVModel { 0.0, maxAirMassFlow, CoolingLoad, - 1.0); + iterWaterAirOrNot); }; General::SolveRoot(state, 0.001, MaxIter, SolFlag, PartLoadRatio, fR2, 0.0, 1.0); if (SolFlag == -2 && ((CoolingLoad && SZVAVModel.m_CoolingSpeedNum < SZVAVModel.m_NumOfSpeedCooling) || @@ -885,6 +888,7 @@ namespace SZVAVModel { lowSpeedFanRatio, AirMassFlow, maxAirMassFlow, + iterWaterAirOrNot, CoolingLoad, maxCoilFluidFlow](Real64 const PartLoadRatio) { return UnitarySystems::UnitarySys::calcUnitarySystemWaterFlowResidual(state, @@ -902,7 +906,7 @@ namespace SZVAVModel { 0.0, maxAirMassFlow, CoolingLoad, - 1.0); + iterWaterAirOrNot); }; General::SolveRoot(state, 0.001, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0); if (SolFlag > 0) { @@ -930,34 +934,34 @@ namespace SZVAVModel { if (SZVAVModel.MaxCoolCoilFluidFlow > 0.0) { SZVAVModel.CoolCoilWaterFlowRatio = maxCoilFluidFlow / SZVAVModel.MaxCoolCoilFluidFlow; } - thisSys.calcUnitarySystemToLoad(state, - AirLoopNum, - FirstHVACIteration, - PartLoadRatio, - 0.0, - OnOffAirFlowRatio, - TempSensOutput, - TempLatOutput, - HXUnitOn, - HeatCoilLoad, - SupHeaterLoad, - CompressorONFlag); + SZVAVModel.calcUnitarySystemToLoad(state, + AirLoopNum, + FirstHVACIteration, + PartLoadRatio, + 0.0, + OnOffAirFlowRatio, + TempSensOutput, + TempLatOutput, + HXUnitOn, + HeatCoilLoad, + SupHeaterLoad, + CompressorONFlag); } else { if (SZVAVModel.MaxHeatCoilFluidFlow > 0.0) { SZVAVModel.HeatCoilWaterFlowRatio = maxCoilFluidFlow / SZVAVModel.MaxHeatCoilFluidFlow; } - thisSys.calcUnitarySystemToLoad(state, - AirLoopNum, - FirstHVACIteration, - 0.0, - PartLoadRatio, - OnOffAirFlowRatio, - TempSensOutput, - TempLatOutput, - HXUnitOn, - ZoneLoad, - SupHeaterLoad, - CompressorONFlag); + SZVAVModel.calcUnitarySystemToLoad(state, + AirLoopNum, + FirstHVACIteration, + 0.0, + PartLoadRatio, + OnOffAirFlowRatio, + TempSensOutput, + TempLatOutput, + HXUnitOn, + ZoneLoad, + SupHeaterLoad, + CompressorONFlag); } coilActive = std::abs(state.dataLoopNodes->Node(coilAirInletNode).Temp - state.dataLoopNodes->Node(coilAirOutletNode).Temp) > 0; @@ -975,6 +979,7 @@ namespace SZVAVModel { return; // system cannot meet load, leave at max capacity } + iterWaterAirOrNot = 0.0; // don't iterate on air flow in region 3 // otherwise iterate on load auto fR3 = [&state, SysIndex, @@ -987,6 +992,7 @@ namespace SZVAVModel { lowSpeedFanRatio, maxCoilFluidFlow, maxAirMassFlow, + iterWaterAirOrNot, CoolingLoad](Real64 const PartLoadRatio) { return UnitarySystems::UnitarySys::calcUnitarySystemWaterFlowResidual(state, PartLoadRatio, // coil part load ratio @@ -1003,7 +1009,7 @@ namespace SZVAVModel { 0.0, maxAirMassFlow, CoolingLoad, - 1.0); + iterWaterAirOrNot); }; General::SolveRoot(state, 0.001, MaxIter, SolFlag, PartLoadRatio, fR3, 0.0, 1.0); // Par[12] = maxAirMassFlow; // operating air flow rate, minAirMassFlow indicates low speed air flow rate, @@ -1027,31 +1033,31 @@ namespace SZVAVModel { if (SolFlag == -1) { // get capacity for warning if (CoolingLoad) { // Function CalcUnitarySystemToLoad, 4th and 5th arguments are CoolPLR and HeatPLR - thisSys.calcUnitarySystemToLoad(state, - AirLoopNum, - FirstHVACIteration, - PartLoadRatio, - 0.0, - OnOffAirFlowRatio, - TempSensOutput, - TempLatOutput, - HXUnitOn, - HeatCoilLoad, - SupHeaterLoad, - CompressorONFlag); + SZVAVModel.calcUnitarySystemToLoad(state, + AirLoopNum, + FirstHVACIteration, + PartLoadRatio, + 0.0, + OnOffAirFlowRatio, + TempSensOutput, + TempLatOutput, + HXUnitOn, + HeatCoilLoad, + SupHeaterLoad, + CompressorONFlag); } else { - thisSys.calcUnitarySystemToLoad(state, - AirLoopNum, - FirstHVACIteration, - 0.0, - PartLoadRatio, - OnOffAirFlowRatio, - TempSensOutput, - TempLatOutput, - HXUnitOn, - ZoneLoad, - SupHeaterLoad, - CompressorONFlag); + SZVAVModel.calcUnitarySystemToLoad(state, + AirLoopNum, + FirstHVACIteration, + 0.0, + PartLoadRatio, + OnOffAirFlowRatio, + TempSensOutput, + TempLatOutput, + HXUnitOn, + ZoneLoad, + SupHeaterLoad, + CompressorONFlag); } if (std::abs(TempSensOutput - ZoneLoad) * SZVAVModel.ControlZoneMassFlowFrac > diff --git a/src/EnergyPlus/UnitarySystem.cc b/src/EnergyPlus/UnitarySystem.cc index 4e88cf29c1e..e031f9937a0 100644 --- a/src/EnergyPlus/UnitarySystem.cc +++ b/src/EnergyPlus/UnitarySystem.cc @@ -16955,20 +16955,26 @@ namespace UnitarySystems { } else { SATempTarget = par13_SATempTarget; } - bool iterateOnAirOnly = (par16_IterationMethod > 1.0); + bool modulateAirFlow = (par16_IterationMethod > 0.0); bool HXUnitOn = true; - if (iterateOnAirOnly) { + if (modulateAirFlow) { + // in Region 2 // set air flow rate bounded by low speed and high speed air flow rates - state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot * (lowSpeedRatio + (PartLoadRatio * (1.0 - lowSpeedRatio))); + state.dataLoopNodes->Node(AirControlNode).MassFlowRate = systemMaxAirFlowRate * (lowSpeedRatio + (PartLoadRatio * (1.0 - lowSpeedRatio))); // FanPartLoadRatio is used to pass info over to function SetAverageAirFlow since air and coil PLR are disassociated in the model // FanPartLoadRatio is a report variable that is updated (overwritten) in ReportUnitarySystem thisSys.FanPartLoadRatio = PartLoadRatio; // if( WaterControlNode > 0 ) Node( WaterControlNode ).MassFlowRate = highWaterMdot; + if (WaterControlNode > 0) { + Real64 waterMdot = highWaterMdot * PartLoadRatio; + state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = waterMdot; + } } else { + // in Region 1 or 3 where air flow is constant and water flow or compressor is modulated to meet the load state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot; if (lowSpeedRatio != 1.0) { diff --git a/tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc b/tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc index 7bfd1e226ef..daf458679be 100644 --- a/tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc +++ b/tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc @@ -1317,7 +1317,7 @@ TEST_F(EnergyPlusFixture, SimPTAC_SZVAVTest) // QZnReq = state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).RemainingOutputRequired; // initialize zone heating load thisSys.simulate(*state, thisSys.Name, FirstHVACIteration, 0, PTUnitNum, HeatActive, CoolActive, 0, 0, true, QUnitOut, latOut); EXPECT_NEAR(QUnitOut, 2010.0, 0.01); - ASSERT_NEAR(thisSys.DesignMaxOutletTemp, state->dataHeatingCoils->HeatingCoil(1).OutletAirTemp, 0.1); + ASSERT_NEAR(thisSys.DesignMaxOutletTemp, state->dataHeatingCoils->HeatingCoil(1).OutletAirTemp, 1.0); ASSERT_GT(state->dataLoopNodes->Node(thisSys.AirInNode).MassFlowRate, thisSys.MaxNoCoolHeatAirMassFlow); // Boundary load for this system in Region 1 at maximum air flow rate is 2995.2 W (upper boundary load of Region 1) @@ -1327,7 +1327,7 @@ TEST_F(EnergyPlusFixture, SimPTAC_SZVAVTest) // QZnReq = state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).RemainingOutputRequired; // initialize zone heating load thisSys.simulate(*state, thisSys.Name, FirstHVACIteration, 0, PTUnitNum, HeatActive, CoolActive, 0, 0, true, QUnitOut, latOut); EXPECT_NEAR(QUnitOut, 2990.0, 0.01); - ASSERT_NEAR(thisSys.DesignMaxOutletTemp, state->dataHeatingCoils->HeatingCoil(1).OutletAirTemp, 0.1); + ASSERT_NEAR(thisSys.DesignMaxOutletTemp, state->dataHeatingCoils->HeatingCoil(1).OutletAirTemp, 1.0); ASSERT_GT(state->dataLoopNodes->Node(thisSys.AirInNode).MassFlowRate, thisSys.MaxNoCoolHeatAirMassFlow); ASSERT_LT(state->dataLoopNodes->Node(thisSys.AirInNode).MassFlowRate, thisSys.MaxHeatAirMassFlow); diff --git a/tst/EnergyPlus/unit/SZVAVModel.unit.cc b/tst/EnergyPlus/unit/SZVAVModel.unit.cc index e769fa39283..6385e6f458b 100644 --- a/tst/EnergyPlus/unit/SZVAVModel.unit.cc +++ b/tst/EnergyPlus/unit/SZVAVModel.unit.cc @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -203,7 +204,6 @@ TEST_F(EnergyPlusFixture, SZVAV_PTUnit_Testing) state->dataLoopNodes->Node(zoneNodeNum).Temp = 21.0; state->dataLoopNodes->Node(zoneNodeNum).HumRat = 0.08; thisUnit.ATMixerExists = false; - thisUnit.MaxCoolCoilFluidFlow = 0.1; thisUnit.DesignMinOutletTemp = 10.0; thisUnit.MaxNoCoolHeatAirMassFlow = 0.1; thisUnit.MaxCoolAirMassFlow = 0.2; @@ -338,7 +338,7 @@ TEST_F(EnergyPlusFixture, SZVAV_PTUnit_Testing) state->dataLoopNodes->Node(thisUnit.AirInNode).MassFlowRate, thisUnit.MaxNoCoolHeatAirMassFlow, 0.00000001); // low speed air flow rate EXPECT_LT(state->dataLoopNodes->Node(thisUnit.AirOutNode).Temp, state->dataLoopNodes->Node(thisUnit.AirInNode).Temp); // active cooling Real64 AirMassFlow = state->dataLoopNodes->Node(thisUnit.AirOutNode).MassFlowRate; - Real64 MinHumRat = min(state->dataLoopNodes->Node(thisUnit.AirOutNode).HumRat, state->dataLoopNodes->Node(thisUnit.AirInNode).HumRat); + Real64 MinHumRat = min(state->dataLoopNodes->Node(thisUnit.AirOutNode).HumRat, state->dataLoopNodes->Node(zoneNodeNum).HumRat); Real64 OutletTemp = state->dataLoopNodes->Node(thisUnit.AirOutNode).Temp; Real64 InletTemp = state->dataLoopNodes->Node(thisUnit.AirInNode).Temp; Real64 LoadMet = AirMassFlow * (Psychrometrics::PsyHFnTdbW(OutletTemp, MinHumRat) - Psychrometrics::PsyHFnTdbW(InletTemp, MinHumRat)); @@ -346,7 +346,8 @@ TEST_F(EnergyPlusFixture, SZVAV_PTUnit_Testing) EXPECT_NEAR(LoadMet, -200.0, 0.2); // Region 2 of control, modulate air flow rate, modulate coil capacity - QZnReq = -2500.0; // see issue 9090 + // set sensible load to mid point of coil sensible capacity (e.g., TotCap * SHR = 4000 * 0.7 = 2800 W) for region 2 of control + QZnReq = -2000.0; SZVAVModel::calcSZVAVModel(*state, SZVAVModel, UnitNum, @@ -362,19 +363,20 @@ TEST_F(EnergyPlusFixture, SZVAV_PTUnit_Testing) EXPECT_GT(state->dataLoopNodes->Node(thisUnit.AirInNode).MassFlowRate, thisUnit.MaxNoCoolHeatAirMassFlow); // air flow higher than low speed EXPECT_LT(state->dataLoopNodes->Node(thisUnit.AirInNode).MassFlowRate, thisUnit.MaxCoolAirMassFlow); // air flow lower than high speed - EXPECT_LT(state->dataLoopNodes->Node(thisUnit.AirOutNode).Temp, state->dataLoopNodes->Node(1).Temp); // active cooling + EXPECT_NEAR(state->dataLoopNodes->Node(thisUnit.AirInNode).MassFlowRate, 0.177, 0.001); // air flow between low and high speed, issue 9090 + EXPECT_LT(state->dataLoopNodes->Node(thisUnit.AirOutNode).Temp, state->dataLoopNodes->Node(1).Temp); // active cooling AirMassFlow = state->dataLoopNodes->Node(thisUnit.AirOutNode).MassFlowRate; - MinHumRat = min(state->dataLoopNodes->Node(thisUnit.AirOutNode).HumRat, state->dataLoopNodes->Node(thisUnit.AirInNode).HumRat); + MinHumRat = min(state->dataLoopNodes->Node(thisUnit.AirOutNode).HumRat, state->dataLoopNodes->Node(zoneNodeNum).HumRat); OutletTemp = state->dataLoopNodes->Node(thisUnit.AirOutNode).Temp; InletTemp = state->dataLoopNodes->Node(thisUnit.AirInNode).Temp; LoadMet = AirMassFlow * (Psychrometrics::PsyHFnTdbW(OutletTemp, MinHumRat) - Psychrometrics::PsyHFnTdbW(InletTemp, MinHumRat)); EXPECT_NEAR(LoadMet, QZnReq, 15.0); - EXPECT_NEAR(LoadMet, -2486.0, 1.0); - EXPECT_NEAR(thisUnit.DesignMinOutletTemp, OutletTemp, 0.001); + EXPECT_NEAR(LoadMet, -1989.8, 1.0); + EXPECT_GT(OutletTemp, thisUnit.DesignMinOutletTemp); // coil and air flow are modulating to meet the load // Region 3 of control, high air flow rate, modulate coil capacity - QZnReq = -4000.0; + QZnReq = -4000.0; // total capacity of coil, not sensible capacity of coil SZVAVModel::calcSZVAVModel(*state, SZVAVModel, UnitNum, @@ -388,17 +390,35 @@ TEST_F(EnergyPlusFixture, SZVAV_PTUnit_Testing) PLR, CompressorOnFlag); - // test fails, expected MaxCoolAirMassFlow, only got 87% of that, issue 9090 - // test here should be EXPECT_EQ or EXPECT_NEAR thisUnit.MaxCoolAirMassFlow - EXPECT_GT(state->dataLoopNodes->Node(1).MassFlowRate, thisUnit.MaxNoCoolHeatAirMassFlow); // high speed air flow rate - EXPECT_LT(state->dataLoopNodes->Node(4).Temp, state->dataLoopNodes->Node(1).Temp); // active cooling + EXPECT_EQ(state->dataLoopNodes->Node(1).MassFlowRate, thisUnit.MaxCoolAirMassFlow); // high speed air flow rate + EXPECT_LT(state->dataLoopNodes->Node(4).Temp, state->dataLoopNodes->Node(1).Temp); // active cooling - MinHumRat = min(state->dataLoopNodes->Node(4).HumRat, state->dataLoopNodes->Node(1).HumRat); + OutletTemp = state->dataLoopNodes->Node(thisUnit.AirOutNode).Temp; + EXPECT_NEAR(OutletTemp, thisUnit.DesignMinOutletTemp, 2.0); // outlet temp driven towards design min outlet temp at high speed and full load + EXPECT_NEAR(OutletTemp, 11.4, 0.1); // outlet node at 11.4 C, could not get to 10 C at full load and high speed, issue 9090 + + MinHumRat = min(state->dataLoopNodes->Node(4).HumRat, state->dataLoopNodes->Node(zoneNodeNum).HumRat); OutletTemp = state->dataLoopNodes->Node(4).Temp; InletTemp = state->dataLoopNodes->Node(1).Temp; LoadMet = thisUnit.MaxCoolAirMassFlow * (Psychrometrics::PsyHFnTdbW(OutletTemp, MinHumRat) - Psychrometrics::PsyHFnTdbW(InletTemp, MinHumRat)); - EXPECT_NEAR(LoadMet, QZnReq, 1600.0); // coil could not meet load, not a failure just issue with testing results - EXPECT_NEAR(LoadMet, -2859.0, 500.0); + EXPECT_NEAR(QZnReq, -4000.0, 0.001); // load is greater than full load sensible capacity + EXPECT_NEAR(LoadMet, -2567.0, 1.0); + EXPECT_NEAR(thisUnit.m_SensibleLoadMet, -2580.0, 1.0); // why different than LoadMet? + EXPECT_NEAR(thisUnit.m_CoolingPartLoadFrac, 1.0, 0.001); // coil at full capacity + + // calculate sensible and latent output based on inlet and outlet conditions and mass flow rate to compare to unit variables + Real64 SensibleOutput, LatentOutput, TotalOutput; + CalcZoneSensibleLatentOutput(thisUnit.MaxCoolAirMassFlow, + OutletTemp, + state->dataLoopNodes->Node(4).HumRat, + state->dataLoopNodes->Node(zoneNodeNum).Temp, + state->dataLoopNodes->Node(zoneNodeNum).HumRat, + SensibleOutput, + LatentOutput, + TotalOutput); + EXPECT_NEAR(thisUnit.m_SensibleLoadMet, SensibleOutput, 1.0); + EXPECT_NEAR(SensibleOutput, -2580.0, 1.0); + EXPECT_NEAR(TotalOutput, -3996.0, 1.0); CoolingLoad = false; HeatingLoad = true; @@ -431,13 +451,13 @@ TEST_F(EnergyPlusFixture, SZVAV_PTUnit_Testing) EXPECT_NEAR(state->dataLoopNodes->Node(1).MassFlowRate, thisUnit.MaxNoCoolHeatAirMassFlow, 0.00000001); // high speed air flow rate EXPECT_GT(state->dataLoopNodes->Node(4).Temp, state->dataLoopNodes->Node(1).Temp); // active heating - MinHumRat = min(state->dataLoopNodes->Node(4).HumRat, state->dataLoopNodes->Node(1).HumRat); + MinHumRat = min(state->dataLoopNodes->Node(4).HumRat, state->dataLoopNodes->Node(zoneNodeNum).HumRat); OutletTemp = state->dataLoopNodes->Node(4).Temp; InletTemp = state->dataLoopNodes->Node(1).Temp; LoadMet = thisUnit.MaxNoCoolHeatAirMassFlow * (Psychrometrics::PsyHFnTdbW(OutletTemp, MinHumRat) - Psychrometrics::PsyHFnTdbW(InletTemp, MinHumRat)); - EXPECT_NEAR(LoadMet, QZnReq, 0.0001); - EXPECT_NEAR(LoadMet, 200.0, 0.0001); + EXPECT_NEAR(LoadMet, QZnReq, 0.001); + EXPECT_NEAR(LoadMet, 200.0, 0.001); // Region 2 of control, modulate air flow rate, modulate coil capacity QZnReq = 1200.0; @@ -459,12 +479,12 @@ TEST_F(EnergyPlusFixture, SZVAV_PTUnit_Testing) EXPECT_GT(state->dataLoopNodes->Node(4).Temp, state->dataLoopNodes->Node(1).Temp); // active heating AirMassFlow = state->dataLoopNodes->Node(4).MassFlowRate; - MinHumRat = min(state->dataLoopNodes->Node(4).HumRat, state->dataLoopNodes->Node(1).HumRat); + MinHumRat = min(state->dataLoopNodes->Node(4).HumRat, state->dataLoopNodes->Node(zoneNodeNum).HumRat); OutletTemp = state->dataLoopNodes->Node(4).Temp; InletTemp = state->dataLoopNodes->Node(1).Temp; LoadMet = AirMassFlow * (Psychrometrics::PsyHFnTdbW(OutletTemp, MinHumRat) - Psychrometrics::PsyHFnTdbW(InletTemp, MinHumRat)); - EXPECT_NEAR(LoadMet, QZnReq, 0.0001); - EXPECT_NEAR(LoadMet, 1200.0, 0.0001); + EXPECT_NEAR(LoadMet, QZnReq, 0.001); + EXPECT_NEAR(LoadMet, 1200.0, 0.001); // Region 3 of control, high air flow rate, modulate coil capacity QZnReq = 2000.0; @@ -484,12 +504,12 @@ TEST_F(EnergyPlusFixture, SZVAV_PTUnit_Testing) EXPECT_NEAR(state->dataLoopNodes->Node(1).MassFlowRate, thisUnit.MaxHeatAirMassFlow, 0.00000001); // high speed air flow rate EXPECT_GT(state->dataLoopNodes->Node(4).Temp, state->dataLoopNodes->Node(1).Temp); // active heating - MinHumRat = min(state->dataLoopNodes->Node(4).HumRat, state->dataLoopNodes->Node(1).HumRat); + MinHumRat = min(state->dataLoopNodes->Node(4).HumRat, state->dataLoopNodes->Node(zoneNodeNum).HumRat); OutletTemp = state->dataLoopNodes->Node(4).Temp; InletTemp = state->dataLoopNodes->Node(1).Temp; LoadMet = thisUnit.MaxHeatAirMassFlow * (Psychrometrics::PsyHFnTdbW(OutletTemp, MinHumRat) - Psychrometrics::PsyHFnTdbW(InletTemp, MinHumRat)); - EXPECT_NEAR(LoadMet, QZnReq, 0.0001); - EXPECT_NEAR(LoadMet, 2000.0, 0.0001); + EXPECT_NEAR(LoadMet, QZnReq, 0.001); + EXPECT_NEAR(LoadMet, 2000.0, 0.001); } TEST_F(EnergyPlusFixture, SZVAV_FanCoilUnit_Testing) @@ -1338,7 +1358,7 @@ TEST_F(EnergyPlusFixture, SZVAV_UnitarySys_VarSpeed_Testing) latOut); EXPECT_TRUE((thisSys->m_MaxHeatAirVolFlow * state->dataEnvrn->StdRhoAir > state->dataLoopNodes->Node(thisSys->AirOutNode).MassFlowRate) && (state->dataLoopNodes->Node(thisSys->AirOutNode).MassFlowRate > thisSys->MaxNoCoolHeatAirMassFlow)); - EXPECT_NEAR(state->dataLoopNodes->Node(thisSys->AirOutNode).Temp, thisSys->DesignMaxOutletTemp, 0.1); + EXPECT_NEAR(state->dataLoopNodes->Node(thisSys->AirOutNode).Temp, thisSys->DesignMaxOutletTemp, 1.0); // Test for zone 3 - Heating state->dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlZoneNum).RemainingOutputRequired = 3000; @@ -1391,7 +1411,7 @@ TEST_F(EnergyPlusFixture, SZVAV_UnitarySys_VarSpeed_Testing) latOut); EXPECT_TRUE((thisSys->m_MaxCoolAirVolFlow * state->dataEnvrn->StdRhoAir > state->dataLoopNodes->Node(thisSys->AirOutNode).MassFlowRate) && (state->dataLoopNodes->Node(thisSys->AirOutNode).MassFlowRate > thisSys->MaxNoCoolHeatAirMassFlow)); - EXPECT_NEAR(state->dataLoopNodes->Node(thisSys->AirOutNode).Temp, thisSys->DesignMinOutletTemp, 0.1); + EXPECT_NEAR(state->dataLoopNodes->Node(thisSys->AirOutNode).Temp, thisSys->DesignMinOutletTemp, 3.0); // Test for zone 3 - Cooling state->dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlZoneNum).RemainingOutputRequired = -3500; diff --git a/tst/EnergyPlus/unit/UnitarySystem.unit.cc b/tst/EnergyPlus/unit/UnitarySystem.unit.cc index f61678e7a84..b22339b22b4 100644 --- a/tst/EnergyPlus/unit/UnitarySystem.unit.cc +++ b/tst/EnergyPlus/unit/UnitarySystem.unit.cc @@ -13060,12 +13060,12 @@ Schedule:Compact, EXPECT_LT(state->dataLoopNodes->Node(InletNode).MassFlowRate, thisSys->MaxHeatAirMassFlow); // air flow lower than high speed fan flow EXPECT_DOUBLE_EQ(state->dataLoopNodes->Node(InletNode).MassFlowRate, state->dataLoopNodes->Node(OutletNode).MassFlowRate); // inlet = outlet flow rate - EXPECT_NEAR(thisSys->HeatCoilWaterFlowRatio, 0.3592, 0.0001); // heating coil water flow ratio, heating coil is on + EXPECT_NEAR(thisSys->HeatCoilWaterFlowRatio, 0.3277, 0.0001); // heating coil water flow ratio, heating coil is on EXPECT_NEAR(thisSys->CoolCoilWaterFlowRatio, 0.0, 0.0001); // cooling coil water flow ratio, cooling coil is off EXPECT_NEAR(thisSys->FanPartLoadRatio, - 0.6198, + 0.6638, 0.0001); // fan PLR above minimum and below maximum speed (0-1 means fraction between no load flow and full flow) - EXPECT_NEAR(state->dataLoopNodes->Node(OutletNode).Temp, thisSys->DesignMaxOutletTemp, 0.02); // outlet temperature modulated to meet max limit + EXPECT_NEAR(state->dataLoopNodes->Node(OutletNode).Temp, thisSys->DesignMaxOutletTemp, 1.0); // outlet temperature modulated to meet max limit // increase heating load again so that upper temperature limit is exceeded to meet load state->dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlZoneNum).RemainingOutputRequired = 10000.0; // heating load @@ -13245,11 +13245,11 @@ Schedule:Compact, EXPECT_GT(state->dataLoopNodes->Node(InletNode).MassFlowRate, thisSys->MaxNoCoolHeatAirMassFlow); // air flow higher than low speed fan flow EXPECT_LT(state->dataLoopNodes->Node(InletNode).MassFlowRate, thisSys->MaxCoolAirMassFlow); // air flow lower than high speed fan flow EXPECT_DOUBLE_EQ(state->dataLoopNodes->Node(InletNode).MassFlowRate, - state->dataLoopNodes->Node(OutletNode).MassFlowRate); // inlet = outlet flow rate - EXPECT_NEAR(thisSys->HeatCoilWaterFlowRatio, 0.0, 0.0001); // heating coil water flow ratio, heating coil is off - EXPECT_NEAR(thisSys->CoolCoilWaterFlowRatio, 0.396, 0.001); // cooling coil water flow ratio, cooling coil is on - EXPECT_NEAR(thisSys->FanPartLoadRatio, 0.5117, 0.0001); // fan PLR above minimum speed - EXPECT_NEAR(state->dataLoopNodes->Node(OutletNode).Temp, thisSys->DesignMinOutletTemp, 0.09); // outlet temperature modulated to meet max limit + state->dataLoopNodes->Node(OutletNode).MassFlowRate); // inlet = outlet flow rate + EXPECT_NEAR(thisSys->HeatCoilWaterFlowRatio, 0.0, 0.0001); // heating coil water flow ratio, heating coil is off + EXPECT_NEAR(thisSys->CoolCoilWaterFlowRatio, 0.392, 0.001); // cooling coil water flow ratio, cooling coil is on + EXPECT_NEAR(thisSys->FanPartLoadRatio, 0.6961, 0.0001); // fan PLR above minimum speed + EXPECT_NEAR(state->dataLoopNodes->Node(OutletNode).Temp, thisSys->DesignMinOutletTemp, 3.0); // outlet temperature modulated towards minimum limit // test with 0 water flow rate to ensure divide by 0 does not happen (plant off, size = 0, etc.) Real64 saveSystemCoolWaterFlowRate = thisSys->MaxCoolCoilFluidFlow;