From ca5d09dd2e95dac54670e77674c58fe7a96c2c35 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Tue, 19 Nov 2024 10:30:38 -0600 Subject: [PATCH 1/3] If no fan do not touch inlet mass flow rate --- src/EnergyPlus/UnitarySystem.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/EnergyPlus/UnitarySystem.cc b/src/EnergyPlus/UnitarySystem.cc index 90f2caa8803..11444177364 100644 --- a/src/EnergyPlus/UnitarySystem.cc +++ b/src/EnergyPlus/UnitarySystem.cc @@ -916,8 +916,8 @@ namespace UnitarySystems { this->m_IterationCounter = 0; std::fill(this->m_IterationMode.begin(), this->m_IterationMode.end(), 0); - // for DX systems, just read the inlet node flow rate and let air loop decide flow - if (this->m_ControlType == UnitarySysCtrlType::Setpoint && this->m_sysType == SysType::Unitary) { + // for systems without a fan, just read the inlet node flow rate and let air loop decide flow + if (this->m_ControlType == UnitarySysCtrlType::Setpoint && this->m_sysType == SysType::Unitary && this->m_FanExists) { if (ScheduleManager::GetCurrentScheduleValue(state, this->m_SysAvailSchedPtr) > 0.0) { if (this->m_LastMode == CoolingMode) { if (this->m_MultiOrVarSpeedCoolCoil) { @@ -1046,7 +1046,7 @@ namespace UnitarySystems { state, "Coil:Heating:Steam", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound); } // from IF(UnitarySystem(UnitarySysNum)%SuppHeatCoilType_Num == Coil_HeatingSteam) THEN - } // from IF( FirstHVACIteration ) THEN + } // from IF( FirstHVACIteration ) THEN this->m_IterationCounter += 1; @@ -9511,7 +9511,7 @@ namespace UnitarySystems { HeatPLR = 0.0; PartLoadRatio = 0.0; } // IF((HeatingLoad .AND. ZoneLoad > SensOutputOff) .OR. (CoolingLoad .AND. ZoneLoad < SensOutputOff))THEN - } // IF((HeatingLoad .AND. ZoneLoad < SensOutputOn) .OR. (CoolingLoad .AND. ZoneLoad > SensOutputOn))THEN + } // IF((HeatingLoad .AND. ZoneLoad < SensOutputOn) .OR. (CoolingLoad .AND. ZoneLoad > SensOutputOn))THEN } if (state.dataUnitarySystems->HeatingLoad && (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil)) { @@ -10829,8 +10829,8 @@ namespace UnitarySystems { state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow; state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio; } // IF(MultiOrVarSpeedCoolCoil) THEN - } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN - } // IF(CompOnMassFlow .EQ. 0.0d0)THEN + } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN + } // IF(CompOnMassFlow .EQ. 0.0d0)THEN if (this->m_FanOpMode == HVAC::FanOp::Continuous) { if (this->m_AirFlowControl == UseCompFlow::On) { @@ -10889,7 +10889,7 @@ namespace UnitarySystems { state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio; state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow; } - } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN + } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN } else { // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN if (this->m_LastMode == HeatingMode) { if (this->m_MultiOrVarSpeedHeatCoil) { @@ -10910,9 +10910,9 @@ namespace UnitarySystems { } state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow; } // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN - } // IF(UnitarySystem(UnitarySysNum)%FanOpMode == HVAC::FanOp::Continuous)THEN - } // ELSE ! No Moisture Load - } // No Heating/Cooling Load + } // IF(UnitarySystem(UnitarySysNum)%FanOpMode == HVAC::FanOp::Continuous)THEN + } // ELSE ! No Moisture Load + } // No Heating/Cooling Load if (this->m_FanOpMode == HVAC::FanOp::Continuous) { if (this->m_AirFlowControl == UseCompFlow::On && @@ -12507,7 +12507,7 @@ namespace UnitarySystems { PartLoadFrac = 0.0; } else { // need to turn on compressor to see if load is met doIt = true; // CoilSystem:Cooling:DX - } // CoilSystem:Cooling:DX + } // CoilSystem:Cooling:DX if (this->m_EMSOverrideCoilSpeedNumOn) doIt = false; if (doIt) { // CoilSystem:Cooling:DX @@ -14979,7 +14979,7 @@ namespace UnitarySystems { } // IF (NOT EMS OVERRIDE) THEN } // IF SENSIBLE LOAD - } // IF((GetCurrentScheduleValue(state, UnitarySystem(UnitarySysNum)%m_SysAvailSchedPtr) > 0.0d0) .AND. & + } // IF((GetCurrentScheduleValue(state, UnitarySystem(UnitarySysNum)%m_SysAvailSchedPtr) > 0.0d0) .AND. & // LoopHeatingCoilMaxRTF used for AirflowNetwork gets set in child components (gas and fuel) if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP && From bb5da46a0c6874557b874b8e01be2ba9bf8c42c0 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Tue, 19 Nov 2024 12:13:39 -0600 Subject: [PATCH 2/3] undo VS formatting --- src/EnergyPlus/UnitarySystem.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/EnergyPlus/UnitarySystem.cc b/src/EnergyPlus/UnitarySystem.cc index 11444177364..2ea0e195e68 100644 --- a/src/EnergyPlus/UnitarySystem.cc +++ b/src/EnergyPlus/UnitarySystem.cc @@ -1046,7 +1046,7 @@ namespace UnitarySystems { state, "Coil:Heating:Steam", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound); } // from IF(UnitarySystem(UnitarySysNum)%SuppHeatCoilType_Num == Coil_HeatingSteam) THEN - } // from IF( FirstHVACIteration ) THEN + } // from IF( FirstHVACIteration ) THEN this->m_IterationCounter += 1; @@ -9511,7 +9511,7 @@ namespace UnitarySystems { HeatPLR = 0.0; PartLoadRatio = 0.0; } // IF((HeatingLoad .AND. ZoneLoad > SensOutputOff) .OR. (CoolingLoad .AND. ZoneLoad < SensOutputOff))THEN - } // IF((HeatingLoad .AND. ZoneLoad < SensOutputOn) .OR. (CoolingLoad .AND. ZoneLoad > SensOutputOn))THEN + } // IF((HeatingLoad .AND. ZoneLoad < SensOutputOn) .OR. (CoolingLoad .AND. ZoneLoad > SensOutputOn))THEN } if (state.dataUnitarySystems->HeatingLoad && (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil)) { @@ -10829,8 +10829,8 @@ namespace UnitarySystems { state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow; state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio; } // IF(MultiOrVarSpeedCoolCoil) THEN - } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN - } // IF(CompOnMassFlow .EQ. 0.0d0)THEN + } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN + } // IF(CompOnMassFlow .EQ. 0.0d0)THEN if (this->m_FanOpMode == HVAC::FanOp::Continuous) { if (this->m_AirFlowControl == UseCompFlow::On) { @@ -10889,7 +10889,7 @@ namespace UnitarySystems { state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio; state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow; } - } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN + } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN } else { // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN if (this->m_LastMode == HeatingMode) { if (this->m_MultiOrVarSpeedHeatCoil) { @@ -10910,9 +10910,9 @@ namespace UnitarySystems { } state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow; } // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN - } // IF(UnitarySystem(UnitarySysNum)%FanOpMode == HVAC::FanOp::Continuous)THEN - } // ELSE ! No Moisture Load - } // No Heating/Cooling Load + } // IF(UnitarySystem(UnitarySysNum)%FanOpMode == HVAC::FanOp::Continuous)THEN + } // ELSE ! No Moisture Load + } // No Heating/Cooling Load if (this->m_FanOpMode == HVAC::FanOp::Continuous) { if (this->m_AirFlowControl == UseCompFlow::On && @@ -12507,7 +12507,7 @@ namespace UnitarySystems { PartLoadFrac = 0.0; } else { // need to turn on compressor to see if load is met doIt = true; // CoilSystem:Cooling:DX - } // CoilSystem:Cooling:DX + } // CoilSystem:Cooling:DX if (this->m_EMSOverrideCoilSpeedNumOn) doIt = false; if (doIt) { // CoilSystem:Cooling:DX @@ -14979,7 +14979,7 @@ namespace UnitarySystems { } // IF (NOT EMS OVERRIDE) THEN } // IF SENSIBLE LOAD - } // IF((GetCurrentScheduleValue(state, UnitarySystem(UnitarySysNum)%m_SysAvailSchedPtr) > 0.0d0) .AND. & + } // IF((GetCurrentScheduleValue(state, UnitarySystem(UnitarySysNum)%m_SysAvailSchedPtr) > 0.0d0) .AND. & // LoopHeatingCoilMaxRTF used for AirflowNetwork gets set in child components (gas and fuel) if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP && From 3cce73cdf37e82b76f29b48eea887d5e74d8e835 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Tue, 19 Nov 2024 17:18:55 -0600 Subject: [PATCH 3/3] UnitarySystemModel_MultiSpeedDXCoolCoil_Only_NoFan test --- tst/EnergyPlus/unit/UnitarySystem.unit.cc | 327 ++++++++++++++++++++++ 1 file changed, 327 insertions(+) diff --git a/tst/EnergyPlus/unit/UnitarySystem.unit.cc b/tst/EnergyPlus/unit/UnitarySystem.unit.cc index 9483baea27f..1bd5f84de2f 100644 --- a/tst/EnergyPlus/unit/UnitarySystem.unit.cc +++ b/tst/EnergyPlus/unit/UnitarySystem.unit.cc @@ -1438,6 +1438,333 @@ TEST_F(ZoneUnitarySysTest, UnitarySystemModel_MultiSpeedDXCoolCoil_Only) EXPECT_NEAR(thisSys->m_CoolingSpeedRatio, 1.0, 0.001); // RESET TO MAX SPEED ALLOWED } +TEST_F(ZoneUnitarySysTest, UnitarySystemModel_MultiSpeedDXCoolCoil_Only_NoFan) +{ + + std::string_view constexpr idf_objects = R"IDF( + + AirLoopHVAC:UnitarySystem, + Unitary System Model, !- Name + Setpoint, !- Control Type + , !- Controlling Zone or Thermostat Location + None, !- Dehumidification Control Type + AlwaysOne, !- Availability Schedule Name + Zone Exhaust Node, !- Air Inlet Node Name + Zone 2 Inlet Node, !- Air Outlet Node Name + , !- Supply Fan Object Type + , !- Supply Fan Name + , !- Fan Placement + , !- Supply Air Fan Operating Mode Schedule Name + , !- Heating Coil Object Type + , !- Heating Coil Name + , !- DX Heating Coil Sizing Ratio + Coil:Cooling:DX:MultiSpeed, !- Cooling Coil Object Type + DX Cooling Coil, !- Cooling Coil Name + No, !- Use DOAS DX Cooling Coil + 2.0, !- DOAS DX Cooling Coil Leaving Minimum Air Temperature{ C } + SensibleOnlyLoadControl, !- Latent Load Control + , !- Supplemental Heating Coil Object Type + , !- Supplemental Heating Coil Name + SupplyAirFlowRate, !- Supply Air Flow Rate Method During Cooling Operation + 1.8, !- Supply Air Flow Rate During Cooling Operation{ m3/s } + , !- Supply Air Flow Rate Per Floor Area During Cooling Operation{ m3/s-m2 } + , !- Fraction of Autosized Design Cooling Supply Air Flow Rate + , !- Design Supply Air Flow Rate Per Unit of Capacity During Cooling Operation{ m3/s-W } + SupplyAirFlowRate, !- Supply air Flow Rate Method During Heating Operation + 1.8, !- Supply Air Flow Rate During Heating Operation{ m3/s } + , !- Supply Air Flow Rate Per Floor Area during Heating Operation{ m3/s-m2 } + , !- Fraction of Autosized Design Heating Supply Air Flow Rate + , !- Design Supply Air Flow Rate Per Unit of Capacity During Heating Operation{ m3/s-W } + , !- Supply Air Flow Rate Method When No Cooling or Heating is Required + , !- Supply Air Flow Rate When No Cooling or Heating is Required{ m3/s } + , !- Supply Air Flow Rate Per Floor Area When No Cooling or Heating is Required{ m3/s-m2 } + , !- Fraction of Autosized Design Cooling Supply Air Flow Rate + , !- Fraction of Autosized Design Heating Supply Air Flow Rate + , !- Design Supply Air Flow Rate Per Unit of Capacity During Cooling Operation{ m3/s-W } + , !- Design Supply Air Flow Rate Per Unit of Capacity During Heating Operation{ m3/s-W } + , !- No Load Supply Air Flow Rate Control Set To Low Speed + 80.0, !- Maximum Supply Air Temperature{ C } + , !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + , !- Outdoor Dry-Bulb Temperature Sensor Node Name + , !- Ancilliary On-Cycle Electric Power + , !- Ancilliary Off-Cycle Electric Power + , !- Design Heat Recovery Water Flow Rate + , !- Maximum Temperature for Heat Recovery + , !- Heat Recovery Water Inlet Node Name + , !- Heat Recovery Water Outlet Node Name + UnitarySystemPerformance:Multispeed, !- Design Specification Multispeed Object Type + DX Cool MultiSpd Unitary System MultiSpeed Performance; !- Design Specification Multispeed Object Name + + UnitarySystemPerformance:Multispeed, + DX Cool MultiSpd Unitary System MultiSpeed Performance, !- Name + 1, !- Number of Speeds for Heating + 2, !- Number of Speeds for Cooling + No, !- Single Mode Operation + , !- No Load Supply Air Flow Rate Ratio + 1, !- Heating Speed 1 Supply Air Flow Ratio + 1, !- Cooling Speed 1 Supply Air Flow Ratio + Autosize, !- Heating Speed 2 Supply Air Flow Ratio + Autosize; !- Cooling Speed 2 Supply Air Flow Ratio + + Coil:Cooling:DX:MultiSpeed, + DX Cooling Coil, !- Name + , !- Availability Schedule Name + Zone Exhaust Node, !- Air Inlet Node Name + Zone 2 Inlet Node, !- Air Outlet Node Name + , !- Condenser Air Inlet Node Name + AirCooled, !- Condenser Type + , !- Minimum Outdoor Dry - Bulb Temperature for Compressor Operation{ C } + , !- Supply Water Storage Tank Name + , !- Condensate Collection Water Storage Tank Name + No, !- Apply Part Load Fraction to Speeds Greater than 1 + No, !- Apply Latent Degradation to Speeds Greater than 1 + 0, !- Crankcase Heater Capacity{ W } + , !- Crankcase Heater Capacity Function of Temperature Curve Name + 10, !- Maximum Outdoor Dry - Bulb Temperature for Crankcase Heater Operation{ C } + 0, !- Basin Heater Capacity{ W / K } + 2, !- Basin Heater Setpoint Temperature{ C } + , !- Basin Heater Operating Schedule Name + Electricity, !- Fuel Type + 2, !- Number of Speeds + AutoSize, !- Speed 1 Gross Rated Total Cooling Capacity{ W } + AutoSize, !- Speed 1 Gross Rated Sensible Heat Ratio + 5.12895662368113, !- Speed 1 Gross Rated Cooling COP{ W / W } + AutoSize, !- Speed 1 Rated Air Flow Rate{ m3 / s } + 773.3, !- 2017 Speed 1 Rated Evaporator Fan Power Per Volume Flow Rate {W/(m3/s)} + 934.4, !- 2023 Speed 1 Rated Evaporator Fan Power Per Volume Flow Rate {W/(m3/s)}", //??BPS:T + Biquadratic, !- Speed 1 Total Cooling Capacity Function of Temperature Curve Name + Quadratic, !- Speed 1 Total Cooling Capacity Function of Flow Fraction Curve Name + Biquadratic, !- Speed 1 Energy Input Ratio Function of Temperature Curve Name + Quadratic, !- Speed 1 Energy Input Ratio Function of Flow Fraction Curve Name + Quadratic, !- Speed 1 Part Load Fraction Correlation Curve Name + 0, !- Speed 1 Nominal Time for Condensate Removal to Begin{ s } + 0, !- Speed 1 Ratio of Initial Moisture Evaporation Rate and Steady State Latent Capacity{ dimensionless } + 0, !- Speed 1 Maximum Cycling Rate{ cycles / hr } + 0, !- Speed 1 Latent Capacity Time Constant{ s } + 0.5, !- Speed 1 Rated Waste Heat Fraction of Power Input{ dimensionless } + Biquadratic, !- Speed 1 Waste Heat Function of Temperature Curve Name + 0.9, !- Speed 1 Evaporative Condenser Effectiveness{ dimensionless } + AutoSize, !- Speed 1 Evaporative Condenser Air Flow Rate{ m3 / s } + AutoSize, !- Speed 1 Rated Evaporative Condenser Pump Power Consumption{ W } + AutoSize, !- Speed 2 Gross Rated Total Cooling Capacity{ W } + AutoSize, !- Speed 2 Gross Rated Sensible Heat Ratio + 4.68933177022274, !- Speed 2 Gross Rated Cooling COP{ W / W } + AutoSize, !- Speed 2 Rated Air Flow Rate{ m3 / s } + 773.3, !- 2017 Speed 2 Rated Evaporator Fan Power Per Volume Flow Rate {W/(m3/s)} + 934.4, !- 2023 Speed 2 Rated Evaporator Fan Power Per Volume Flow Rate {W/(m3/s)}", //??BPS:T + Biquadratic, !- Speed 2 Total Cooling Capacity Function of Temperature Curve Name + Quadratic, !- Speed 2 Total Cooling Capacity Function of Flow Fraction Curve Name + Biquadratic, !- Speed 2 Energy Input Ratio Function of Temperature Curve Name + Quadratic, !- Speed 2 Energy Input Ratio Function of Flow Fraction Curve Name + Quadratic, !- Speed 2 Part Load Fraction Correlation Curve Name + 0, !- Speed 2 Nominal Time for Condensate Removal to Begin{ s } + 0, !- Speed 2 Ratio of Initial Moisture Evaporation Rate and steady state Latent Capacity{ dimensionless } + 0, !- Speed 2 Maximum Cycling Rate{ cycles / hr } + 0, !- Speed 2 Latent Capacity Time Constant{ s } + 0.5, !- Speed 2 Rated Waste Heat Fraction of Power Input{ dimensionless } + Biquadratic, !- Speed 2 Waste Heat Function of Temperature Curve Name + 0.9, !- Speed 2 Evaporative Condenser Effectiveness{ dimensionless } + AutoSize, !- Speed 2 Evaporative Condenser Air Flow Rate{ m3 / s } + AutoSize; !- Speed 2 Rated Evaporative Condenser Pump Power Consumption{ W } + + ScheduleTypeLimits, + Any Number; !- Name + + Schedule:Compact, + AlwaysOne, !- Name + Any Number, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00, 1.0; !- Field 3 + + Schedule:Compact, + Always 20C, !- Name + Any Number, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00, 20.0; !- Field 3 + + SetpointManager:Scheduled, + Cooling Coil Setpoint Manager, !- Name + Temperature, !- Control Variable + Always 20C, !- Schedule Name + Zone 2 Inlet Node; !- Setpoint Node or NodeList Name + + Curve:Quadratic, + Quadratic, !- Name + 0.8, !- Coefficient1 Constant + 0.2, !- Coefficient2 x + 0.0, !- Coefficient3 x**2 + 0.5, !- Minimum Value of x + 1.5; !- Maximum Value of x + + Curve:Biquadratic, + Biquadratic, !- Name + 0.942587793, !- Coefficient1 Constant + 0.009543347, !- Coefficient2 x + 0.000683770, !- Coefficient3 x**2 + -0.011042676, !- Coefficient4 y + 0.000005249, !- Coefficient5 y**2 + -0.000009720, !- Coefficient6 x*y + 12.77778, !- Minimum Value of x + 23.88889, !- Maximum Value of x + 18.0, !- Minimum Value of y + 46.11111, !- Maximum Value of y + , !- Minimum Curve Output + , !- Maximum Curve Output + Temperature, !- Input Unit Type for X + Temperature, !- Input Unit Type for Y + Dimensionless; !- Output Unit Type + + )IDF"; + + ASSERT_TRUE(process_idf(idf_objects)); // read idf objects + + // call the UnitarySystem factory + std::string compName = "UNITARY SYSTEM MODEL"; + bool zoneEquipment = false; + bool FirstHVACIteration = true; + UnitarySystems::UnitarySys::factory(*state, HVAC::UnitarySysType::Unitary_AnyCoilType, compName, zoneEquipment, 0); + UnitarySystems::UnitarySys *thisSys = &state->dataUnitarySystems->unitarySys[0]; + + int AirLoopNum = 1; + state->dataHVACGlobal->NumPrimaryAirSys = 1; + state->dataAirLoop->AirLoopControlInfo.allocate(1); + state->dataAirSystemsData->PrimaryAirSystems.allocate(1); + state->dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch.allocate(1); + state->dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches = 1; + int BranchNum = 1; + state->dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp.allocate(1); + state->dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents = 1; + int CompNum = 1; + state->dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).CompType_Num = + SimAirServingZones::CompType::UnitarySystemModel; + state->dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).Name = thisSys->Name; + + state->dataZoneEquip->ZoneEquipInputsFilled = true; // indicate zone data is available + thisSys->getUnitarySystemInputData(*state, compName, zoneEquipment, 0, ErrorsFound); // get UnitarySystem input from object above + compare_err_stream(""); + EXPECT_FALSE(ErrorsFound); // expect no errors + thisSys->m_ThisSysInputShouldBeGotten = false; + + OutputReportPredefined::SetPredefinedTables(*state); + + // UnitarySystem used as zone equipment will not be modeled when FirstHAVCIteration is true, first time FirstHVACIteration = false will disable + // the 'return' on FirstHVACIteration = true set FirstHVACIteration to false for unit testing to size water coils + FirstHVACIteration = false; + state->dataGlobal->BeginEnvrnFlag = false; + state->dataHVACGlobal->DoSetPointTest = true; + state->dataEnvrn->Month = 5; + state->dataEnvrn->DayOfMonth = 31; + state->dataGlobal->HourOfDay = 23; + state->dataEnvrn->DSTIndicator = 1; // DST IS ON + state->dataEnvrn->MonthTomorrow = 6; + state->dataEnvrn->DayOfWeek = 4; + state->dataEnvrn->DayOfWeekTomorrow = 5; + state->dataEnvrn->HolidayIndex = 0; + state->dataGlobal->TimeStep = 4; + state->dataEnvrn->DayOfYear_Schedule = General::OrdinalDay(state->dataEnvrn->Month, state->dataEnvrn->DayOfMonth, 1); + + ScheduleManager::UpdateScheduleValues(*state); + SetPointManager::ManageSetPoints(*state); + + // overwrite outdoor weather temp to variable speed coil rated water temp until this gets fixed + state->dataSize->DesDayWeath(1).Temp(1) = 29.4; + + int CompIndex = 1; + bool HeatActive = false; + bool CoolActive = true; + int constexpr ZoneOAUnitNum = 0; + Real64 constexpr OAUCoilOutTemp = 0.0; + Real64 sensOut = 0.0; + Real64 latOut = 0.0; + + thisSys->CoolCtrlNode = thisSys->AirOutNode; + thisSys->CoolCoilInletNodeNum = thisSys->AirInNode; + + thisSys->simulate(*state, + thisSys->Name, + FirstHVACIteration, + AirLoopNum, + CompIndex, + HeatActive, + CoolActive, + ZoneOAUnitNum, + OAUCoilOutTemp, + zoneEquipment, + sensOut, + latOut); + + // Test System behavior with no supply fan + EXPECT_FALSE(thisSys->m_FanExists); + + // set up node conditions to test UnitarySystem set point based control + // Unitary system air inlet node = 1 + state->dataLoopNodes->Node(thisSys->AirInNode).MassFlowRate = 1.2; + + // test COOLING condition + state->dataLoopNodes->Node(1).Temp = 24.0; // 24C db + state->dataLoopNodes->Node(1).HumRat = 0.00922; // 17C wb + state->dataLoopNodes->Node(1).Enthalpy = 47597.03; // www.sugartech.com/psychro/index.php + + // ScheduleManager::ProcessScheduleInput(*state); // read schedules + + state->dataLoopNodes->Node(thisSys->AirOutNode).TempSetPoint = 17.0; + + state->dataScheduleMgr->Schedule(1).CurrentValue = 1.0; // Enable schedule without calling schedule manager + + state->dataGlobal->BeginEnvrnFlag = true; // act as if simulation is beginning + thisSys->m_EMSOverrideCoilSpeedNumOn = false; + FirstHVACIteration = true; + + // COOLING mode + thisSys->simulate(*state, + thisSys->Name, + FirstHVACIteration, + AirLoopNum, + CompIndex, + HeatActive, + CoolActive, + ZoneOAUnitNum, + OAUCoilOutTemp, + zoneEquipment, + sensOut, + latOut); + + // check that cooling coil air outlet node is at set point + EXPECT_NEAR(state->dataLoopNodes->Node(thisSys->AirOutNode).Temp, state->dataLoopNodes->Node(thisSys->AirOutNode).TempSetPoint, 0.1); + // cooling coil air inlet node temp is greater than cooling coil air outlet node temp + EXPECT_GT(state->dataLoopNodes->Node(thisSys->AirInNode).Temp, state->dataLoopNodes->Node(thisSys->AirOutNode).Temp); + EXPECT_NEAR(thisSys->m_CoolingCycRatio, 0.36056, 0.001); + EXPECT_EQ(thisSys->m_CoolingSpeedRatio, 0); + EXPECT_EQ(thisSys->m_CoolingSpeedNum, 1); + EXPECT_EQ(state->dataLoopNodes->Node(thisSys->AirInNode).MassFlowRate, 1.2); + EXPECT_EQ(state->dataLoopNodes->Node(thisSys->AirInNode).MassFlowRate, state->dataLoopNodes->Node(thisSys->AirOutNode).MassFlowRate); + + // Set system availability schedule to off + state->dataScheduleMgr->Schedule(1).CurrentValue = 0.0; + thisSys->simulate(*state, + thisSys->Name, + FirstHVACIteration, + AirLoopNum, + CompIndex, + HeatActive, + CoolActive, + ZoneOAUnitNum, + OAUCoilOutTemp, + zoneEquipment, + sensOut, + latOut); + + // no cooling, pass thru mass flow rate + EXPECT_EQ(state->dataLoopNodes->Node(thisSys->AirInNode).Temp, state->dataLoopNodes->Node(thisSys->AirOutNode).Temp); + EXPECT_NEAR(thisSys->m_CoolingCycRatio, 0.0, 0.001); + EXPECT_EQ(thisSys->m_CoolingSpeedRatio, 0); + EXPECT_EQ(thisSys->m_CoolingSpeedNum, 0); + EXPECT_EQ(state->dataLoopNodes->Node(thisSys->AirInNode).MassFlowRate, 1.2); + EXPECT_EQ(state->dataLoopNodes->Node(thisSys->AirInNode).MassFlowRate, state->dataLoopNodes->Node(thisSys->AirOutNode).MassFlowRate); +} + TEST_F(ZoneUnitarySysTest, UnitarySystemModel_MultiStageGasHeatCoil_Only) {