From c6bd3f7c497dbf626441e0ef613b17e1050c0d2f Mon Sep 17 00:00:00 2001 From: nigusse Date: Fri, 17 Jan 2020 10:51:46 -0500 Subject: [PATCH 1/5] update damper position --- src/EnergyPlus/SingleDuct.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/EnergyPlus/SingleDuct.cc b/src/EnergyPlus/SingleDuct.cc index 5e735b43228..5483c8125c4 100644 --- a/src/EnergyPlus/SingleDuct.cc +++ b/src/EnergyPlus/SingleDuct.cc @@ -4883,6 +4883,14 @@ namespace SingleDuct { ShowFatalError("Invalid Reheat Component=" + Sys(SysNum).ReheatComp); } } + // Calculate Damper Position. + if (AirMassFlow == 0.0) { + Sys(SysNum).DamperPosition = 0.0; + } else if ((AirMassFlow > 0.0) && (AirMassFlow < Sys(SysNum).AirMassFlowRateMax)) { + Sys(SysNum).DamperPosition = AirMassFlow / Sys(SysNum).AirMassFlowRateMax; + } else if (AirMassFlow == Sys(SysNum).AirMassFlowRateMax) { + Sys(SysNum).DamperPosition = 1.0; + } LoadMet = AirMassFlow * CpAirZn * (Node(HCOutNode).Temp - Node(ZoneNode).Temp); } From 2a443fa665e4ec21bca4ef9824e930a56b5390fe Mon Sep 17 00:00:00 2001 From: nigusse Date: Fri, 17 Jan 2020 13:33:57 -0500 Subject: [PATCH 2/5] modified the fix --- src/EnergyPlus/SingleDuct.cc | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/EnergyPlus/SingleDuct.cc b/src/EnergyPlus/SingleDuct.cc index 5483c8125c4..1925407665c 100644 --- a/src/EnergyPlus/SingleDuct.cc +++ b/src/EnergyPlus/SingleDuct.cc @@ -4493,6 +4493,25 @@ namespace SingleDuct { FanOp = 0; CalcVAVVS(SysNum, FirstHVACIteration, ZoneNodeNum, HCType, 0.0, 0.0, FanType, MassFlow, FanOp, QDelivered); } + + //MassFlow = Node(SysInletNode).MassFlowRate; + // Move data to the damper outlet node + SysOutlet(SysNum).AirTemp = SysInlet(SysNum).AirTemp; + SysOutlet(SysNum).AirHumRat = SysInlet(SysNum).AirHumRat; + SysOutlet(SysNum).AirMassFlowRate = MassFlow; + SysOutlet(SysNum).AirMassFlowRateMaxAvail = SysInlet(SysNum).AirMassFlowRateMaxAvail; + SysOutlet(SysNum).AirMassFlowRateMinAvail = SysInlet(SysNum).AirMassFlowRateMinAvail; + SysOutlet(SysNum).AirEnthalpy = SysInlet(SysNum).AirEnthalpy; + + // calculate damper Position. + if (Sys(SysNum).AirMassFlowRateMax == 0.0) { + Sys(SysNum).DamperPosition = 0.0; + } else { + Sys(SysNum).DamperPosition = MassFlow / Sys(SysNum).AirMassFlowRateMax; + } + // update the air terminal outlet node data + UpdateSys(SysNum); + } void SimConstVol(int const SysNum, bool const FirstHVACIteration, int const ZoneNum, int const ZoneNodeNum) @@ -4883,14 +4902,6 @@ namespace SingleDuct { ShowFatalError("Invalid Reheat Component=" + Sys(SysNum).ReheatComp); } } - // Calculate Damper Position. - if (AirMassFlow == 0.0) { - Sys(SysNum).DamperPosition = 0.0; - } else if ((AirMassFlow > 0.0) && (AirMassFlow < Sys(SysNum).AirMassFlowRateMax)) { - Sys(SysNum).DamperPosition = AirMassFlow / Sys(SysNum).AirMassFlowRateMax; - } else if (AirMassFlow == Sys(SysNum).AirMassFlowRateMax) { - Sys(SysNum).DamperPosition = 1.0; - } LoadMet = AirMassFlow * CpAirZn * (Node(HCOutNode).Temp - Node(ZoneNode).Temp); } From 1e697b297125ad38885f0c14542c6eee48803ca7 Mon Sep 17 00:00:00 2001 From: nigusse Date: Tue, 21 Jan 2020 09:03:32 -0500 Subject: [PATCH 3/5] addressed warning --- src/EnergyPlus/SingleDuct.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/EnergyPlus/SingleDuct.cc b/src/EnergyPlus/SingleDuct.cc index 1925407665c..49769e37a0c 100644 --- a/src/EnergyPlus/SingleDuct.cc +++ b/src/EnergyPlus/SingleDuct.cc @@ -4463,6 +4463,7 @@ namespace SingleDuct { Par(7) = double(FanOp); Par(8) = QTotLoad; SolveRoot(UnitFlowToler, 50, SolFlag, FracDelivered, VAVVSHCFanOnResidual, 0.0, 1.0, Par); + MassFlow = Node(SysInletNode).MassFlowRate; if (SolFlag == -1) { if (Sys(SysNum).IterationLimit == 0) { ShowWarningError("Heating coil control failed in VS VAV terminal unit " + Sys(SysNum).SysName); From 9e810953161b43d441f03e0545c7c69ed7eb42b6 Mon Sep 17 00:00:00 2001 From: nigusse Date: Tue, 21 Jan 2020 09:21:34 -0500 Subject: [PATCH 4/5] added unit test --- .../unit/AirTerminalSingleDuct.unit.cc | 177 ++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/tst/EnergyPlus/unit/AirTerminalSingleDuct.unit.cc b/tst/EnergyPlus/unit/AirTerminalSingleDuct.unit.cc index dea5a0d48b6..9fafe271016 100644 --- a/tst/EnergyPlus/unit/AirTerminalSingleDuct.unit.cc +++ b/tst/EnergyPlus/unit/AirTerminalSingleDuct.unit.cc @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -682,4 +683,180 @@ TEST_F(EnergyPlusFixture, AirTerminalSingleDuctVAVReheat_NormalActionTest) EXPECT_EQ(1.0, Sys(SysNum).AirMassFlowRateMax); } +TEST_F(EnergyPlusFixture, SingleDuctVAVReheatVSFan_DamperPositionTest) +{ + std::string const idf_objects = delimited_string({ + " Zone,", + " Thermal Zone; !- Name", + + " ZoneHVAC:EquipmentConnections,", + " Thermal Zone, !- Zone Name", + " Thermal Zone Equipment, !- Zone Conditioning Equipment List Name", + " Zone 1 In Node, !- Zone Air Inlet Node or NodeList Name", + " , !- Zone Air Exhaust Node or NodeList Name", + " Zone 1 Air Node, !- Zone Air Node Name", + " Zone 1 Return Node; !- Zone Return Air Node Name", + + " ZoneHVAC:EquipmentList,", + " Thermal Zone Equipment, !- Name", + " SequentialLoad, !- Load Distribution Scheme", + " ZoneHVAC:AirDistributionUnit, !- Zone Equipment 1 Object Type", + " ADU VAV Rht VS Fan, !- Zone Equipment 1 Name", + " 1, !- Zone Equipment 1 Cooling Sequence", + " 1; !- Zone Equipment 1 Heating or No-Load Sequence", + + " ZoneHVAC:AirDistributionUnit,", + " ADU VAV Rht VS Fan, !- Name", + " Zone 1 In Node, !- Air Distribution Unit Outlet Node Name", + " AirTerminal:SingleDuct:VAV:Reheat:VariableSpeedFan, !- Air Terminal Object Type", + " VAV Rht VS Fan AirTerm; !- Air Terminal Name", + + " AirTerminal:SingleDuct:VAV:Reheat:VariableSpeedFan,", + " VAV Rht VS Fan AirTerm, !- Name", + " , !- Availability Schedule Name", + " 1.0, !- Maximum Cooling Air Flow Rate {m3/s}", + " 0.5, !- Maximum Heating Air Flow Rate {m3/s}", + " 0.05, !- Zone Minimum Air Flow Fraction", + " Zone 1 ATU In Node, !- Air Inlet Node Name", + " Zone 1 In Node, !- Air Outlet Node Name", + " Fan:SystemModel, !- Fan Object Type", + " Zone 1 VS Fan, !- Fan Name", + " Coil:Heating:Electric, !- Heating Coil Object Type", + " Zone 1 Reheat Coil, !- Heating Coil Name", + " autosize, !- Maximum Hot Water or Steam Flow Rate {m3/s}", + " 0.0, !- Minimum Hot Water or Steam Flow Rate {m3/s}", + " 0.001; !- Heating Convergence Tolerance", + + " Coil:Heating:Electric,", + " Zone 1 Reheat Coil, !- Name", + " , !- Availability Schedule Name", + " 1.0, !- Efficiency", + " autosize, !- Nominal Capacity {W}", + " Reheat Air Inlet Node, !- Air Inlet Node Name", + " Zone 1 In Node; !- Air Outlet Node Name", + + " Fan:SystemModel,", + " Zone 1 VS Fan, !- Name", + " , !- Availability Schedule Name", + " Zone 1 ATU In Node, !- Air Inlet Node Name", + " Reheat Air Inlet Node, !- Air Outlet Node Name", + " 1.0, !- Design Maximum Air Flow Rate {m3/s}", + " Continuous, !- Speed Control Method", + " 0.0, !- Electric Power Minimum Flow Rate Fraction", + " 125.0, !- Design Pressure Rise {Pa}", + " 0.9, !- Motor Efficiency", + " 1.0, !- Motor In Air Stream Fraction", + " AUTOSIZE, !- Design Electric Power Consumption {W}", + " TotalEfficiencyAndPressure, !- Design Power Sizing Method", + " , !- Electric Power Per Unit Flow Rate {W/(m3/s)}", + " , !- Electric Power Per Unit Flow Rate Per Unit Pressure {W/((m3/s)-Pa)}", + " 0.7, !- Fan Total Efficiency", + " VAV Fan Curve, !- Electric Power Function of Flow Fraction Curve Name", + " , !- Night Ventilation Mode Pressure Rise {Pa}", + " , !- Night Ventilation Mode Flow Fraction", + " , !- Motor Loss Zone Name", + " , !- Motor Loss Radiative Fraction", + " ATU Fan Energy; !- End-Use Subcategory", + + " Curve:Quartic,", + " VAV Fan Curve, !- Name", + " 0.00153028, !- Coefficient1 Constant", + " 0.00520806, !- Coefficient2 x", + " 1.1086242, !- Coefficient3 x**2", + " -.11635563, !- Coefficient4 x**3", + " 0.0, !- Coefficient5 x**4", + " 0.0, !- Minimum Value of x", + " 1.0, !- Maximum Value of x", + " 0.0, !- Minimum Curve Output", + " 1.0, !- Maximum Curve Output", + " Dimensionless, !- Input Unit Type for X", + " Dimensionless; !- Output Unit Type", + }); + + ASSERT_TRUE(process_idf(idf_objects)); + // setup variables for VAV Reheat VS Fan + int SysNum = 1; + int ZoneNum = 1; + int ZoneNodeNum = 1; + int InletNodeNum = 5; + bool ErrorsFound = false; + bool FirstHVACIteration = true; + + DataGlobals::NumOfTimeStepInHour = 1; + DataGlobals::MinutesPerTimeStep = 60; + ScheduleManager::ProcessScheduleInput(); + ScheduleManager::ScheduleInputProcessed = true; + DataEnvironment::Month = 1; + DataEnvironment::DayOfMonth = 21; + DataGlobals::HourOfDay = 1; + DataGlobals::TimeStep = 1; + DataEnvironment::DSTIndicator = 0; + DataEnvironment::DayOfWeek = 2; + DataEnvironment::HolidayIndex = 0; + DataEnvironment::DayOfYear_Schedule = General::OrdinalDay(DataEnvironment::Month, DataEnvironment::DayOfMonth, 1); + DataEnvironment::StdRhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(101325.0, 20.0, 0.0); + ScheduleManager::UpdateScheduleValues(); + DataZoneEnergyDemands::ZoneSysEnergyDemand.allocate(1); + DataHeatBalFanSys::TempControlType.allocate(1); + DataHeatBalFanSys::TempControlType(1) = DataHVACGlobals::DualSetPointWithDeadBand; + HeatBalanceManager::GetZoneData(ErrorsFound); + ASSERT_FALSE(ErrorsFound); + DataZoneEquipment::GetZoneEquipmentData1(); + ZoneAirLoopEquipmentManager::GetZoneAirLoopEquipment(); + SingleDuct::GetSysInput(); + EXPECT_TRUE(compare_err_stream("")); + + auto &thisAirTerminal = SingleDuct::Sys(SysNum); + auto &thisAirTerminalOutlet = SingleDuct::SysOutlet(SysNum); + + // check VAV reheat VS Fan air terminal inputs + EXPECT_EQ("AirTerminal:SingleDuct:VAV:Reheat:VariableSpeedFan", thisAirTerminal.SysType); + EXPECT_EQ("VAV RHT VS FAN AIRTERM", thisAirTerminal.SysName); + EXPECT_EQ("COIL:HEATING:ELECTRIC", thisAirTerminal.ReheatComp); + EXPECT_EQ("ZONE 1 REHEAT COIL", thisAirTerminal.ReheatName); + EXPECT_EQ("FAN:SYSTEMMODEL", thisAirTerminal.FanType); + EXPECT_EQ("ZONE 1 VS FAN", thisAirTerminal.FanName); + EXPECT_EQ(thisAirTerminal.ZoneMinAirFrac, 0.05); + EXPECT_EQ(thisAirTerminal.MaxAirVolFlowRate, 1.0); + // test 1: 0.05 fraction damper position + Real64 SysMinMassFlowRes = 1.0 * DataEnvironment::StdRhoAir * 0.05; + Real64 SysMaxMassFlowRes = 1.0 * DataEnvironment::StdRhoAir; + DataZoneEnergyDemands::ZoneSysEnergyDemand(1).RemainingOutputRequired = 0.0; + DataLoopNode::Node(InletNodeNum).MassFlowRate = SysMaxMassFlowRes; + DataLoopNode::Node(InletNodeNum).MassFlowRateMaxAvail = SysMaxMassFlowRes; + CurDeadBandOrSetback.allocate(1); + CurDeadBandOrSetback(1) = false; + DataGlobals::BeginEnvrnFlag = true; + FirstHVACIteration = true; + SingleDuct::InitSys(SysNum, FirstHVACIteration); + DataGlobals::BeginEnvrnFlag = false; + FirstHVACIteration = false; + SingleDuct::InitSys(SysNum, FirstHVACIteration); + SingleDuct::SimVAVVS(SysNum, FirstHVACIteration, ZoneNum, ZoneNodeNum); + // check inputs and calculated values for zone air fraction 0.05 + EXPECT_EQ(0.05,thisAirTerminal.ZoneMinAirFrac); // user input + EXPECT_EQ(0.05, thisAirTerminal.DamperPosition); + EXPECT_EQ(SysMinMassFlowRes, thisAirTerminal.AirMassFlowRateMax * thisAirTerminal.ZoneMinAirFrac); + EXPECT_EQ(SysMinMassFlowRes, thisAirTerminalOutlet.AirMassFlowRate); + + // test 2: 0.10 fraction damper position + thisAirTerminal.ZoneMinAirFrac = 0.10; // modified user input + SysMinMassFlowRes = 1.0 * DataEnvironment::StdRhoAir * 0.10; + DataZoneEnergyDemands::ZoneSysEnergyDemand(1).RemainingOutputRequired = 0.0; + DataLoopNode::Node(InletNodeNum).MassFlowRate = SysMaxMassFlowRes; + DataLoopNode::Node(InletNodeNum).MassFlowRateMaxAvail = SysMaxMassFlowRes; + DataGlobals::BeginEnvrnFlag = true; + FirstHVACIteration = true; + SingleDuct::InitSys(SysNum, FirstHVACIteration); + DataGlobals::BeginEnvrnFlag = false; + FirstHVACIteration = false; + SingleDuct::InitSys(SysNum, FirstHVACIteration); + SingleDuct::SimVAVVS(SysNum, FirstHVACIteration, ZoneNum, ZoneNodeNum); + // check inputs and calculated values for zone air fraction 0.10 + EXPECT_EQ(0.10, thisAirTerminal.ZoneMinAirFrac); + EXPECT_EQ(0.10, thisAirTerminal.DamperPosition); + EXPECT_EQ(SysMinMassFlowRes, thisAirTerminal.AirMassFlowRateMax * thisAirTerminal.ZoneMinAirFrac); + EXPECT_EQ(SysMinMassFlowRes, thisAirTerminalOutlet.AirMassFlowRate); +} + } // namespace EnergyPlus From 6cda2a7cfcd99d0ca75105aa62e4c6870d377b0d Mon Sep 17 00:00:00 2001 From: nigusse Date: Tue, 21 Jan 2020 11:32:36 -0500 Subject: [PATCH 5/5] modified the fix --- src/EnergyPlus/SingleDuct.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/EnergyPlus/SingleDuct.cc b/src/EnergyPlus/SingleDuct.cc index 49769e37a0c..235fbbeb201 100644 --- a/src/EnergyPlus/SingleDuct.cc +++ b/src/EnergyPlus/SingleDuct.cc @@ -4495,16 +4495,12 @@ namespace SingleDuct { CalcVAVVS(SysNum, FirstHVACIteration, ZoneNodeNum, HCType, 0.0, 0.0, FanType, MassFlow, FanOp, QDelivered); } - //MassFlow = Node(SysInletNode).MassFlowRate; - // Move data to the damper outlet node - SysOutlet(SysNum).AirTemp = SysInlet(SysNum).AirTemp; - SysOutlet(SysNum).AirHumRat = SysInlet(SysNum).AirHumRat; + // Move mass flow rates to the damper outlet node SysOutlet(SysNum).AirMassFlowRate = MassFlow; SysOutlet(SysNum).AirMassFlowRateMaxAvail = SysInlet(SysNum).AirMassFlowRateMaxAvail; SysOutlet(SysNum).AirMassFlowRateMinAvail = SysInlet(SysNum).AirMassFlowRateMinAvail; - SysOutlet(SysNum).AirEnthalpy = SysInlet(SysNum).AirEnthalpy; - // calculate damper Position. + // calculate VAV damper Position. if (Sys(SysNum).AirMassFlowRateMax == 0.0) { Sys(SysNum).DamperPosition = 0.0; } else {