From 89671cc497fbe427a0b3396afe01b4dfc03f02e8 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Thu, 21 Dec 2023 19:27:19 -0800 Subject: [PATCH 01/81] consider cycling in VRF fan power calculation --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index d0e65502f05..58e120ba353 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -12492,6 +12492,15 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) this->ElecHeatingPower = 0; } this->VRFCondRTF = VRFRTF; + // consider cycling in fan calculation + for (int TUListNum = 1; TUListNum <= state.dataHVACVarRefFlow->NumVRFTULists; ++TUListNum) { + auto &thisTUList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum); + for (int TUNum = 1; TUNum <= thisTUList.NumTUInList; ++TUNum) { + auto &fan = state.dataFans->Fan(state.dataHVACVarRefFlow->VRFTU(TUNum).FanIndex); + fan.FanPower *= state.dataHVACVarRefFlow->VRF(VRFCond).VRFCondCyclingRatio; + fan.FanEnergy = fan.FanPower * state.dataHVACGlobal->TimeStepSysSec; + } + } // Calculate CrankCaseHeaterPower: VRF Heat Pump Crankcase Heater Electric Power [W] if (this->MaxOATCCHeater > OutdoorDryBulb) { From 5a00a65b7e1b3e66987566f90156d47534b3a1f3 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 3 Jan 2024 09:25:08 -0800 Subject: [PATCH 02/81] multiply by coil runtime fraction not VRF RTF --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 58e120ba353..d2be1586450 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -12497,8 +12497,17 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) auto &thisTUList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum); for (int TUNum = 1; TUNum <= thisTUList.NumTUInList; ++TUNum) { auto &fan = state.dataFans->Fan(state.dataHVACVarRefFlow->VRFTU(TUNum).FanIndex); - fan.FanPower *= state.dataHVACVarRefFlow->VRF(VRFCond).VRFCondCyclingRatio; - fan.FanEnergy = fan.FanPower * state.dataHVACGlobal->TimeStepSysSec; + int heatingCoilNum = state.dataHVACVarRefFlow->VRFTU(TUNum).HeatCoilIndex; + int coolingCoilNum = state.dataHVACVarRefFlow->VRFTU(TUNum).CoolCoilIndex; + auto &heatingCoil = state.dataDXCoils->DXCoil(heatingCoilNum); + auto &coolingCoil = state.dataDXCoils->DXCoil(coolingCoilNum); + // only deal with cooling for now. heating RTF might have some issue + if (heatingCoil.HeatingCoilRuntimeFraction == 0.0) { // in cooling mode + // here coolingCoil.CoolingCoilRuntimeFraction equals state.dataHVACVarRefFlow->VRF(VRFCond).VRFCondCyclingRatio + // this is not the case for heating + fan.FanPower *= coolingCoil.CoolingCoilRuntimeFraction; + fan.FanEnergy = fan.FanPower * state.dataHVACGlobal->TimeStepSysSec; + } } } From 9a0cc0b04d3fce88039a34e863372806ced642e3 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 24 Jan 2024 15:55:06 -0800 Subject: [PATCH 03/81] add fan heat gain adjustment --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index d2be1586450..1ee5604a95c 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -12507,6 +12507,7 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) // this is not the case for heating fan.FanPower *= coolingCoil.CoolingCoilRuntimeFraction; fan.FanEnergy = fan.FanPower * state.dataHVACGlobal->TimeStepSysSec; + fan.PowerLossToAir *= coolingCoil.CoolingCoilRuntimeFraction; } } } From 89019063a8782ace88a8aa41dc12bd41d1a7d8f2 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Thu, 1 Feb 2024 17:23:15 -0800 Subject: [PATCH 04/81] Consider run time fraction in OU fan power --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index d63c5096f74..5c7a11b0d5f 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -11721,7 +11721,7 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) // Key outputs of this subroutine this->CompActSpeed = max(CompSpdActual, 0.0); this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter; // 0.95 is the efficiency of the compressor inverter, can come from IDF //@minor - this->OUFanPower = this->RatedOUFanPower; //@ * pow_3( CondFlowRatio ) + this->OUFanPower = this->RatedOUFanPower * CyclingRatio; //@ * pow_3( CondFlowRatio ) this->VRFCondCyclingRatio = CyclingRatio; // report variable for cycling rate Tdischarge = this->CondensingTemp; // outdoor unit condensing temperature @@ -11934,7 +11934,7 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) // Key outputs of this subroutine this->CompActSpeed = max(CompSpdActual, 0.0); this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter; - this->OUFanPower = this->RatedOUFanPower; + this->OUFanPower = this->RatedOUFanPower * CyclingRatio; this->VRFCondCyclingRatio = CyclingRatio; Tsuction = this->EvaporatingTemp; // Outdoor unit evaporating temperature From 7c1a00884f5cce2a1e80c92f0fac1443b0797e20 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Thu, 1 Feb 2024 17:24:03 -0800 Subject: [PATCH 05/81] clang-format --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 5c7a11b0d5f..9c19c040ac7 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -11720,9 +11720,9 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) // Key outputs of this subroutine this->CompActSpeed = max(CompSpdActual, 0.0); - this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter; // 0.95 is the efficiency of the compressor inverter, can come from IDF //@minor - this->OUFanPower = this->RatedOUFanPower * CyclingRatio; //@ * pow_3( CondFlowRatio ) - this->VRFCondCyclingRatio = CyclingRatio; // report variable for cycling rate + this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter; // 0.95 is the efficiency of the compressor inverter, can come from IDF //@minor + this->OUFanPower = this->RatedOUFanPower * CyclingRatio; //@ * pow_3( CondFlowRatio ) + this->VRFCondCyclingRatio = CyclingRatio; // report variable for cycling rate Tdischarge = this->CondensingTemp; // outdoor unit condensing temperature this->CoolingCapacity = From 5fcc817265e39220a045e7e251bb32487cbc4dfe Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Fri, 2 Feb 2024 16:31:48 -0800 Subject: [PATCH 06/81] Add check of fan index before accessing dataFans->Fan(.) --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 9c19c040ac7..8c17f4c469b 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -12485,15 +12485,17 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) for (int TUListNum = 1; TUListNum <= state.dataHVACVarRefFlow->NumVRFTULists; ++TUListNum) { auto &thisTUList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum); for (int TUNum = 1; TUNum <= thisTUList.NumTUInList; ++TUNum) { - auto &fan = state.dataFans->Fan(state.dataHVACVarRefFlow->VRFTU(TUNum).FanIndex); int heatingCoilNum = state.dataHVACVarRefFlow->VRFTU(TUNum).HeatCoilIndex; int coolingCoilNum = state.dataHVACVarRefFlow->VRFTU(TUNum).CoolCoilIndex; auto &heatingCoil = state.dataDXCoils->DXCoil(heatingCoilNum); auto &coolingCoil = state.dataDXCoils->DXCoil(coolingCoilNum); + int fanIndex = state.dataHVACVarRefFlow->VRFTU(TUNum).FanIndex; // only deal with cooling for now. heating RTF might have some issue - if (heatingCoil.HeatingCoilRuntimeFraction == 0.0) { // in cooling mode + // does Fan:SystemModel need adjustment as well? if so consider 0-indexing and it's in state.dataHVACFan->fanObjs vector + if (fanIndex > 0 && heatingCoil.HeatingCoilRuntimeFraction == 0.0) { // in cooling mode // here coolingCoil.CoolingCoilRuntimeFraction equals state.dataHVACVarRefFlow->VRF(VRFCond).VRFCondCyclingRatio // this is not the case for heating + auto &fan = state.dataFans->Fan(fanIndex); fan.FanPower *= coolingCoil.CoolingCoilRuntimeFraction; fan.FanEnergy = fan.FanPower * state.dataHVACGlobal->TimeStepSysSec; fan.PowerLossToAir *= coolingCoil.CoolingCoilRuntimeFraction; From 026be04bf4919a0fa0231ad3450806b560d9e3ff Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Fri, 2 Feb 2024 16:32:12 -0800 Subject: [PATCH 07/81] fix unit test uninitialized cycling ratio --- tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index 98f3b25a4db..2628b2c847a 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -13192,6 +13192,8 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_ReportOutputVerificationTest) Real64 OAUCoilOutTemp = 0.0; bool ZoneEquipment = true; + // add VRF cycling ratio initialization. Since TU's are simulated first, if there's no initialization, the coil runtime fraction will be zero + state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio = 1.0; SimulateVRF(*state, state->dataHVACVarRefFlow->VRFTU(VRFTUNum).Name, FirstHVACIteration, @@ -13219,7 +13221,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_ReportOutputVerificationTest) EXPECT_EQ(0.0, thisVRFTU.NoCoolHeatOutAirMassFlow); EXPECT_NEAR(5125.0840, thisDXCoolingCoil.TotalCoolingEnergyRate, 0.0001); EXPECT_NEAR(4999.8265, thisVRFTU.TotalCoolingRate, 0.0001); - EXPECT_NEAR(125.2573, thisFan.FanPower, 0.0001); + EXPECT_NEAR(125.2573 * thisDXCoolingCoil.CoolingCoilRuntimeFraction, thisFan.FanPower, 0.0001); EXPECT_NEAR(thisDXCoolingCoil.TotalCoolingEnergyRate, (thisVRFTU.TotalCoolingRate + thisFan.FanPower), 0.0001); } From b9c6bff967469f657cccd826f8481dcd3e387b8d Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Fri, 2 Feb 2024 16:33:16 -0800 Subject: [PATCH 08/81] clang-format --- .../unit/HVACVariableRefrigerantFlow.unit.cc | 468 +++++++++--------- 1 file changed, 235 insertions(+), 233 deletions(-) diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index 2628b2c847a..c6f2b82fc46 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -2487,109 +2487,109 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Compressor) } // Run and Check: VRFOU_CompSpd - {// Test the method VRFOU_CompSpd, which calculates the compressor speed at given - // operational conditions to meet the evaporator or condenser capacity provided. + { // Test the method VRFOU_CompSpd, which calculates the compressor speed at given + // operational conditions to meet the evaporator or condenser capacity provided. - {// a. Evaporator + { // a. Evaporator - // Inputs_condition - Real64 constexpr Q_req = 6971; // Required capacity [W] - Real64 constexpr T_suction = -13.35; // Compressor suction temperature Te' [C] - Real64 constexpr T_discharge = 36.37; // Compressor discharge temperature Tc' [C] - Real64 constexpr h_IU_evap_in = 225016; // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg] - Real64 constexpr h_comp_in = 429529; // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg] - Real64 CompSpdActual; // Actual compressor running speed [rps] + // Inputs_condition + Real64 constexpr Q_req = 6971; // Required capacity [W] + Real64 constexpr T_suction = -13.35; // Compressor suction temperature Te' [C] + Real64 constexpr T_discharge = 36.37; // Compressor discharge temperature Tc' [C] + Real64 constexpr h_IU_evap_in = 225016; // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg] + Real64 constexpr h_comp_in = 429529; // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg] + Real64 CompSpdActual; // Actual compressor running speed [rps] - // Run - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompSpd( - *state, Q_req, HXOpMode::EvapMode, T_suction, T_discharge, h_IU_evap_in, h_comp_in, CompSpdActual); + // Run + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompSpd( + *state, Q_req, HXOpMode::EvapMode, T_suction, T_discharge, h_IU_evap_in, h_comp_in, CompSpdActual); - // Test - EXPECT_NEAR(1295, CompSpdActual, 5); -} + // Test + EXPECT_NEAR(1295, CompSpdActual, 5); + } -{ - // b. Condenser - - // Inputs_condition - Real64 constexpr Q_req = 6953; // Required capacity [W] - Real64 constexpr T_suction = -13.35; // Compressor suction temperature Te' [C] - Real64 constexpr T_discharge = 36.37; // Compressor discharge temperature Tc' [C] - Real64 constexpr h_IU_evap_in = 225016; // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg] - Real64 constexpr h_comp_in = 429529; // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg] - Real64 CompSpdActual; // Actual compressor running speed [rps] - - // Run - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompSpd( - *state, Q_req, HXOpMode::CondMode, T_suction, T_discharge, h_IU_evap_in, h_comp_in, CompSpdActual); - - // Test - EXPECT_NEAR(950, CompSpdActual, 5); -} -} // namespace EnergyPlus + { + // b. Condenser -// Run and Check: VRFOU_CompCap -{ - // Test the method VRFOU_CompCap, which calculates the compressor performance (power and capacity) - // at given compressor speed and operational conditions. - - // Inputs_condition - Real64 constexpr CompSpdActual = 1298; // Actual compressor running speed [rps] - Real64 constexpr T_suction = -13.35; // Compressor suction temperature Te' [C] - Real64 constexpr T_discharge = 36.37; // Compressor discharge temperature Tc' [C] - Real64 constexpr h_IU_evap_in = 225016; // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg] - Real64 constexpr h_comp_in = 429529; // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg] - Real64 Q_c_tot; // Compressor evaporative capacity [W] - Real64 Ncomp; // Compressor power [W] - - // Run - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompCap(*state, CompSpdActual, T_suction, T_discharge, h_IU_evap_in, h_comp_in, Q_c_tot, Ncomp); - - // Test - EXPECT_NEAR(6990, Q_c_tot, 10); - EXPECT_NEAR(1601, Ncomp, 10); -} + // Inputs_condition + Real64 constexpr Q_req = 6953; // Required capacity [W] + Real64 constexpr T_suction = -13.35; // Compressor suction temperature Te' [C] + Real64 constexpr T_discharge = 36.37; // Compressor discharge temperature Tc' [C] + Real64 constexpr h_IU_evap_in = 225016; // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg] + Real64 constexpr h_comp_in = 429529; // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg] + Real64 CompSpdActual; // Actual compressor running speed [rps] -// Run and Check: VRFOU_CalcComp -{ - // Test the method VRFOU_CalcCompH, which simulates the compressor performance at given oprtaional conditions. More specifically, it - // sepcifies the compressor speed to provide sufficient evaporative capacity, and calculate the power of the compressor running at the - // specified speed. Note that it may be needed to manipulate the operational conditions to further adjust system capacity at low load - // conditions. The low load modification logics are different for cooling mode and heating mode. - - // Inputs_condition - Real64 TU_load = 6006; // Indoor unit cooling load [W] - Real64 T_suction = 8.86; // Compressor suction temperature Te' [C] - Real64 T_discharge = 40.26; // Compressor discharge temperature Tc' [C] - Real64 Pipe_h_out_ave = 233428; // Average Enthalpy of the refrigerant leaving IUs [kJ/kg] - Real64 IUMaxCondTemp = 36; // VRV IU condensing temperature, max among all indoor units [C] - Real64 MinOutdoorUnitTe = -72; // The minimum temperature that OU Te can be at cooling mode (only used for calculating Min capacity) - Real64 Tfs = 10.90; // Temperature of the air at the OU evaporator coil surface [C]] - Real64 Pipe_Q = 162.67; // Piping Loss Algorithm Parameter: Heat loss [W] - Real64 OUEvapHeatExtract = 5110.40; // Evaporator heat extract [W] - Real64 Ncomp = 1058; // Compressor power [W] - Real64 CompSpdActual; // Actual compressor running speed [rps] - - // Run - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CalcCompH(*state, - TU_load, - T_suction, - T_discharge, - Pipe_h_out_ave, - IUMaxCondTemp, - MinOutdoorUnitTe, - Tfs, - Pipe_Q, - OUEvapHeatExtract, - CompSpdActual, - Ncomp); - - // Test - EXPECT_NEAR(5110, OUEvapHeatExtract, 1); - EXPECT_NEAR(1500, CompSpdActual, 1); - EXPECT_NEAR(2080, Ncomp, 1); - EXPECT_EQ(state->dataLoopNodes->Node(state->dataHVACVarRefFlow->VRFTU(1).VRFTUInletNodeNum).MassFlowRate, 0.0); -} + // Run + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompSpd( + *state, Q_req, HXOpMode::CondMode, T_suction, T_discharge, h_IU_evap_in, h_comp_in, CompSpdActual); + + // Test + EXPECT_NEAR(950, CompSpdActual, 5); + } + } // namespace EnergyPlus + + // Run and Check: VRFOU_CompCap + { + // Test the method VRFOU_CompCap, which calculates the compressor performance (power and capacity) + // at given compressor speed and operational conditions. + + // Inputs_condition + Real64 constexpr CompSpdActual = 1298; // Actual compressor running speed [rps] + Real64 constexpr T_suction = -13.35; // Compressor suction temperature Te' [C] + Real64 constexpr T_discharge = 36.37; // Compressor discharge temperature Tc' [C] + Real64 constexpr h_IU_evap_in = 225016; // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg] + Real64 constexpr h_comp_in = 429529; // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg] + Real64 Q_c_tot; // Compressor evaporative capacity [W] + Real64 Ncomp; // Compressor power [W] + + // Run + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompCap(*state, CompSpdActual, T_suction, T_discharge, h_IU_evap_in, h_comp_in, Q_c_tot, Ncomp); + + // Test + EXPECT_NEAR(6990, Q_c_tot, 10); + EXPECT_NEAR(1601, Ncomp, 10); + } + + // Run and Check: VRFOU_CalcComp + { + // Test the method VRFOU_CalcCompH, which simulates the compressor performance at given oprtaional conditions. More specifically, it + // sepcifies the compressor speed to provide sufficient evaporative capacity, and calculate the power of the compressor running at the + // specified speed. Note that it may be needed to manipulate the operational conditions to further adjust system capacity at low load + // conditions. The low load modification logics are different for cooling mode and heating mode. + + // Inputs_condition + Real64 TU_load = 6006; // Indoor unit cooling load [W] + Real64 T_suction = 8.86; // Compressor suction temperature Te' [C] + Real64 T_discharge = 40.26; // Compressor discharge temperature Tc' [C] + Real64 Pipe_h_out_ave = 233428; // Average Enthalpy of the refrigerant leaving IUs [kJ/kg] + Real64 IUMaxCondTemp = 36; // VRV IU condensing temperature, max among all indoor units [C] + Real64 MinOutdoorUnitTe = -72; // The minimum temperature that OU Te can be at cooling mode (only used for calculating Min capacity) + Real64 Tfs = 10.90; // Temperature of the air at the OU evaporator coil surface [C]] + Real64 Pipe_Q = 162.67; // Piping Loss Algorithm Parameter: Heat loss [W] + Real64 OUEvapHeatExtract = 5110.40; // Evaporator heat extract [W] + Real64 Ncomp = 1058; // Compressor power [W] + Real64 CompSpdActual; // Actual compressor running speed [rps] + + // Run + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CalcCompH(*state, + TU_load, + T_suction, + T_discharge, + Pipe_h_out_ave, + IUMaxCondTemp, + MinOutdoorUnitTe, + Tfs, + Pipe_Q, + OUEvapHeatExtract, + CompSpdActual, + Ncomp); + + // Test + EXPECT_NEAR(5110, OUEvapHeatExtract, 1); + EXPECT_NEAR(1500, CompSpdActual, 1); + EXPECT_NEAR(2080, Ncomp, 1); + EXPECT_EQ(state->dataLoopNodes->Node(state->dataHVACVarRefFlow->VRFTU(1).VRFTUInletNodeNum).MassFlowRate, 0.0); + } } TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Coil) @@ -2632,163 +2632,165 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Coil) InitializePsychRoutines(*state); // Run and Check: VRFOU_Cap - { // Test the method VRFOU_Cap, which determines the VRF OU heat transfer rate, given refrigerant side temperature, - // i.e., condensing temperature and SC for condenser, or evaporating temperature and SH for evaporator. - {// a. Condenser - - // Inputs_condition - m_air = 3.6; - OutDryBulbTemp = 28; - OutHumRat = 0.0146; - SC = 1; - Tdischarge = 36; - - // Run - Q_h_OU = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_Cap(*state, HXOpMode::CondMode, Tdischarge, SC, m_air, OutDryBulbTemp, OutHumRat); - - // Test - EXPECT_NEAR(27551, Q_h_OU, 10); -} - -{ - // b. Evaporator - - // Inputs_condition - m_air = 3.6; - OutDryBulbTemp = 7; - OutHumRat = 0.0019; - SH = 1; - Tsuction = -3; - - // Run - Q_c_OU = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_Cap(*state, HXOpMode::EvapMode, Tsuction, SH, m_air, OutDryBulbTemp, OutHumRat); - - // Test - EXPECT_NEAR(24456, Q_c_OU, 10); -} -} // namespace EnergyPlus - -// Run and Check: VRFOU_FlowRate -{ // Test the method VRFOU_Cap, which calculates the outdoor unit fan flow rate, given VRF OU load and refrigerant side temperature, i.e., - // condensing temperature and SC for condenser, or evaporating temperature and SH for evaporator. - {// a. Condenser + { // Test the method VRFOU_Cap, which determines the VRF OU heat transfer rate, given refrigerant side temperature, + // i.e., condensing temperature and SC for condenser, or evaporating temperature and SH for evaporator. + { // a. Condenser + + // Inputs_condition + m_air = 3.6; + OutDryBulbTemp = 28; + OutHumRat = 0.0146; + SC = 1; + Tdischarge = 36; + + // Run + Q_h_OU = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_Cap(*state, HXOpMode::CondMode, Tdischarge, SC, m_air, OutDryBulbTemp, OutHumRat); + + // Test + EXPECT_NEAR(27551, Q_h_OU, 10); + } - // Inputs_condition - Q_h_OU = 27551; -OutDryBulbTemp = 28; -OutHumRat = 0.0146; -SC = 1; -Tdischarge = 36; + { + // b. Evaporator -// Run -m_air = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_FlowRate(*state, HXOpMode::CondMode, Tdischarge, SC, Q_h_OU, OutDryBulbTemp, OutHumRat); + // Inputs_condition + m_air = 3.6; + OutDryBulbTemp = 7; + OutHumRat = 0.0019; + SH = 1; + Tsuction = -3; -// Test -EXPECT_NEAR(3.6, m_air, 0.01); -} + // Run + Q_c_OU = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_Cap(*state, HXOpMode::EvapMode, Tsuction, SH, m_air, OutDryBulbTemp, OutHumRat); -{ - // b. Evaporator + // Test + EXPECT_NEAR(24456, Q_c_OU, 10); + } + } // namespace EnergyPlus + + // Run and Check: VRFOU_FlowRate + { // Test the method VRFOU_Cap, which calculates the outdoor unit fan flow rate, given VRF OU load and refrigerant side temperature, i.e., + // condensing temperature and SC for condenser, or evaporating temperature and SH for evaporator. + { // a. Condenser + + // Inputs_condition + Q_h_OU = 27551; + OutDryBulbTemp = 28; + OutHumRat = 0.0146; + SC = 1; + Tdischarge = 36; + + // Run + m_air = + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_FlowRate(*state, HXOpMode::CondMode, Tdischarge, SC, Q_h_OU, OutDryBulbTemp, OutHumRat); + + // Test + EXPECT_NEAR(3.6, m_air, 0.01); + } - // Inputs_condition - Q_c_OU = 24456; - OutDryBulbTemp = 7; - OutHumRat = 0.0019; - SH = 1; - Tsuction = -3; + { + // b. Evaporator - // Run - m_air = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_FlowRate(*state, HXOpMode::EvapMode, Tsuction, SH, Q_c_OU, OutDryBulbTemp, OutHumRat); + // Inputs_condition + Q_c_OU = 24456; + OutDryBulbTemp = 7; + OutHumRat = 0.0019; + SH = 1; + Tsuction = -3; - // Test - EXPECT_NEAR(3.6, m_air, 0.01); -} -} + // Run + m_air = + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_FlowRate(*state, HXOpMode::EvapMode, Tsuction, SH, Q_c_OU, OutDryBulbTemp, OutHumRat); -// Run and Check: VRFOU_TeTc -{ // Test the method VRFOU_Cap, which calculates the VRF OU refrigerant side temperature, i.e., condensing temperature - // at cooling mode, or evaporating temperature at heating mode, given the coil heat - // release/extract amount and air side parameters. - {// a. Condenser - - // Inputs_condition - m_air = 3.6; -Q_h_OU = 27551; -OutDryBulbTemp = 28; -OutHumRat = 0.0146; -SC = 1; - -// Run -state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_TeTc( - *state, HXOpMode::CondMode, Q_h_OU, SC, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress, temp, Tdischarge); - -// Test -EXPECT_NEAR(36, Tdischarge, 0.05); -} + // Test + EXPECT_NEAR(3.6, m_air, 0.01); + } + } -{ - // b. Evaporator - - // Inputs_condition - m_air = 3.6; - Q_c_OU = 24456; - OutDryBulbTemp = 7; - OutHumRat = 0.0019; - SH = 1; - Tsuction = -3; - - // Run - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_TeTc( - *state, HXOpMode::EvapMode, Q_c_OU, SH, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress, temp, Tsuction); - - // Test - EXPECT_NEAR(-3, Tsuction, 0.05); -} -} + // Run and Check: VRFOU_TeTc + { // Test the method VRFOU_Cap, which calculates the VRF OU refrigerant side temperature, i.e., condensing temperature + // at cooling mode, or evaporating temperature at heating mode, given the coil heat + // release/extract amount and air side parameters. + { // a. Condenser + + // Inputs_condition + m_air = 3.6; + Q_h_OU = 27551; + OutDryBulbTemp = 28; + OutHumRat = 0.0146; + SC = 1; + + // Run + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_TeTc( + *state, HXOpMode::CondMode, Q_h_OU, SC, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress, temp, Tdischarge); + + // Test + EXPECT_NEAR(36, Tdischarge, 0.05); + } -// Run and Check: VRFOU_SCSH -{ - // Test the method VRFOU_Cap, which calculates the VRF OU refrigerant side temperature, i.e., condensing temperature - // at cooling mode, or evaporating temperature at heating mode, given the coil heat - // release/extract amount and air side parameters. - { - // a. Condenser + { + // b. Evaporator - // Inputs_condition - m_air = 3.6; - Q_h_OU = 27551; - OutDryBulbTemp = 28; - OutHumRat = 0.0146; - Tdischarge = 36; + // Inputs_condition + m_air = 3.6; + Q_c_OU = 24456; + OutDryBulbTemp = 7; + OutHumRat = 0.0019; + SH = 1; + Tsuction = -3; - // Run - SC = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_SCSH( - *state, HXOpMode::CondMode, Q_h_OU, Tdischarge, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress); + // Run + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_TeTc( + *state, HXOpMode::EvapMode, Q_c_OU, SH, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress, temp, Tsuction); - // Test - EXPECT_NEAR(1, SC, 0.01); + // Test + EXPECT_NEAR(-3, Tsuction, 0.05); + } } + // Run and Check: VRFOU_SCSH { - // b. Evaporator + // Test the method VRFOU_Cap, which calculates the VRF OU refrigerant side temperature, i.e., condensing temperature + // at cooling mode, or evaporating temperature at heating mode, given the coil heat + // release/extract amount and air side parameters. + { + // a. Condenser + + // Inputs_condition + m_air = 3.6; + Q_h_OU = 27551; + OutDryBulbTemp = 28; + OutHumRat = 0.0146; + Tdischarge = 36; + + // Run + SC = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_SCSH( + *state, HXOpMode::CondMode, Q_h_OU, Tdischarge, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress); + + // Test + EXPECT_NEAR(1, SC, 0.01); + } - // Inputs_condition - m_air = 3.6; - Q_c_OU = 24456; - OutDryBulbTemp = 7; - OutHumRat = 0.0019; - Tsuction = -3; + { + // b. Evaporator - // Run - SH = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_SCSH( - *state, HXOpMode::EvapMode, Q_c_OU, Tsuction, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress); + // Inputs_condition + m_air = 3.6; + Q_c_OU = 24456; + OutDryBulbTemp = 7; + OutHumRat = 0.0019; + Tsuction = -3; - // Test - EXPECT_NEAR(1, SH, 0.01); + // Run + SH = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_SCSH( + *state, HXOpMode::EvapMode, Q_c_OU, Tsuction, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress); + + // Test + EXPECT_NEAR(1, SH, 0.01); + } } -} -// Clean up -state->dataHVACVarRefFlow->VRF.deallocate(); + // Clean up + state->dataHVACVarRefFlow->VRF.deallocate(); } TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_GetCoilInput) From 7d79eaca627af62fbe29b2acd5557fff8c3de7e3 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Mon, 26 Feb 2024 11:34:37 -0800 Subject: [PATCH 09/81] Move cycling ratio to inside compressor spd calc for heating after multiplying cycling ratio to the outdoor unit, some super large COP appeared in some timesteps. This is probably due to the cycling ratio calculation, moving it to inside the compressor speed calculation fixed this problem. --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 134 ++++++++---------- src/EnergyPlus/HVACVariableRefrigerantFlow.hh | 3 +- .../unit/HVACVariableRefrigerantFlow.unit.cc | 4 +- 3 files changed, 65 insertions(+), 76 deletions(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 8c17f4c469b..b3d786b84c0 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -11856,80 +11856,61 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) CapMinTe + 8, this->IUCondensingTemp - 5); - if ((Q_c_OU * C_cap_operation) <= CompEvaporatingCAPSpdMin) { - // Required heating load is smaller than the min heating capacity - - if (Q_c_OU == 0) { - // Q_h_TU_PL is less than or equal to CompEvaporatingPWRSpdMin - CyclingRatio = Q_h_TU_PL / CompEvaporatingPWRSpdMin; - this->EvaporatingTemp = OutdoorDryBulb; - } else { - // Q_h_TU_PL is greater than CompEvaporatingPWRSpdMin - CyclingRatio = Q_c_OU * C_cap_operation / CompEvaporatingCAPSpdMin; - this->EvaporatingTemp = max(CapMinTe, RefTLow); - } - - double CyclingRatioFrac = 0.85 + 0.15 * CyclingRatio; - double HPRTF = CyclingRatio / CyclingRatioFrac; - Ncomp = CompEvaporatingPWRSpdMin * HPRTF; - CompSpdActual = this->CompressorSpeed(1); - - } else { - // Required heating load is greater than or equal to the min heating capacity - - // Iteration_Ncomp: Perform iterations to calculate Ncomp (Label20) - Counter = 1; - Label20:; - Ncomp_new = Ncomp; - Q_c_OU = max(0.0, Q_h_TU_PL - Ncomp); - - // *VRF OU Te calculations - m_air = this->OUAirFlowRate * RhoAir; - SH_OU = this->SH; - this->VRFOU_TeTc( - state, HXOpMode::EvapMode, Q_c_OU, SH_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->EvaporatingTemp); - this->SH = SH_OU; - - // *VRF OU Compressor Simulation at heating mode: Specify the compressor speed and power consumption - this->VRFOU_CalcCompH(state, - TU_HeatingLoad, - this->EvaporatingTemp, - Tdischarge, - h_IU_cond_out_ave, - this->IUCondensingTemp, - CapMinTe, - Tfs, - Pipe_Q_h, - Q_c_OU, - CompSpdActual, - Ncomp_new); - - if ((std::abs(Ncomp_new - Ncomp) > (Tolerance * Ncomp)) && (Counter < 30)) { - Ncomp = Ncomp_new; - Counter = Counter + 1; - goto Label20; - } + // Required heating load is greater than or equal to the min heating capacity + + // Iteration_Ncomp: Perform iterations to calculate Ncomp (Label20) + Counter = 1; + Label20:; + Ncomp_new = Ncomp; + Q_c_OU = max(0.0, Q_h_TU_PL - Ncomp); + + // *VRF OU Te calculations + m_air = this->OUAirFlowRate * RhoAir; + SH_OU = this->SH; + this->VRFOU_TeTc(state, HXOpMode::EvapMode, Q_c_OU, SH_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->EvaporatingTemp); + this->SH = SH_OU; + + Real64 CyclingRatio = 1.0; + // *VRF OU Compressor Simulation at heating mode: Specify the compressor speed and power consumption + this->VRFOU_CalcCompH(state, + TU_HeatingLoad, + this->EvaporatingTemp, + Tdischarge, + h_IU_cond_out_ave, + this->IUCondensingTemp, + CapMinTe, + Tfs, + Pipe_Q_h, + Q_c_OU, + CompSpdActual, + Ncomp_new, + CyclingRatio); + + if ((std::abs(Ncomp_new - Ncomp) > (Tolerance * Ncomp)) && (Counter < 30)) { + Ncomp = Ncomp_new; + Counter = Counter + 1; + goto Label20; + } - // Update h_comp_out in iteration Label23 - P_comp_in = GetSatPressureRefrig(state, this->RefrigerantName, this->EvaporatingTemp, RefrigerantIndex, RoutineName); - RefTSat = GetSatTemperatureRefrig(state, this->RefrigerantName, max(min(P_comp_in, RefPHigh), RefPLow), RefrigerantIndex, RoutineName); - h_comp_in_new = GetSupHeatEnthalpyRefrig(state, - this->RefrigerantName, - max(RefTSat, this->SH + this->EvaporatingTemp), - max(min(P_comp_in, RefPHigh), RefPLow), - RefrigerantIndex, - RoutineName); - h_comp_out_new = Ncomp_new / m_ref_IU_cond + h_comp_in_new; + // Update h_comp_out in iteration Label23 + P_comp_in = GetSatPressureRefrig(state, this->RefrigerantName, this->EvaporatingTemp, RefrigerantIndex, RoutineName); + RefTSat = GetSatTemperatureRefrig(state, this->RefrigerantName, max(min(P_comp_in, RefPHigh), RefPLow), RefrigerantIndex, RoutineName); + h_comp_in_new = GetSupHeatEnthalpyRefrig(state, + this->RefrigerantName, + max(RefTSat, this->SH + this->EvaporatingTemp), + max(min(P_comp_in, RefPHigh), RefPLow), + RefrigerantIndex, + RoutineName); + h_comp_out_new = Ncomp_new / m_ref_IU_cond + h_comp_in_new; - if ((std::abs(h_comp_out - h_comp_out_new) > Tolerance * h_comp_out) && (h_IU_cond_in < h_IU_cond_in_up)) { - h_IU_cond_in = h_IU_cond_in + 0.1 * (h_IU_cond_in_up - h_IU_cond_in_low); - goto Label23; - } - if (h_IU_cond_in > h_IU_cond_in_up) { - h_IU_cond_in = 0.5 * (h_IU_cond_in_up + h_IU_cond_in_low); - } - Ncomp = Ncomp_new; + if ((std::abs(h_comp_out - h_comp_out_new) > Tolerance * h_comp_out) && (h_IU_cond_in < h_IU_cond_in_up)) { + h_IU_cond_in = h_IU_cond_in + 0.1 * (h_IU_cond_in_up - h_IU_cond_in_low); + goto Label23; } + if (h_IU_cond_in > h_IU_cond_in_up) { + h_IU_cond_in = 0.5 * (h_IU_cond_in_up + h_IU_cond_in_low); + } + Ncomp = Ncomp_new; // Key outputs of this subroutine this->CompActSpeed = max(CompSpdActual, 0.0); @@ -14487,7 +14468,8 @@ void VRFCondenserEquipment::VRFOU_CalcCompH( Real64 Pipe_Q, // Piping Loss Algorithm Parameter: Heat loss [W] Real64 &OUEvapHeatExtract, // Condenser heat release (cooling mode) [W] Real64 &CompSpdActual, // Actual compressor running speed [rps] - Real64 &Ncomp // Compressor power [W] + Real64 &Ncomp, // Compressor power [W] + Real64 &CyclingRatio // Compressor cycling ratio ) { @@ -14651,9 +14633,13 @@ void VRFCondenserEquipment::VRFOU_CalcCompH( NumIteCcap = NumIteCcap + 1; goto Label19; } - if (CapDiff > (Tolerance * Cap_Eva0)) NumIteCcap = 999; + if (CapDiff > (Tolerance * Cap_Eva0)) { + NumIteCcap = 999; + CyclingRatio = (TU_load + Pipe_Q) * C_cap_operation / Cap_Eva1; + } - Ncomp = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction); + Ncomp = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction) * CyclingRatio; + OUEvapHeatExtract = CompEvaporatingCAPSpd(1) * CyclingRatio; break; // EXIT DoName2 diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.hh b/src/EnergyPlus/HVACVariableRefrigerantFlow.hh index 4cd628289b2..4a0f0478ff0 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.hh +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.hh @@ -530,7 +530,8 @@ namespace HVACVariableRefrigerantFlow { Real64 Pipe_Q, // Piping Loss Algorithm Parameter: Heat loss [W] Real64 &OUEvapHeatExtract, // Condenser heat release (cooling mode) [W] Real64 &CompSpdActual, // Actual compressor running speed [rps] - Real64 &Ncomp // Compressor power [W] + Real64 &Ncomp, // Compressor power [W] + Real64 &CyclingRatio // Compressor cycling ratio ); void VRFHR_OU_HR_Mode(EnergyPlusData &state, diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index c6f2b82fc46..dfd5bcf9a05 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -2570,6 +2570,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Compressor) Real64 Ncomp = 1058; // Compressor power [W] Real64 CompSpdActual; // Actual compressor running speed [rps] + Real64 CyclingRatio = 1.0; // Run state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CalcCompH(*state, TU_load, @@ -2582,7 +2583,8 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Compressor) Pipe_Q, OUEvapHeatExtract, CompSpdActual, - Ncomp); + Ncomp, + CyclingRatio); // Test EXPECT_NEAR(5110, OUEvapHeatExtract, 1); From aee8c4a2512524aabc95bd119a98f7a9db1667e3 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Tue, 27 Feb 2024 16:14:28 -0800 Subject: [PATCH 10/81] Revert "Move cycling ratio to inside compressor spd calc for heating" This reverts commit 7d79eaca627af62fbe29b2acd5557fff8c3de7e3. --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 134 ++++++++++-------- src/EnergyPlus/HVACVariableRefrigerantFlow.hh | 3 +- .../unit/HVACVariableRefrigerantFlow.unit.cc | 4 +- 3 files changed, 76 insertions(+), 65 deletions(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index b3d786b84c0..8c17f4c469b 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -11856,61 +11856,80 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) CapMinTe + 8, this->IUCondensingTemp - 5); - // Required heating load is greater than or equal to the min heating capacity - - // Iteration_Ncomp: Perform iterations to calculate Ncomp (Label20) - Counter = 1; - Label20:; - Ncomp_new = Ncomp; - Q_c_OU = max(0.0, Q_h_TU_PL - Ncomp); - - // *VRF OU Te calculations - m_air = this->OUAirFlowRate * RhoAir; - SH_OU = this->SH; - this->VRFOU_TeTc(state, HXOpMode::EvapMode, Q_c_OU, SH_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->EvaporatingTemp); - this->SH = SH_OU; - - Real64 CyclingRatio = 1.0; - // *VRF OU Compressor Simulation at heating mode: Specify the compressor speed and power consumption - this->VRFOU_CalcCompH(state, - TU_HeatingLoad, - this->EvaporatingTemp, - Tdischarge, - h_IU_cond_out_ave, - this->IUCondensingTemp, - CapMinTe, - Tfs, - Pipe_Q_h, - Q_c_OU, - CompSpdActual, - Ncomp_new, - CyclingRatio); - - if ((std::abs(Ncomp_new - Ncomp) > (Tolerance * Ncomp)) && (Counter < 30)) { - Ncomp = Ncomp_new; - Counter = Counter + 1; - goto Label20; - } + if ((Q_c_OU * C_cap_operation) <= CompEvaporatingCAPSpdMin) { + // Required heating load is smaller than the min heating capacity - // Update h_comp_out in iteration Label23 - P_comp_in = GetSatPressureRefrig(state, this->RefrigerantName, this->EvaporatingTemp, RefrigerantIndex, RoutineName); - RefTSat = GetSatTemperatureRefrig(state, this->RefrigerantName, max(min(P_comp_in, RefPHigh), RefPLow), RefrigerantIndex, RoutineName); - h_comp_in_new = GetSupHeatEnthalpyRefrig(state, - this->RefrigerantName, - max(RefTSat, this->SH + this->EvaporatingTemp), - max(min(P_comp_in, RefPHigh), RefPLow), - RefrigerantIndex, - RoutineName); - h_comp_out_new = Ncomp_new / m_ref_IU_cond + h_comp_in_new; + if (Q_c_OU == 0) { + // Q_h_TU_PL is less than or equal to CompEvaporatingPWRSpdMin + CyclingRatio = Q_h_TU_PL / CompEvaporatingPWRSpdMin; + this->EvaporatingTemp = OutdoorDryBulb; + } else { + // Q_h_TU_PL is greater than CompEvaporatingPWRSpdMin + CyclingRatio = Q_c_OU * C_cap_operation / CompEvaporatingCAPSpdMin; + this->EvaporatingTemp = max(CapMinTe, RefTLow); + } - if ((std::abs(h_comp_out - h_comp_out_new) > Tolerance * h_comp_out) && (h_IU_cond_in < h_IU_cond_in_up)) { - h_IU_cond_in = h_IU_cond_in + 0.1 * (h_IU_cond_in_up - h_IU_cond_in_low); - goto Label23; - } - if (h_IU_cond_in > h_IU_cond_in_up) { - h_IU_cond_in = 0.5 * (h_IU_cond_in_up + h_IU_cond_in_low); + double CyclingRatioFrac = 0.85 + 0.15 * CyclingRatio; + double HPRTF = CyclingRatio / CyclingRatioFrac; + Ncomp = CompEvaporatingPWRSpdMin * HPRTF; + CompSpdActual = this->CompressorSpeed(1); + + } else { + // Required heating load is greater than or equal to the min heating capacity + + // Iteration_Ncomp: Perform iterations to calculate Ncomp (Label20) + Counter = 1; + Label20:; + Ncomp_new = Ncomp; + Q_c_OU = max(0.0, Q_h_TU_PL - Ncomp); + + // *VRF OU Te calculations + m_air = this->OUAirFlowRate * RhoAir; + SH_OU = this->SH; + this->VRFOU_TeTc( + state, HXOpMode::EvapMode, Q_c_OU, SH_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->EvaporatingTemp); + this->SH = SH_OU; + + // *VRF OU Compressor Simulation at heating mode: Specify the compressor speed and power consumption + this->VRFOU_CalcCompH(state, + TU_HeatingLoad, + this->EvaporatingTemp, + Tdischarge, + h_IU_cond_out_ave, + this->IUCondensingTemp, + CapMinTe, + Tfs, + Pipe_Q_h, + Q_c_OU, + CompSpdActual, + Ncomp_new); + + if ((std::abs(Ncomp_new - Ncomp) > (Tolerance * Ncomp)) && (Counter < 30)) { + Ncomp = Ncomp_new; + Counter = Counter + 1; + goto Label20; + } + + // Update h_comp_out in iteration Label23 + P_comp_in = GetSatPressureRefrig(state, this->RefrigerantName, this->EvaporatingTemp, RefrigerantIndex, RoutineName); + RefTSat = GetSatTemperatureRefrig(state, this->RefrigerantName, max(min(P_comp_in, RefPHigh), RefPLow), RefrigerantIndex, RoutineName); + h_comp_in_new = GetSupHeatEnthalpyRefrig(state, + this->RefrigerantName, + max(RefTSat, this->SH + this->EvaporatingTemp), + max(min(P_comp_in, RefPHigh), RefPLow), + RefrigerantIndex, + RoutineName); + h_comp_out_new = Ncomp_new / m_ref_IU_cond + h_comp_in_new; + + if ((std::abs(h_comp_out - h_comp_out_new) > Tolerance * h_comp_out) && (h_IU_cond_in < h_IU_cond_in_up)) { + h_IU_cond_in = h_IU_cond_in + 0.1 * (h_IU_cond_in_up - h_IU_cond_in_low); + goto Label23; + } + if (h_IU_cond_in > h_IU_cond_in_up) { + h_IU_cond_in = 0.5 * (h_IU_cond_in_up + h_IU_cond_in_low); + } + Ncomp = Ncomp_new; } - Ncomp = Ncomp_new; // Key outputs of this subroutine this->CompActSpeed = max(CompSpdActual, 0.0); @@ -14468,8 +14487,7 @@ void VRFCondenserEquipment::VRFOU_CalcCompH( Real64 Pipe_Q, // Piping Loss Algorithm Parameter: Heat loss [W] Real64 &OUEvapHeatExtract, // Condenser heat release (cooling mode) [W] Real64 &CompSpdActual, // Actual compressor running speed [rps] - Real64 &Ncomp, // Compressor power [W] - Real64 &CyclingRatio // Compressor cycling ratio + Real64 &Ncomp // Compressor power [W] ) { @@ -14633,13 +14651,9 @@ void VRFCondenserEquipment::VRFOU_CalcCompH( NumIteCcap = NumIteCcap + 1; goto Label19; } - if (CapDiff > (Tolerance * Cap_Eva0)) { - NumIteCcap = 999; - CyclingRatio = (TU_load + Pipe_Q) * C_cap_operation / Cap_Eva1; - } + if (CapDiff > (Tolerance * Cap_Eva0)) NumIteCcap = 999; - Ncomp = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction) * CyclingRatio; - OUEvapHeatExtract = CompEvaporatingCAPSpd(1) * CyclingRatio; + Ncomp = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction); break; // EXIT DoName2 diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.hh b/src/EnergyPlus/HVACVariableRefrigerantFlow.hh index 4a0f0478ff0..4cd628289b2 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.hh +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.hh @@ -530,8 +530,7 @@ namespace HVACVariableRefrigerantFlow { Real64 Pipe_Q, // Piping Loss Algorithm Parameter: Heat loss [W] Real64 &OUEvapHeatExtract, // Condenser heat release (cooling mode) [W] Real64 &CompSpdActual, // Actual compressor running speed [rps] - Real64 &Ncomp, // Compressor power [W] - Real64 &CyclingRatio // Compressor cycling ratio + Real64 &Ncomp // Compressor power [W] ); void VRFHR_OU_HR_Mode(EnergyPlusData &state, diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index dfd5bcf9a05..c6f2b82fc46 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -2570,7 +2570,6 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Compressor) Real64 Ncomp = 1058; // Compressor power [W] Real64 CompSpdActual; // Actual compressor running speed [rps] - Real64 CyclingRatio = 1.0; // Run state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CalcCompH(*state, TU_load, @@ -2583,8 +2582,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Compressor) Pipe_Q, OUEvapHeatExtract, CompSpdActual, - Ncomp, - CyclingRatio); + Ncomp); // Test EXPECT_NEAR(5110, OUEvapHeatExtract, 1); From 97349228502d8300d10345c019d2dbd9356db2b5 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 28 Feb 2024 16:13:09 -0800 Subject: [PATCH 11/81] move fan mult RTF to after OU update, as other branch updates RTF --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 8c17f4c469b..b1cad9c5de0 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -283,6 +283,29 @@ void SimulateVRF(EnergyPlusData &state, if (state.dataHVACVarRefFlow->VRF(VRFCondenser).CondenserType == DataHeatBalance::RefrigCondenserType::Water) UpdateVRFCondenser(state, VRFCondenser); } + if (state.dataHVACVarRefFlow->VRF(VRFCondenser).VRFAlgorithmType == AlgorithmType::FluidTCtrl) { + // consider cycling in fan calculation + for (int TUListNum = 1; TUListNum <= state.dataHVACVarRefFlow->NumVRFTULists; ++TUListNum) { + auto &thisTUList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum); + for (int TUNum = 1; TUNum <= thisTUList.NumTUInList; ++TUNum) { + int heatingCoilNum = state.dataHVACVarRefFlow->VRFTU(TUNum).HeatCoilIndex; + int coolingCoilNum = state.dataHVACVarRefFlow->VRFTU(TUNum).CoolCoilIndex; + auto &heatingCoil = state.dataDXCoils->DXCoil(heatingCoilNum); + auto &coolingCoil = state.dataDXCoils->DXCoil(coolingCoilNum); + int fanIndex = state.dataHVACVarRefFlow->VRFTU(TUNum).FanIndex; + // only deal with cooling for now. heating RTF might have some issue + // does Fan:SystemModel need adjustment as well? if so consider 0-indexing and it's in state.dataHVACFan->fanObjs vector + if (fanIndex > 0 && heatingCoil.HeatingCoilRuntimeFraction == 0.0) { // in cooling mode + // here coolingCoil.CoolingCoilRuntimeFraction equals state.dataHVACVarRefFlow->VRF(VRFCond).VRFCondCyclingRatio + // this is not the case for heating + auto &fan = state.dataFans->Fan(fanIndex); + fan.FanPower *= coolingCoil.CoolingCoilRuntimeFraction; + fan.FanEnergy = fan.FanPower * state.dataHVACGlobal->TimeStepSysSec; + fan.PowerLossToAir *= coolingCoil.CoolingCoilRuntimeFraction; + } + } + } + } } PlantComponent *VRFCondenserEquipment::factory(EnergyPlusData &state, std::string const &objectName) @@ -12481,27 +12504,6 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) this->ElecHeatingPower = 0; } this->VRFCondRTF = VRFRTF; - // consider cycling in fan calculation - for (int TUListNum = 1; TUListNum <= state.dataHVACVarRefFlow->NumVRFTULists; ++TUListNum) { - auto &thisTUList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum); - for (int TUNum = 1; TUNum <= thisTUList.NumTUInList; ++TUNum) { - int heatingCoilNum = state.dataHVACVarRefFlow->VRFTU(TUNum).HeatCoilIndex; - int coolingCoilNum = state.dataHVACVarRefFlow->VRFTU(TUNum).CoolCoilIndex; - auto &heatingCoil = state.dataDXCoils->DXCoil(heatingCoilNum); - auto &coolingCoil = state.dataDXCoils->DXCoil(coolingCoilNum); - int fanIndex = state.dataHVACVarRefFlow->VRFTU(TUNum).FanIndex; - // only deal with cooling for now. heating RTF might have some issue - // does Fan:SystemModel need adjustment as well? if so consider 0-indexing and it's in state.dataHVACFan->fanObjs vector - if (fanIndex > 0 && heatingCoil.HeatingCoilRuntimeFraction == 0.0) { // in cooling mode - // here coolingCoil.CoolingCoilRuntimeFraction equals state.dataHVACVarRefFlow->VRF(VRFCond).VRFCondCyclingRatio - // this is not the case for heating - auto &fan = state.dataFans->Fan(fanIndex); - fan.FanPower *= coolingCoil.CoolingCoilRuntimeFraction; - fan.FanEnergy = fan.FanPower * state.dataHVACGlobal->TimeStepSysSec; - fan.PowerLossToAir *= coolingCoil.CoolingCoilRuntimeFraction; - } - } - } // Calculate CrankCaseHeaterPower: VRF Heat Pump Crankcase Heater Electric Power [W] if (this->MaxOATCCHeater > OutdoorDryBulb) { From 740bd9274ed6e9d96de530ff8229b8a7069c77f6 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 6 Mar 2024 15:28:55 -0800 Subject: [PATCH 12/81] add test for OU fan power change --- tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index c6f2b82fc46..ab63d1169a7 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -13225,6 +13225,10 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_ReportOutputVerificationTest) EXPECT_NEAR(4999.8265, thisVRFTU.TotalCoolingRate, 0.0001); EXPECT_NEAR(125.2573 * thisDXCoolingCoil.CoolingCoilRuntimeFraction, thisFan.FanPower, 0.0001); EXPECT_NEAR(thisDXCoolingCoil.TotalCoolingEnergyRate, (thisVRFTU.TotalCoolingRate + thisFan.FanPower), 0.0001); + EXPECT_NEAR(0.8930, state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio, 0.0001); + EXPECT_NEAR(state->dataHVACVarRefFlow->VRF(1).OUFanPower, + state->dataHVACVarRefFlow->VRF(1).RatedOUFanPower * state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio, + 0.0001); } // Test for #7648: HREIRFTHeat wrongly used HRCAPFTHeatConst. Occurs only if you have Heat Recovery From 902baeac0014b622ffe8d7b26c1c93378ad9d12c Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Fri, 8 Mar 2024 11:45:18 -0800 Subject: [PATCH 13/81] clang-format --- .../unit/HVACVariableRefrigerantFlow.unit.cc | 468 +++++++++--------- 1 file changed, 233 insertions(+), 235 deletions(-) diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index ab63d1169a7..a8498472a93 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -2487,109 +2487,109 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Compressor) } // Run and Check: VRFOU_CompSpd - { // Test the method VRFOU_CompSpd, which calculates the compressor speed at given - // operational conditions to meet the evaporator or condenser capacity provided. + {// Test the method VRFOU_CompSpd, which calculates the compressor speed at given + // operational conditions to meet the evaporator or condenser capacity provided. - { // a. Evaporator + {// a. Evaporator - // Inputs_condition - Real64 constexpr Q_req = 6971; // Required capacity [W] - Real64 constexpr T_suction = -13.35; // Compressor suction temperature Te' [C] - Real64 constexpr T_discharge = 36.37; // Compressor discharge temperature Tc' [C] - Real64 constexpr h_IU_evap_in = 225016; // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg] - Real64 constexpr h_comp_in = 429529; // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg] - Real64 CompSpdActual; // Actual compressor running speed [rps] + // Inputs_condition + Real64 constexpr Q_req = 6971; // Required capacity [W] + Real64 constexpr T_suction = -13.35; // Compressor suction temperature Te' [C] + Real64 constexpr T_discharge = 36.37; // Compressor discharge temperature Tc' [C] + Real64 constexpr h_IU_evap_in = 225016; // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg] + Real64 constexpr h_comp_in = 429529; // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg] + Real64 CompSpdActual; // Actual compressor running speed [rps] - // Run - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompSpd( - *state, Q_req, HXOpMode::EvapMode, T_suction, T_discharge, h_IU_evap_in, h_comp_in, CompSpdActual); + // Run + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompSpd( + *state, Q_req, HXOpMode::EvapMode, T_suction, T_discharge, h_IU_evap_in, h_comp_in, CompSpdActual); - // Test - EXPECT_NEAR(1295, CompSpdActual, 5); - } - - { - // b. Condenser - - // Inputs_condition - Real64 constexpr Q_req = 6953; // Required capacity [W] - Real64 constexpr T_suction = -13.35; // Compressor suction temperature Te' [C] - Real64 constexpr T_discharge = 36.37; // Compressor discharge temperature Tc' [C] - Real64 constexpr h_IU_evap_in = 225016; // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg] - Real64 constexpr h_comp_in = 429529; // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg] - Real64 CompSpdActual; // Actual compressor running speed [rps] - - // Run - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompSpd( - *state, Q_req, HXOpMode::CondMode, T_suction, T_discharge, h_IU_evap_in, h_comp_in, CompSpdActual); - - // Test - EXPECT_NEAR(950, CompSpdActual, 5); - } - } // namespace EnergyPlus - - // Run and Check: VRFOU_CompCap - { - // Test the method VRFOU_CompCap, which calculates the compressor performance (power and capacity) - // at given compressor speed and operational conditions. - - // Inputs_condition - Real64 constexpr CompSpdActual = 1298; // Actual compressor running speed [rps] - Real64 constexpr T_suction = -13.35; // Compressor suction temperature Te' [C] - Real64 constexpr T_discharge = 36.37; // Compressor discharge temperature Tc' [C] - Real64 constexpr h_IU_evap_in = 225016; // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg] - Real64 constexpr h_comp_in = 429529; // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg] - Real64 Q_c_tot; // Compressor evaporative capacity [W] - Real64 Ncomp; // Compressor power [W] - - // Run - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompCap(*state, CompSpdActual, T_suction, T_discharge, h_IU_evap_in, h_comp_in, Q_c_tot, Ncomp); - - // Test - EXPECT_NEAR(6990, Q_c_tot, 10); - EXPECT_NEAR(1601, Ncomp, 10); - } - - // Run and Check: VRFOU_CalcComp - { - // Test the method VRFOU_CalcCompH, which simulates the compressor performance at given oprtaional conditions. More specifically, it - // sepcifies the compressor speed to provide sufficient evaporative capacity, and calculate the power of the compressor running at the - // specified speed. Note that it may be needed to manipulate the operational conditions to further adjust system capacity at low load - // conditions. The low load modification logics are different for cooling mode and heating mode. + // Test + EXPECT_NEAR(1295, CompSpdActual, 5); +} - // Inputs_condition - Real64 TU_load = 6006; // Indoor unit cooling load [W] - Real64 T_suction = 8.86; // Compressor suction temperature Te' [C] - Real64 T_discharge = 40.26; // Compressor discharge temperature Tc' [C] - Real64 Pipe_h_out_ave = 233428; // Average Enthalpy of the refrigerant leaving IUs [kJ/kg] - Real64 IUMaxCondTemp = 36; // VRV IU condensing temperature, max among all indoor units [C] - Real64 MinOutdoorUnitTe = -72; // The minimum temperature that OU Te can be at cooling mode (only used for calculating Min capacity) - Real64 Tfs = 10.90; // Temperature of the air at the OU evaporator coil surface [C]] - Real64 Pipe_Q = 162.67; // Piping Loss Algorithm Parameter: Heat loss [W] - Real64 OUEvapHeatExtract = 5110.40; // Evaporator heat extract [W] - Real64 Ncomp = 1058; // Compressor power [W] - Real64 CompSpdActual; // Actual compressor running speed [rps] +{ + // b. Condenser + + // Inputs_condition + Real64 constexpr Q_req = 6953; // Required capacity [W] + Real64 constexpr T_suction = -13.35; // Compressor suction temperature Te' [C] + Real64 constexpr T_discharge = 36.37; // Compressor discharge temperature Tc' [C] + Real64 constexpr h_IU_evap_in = 225016; // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg] + Real64 constexpr h_comp_in = 429529; // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg] + Real64 CompSpdActual; // Actual compressor running speed [rps] + + // Run + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompSpd( + *state, Q_req, HXOpMode::CondMode, T_suction, T_discharge, h_IU_evap_in, h_comp_in, CompSpdActual); + + // Test + EXPECT_NEAR(950, CompSpdActual, 5); +} +} // namespace EnergyPlus - // Run - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CalcCompH(*state, - TU_load, - T_suction, - T_discharge, - Pipe_h_out_ave, - IUMaxCondTemp, - MinOutdoorUnitTe, - Tfs, - Pipe_Q, - OUEvapHeatExtract, - CompSpdActual, - Ncomp); +// Run and Check: VRFOU_CompCap +{ + // Test the method VRFOU_CompCap, which calculates the compressor performance (power and capacity) + // at given compressor speed and operational conditions. + + // Inputs_condition + Real64 constexpr CompSpdActual = 1298; // Actual compressor running speed [rps] + Real64 constexpr T_suction = -13.35; // Compressor suction temperature Te' [C] + Real64 constexpr T_discharge = 36.37; // Compressor discharge temperature Tc' [C] + Real64 constexpr h_IU_evap_in = 225016; // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg] + Real64 constexpr h_comp_in = 429529; // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg] + Real64 Q_c_tot; // Compressor evaporative capacity [W] + Real64 Ncomp; // Compressor power [W] + + // Run + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompCap(*state, CompSpdActual, T_suction, T_discharge, h_IU_evap_in, h_comp_in, Q_c_tot, Ncomp); + + // Test + EXPECT_NEAR(6990, Q_c_tot, 10); + EXPECT_NEAR(1601, Ncomp, 10); +} - // Test - EXPECT_NEAR(5110, OUEvapHeatExtract, 1); - EXPECT_NEAR(1500, CompSpdActual, 1); - EXPECT_NEAR(2080, Ncomp, 1); - EXPECT_EQ(state->dataLoopNodes->Node(state->dataHVACVarRefFlow->VRFTU(1).VRFTUInletNodeNum).MassFlowRate, 0.0); - } +// Run and Check: VRFOU_CalcComp +{ + // Test the method VRFOU_CalcCompH, which simulates the compressor performance at given oprtaional conditions. More specifically, it + // sepcifies the compressor speed to provide sufficient evaporative capacity, and calculate the power of the compressor running at the + // specified speed. Note that it may be needed to manipulate the operational conditions to further adjust system capacity at low load + // conditions. The low load modification logics are different for cooling mode and heating mode. + + // Inputs_condition + Real64 TU_load = 6006; // Indoor unit cooling load [W] + Real64 T_suction = 8.86; // Compressor suction temperature Te' [C] + Real64 T_discharge = 40.26; // Compressor discharge temperature Tc' [C] + Real64 Pipe_h_out_ave = 233428; // Average Enthalpy of the refrigerant leaving IUs [kJ/kg] + Real64 IUMaxCondTemp = 36; // VRV IU condensing temperature, max among all indoor units [C] + Real64 MinOutdoorUnitTe = -72; // The minimum temperature that OU Te can be at cooling mode (only used for calculating Min capacity) + Real64 Tfs = 10.90; // Temperature of the air at the OU evaporator coil surface [C]] + Real64 Pipe_Q = 162.67; // Piping Loss Algorithm Parameter: Heat loss [W] + Real64 OUEvapHeatExtract = 5110.40; // Evaporator heat extract [W] + Real64 Ncomp = 1058; // Compressor power [W] + Real64 CompSpdActual; // Actual compressor running speed [rps] + + // Run + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CalcCompH(*state, + TU_load, + T_suction, + T_discharge, + Pipe_h_out_ave, + IUMaxCondTemp, + MinOutdoorUnitTe, + Tfs, + Pipe_Q, + OUEvapHeatExtract, + CompSpdActual, + Ncomp); + + // Test + EXPECT_NEAR(5110, OUEvapHeatExtract, 1); + EXPECT_NEAR(1500, CompSpdActual, 1); + EXPECT_NEAR(2080, Ncomp, 1); + EXPECT_EQ(state->dataLoopNodes->Node(state->dataHVACVarRefFlow->VRFTU(1).VRFTUInletNodeNum).MassFlowRate, 0.0); +} } TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Coil) @@ -2632,165 +2632,163 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Coil) InitializePsychRoutines(*state); // Run and Check: VRFOU_Cap - { // Test the method VRFOU_Cap, which determines the VRF OU heat transfer rate, given refrigerant side temperature, - // i.e., condensing temperature and SC for condenser, or evaporating temperature and SH for evaporator. - { // a. Condenser - - // Inputs_condition - m_air = 3.6; - OutDryBulbTemp = 28; - OutHumRat = 0.0146; - SC = 1; - Tdischarge = 36; - - // Run - Q_h_OU = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_Cap(*state, HXOpMode::CondMode, Tdischarge, SC, m_air, OutDryBulbTemp, OutHumRat); - - // Test - EXPECT_NEAR(27551, Q_h_OU, 10); - } + { // Test the method VRFOU_Cap, which determines the VRF OU heat transfer rate, given refrigerant side temperature, + // i.e., condensing temperature and SC for condenser, or evaporating temperature and SH for evaporator. + {// a. Condenser + + // Inputs_condition + m_air = 3.6; + OutDryBulbTemp = 28; + OutHumRat = 0.0146; + SC = 1; + Tdischarge = 36; + + // Run + Q_h_OU = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_Cap(*state, HXOpMode::CondMode, Tdischarge, SC, m_air, OutDryBulbTemp, OutHumRat); + + // Test + EXPECT_NEAR(27551, Q_h_OU, 10); +} - { - // b. Evaporator +{ + // b. Evaporator - // Inputs_condition - m_air = 3.6; - OutDryBulbTemp = 7; - OutHumRat = 0.0019; - SH = 1; - Tsuction = -3; + // Inputs_condition + m_air = 3.6; + OutDryBulbTemp = 7; + OutHumRat = 0.0019; + SH = 1; + Tsuction = -3; - // Run - Q_c_OU = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_Cap(*state, HXOpMode::EvapMode, Tsuction, SH, m_air, OutDryBulbTemp, OutHumRat); + // Run + Q_c_OU = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_Cap(*state, HXOpMode::EvapMode, Tsuction, SH, m_air, OutDryBulbTemp, OutHumRat); - // Test - EXPECT_NEAR(24456, Q_c_OU, 10); - } - } // namespace EnergyPlus - - // Run and Check: VRFOU_FlowRate - { // Test the method VRFOU_Cap, which calculates the outdoor unit fan flow rate, given VRF OU load and refrigerant side temperature, i.e., - // condensing temperature and SC for condenser, or evaporating temperature and SH for evaporator. - { // a. Condenser - - // Inputs_condition - Q_h_OU = 27551; - OutDryBulbTemp = 28; - OutHumRat = 0.0146; - SC = 1; - Tdischarge = 36; - - // Run - m_air = - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_FlowRate(*state, HXOpMode::CondMode, Tdischarge, SC, Q_h_OU, OutDryBulbTemp, OutHumRat); - - // Test - EXPECT_NEAR(3.6, m_air, 0.01); - } + // Test + EXPECT_NEAR(24456, Q_c_OU, 10); +} +} // namespace EnergyPlus - { - // b. Evaporator +// Run and Check: VRFOU_FlowRate +{ // Test the method VRFOU_Cap, which calculates the outdoor unit fan flow rate, given VRF OU load and refrigerant side temperature, i.e., + // condensing temperature and SC for condenser, or evaporating temperature and SH for evaporator. + {// a. Condenser - // Inputs_condition - Q_c_OU = 24456; - OutDryBulbTemp = 7; - OutHumRat = 0.0019; - SH = 1; - Tsuction = -3; + // Inputs_condition + Q_h_OU = 27551; +OutDryBulbTemp = 28; +OutHumRat = 0.0146; +SC = 1; +Tdischarge = 36; - // Run - m_air = - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_FlowRate(*state, HXOpMode::EvapMode, Tsuction, SH, Q_c_OU, OutDryBulbTemp, OutHumRat); +// Run +m_air = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_FlowRate(*state, HXOpMode::CondMode, Tdischarge, SC, Q_h_OU, OutDryBulbTemp, OutHumRat); - // Test - EXPECT_NEAR(3.6, m_air, 0.01); - } - } +// Test +EXPECT_NEAR(3.6, m_air, 0.01); +} - // Run and Check: VRFOU_TeTc - { // Test the method VRFOU_Cap, which calculates the VRF OU refrigerant side temperature, i.e., condensing temperature - // at cooling mode, or evaporating temperature at heating mode, given the coil heat - // release/extract amount and air side parameters. - { // a. Condenser - - // Inputs_condition - m_air = 3.6; - Q_h_OU = 27551; - OutDryBulbTemp = 28; - OutHumRat = 0.0146; - SC = 1; - - // Run - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_TeTc( - *state, HXOpMode::CondMode, Q_h_OU, SC, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress, temp, Tdischarge); - - // Test - EXPECT_NEAR(36, Tdischarge, 0.05); - } +{ + // b. Evaporator - { - // b. Evaporator + // Inputs_condition + Q_c_OU = 24456; + OutDryBulbTemp = 7; + OutHumRat = 0.0019; + SH = 1; + Tsuction = -3; - // Inputs_condition - m_air = 3.6; - Q_c_OU = 24456; - OutDryBulbTemp = 7; - OutHumRat = 0.0019; - SH = 1; - Tsuction = -3; + // Run + m_air = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_FlowRate(*state, HXOpMode::EvapMode, Tsuction, SH, Q_c_OU, OutDryBulbTemp, OutHumRat); + + // Test + EXPECT_NEAR(3.6, m_air, 0.01); +} +} - // Run - state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_TeTc( - *state, HXOpMode::EvapMode, Q_c_OU, SH, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress, temp, Tsuction); +// Run and Check: VRFOU_TeTc +{ // Test the method VRFOU_Cap, which calculates the VRF OU refrigerant side temperature, i.e., condensing temperature + // at cooling mode, or evaporating temperature at heating mode, given the coil heat + // release/extract amount and air side parameters. + {// a. Condenser + + // Inputs_condition + m_air = 3.6; +Q_h_OU = 27551; +OutDryBulbTemp = 28; +OutHumRat = 0.0146; +SC = 1; + +// Run +state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_TeTc( + *state, HXOpMode::CondMode, Q_h_OU, SC, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress, temp, Tdischarge); + +// Test +EXPECT_NEAR(36, Tdischarge, 0.05); +} - // Test - EXPECT_NEAR(-3, Tsuction, 0.05); - } - } +{ + // b. Evaporator + + // Inputs_condition + m_air = 3.6; + Q_c_OU = 24456; + OutDryBulbTemp = 7; + OutHumRat = 0.0019; + SH = 1; + Tsuction = -3; + + // Run + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_TeTc( + *state, HXOpMode::EvapMode, Q_c_OU, SH, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress, temp, Tsuction); + + // Test + EXPECT_NEAR(-3, Tsuction, 0.05); +} +} - // Run and Check: VRFOU_SCSH +// Run and Check: VRFOU_SCSH +{ + // Test the method VRFOU_Cap, which calculates the VRF OU refrigerant side temperature, i.e., condensing temperature + // at cooling mode, or evaporating temperature at heating mode, given the coil heat + // release/extract amount and air side parameters. { - // Test the method VRFOU_Cap, which calculates the VRF OU refrigerant side temperature, i.e., condensing temperature - // at cooling mode, or evaporating temperature at heating mode, given the coil heat - // release/extract amount and air side parameters. - { - // a. Condenser - - // Inputs_condition - m_air = 3.6; - Q_h_OU = 27551; - OutDryBulbTemp = 28; - OutHumRat = 0.0146; - Tdischarge = 36; - - // Run - SC = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_SCSH( - *state, HXOpMode::CondMode, Q_h_OU, Tdischarge, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress); - - // Test - EXPECT_NEAR(1, SC, 0.01); - } + // a. Condenser + + // Inputs_condition + m_air = 3.6; + Q_h_OU = 27551; + OutDryBulbTemp = 28; + OutHumRat = 0.0146; + Tdischarge = 36; - { - // b. Evaporator + // Run + SC = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_SCSH( + *state, HXOpMode::CondMode, Q_h_OU, Tdischarge, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress); - // Inputs_condition - m_air = 3.6; - Q_c_OU = 24456; - OutDryBulbTemp = 7; - OutHumRat = 0.0019; - Tsuction = -3; + // Test + EXPECT_NEAR(1, SC, 0.01); + } - // Run - SH = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_SCSH( - *state, HXOpMode::EvapMode, Q_c_OU, Tsuction, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress); + { + // b. Evaporator - // Test - EXPECT_NEAR(1, SH, 0.01); - } + // Inputs_condition + m_air = 3.6; + Q_c_OU = 24456; + OutDryBulbTemp = 7; + OutHumRat = 0.0019; + Tsuction = -3; + + // Run + SH = state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_SCSH( + *state, HXOpMode::EvapMode, Q_c_OU, Tsuction, m_air, OutDryBulbTemp, OutHumRat, OutBaroPress); + + // Test + EXPECT_NEAR(1, SH, 0.01); } - // Clean up - state->dataHVACVarRefFlow->VRF.deallocate(); +} +// Clean up +state->dataHVACVarRefFlow->VRF.deallocate(); } TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_GetCoilInput) From c4c306708224a2f51d142eaf032425cd20cd2474 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Fri, 10 May 2024 18:11:43 -0700 Subject: [PATCH 14/81] Use OnOffFanPartLoadFraction to control fan power response to this comment https://github.com/NREL/EnergyPlus/pull/10341#discussion_r1586858043 accumulated coil runtime fraction to the OnOffFanPartLoadFraction variable and accessed in SimVariableVolumeFan Not sure if it's good, might affect other models. --- src/EnergyPlus/DXCoils.cc | 2 +- src/EnergyPlus/Fans.cc | 1 + src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 23 ------------------- 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/EnergyPlus/DXCoils.cc b/src/EnergyPlus/DXCoils.cc index e8170e723bb..a4cb24464a8 100644 --- a/src/EnergyPlus/DXCoils.cc +++ b/src/EnergyPlus/DXCoils.cc @@ -16932,7 +16932,7 @@ void CalcVRFCoolingCoil_FluidTCtrl(EnergyPlusData &state, } // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals - if (FanOpMode == CycFanCycCoil) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF; + if (FanOpMode == CycFanCycCoil) state.dataHVACGlobal->OnOffFanPartLoadFraction = thisDXCoil.CoolingCoilRuntimeFraction; // Check for saturation error and modify temperature at constant enthalpy if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) { diff --git a/src/EnergyPlus/Fans.cc b/src/EnergyPlus/Fans.cc index 6c86e82c2af..4b9c22ba014 100644 --- a/src/EnergyPlus/Fans.cc +++ b/src/EnergyPlus/Fans.cc @@ -1773,6 +1773,7 @@ void SimVariableVolumeFan(EnergyPlusData &state, int const FanNum, ObjexxFCL::Op fan.MassFlowRateMaxAvail = 0.0; fan.MassFlowRateMinAvail = 0.0; } + fan.FanPower *= state.dataHVACGlobal->OnOffFanPartLoadFraction; } void SimOnOffFan(EnergyPlusData &state, int const FanNum, ObjexxFCL::Optional SpeedRatio) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index b1cad9c5de0..e33e2531001 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -283,29 +283,6 @@ void SimulateVRF(EnergyPlusData &state, if (state.dataHVACVarRefFlow->VRF(VRFCondenser).CondenserType == DataHeatBalance::RefrigCondenserType::Water) UpdateVRFCondenser(state, VRFCondenser); } - if (state.dataHVACVarRefFlow->VRF(VRFCondenser).VRFAlgorithmType == AlgorithmType::FluidTCtrl) { - // consider cycling in fan calculation - for (int TUListNum = 1; TUListNum <= state.dataHVACVarRefFlow->NumVRFTULists; ++TUListNum) { - auto &thisTUList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum); - for (int TUNum = 1; TUNum <= thisTUList.NumTUInList; ++TUNum) { - int heatingCoilNum = state.dataHVACVarRefFlow->VRFTU(TUNum).HeatCoilIndex; - int coolingCoilNum = state.dataHVACVarRefFlow->VRFTU(TUNum).CoolCoilIndex; - auto &heatingCoil = state.dataDXCoils->DXCoil(heatingCoilNum); - auto &coolingCoil = state.dataDXCoils->DXCoil(coolingCoilNum); - int fanIndex = state.dataHVACVarRefFlow->VRFTU(TUNum).FanIndex; - // only deal with cooling for now. heating RTF might have some issue - // does Fan:SystemModel need adjustment as well? if so consider 0-indexing and it's in state.dataHVACFan->fanObjs vector - if (fanIndex > 0 && heatingCoil.HeatingCoilRuntimeFraction == 0.0) { // in cooling mode - // here coolingCoil.CoolingCoilRuntimeFraction equals state.dataHVACVarRefFlow->VRF(VRFCond).VRFCondCyclingRatio - // this is not the case for heating - auto &fan = state.dataFans->Fan(fanIndex); - fan.FanPower *= coolingCoil.CoolingCoilRuntimeFraction; - fan.FanEnergy = fan.FanPower * state.dataHVACGlobal->TimeStepSysSec; - fan.PowerLossToAir *= coolingCoil.CoolingCoilRuntimeFraction; - } - } - } - } } PlantComponent *VRFCondenserEquipment::factory(EnergyPlusData &state, std::string const &objectName) From 154343d15f1d23ee6693bdf6b89222c354cb8dec Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Mon, 13 May 2024 09:51:32 -0700 Subject: [PATCH 15/81] resolve merge conflict --- src/EnergyPlus/Fans.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/EnergyPlus/Fans.cc b/src/EnergyPlus/Fans.cc index 6df784cc36b..2db5a325677 100644 --- a/src/EnergyPlus/Fans.cc +++ b/src/EnergyPlus/Fans.cc @@ -1866,7 +1866,6 @@ void FanComponent::simulateVAV(EnergyPlusData &state, ObjexxFCL::OptionalOnOffFanPartLoadFraction; -} } // FanComponent::SimVAV() void FanComponent::simulateOnOff(EnergyPlusData &state, ObjexxFCL::Optional _speedRatio) From cf886aa43523f04d29d21ef7e1dcbaa72f88950b Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 22 May 2024 13:51:53 -0700 Subject: [PATCH 16/81] move fan power mod out of SimulateVAV resolving regression diffs --- src/EnergyPlus/Fans.cc | 1 - src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/EnergyPlus/Fans.cc b/src/EnergyPlus/Fans.cc index 2db5a325677..39b2e5a5040 100644 --- a/src/EnergyPlus/Fans.cc +++ b/src/EnergyPlus/Fans.cc @@ -1865,7 +1865,6 @@ void FanComponent::simulateVAV(EnergyPlusData &state, ObjexxFCL::OptionalOnOffFanPartLoadFraction; } // FanComponent::SimVAV() void FanComponent::simulateOnOff(EnergyPlusData &state, ObjexxFCL::Optional _speedRatio) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index ed63ece2202..457b5c767dd 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -12841,6 +12841,10 @@ void VRFTerminalUnitEquipment::CalcVRF_FluidTCtrl(EnergyPlusData &state, } } + if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OpMode == HVAC::CycFanCycCoil && + state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::VAV) { + state.dataFans->fans(this->FanIndex)->totalPower *= state.dataHVACGlobal->OnOffFanPartLoadFraction; + } // track fan power per terminal unit for calculating COP this->FanPower = state.dataFans->fans(this->FanIndex)->totalPower; From aef9b67a9e13566756946fc590596ae0c627fa03 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 22 May 2024 14:23:22 -0700 Subject: [PATCH 17/81] resolve unit test by init compressor cycling ratio now the compressor cycling ratio is needed in the calculation as it affects the OnOffFanPartLoadFraction value, which affects fan power --- tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index 8961567353e..ad1eaded23a 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -18155,6 +18155,9 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_SupplementalHtgCoilTest) GetVRFInput(*state); state->dataHVACVarRefFlow->GetVRFInputFlag = false; + state->dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; + state->dataHVACVarRefFlow->VRF(VRFCond).VRFCondCyclingRatio = 1.0; + state->dataScheduleMgr->Schedule(state->dataHVACVarRefFlow->VRF(VRFCond).SchedPtr).CurrentValue = 1.0; VRFTUNum = zone_num_TU1; state->dataScheduleMgr->Schedule(state->dataHVACVarRefFlow->VRFTU(VRFTUNum).SchedPtr).CurrentValue = 1.0; @@ -20268,6 +20271,9 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_offSupplementalHtgCoilTest) GetVRFInput(*state); state->dataHVACVarRefFlow->GetVRFInputFlag = false; + state->dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; + state->dataHVACVarRefFlow->VRF(VRFCond).VRFCondCyclingRatio = 1.0; + state->dataScheduleMgr->Schedule(state->dataHVACVarRefFlow->VRF(VRFCond).SchedPtr).CurrentValue = 1.0; VRFTUNum = zone_num_TU1; state->dataScheduleMgr->Schedule(state->dataHVACVarRefFlow->VRFTU(VRFTUNum).SchedPtr).CurrentValue = 1.0; From 26414a6f897d99351d7718b3d44a49cadfbfb148 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 29 May 2024 18:06:40 -0700 Subject: [PATCH 18/81] resolve build error from merge --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 577724b440c..fcb718818ef 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -12852,7 +12852,7 @@ void VRFTerminalUnitEquipment::CalcVRF_FluidTCtrl(EnergyPlusData &state, } } - if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OpMode == HVAC::CycFanCycCoil && + if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Cycling && state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::VAV) { state.dataFans->fans(this->FanIndex)->totalPower *= state.dataHVACGlobal->OnOffFanPartLoadFraction; } From 9de83a18a2dc02f4b9a180a76a45fd3f5dda19bd Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 12 Jun 2024 14:20:42 -0700 Subject: [PATCH 19/81] use optional arg in SimulateVAV to control for cycling --- src/EnergyPlus/Fans.cc | 8 +++++-- src/EnergyPlus/Fans.hh | 22 +++++++++++-------- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 11 +++++----- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/EnergyPlus/Fans.cc b/src/EnergyPlus/Fans.cc index 948c3084e3a..c5972d085a8 100644 --- a/src/EnergyPlus/Fans.cc +++ b/src/EnergyPlus/Fans.cc @@ -103,6 +103,7 @@ void FanBase::simulate(EnergyPlusData &state, // the legacy speed ratio that was used with SimulateFanComponents. ObjexxFCL::Optional _pressureRise, // Pressure difference to use for DeltaPress, for rating DX coils at a ObjexxFCL::Optional _flowFraction, // when used, this directs the fan to set the flow at this flow fraction + ObjexxFCL::Optional _onOffFanPartLoadFraction, // to control for cycling in VAV fan in VRFFluidTCtrl // different pressure without entire duct system ObjexxFCL::Optional _massFlowRate1, // Mass flow rate in operating mode 1 [kg/s] ObjexxFCL::Optional _runTimeFraction1, // Run time fraction in operating mode 1 @@ -138,7 +139,7 @@ void FanBase::simulate(EnergyPlusData &state, _thisFan->simulateConstant(state); } break; case HVAC::FanType::VAV: { - _thisFan->simulateVAV(state, _pressureRise); + _thisFan->simulateVAV(state, _pressureRise, _onOffFanPartLoadFraction); } break; case HVAC::FanType::OnOff: { _thisFan->simulateOnOff(state, _speedRatio); @@ -1700,7 +1701,9 @@ void FanComponent::simulateConstant(EnergyPlusData &state) } } // FanComponent::simulateConstant -void FanComponent::simulateVAV(EnergyPlusData &state, ObjexxFCL::Optional _pressureRise) +void FanComponent::simulateVAV(EnergyPlusData &state, + ObjexxFCL::Optional _pressureRise, + ObjexxFCL::Optional _onOffFanPartLoadFraction) { // SUBROUTINE INFORMATION: @@ -1866,6 +1869,7 @@ void FanComponent::simulateVAV(EnergyPlusData &state, ObjexxFCL::Optional _speedRatio) diff --git a/src/EnergyPlus/Fans.hh b/src/EnergyPlus/Fans.hh index 9c47a241c84..fb4de15706a 100644 --- a/src/EnergyPlus/Fans.hh +++ b/src/EnergyPlus/Fans.hh @@ -97,14 +97,15 @@ namespace Fans { virtual void init(EnergyPlusData &state) = 0; virtual void simulate(EnergyPlusData &state, bool const FirstHVACIteration, - ObjexxFCL::Optional speedRatio = _, // Flow fraction in operating mode 1 - ObjexxFCL::Optional pressureRise = _, // Pressure difference to use for DeltaPress - ObjexxFCL::Optional flowFraction = _, // Flow fraction in operating mode 1 - ObjexxFCL::Optional massFlowRate1 = _, // Mass flow rate in operating mode 1 [kg/s] - ObjexxFCL::Optional runTimeFraction1 = _, // Run time fraction in operating mode 1 - ObjexxFCL::Optional massFlowRate2 = _, // Mass flow rate in operating mode 2 [kg/s] - ObjexxFCL::Optional runTimeFraction2 = _, // Run time fraction in operating mode 2 - ObjexxFCL::Optional pressureRise2 = _ // Pressure difference to use for operating mode 2 + ObjexxFCL::Optional speedRatio = _, // Flow fraction in operating mode 1 + ObjexxFCL::Optional pressureRise = _, // Pressure difference to use for DeltaPress + ObjexxFCL::Optional flowFraction = _, // Flow fraction in operating mode 1 + ObjexxFCL::Optional onOffFanPartLoadFraction = 1.0, // to control for cycling in VAV fan in VRFFluidTCtrl + ObjexxFCL::Optional massFlowRate1 = _, // Mass flow rate in operating mode 1 [kg/s] + ObjexxFCL::Optional runTimeFraction1 = _, // Run time fraction in operating mode 1 + ObjexxFCL::Optional massFlowRate2 = _, // Mass flow rate in operating mode 2 [kg/s] + ObjexxFCL::Optional runTimeFraction2 = _, // Run time fraction in operating mode 2 + ObjexxFCL::Optional pressureRise2 = _ // Pressure difference to use for operating mode 2 ); virtual void update(EnergyPlusData &state) = 0; @@ -226,7 +227,10 @@ namespace Fans { void simulateConstant(EnergyPlusData &state); - void simulateVAV(EnergyPlusData &state, ObjexxFCL::Optional PressureRise = _); + void simulateVAV(EnergyPlusData &state, + ObjexxFCL::Optional PressureRise = _, + // to control for cycling in VAV fan in VRFFluidTCtrl + ObjexxFCL::Optional OnOffFanPartLoadFraction = 1.0); void simulateOnOff(EnergyPlusData &state, ObjexxFCL::Optional SpeedRatio = _); diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index fcb718818ef..47d251dd90f 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -12838,6 +12838,11 @@ void VRFTerminalUnitEquipment::CalcVRF_FluidTCtrl(EnergyPlusData &state, state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = 0.0; } + Real64 OnOffFanPartLoadFraction = 1.0; + if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Cycling && + state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::VAV) { + OnOffFanPartLoadFraction = state.dataHVACGlobal->OnOffFanPartLoadFraction; + } // if draw through, simulate coils then fan if (this->fanPlace == HVAC::FanPlace::DrawThru) { auto *fan = state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex); @@ -12848,14 +12853,10 @@ void VRFTerminalUnitEquipment::CalcVRF_FluidTCtrl(EnergyPlusData &state, fan->simulate(state, FirstHVACIteration, _, _, PartLoadRatio); } } else { - fan->simulate(state, FirstHVACIteration, state.dataHVACVarRefFlow->FanSpeedRatio); + fan->simulate(state, FirstHVACIteration, state.dataHVACVarRefFlow->FanSpeedRatio, _, _, OnOffFanPartLoadFraction); } } - if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Cycling && - state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::VAV) { - state.dataFans->fans(this->FanIndex)->totalPower *= state.dataHVACGlobal->OnOffFanPartLoadFraction; - } // track fan power per terminal unit for calculating COP this->FanPower = state.dataFans->fans(this->FanIndex)->totalPower; From 5bb21f0b853489ac315df1d16d35666107a9ea6d Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Thu, 13 Jun 2024 10:16:15 -0700 Subject: [PATCH 20/81] fix unit and integration tests from optional arg addition --- src/EnergyPlus/Fans.cc | 4 +++- tst/EnergyPlus/unit/HVACFan.unit.cc | 30 ++++++++++++++--------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/EnergyPlus/Fans.cc b/src/EnergyPlus/Fans.cc index c5972d085a8..bc337c1cb8e 100644 --- a/src/EnergyPlus/Fans.cc +++ b/src/EnergyPlus/Fans.cc @@ -1869,7 +1869,9 @@ void FanComponent::simulateVAV(EnergyPlusData &state, massFlowRateMaxAvail = 0.0; massFlowRateMinAvail = 0.0; } - totalPower *= _onOffFanPartLoadFraction; + if (present(_onOffFanPartLoadFraction)) { + totalPower *= _onOffFanPartLoadFraction; + } } // FanComponent::SimVAV() void FanComponent::simulateOnOff(EnergyPlusData &state, ObjexxFCL::Optional _speedRatio) diff --git a/tst/EnergyPlus/unit/HVACFan.unit.cc b/tst/EnergyPlus/unit/HVACFan.unit.cc index 2e485829db9..8f4fa6c1fb3 100644 --- a/tst/EnergyPlus/unit/HVACFan.unit.cc +++ b/tst/EnergyPlus/unit/HVACFan.unit.cc @@ -345,7 +345,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc3) Real64 massFlow2 = designMassFlowRate; Real64 runTimeFrac1 = 0.5; Real64 runTimeFrac2 = 0.5; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); Real64 locFanElecPower = fanSystem->totalPower; Real64 locExpectPower = (runTimeFrac1 * 0.125 * 100.0) + (runTimeFrac2 * 1.0 * 100.0); EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -355,7 +355,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc3) massFlow2 = 0.75 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 1.0; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; // locExpectPower expect the same power as the previous case EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -365,7 +365,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc3) massFlow2 = 1.0 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 1.0; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; locExpectPower = fanSystem->designElecPower; // expect full power EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -375,13 +375,13 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc3) massFlow2 = 1.0 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 0.85; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; locExpectPower = 0.85 * fanSystem->designElecPower; // expect 85% of full power EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); // reverse the 1 and 2 arguments, expect the same result - fanSystem->simulate(*state, false, _, _, _, massFlow2, runTimeFrac2, massFlow1, runTimeFrac1); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow2, runTimeFrac2, massFlow1, runTimeFrac1); locFanElecPower = fanSystem->totalPower; EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); } @@ -445,7 +445,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc4) Real64 massFlow2 = designMassFlowRate; Real64 runTimeFrac1 = 0.5; Real64 runTimeFrac2 = 0.5; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); Real64 locFanElecPower = fanSystem->totalPower; Real64 locExpectPower = (0.5 * pow(0.5, 3) + 0.5 * 1.0) * fanSystem->designElecPower; EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -455,7 +455,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc4) massFlow2 = 0.75 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 1.0; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; locExpectPower = pow(0.75, 3) * fanSystem->designElecPower; EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -465,7 +465,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc4) massFlow2 = 1.0 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 1.0; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; locExpectPower = fanSystem->designElecPower; // expect full power EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -475,7 +475,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc4) massFlow2 = 1.0 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 0.85; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; locExpectPower = 0.85 * fanSystem->designElecPower; // expect 85% of full power EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -536,7 +536,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_DiscreteMode_noPowerFFlowCurve) Real64 massFlow2 = designMassFlowRate; Real64 runTimeFrac1 = 0.5; Real64 runTimeFrac2 = 0.5; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); Real64 locFanElecPower = fanSystem->totalPower; // uses flow weighted power calculation. 50% of time at 50% flow and 50% of time at 100% flow Real64 locExpectPower = (0.5 * 0.5 + 0.5 * 1.0) * fanSystem->designElecPower; // expect 75% of power @@ -547,7 +547,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_DiscreteMode_noPowerFFlowCurve) massFlow2 = 0.75 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 1.0; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; // uses flow weighted power calculation. 0% of time at 0% flow and 100% of time at 75% flow locExpectPower = (0.0 * 0.0 + 1.0 * 0.75) * fanSystem->designElecPower; // expect 75% of power @@ -558,7 +558,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_DiscreteMode_noPowerFFlowCurve) massFlow2 = 1.0 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 1.0; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; // uses flow weighted power calculation. 0% of time at 0% flow and 100% of time at 100% flow locExpectPower = (0.0 * 0.0 + 1.0 * 1.0) * fanSystem->designElecPower; // expect full power @@ -569,7 +569,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_DiscreteMode_noPowerFFlowCurve) massFlow2 = 1.0 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 0.85; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; // uses flow weighted power calculation. 0% of time at 0% flow and 85% of time at 100% flow locExpectPower = (0.0 * 0.25 + 0.85 * 1.0) * fanSystem->designElecPower; // expect 85% of full power @@ -642,7 +642,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_DiscreteMode_EMSPressureRiseResetTest) Real64 massFlow2 = designMassFlowRate; Real64 runTimeFrac1 = 0.5; Real64 runTimeFrac2 = 0.5; - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); Real64 locFanElecPower = fanSystem->totalPower; // uses flow weighted power calculation. 50% of time at 50% flow and 50% of time at 100% flow Real64 locExpectPower = (0.5 * 0.5 + 0.5 * 1.0) * fanSystem->designElecPower; // expect 75% of power @@ -654,7 +654,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_DiscreteMode_EMSPressureRiseResetTest) EMSManager::ManageEMS(*state, EMSManager::EMSCallFrom::BeginTimestepBeforePredictor, anyRan, ObjexxFCL::Optional_int_const()); EXPECT_TRUE(anyRan); // simulate the fan with -100.0 Pa fan pressure rise - fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; // negative fan pressure rise results in zero fan power locExpectPower = 0.0; From 8338dcb66d42d37bab9e55a36ffb02a78f0b2825 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Mon, 17 Jun 2024 15:26:37 -0500 Subject: [PATCH 21/81] Space IV-Initial NFP --- .../FY2024/NFP-Space Sizing and HVAC-Part4.md | 191 ++++++++++++++++++ design/FY2024/SpaceHVACSchematic.png | Bin 0 -> 36414 bytes 2 files changed, 191 insertions(+) create mode 100644 design/FY2024/NFP-Space Sizing and HVAC-Part4.md create mode 100644 design/FY2024/SpaceHVACSchematic.png diff --git a/design/FY2024/NFP-Space Sizing and HVAC-Part4.md b/design/FY2024/NFP-Space Sizing and HVAC-Part4.md new file mode 100644 index 00000000000..5f6aef92e27 --- /dev/null +++ b/design/FY2024/NFP-Space Sizing and HVAC-Part4.md @@ -0,0 +1,191 @@ +Extend Spaces to Sizing and HVAC - Part 4 +================ + +**Michael J. Witte, GARD Analytics, Inc.** + + - Original June 17, 2024 + +## Table of Contents ## + +[E-mail and Conference Call Conclusions](#e-mail-and-conference-call-conclusions) + +[Background and Overiew](#background-and-overview) + +[Approach](#approach) + +[Testing/Validation/Data Sources](#testingvalidationdata-sources) + +[Input Description](#input-description) + +[Outputs Description](#outputs-description) + +[Engineering Reference](#engineering-reference) + +[Example File and Transition Changes](#example-file-and-transition-changes) + +[Design](#design) + +## E-mail and Conference Call Conclusions ## + + +## Background and Overview ## + +Space was added as a new concept in v9.6. Each EnergyPlus Zone contains one or more Spaces which are used for: + + * assigning and allocating internal gains + * specifying enclosure boundaries, + * reporting inputs grouped by space types, and + * reporting select output grouped by space types. + +For the zone heat balance each thermal Zone is composed of one or more Spaces controlled by a single thermostat or HVAC system control point such as a VAV terminal unit. + +In version 23.1 options were added to perform the air heat balance for each Space or each Zone, and space-level heat balance output variables were added. + +In version 23.2, the following capabilities were added: + + * When ZoneAirHeatBalanceAlgorithm "Do Space Heat Balance for Sizing" = Yes, zone sizing is also done for all spaces. The HVAC Sizing Summary table report will include subtables for Space Sensible Cooling and Heating as well as for Zone Sensible Cooling and Heating. Space Sizing will also be reported to the eio output. The space sizing results are reported, but not used. + + * Three new objects, SpaceHVAC:EquipmentConnections, SpaceHVAC:ZoneEquipmentSplitter, and SpaceHVAC:ZoneEquipmentMixer allow one or more zones to be simulated at the space level for HVAC, leading to independent air temperature and humidity in each space. + + * For zone equipment serving multiple spaces, three thermostat control options (SingleSpace, Ideal, and Maximum). + +This NFP proposes additional optional capabilities: + + * Use the Space-level (room-by-room) sizing results to size Zone-level equipment to either the coincident or non-coincident peak across the Spaces (rooms). + + * Refine existing Space-level HVAC simulation. + + * Extend space HVAC to support more special objects (e.g. ZoneThermalChimney, if budget allows). + + + +## Approach ## +### Sizing +* Currently zone sizing is independent of space sizing, essentially sizing all zone equipment to the coincident space peak. A new input will be added to Sizing:Zone to allow zone sizing using the non-coincident space peaks. + +### HVAC +* Calculate return flows at the Space level. Currently, space return nodes can be specified, but there is no flow assigned to them. All return flow is lumped at the zone level. + + +![SpaceHVACSchematic](SpaceHVACSchematic.png) + + + +## Testing/Validation/Data Sources ## + +Compare Space vs Zone-level results. + +## Input Description ## +Some new objects and some changes to existing objects are proposed. + +### Sizing:Zone +* *New field:"* +``` + A??, \field Type of Space Sum to Use + \type choice + \key Coincident + \key NonCoincident + \default Coincident +``` +### ZoneRefrigerationDoorMixing +(If budget allows, otherwise limit these to single-space zones.) +* *Change field "Zone 1 Name" to "Zone or Space Name 1."* + +* *Change field "Zone 2 Name" to "Zone or Space Name 2."* + +### ZoneCoolTower:Shower +(If budget allows, otherwise limit these to single-space zones.) +* *Change field "Zone Name" to "Zone or Space Name."* + +### ZoneThermalChimney +(If budget allows, otherwise limit these to single-space zones.) +* *Change field "Zone N Name" to "Inlet Zone or Space Name N."* + +### idf Example + + +## Outputs Description ## + + +## Engineering Reference ## + + +## Example File and Transition Changes ## + +* Transition may be required for idf Sizing:Zone if the new field is placed in the middle of the object. + +* Field name changes may be required for epJSON inputs for ZoneRefrigerationDoorMixing, ZoneCoolTower:Shower, and/or ZoneThermalChimney. + +* The existing example file 5ZoneAirCooledWithSpaces will be copied to a new example file that uses the new Sizing:Zone Conincident Space sum option. + + +## Design ## + +### Sizing ### + +When Space sizing is requested, the following arrays are created for Spaces. + +``` + Array2D SpaceSizing; // Data for space sizing (all data, all design) + EPVector FinalSpaceSizing; // Final data for space sizing including effects + Array2D CalcSpaceSizing; // Data for space sizing (all data) + EPVector CalcFinalSpaceSizing; // Final data for space sizing (calculated only) +``` + +The main calculation flow for Zone sizing is: + +* `SizingManager::ManageSizing` + * Get sizing inputs (`GetOARequirements . . . GetPlantSizingInput`). + * Loop over sizing environments and days + ``` + UpdateZoneSizing(state, Constant::CallIndicator::BeginDay); + Loop over hours and timesteps + ManageWeather(state); + UpdateSysSizing(state, Constant::CallIndicator::DuringDay); + ManageHeatBalance(state); + UpdateZoneSizing(state, Constant::CallIndicator::EndDay); + UpdateZoneSizing(state, Constant::CallIndicator::EndZoneSizingCalc); + ``` + * Repeat (with a pulse) if zone component loads report is requested. + * `ZoneEquipmentManager::UpdateZoneSizing` (where all the work is done.) + * `case Constant::CallIndicator::BeginDay:` + * Do some initializations on `CalcZoneSizing` + * `case Constant::CallIndicator::DuringDay:` + * Called from `HVACManager` + * save the results of the ideal zone component calculation in the CalcZoneSizing sequence variables + * Works on `ZoneSizing` and `CalcZoneSizing` + * `case Constant::CallIndicator::EndDay:` + * Compute moving averages + * Save values at peak heating and cooling + * Works on `CalcZoneSizing` and `CalcFinalZoneSizing` + * *In this function add the zone sizing coincident/non-coincident option and calculations.* + + * `case Constant::CallIndicator::EndZoneSizingCalc:` + * Apply EMS overrides + * Output sizing results from `CalcFinalZoneSizing` + * Move sizing data into final sizing array according to sizing method + * Works on `CalcZoneSizing`, `CalcFinalZoneSizing`, `ZoneSizing`, and `FinalZoneSizing` + * Lots going on in here. + +### HVAC ### + +The main calculation flow for Zone and Space HVAC in `HVACManager:ManageHVAC` is as follows, with notes about changes required for Space-HVAC. + +* `ZoneTempPredictorCorrector::ManageZoneAirUpdates(... GetZoneSetPoints)` + * `CalcZoneAirTempSetPoints` +* `ZoneTempPredictorCorrector::ManageZoneAirUpdates(... PredictStep)` + * `PredictSystemLoads` +* `SimHVAC` + * `SetPointManager::ManageSetPoints(state);` + * `SimSelectedEquipment` + * `SimAirServingZones::ManageAirLoops` + * `ZoneEquipmentManager::ManageZoneEquipment` + * `CalcZoneReturnFlows`* + * *Add space return flow calculations here.* + * *Likely refactor this function to be callable for either zone or space.* + * `PlantManager::ManagePlantLoops` +* `ZoneTempPredictorCorrector::ManageZoneAirUpdates(... CorrectStep)` + * `correctZoneAirTemps` + + + diff --git a/design/FY2024/SpaceHVACSchematic.png b/design/FY2024/SpaceHVACSchematic.png new file mode 100644 index 0000000000000000000000000000000000000000..5a294f7b29d8faa9d2c7ac6906d8705216f206db GIT binary patch literal 36414 zcmce-byQV<^eqYqN{4i(0!nuy-7O*|NF#OVkWi444(V>B`vB4@NOzag-Oc+P{r>K| z_b>Tqy~{%~;cYRHelmF+ol zPVf)Bqq>YZT`WEHYO)2 z_S)^;-W|q|*QQMm53Id|v@a!xTLSSgkOoJ3C6U+>rR1p!9EaHuxvA~o&KTU#QB~VW zk-6145$!6TzLxyChVcPDIGO>~Z1EOpTtePkcplk88{wwTVCr4^Knq=f}z7 zi<2Yh+qx<QI`~>{_lDep1P{+f0ya}@$jDh z&-ba3{QuY2W&gLYk4B!-(9oD#{F1n9=f}a3%i79kLf?>-?2Gpmhy6!TMkEV^q-3;Q z`U*`n-nPhda1r*27Dq)54*K`WiTwNBztK==3J|0iE(9Ltml%+Rhf z)7G6T)$eGEv0Up8YrEP=H@NXs7Tl|bgn;`J{d-LlUaP56jE!jX$zpA>o^WzMUArc3 zJzPXeuTwQXdhkrrf2SZS77VAPs;OC{ODg0BfyzWq|01Ed=#8TF8%X92v;s3mhx>0t zI=Ax~bHAH|mZgEZ4-+q-+uw`kJx3#P#+$uv4A*}pwp|{rb<}{7pUV83U6cR}Qi4IG zw(&v@Kd3SmUfQ%WWn+&jKI@M)=) z##*Q>evESx@CkE9QVr3qKvR;yD|*jPG5J~J{v8kh8|JHeDvIK3zCD>(S)~c+jy}ser*7A)?Z<4U|ZyjCOf!WUgHxTN` z#7@ncK;`*;`95pQtpi_O{}1<*_Ij$##ioyZ@uHQVLK}j>jKu!WkZXkT zX4Mte`jw9{NM4hcXAYkfYgf$+EesL$Ee1s7XE;Sr2+w;;q`1sluIMdGzdQ*{&p%gd z@xGhC``;&)2GQ}heZT}=3QbU#mQ5m+S~SMucW;#KT=UJoZnBN!@MgH+KI8<$c|ucb z0#i#RqtJ0gVw+G=)bu?Rtf5@i5ClgK)%5>oIDrAv{}rqTzJK>W0qAG> z7Z&A;{(|DD-;@_gdR>t0vte^+5S>5R4(jJlM&E2L?;fUh-bvEcpAxgs$Yt&u!^Vbv z7;_Y+$>g*TCg|UY>O7Yv@=8i2x5+_4uOI(k;QSx@_etyV;&XG?99z-Q zs1yI6QQ)a93^=QXM0WCWVNf*nH!#p8!X9P(13=8dundLzhGkzg-!$Qm4VH{Hi$7+# zqr|`N*l; zcRJB;a6*|Z)h7)l*BEXurYGB+3IDoqsKqQx9Tx zwA$4cO3dk7Vchc=79`jl*A)pp>vt>r+nZdeq2h366W=vUS#ZQMDTF<~=vrYzR*0-7 zi&5Tr9!c>=FlyvM=S0q@jctW(ZZD5)=gPd#Uh)q33kT#X#7|Q6?5{QKlsaliJjeS? zMS*q}>=rJx-{$wEapUrIOeOH+S6Eb+eFj^k9127Ulv2l0;eZ+8- zI*@ENFLD263^W68p&eW6Wl$(}L-foEz#}!N6jB$<|XKJdlPs19R zIs&n~*!^K9rVkBgN5IMf8r#^PJ`YK>>2 zjxrM1%D4xl(I!fsx!j~Y%o@OV$MhAZ$ zh5UHIX-uhY!F7pzx9MVWMJH;NZ!0HeJ~pZyIZaY6eq+Ww9V0%vP%4DLRz4t7^i=5N zWPJcF9(D-6*qZRpLnIC_*CIf=6RjXdEl0MEoa%Y}lSN)-iapAR*2-*uzP_}Tv#kDP zNVKIE*%2gPe&>60Px|AS(Jqvqr_mynx`!_`I6Ds6w0}W?Wm~SKxr&l~OO8XrgnCXR zQu~}=yD!$kZY%ma=oad+nHlJ7=e46-8XSbD-srOTVF&H*533K#)K|I~U-4*$H*Yl=g}@pH;Wg(Xska}&;03* zk~Dn^c(?K!oV$WZIkf3MjONJgbH~)$8mBC?XjgVRCnpQJI~*Q%U_EK_IFtXqWZ345 z=A~)LVGa!0Ay1RT_Wv4h{MPcc=FqFvIW1275fpc5IQikYp*FvAj z8Jg!dz&-WF>IGIh@x$HH13Ad%2JV77uMpn3tswD!Yu5&0n9XT(7{a)4d%(2lN1p-_ zKOC>s^(8jHXPKwvCpk{-V%rP-_3e#B06GdL-}0yB>zy*JDOq;a@9!V(F0>ZJ&LU9WKhsn-bIzG)uoRy|FzRAWY-1f`2M6H zd$n_V>j31syv*6LQBUgb4==6<6YrT8N-jTgs?%PG30$-1+jH?(k@&{+WK1g zUN3C~dVKU}gY?b70hAbJfzJG?AFT&zS#ds`WliTvA1S-`)_6YzsyPO_Z)2xAPinWZ z_mHiT=nsHQrfI>p!+tAk{hKfd_uX0v_IAA6~b{&6Cfq*iR= zO{U~c?+;;imiY%v>;~7P@p^`v^NvH#GYQdx_qOYCy0$1AF0RX;pENK!3!zbuedHK_bw_ z)JvR4sincxcGD7#*4oT{+Sl;3Yks)DS&4Jom7(oVy1+j%AwDu*xV<{julVpF!@G|1 z19Cigr>bH+UH+cMjmv(ub9t)e-Wh6+alT<+E_y`UJ&kIhvN$sG!WE|eBl@1mGaM(!el%9uT7xzZ;hXIB| zc0M@+xjrbN#< z1+P&FH;ml!ut5JrdrAEIlD!XWE=28RkTIuX(V6k?aHb#Whok~i zvdO9i3ak=?7VmvNwKrP98|{u4c0G5U3(_t<@eBr%T6*?U(C6fQ?nAsK?3M$DQ zAyrE@ph$D+S5(&Ap!^uC=Y49$lxW0QkIk-(G=4~&L*@aKm$|9K$pCL7^>$g~egh=T zMBEIUSlk32hp2tX=iZSwtkTK~je@uc1F_*5=McARUYa~cTaA!Ca_I`cNEi{q4o4SX zknyx}RZpjb9tLfQ*CCnZ{az4vY}US-n4kEq8Zz97bLgplz=v8IpTsP0C)Vt%-7o$I z@dfLHlu=pg_i}Q^N0dJ+dLH~jMt7F4My6hew4etv)(u=7rha_`W>^+hv?;b z8~r$IH-*7o@VeWPl%o)e!3y^?lvU5$f8{qPv-219Az_1@=W|bF)phc`&jq$*DVx^M zlH%KG5;$CT-@2wbv>_2fchfe~eMF26En4o*L6vv4t<|!fXL2ZM9||(B`cP^sHN+sM zsvs)W=Vbl9auGtuvZ=z8G)hWK+Sh}90RsFc7V4fltJ()NXvf$@t2)V6 zCs0I;#@g`5#x{voN3aCS%BFPU;dVo`@hq&%cts~oQO5|0fOpxxGCV_xi%k;pHESBN z$xUc?$k-_HY~(lgjq-DzR|iDfC-$WG6rO>O$rjdG!>A;9m91F%J&ImxE!N06*spb} z%))j=-xlx^s0rWGGQaAuw?r@bd54p;DmrsWsYJqQHkh(Sfpv3|5XYjwO_L%t31vu| z(5k#y;Q?uh^PKnfSh`s#OCGu1;Yvr~ld*giSG(})V8Qo-ht7V-OE9=sl`ZpUgQQ}n7lGdMy;42V9 zNFg>VOrH~cAKZeUV5iWCyh>>`A`*JOioBd)&kh&jHGKymRVY6)#_dua&WOb5aQ&Mp z23;S?{KPx!4?s>lQ)8tIU_^p{($dPEsFb7PSCAt7&R72jk(x5*bi zOA(aG3}zg1ZNB2?GHb!oGEb`>sIKcavRw}rSM*j6`GR+k(n;?k5FStvePA^Suh)8_ z`TY2S)xpi6Yx7#3y%?)<`|7Y4hQGW`5#2ZrjRu2_^A}GHV$%}pI!pODjP?A_+jO)| zr%6**@4gN-7<8G!c>xM#WuB$1<-Q@=WoL3g>8KM|11QwqVXKZSw*9Vy^PR>r?jr|5?xc?u4Kpc?;Sdc(VQamvO-Kb7HS{!Wbe&~w+A!`5+hLfVA7zS&l(>Hp#0kf z+4Ee41XMJwnhc52il~K#V$?TJ>2-rd?7XY+$^#_tPzSt&`^*v1(3F3i&sy2)Aj^@) zRpMPHtA2^F^|Hi7PSo3BtWX)P{4QHZ2Uie-eze8S8nn}%5%-bSLgFwmNmOs#p1m)2 zWr1;AE^?i8=~8;{K43SqpS5LvA$*SQ8N?A}(v!pji@v;0)U*X1{+Kt8x`I8GUX~Jp zn9e&s7mZ8x2C{oc5KoHyy&hTf`FLTMaD_FI%WrXOH$4O6Za(&ulc6mv`z{}@>Z(CB z{Ovnrf*@g{#gp^OJ-1>}DkDId%l6ez;^C&^LaT$>phQ4rRVJ^u`|9{Jp)1*B8oiWN z4Wd_S4J>$vZ9LWJ8H1!RUNz%6M^oE_<+MyuU~S@p z9{0V}k1yk0@*JCBF_AY6Bza{W(Q#20meXg0{Iueie_6x{L%1cf6QRyDVYy(zyXeK;HJ)AJh^a%`#~jW8KkU+yz3+Am zTr~{zE-Y8^+uJcrrG#^$-$+tJqQdnKo{j&WNFyQfN{vetZ3lbCUW8ZgBIfu$p zBV`|N`6ce`?H(Od%9`5k(8|JXfJ)m{jQZs%;yq_EE2ZYZ9nG5`L`)?~4{SyGlG1n` zJ)cGVL2YBVcQ?KEJ0Umd_8B~}cu<!(S6JXj=|(@>gCz0&@ZG(2HPtD5%4 z$$vE|vDG;5fUJQfW{nzVVLw4}at{d$3oPH1XB^z@s`Fx}ML%-WgpqvfW1KqN2O zoUA<(TBMc;fF?W<(|q9Pcr8pDBV`OnKnmAZX;oU^J%F1G1w@oyS<&Vlp^g}b|E_4i z`q#C?Co5R5#)r;X2^uPoD9LTk#gy>v5X2?#&OsGCyZ7s4)i7D}`tfH9Qt7k@lXqmh zL*oeI))55LkB1UVKe&j_ci)c%6DbU^KJ|pptuJ@-+6)x2o-UuwAZ`(QcC<=_QP0Q1 z>v@PfTssuY=jmRdVk{%REOObBXWG~ju&huAkgN0?=>xY<`=P{H5+P1h5;yE~H@UTH+t9rAm2BwuQK;g6`nl+sKD%eM`nSGPn87$c(UejW0S3F>W!SN_k96 z;+9UTL1>g|TxyNbjG%)a(ff+zQJINDI!lqA7V|N^nfu!(IP<|gFB@dLF>$0hzPhQ+ zy4=&g-7v=@zV{2JdsLy8ymCZ*bgJTDWT+}nMbGsNKiz5nhyD`;GHvJ`}7$YA=imP%{;#N7SN^fku-1HufC?8f3#BvIbLlFC} zxW7&A`&sUZ#O2_4ynsha@p-sedU7%E7;!_bK&R!DsD4rLYxI=3bl>AYz2N56E7 zhB||B7g#mA$l6}zu=na{01EKoISob+_b_4eq5pEe=$$20I%kW4;Wb_2wJ_j;8Ar#7 zx7B?pa zjs|4~5ANzT2Wmzz7+&P6R;*D(bsX2JXg(J6h&|F5x&fjtn51PZEB^sg&567|wE9(T z)Y3+RJD`&Rp?nV|pkb5btppS`x86%jPCx+?@*2**1|(iIwS=#LIH7@O#Wu3sHV*c& z=q(D}oGjYTRGF&=V83t*_0Z)V?#`x)nj^Uwk^FN^o~xwoN`E63_Hcqq(=`b=Z{rQ_ zIgG2x)Ng@09Popdzo(dBeCX118h4b!8gNi5c_ zV@bh<5p41@+Mhw3;Dm1FCAV|akGw|x@>Ao@exs(0>x%ZEO zOjI@4Jnm=3B4F0RE5%{N08ds>9FFau3s8=%6ko13Mnz;s$$ThnFV7x;-$q^_r8hMB zFC}W?01LweY4?Ea0RmtbUP++3Q5$ehN|q> z00D6m)Tn24>T;O;zatI1Ly2wEM3%_~UC^)3b~a{#%Cj?xQ=Ta5(>#~|mT7rBSAo!V zsYJKVrGEzS<3;Bcql)tauw`H@0n|E&#o`ZlHb4wO!es4%R4Y|s*oH8H6a7{CmD%2G zOWeXMNC{9#c46hl{I-bcTSKmM6AGrgDjNW3d)&|H%e?r>`U^)tm z-0LKfj-MZ9>K)CYbpGwV1AlosSUtE2q*v&hoWmqKjouHofFo3;G32`|z~f1i~2H4J!~@ocCtAp&*6Z89$BfW^`8# zdJx*SQ*|^3;2^ft?4|D-0ysv|&6%qF{`RQfNr3npF4b=|1eD+k32d@~m^$TiH|0|w zWj!Q#@B^acVLemXr9=$%Px#!0LG;UX9%_$N=qG1{`Z=$S#G$|K2cm(%hfSDFU_~eA=J>t58jKZ( z;aUO&o<$`|`M~xubdz?hL(865Ea<1cV7pH%<=V@?vq<7%m99(VvC(03*`0>i2z@{w z$z{?IGgoiwWuZwh2_gt5;~zz01nlYSDQ=A2{$cNtR$NPC72&hkem#%dqn-uqZApqY zwEa;9R%fx7#u5E3b`)qh3ese==ILJZ0>=95M41+Vdt90A6Z`V5eH4I+JsXJ4kPBz-a5z=XmVCOSkL1Vh{IsR!@po z`7ubi7@+spJNnw>!`$H%yh_n@5~>BU>w~HN6UA1X=7Z={-9`6U_BWaj6&>8pT{cDc zj~dTldd}GP17e-ZSx6i6*qag^{C$1Dy?dMKc<1@aI9}^%?0xbF=ywAqTk;{+zBJCB zGRa3zFpEiG07%!>ZN+FKJrwbP9_b{z^U(6{f`;bjx4fal?T|Hy@>ke{?$5r&*lkF& zjMcA;pcEC+)9^E$bi5lBs@ogQ4bj~&Xmk`F;t9cl2*p_f3q;8Ry@#N|JWt%7n_|7) zen*-gdCc_ZE)r;%Fs2UI8#UBt2O`p^#n%zP*MDxlN93sdh^jA~5=43-v5q++$l z%_)UcKkzG&bDyJ8)79iAbmKFDI&WZ zwf~;BYq@iQ@<2|Uq}J+3A1b1U^S=p*pZraM}50^fGm1!uXRABh_ z90m2Wh_hrTjJ>(nAda%`jig3GLuY65z+=U{e{=|AJqych=4wIl9Z2C(kgOAyY0ZSY zwUwXlqA~56i$N>vG7P94{gxhROU=KNk2eYIAseVF>A=|0mTcEdTw0>1*MiHM@mVr- zvFYPM97OC5CI#@j#4G*gMI)NAFz%Xc`gj3hp&*tYY5gWlX+)PhX(C1~u}z@HfmVRYZ&Xd;eD#s3I zp^8LO=*fjrNRwqa8nYzh7qV^J_q@+*NZ|r6&b3ZbTzv!FHXOm-KQXq_x<73 z%52hEakl2eMu3%7fWt{3akVH3I-fgM)e4ho3RZ*JzdLl&0 zw0y^dba0`k#{JY|e$shs^x64!vXxuuffoT~P&fT>twR{M>_wpq<3q3m3 z7ArI!CX3a!3$s$A7NJ6B9ep?`TqbBy_I@x9#S3V6+gVm|M=>Zk!T~u|H!C7RWDb<^ z?>sD_TKZ%$J<`9U=E{Gq{drq&c72#YtQ>9&nU8a7w!kT*s}vAN7hVDx1*GKPZsz*d zfhGE*_Ry&im65jw=rx5dzwIjRTF(Tg7Gv#JW_)Ocl_C?3r925JT)d}aMw7QEwe5G{stH*p;BZc_q&_%YIPm68QQ$!kNA!bvxJv)U@Tfc< zkU}iSYA6>Lw2#Fa{rvI?W9s~Et#x9uuZIN8=n~GqP83gNB$X$3OvQt}H!4LH%=e{> zBw@eh;eKWE)) zOf{L!w2%8J0A`8>#7(Kfxc{2>a)b)=RIjM0KU))cxCZ_HZY@n&LiHw54>$;Kw(hlG5bZt z`y&&7`9HWnmcm&N#-)Gr+KZa8^lK3#oxj+tpw?lSEL|GqkeMV7yM;Q-YmEY-k+n4i zgKKq2KXcs|E6LTun}l7n^W7Psk)r9mckuwzYtMk3uVm_Kp5|@_+dflB0g|f) zHwk>ai*Cj+?G!PDkhPRNjM=i6qTy^(*RRHE>bb}7y6Z!$pvBt1^MaXFc|$ZKL1joc z!=KU5+LU+~es3c`@tr}|hG+b>t=7NSSrJ;mE zarM?Ly>7|7anKuP41xBr%ty3DsB6NE5R&o-!1LxT`j}HToYg~FB_wUiaes&#Zs+a} zYJ+#NcF^JQbR;Y^YYd%%4pbQoe?Z|w8#c1RRS0(fdLE#{oHaV0@KRpK8TAo9Y0I`S z3_61qE*j^wP%e{RY(hj1Ps`KY8O{VjSKGa#OHJ|5f5T_gD771~4)SU7WXVKO0H~vc z@aJ#nEe=lcyKejtAt72#f_eICZtR(Cch-_V-&9y3<}uN;vpKcGKY_Lm^KYcAr3K2C zY!lYyjDw=9=rJbQTW*ijO^6bQrqAYB{P*wIk3{t}jK>SqY`tRl4DQ}<#@UGK@)R2z zXxu$pIX`38Zy4X}seZkh76U^WSq+QHUz&7`g}}1eoz~*mJXp&xSuwzNz)I`!Zm2># z{GIW1jifrvQ>h75d(?Qz@85xK%P59k#YLm?OY|@AXMB6rW9{7BX`ncp&Kf(-?E>`I za^CaVz2fT-8aJ4MMW{s@TTS%-a&4g!#z8Ke0!N19-_jR{k)rZ*8gN!D^hr-&dFYK; zf}0;un4JYFp8i-Y#fQNMFZUC2r^w`PXKn>w%7@FIw$D!}h+rOy6%v>mPyK6i-6?%; zxN5XEFPk)N2(A`nR^;%c0!IHoI~zaHP+b03#K`+q;-vV=^h*<=&0elfPM8CKhHanM z)y9J!79IIQFLLPu$R5C;oM2E3;2L64VEE~u+xA2|Z*}xJi?1DgTEO8B$`x}`?mq{w z|F=SD^^h-rGt{|$^?r5mfm7dyuC3*^zXkdUTeMsh9MlyZIbiux??zQH@I2}gD|^?} zUh^{+{Mpu6euM&Zm<|jor8UH=DiB=4uEhVI@~D87o<->DXaE(4wlK`+Iknp^Q2PhB zw;~!h>`JUYg&YvZENqf1TPh+~bbxGleI!QhOXU=k#AT_@1_Pj>2D%rWho5gT{yV5K zilG#*#?yYKDzY@4s`H-7kkB>;vBp@>NF_o5(6gf(DCb1|^D-Uj`P`k^CKXyEmNs91 zxX3OS9VMEPD(;Wd#|v!5g=dhaJh$JKC-zF9oN;GC49KwBi2eRuHMF>^KnHLWbw!wz zHgaV4J1c>dF5gxYc{)$G#)@Dta?c~zgN$JRP&S#B{rHl3O093UCzPk#CcEclO&(O` zFM99|$a7u4JtY&GRh+*Pm_ig8JgHARoN<=OvqG{OnbY(IDV!ELVAC30lo>BDOYb8} z878H^H*XpOQ?DOLPy!Twww}=RDb-@>w}OK~WcxE*KpeQ#98~Y}AVa#*A-{4^J?CIA zDvQ8vwA#!i{ ze8nLp8hpF@^<^pK-(kVQ`CnhmJ^dL&AE>Y;b$S9g7OeXXpZlJ(yWay;-^3Ed|AHqA zIHr0HE~QcDzcNA88W|d?G#(8lJO{u}H1E*QY+E2!NCy1sIUNasFN~qOz=f3rbK#U$ zGBW)A!^{j-e|`Pvd#M+1MHpUvt8PUp^v-FN8oRqC|P|_|IG`^9cg+t_i$VQ62+~dL@n3F2y5@2dM$ajI!UWT_IKm1UJ zhh{F2!MvH(f;1rFJ_|4}woo4OG_P}QEx!#w6FK&S(x+Be1RUFi%D;oWeqIWHYXu*C z0gN+m&%{>d2 zJa$UjW^1hcV20Y2QSwF+O5|kiQ<)l zz~D!aWoODyOU3nJyg-0*9gUEMsc1PA7#pirL(hwfbQ+R^WcgPb;DA@xevH9`X!*y< zprgjmf!&#^1@1|3B5_KixYYAhQPs3I!BjbIIo0FgTcM^z0!!SKmuy!i4|WUUp;cR@ zX}_=iTDQNhuRsfWr|AvEy7}$j6e0qI0J*wFh~B8i+GLq_)pNb?H$_OdbNGXqaJ7Q-;FbWCF%{fo0IRsEEy4Cg{pn0j&%WC3otOKt*br z1Ig9k$(~>{T%{Dg5v36R_SUm0gM&(Mx6tl&X6K3WrRfUej%PSg$9d=gmKe26?jid= zb2fGURv+}d&L(WVSh&AT2clD!viH&mh?4bo5B{kSc-!b=a|lH1deg}Fok#WQ3=bYu zuwrq2tbQYn^uK4xCMC{}R%@--i^A*+zP~9jsm) z)yOtLxWBfJD64S01uLD$h@|Th4`xeU)DG!OXU@^b=NhR`<(fgiOMqi;?!K}AT6&{Q zqsP@VQa*!?C$rWIJ)u5cD|WQ9lCKzaj;R|&JcOg@ru1F)VLr}Abs8E~kj6og`G8Gy z0SPWq;!mH*p`|Aguc>O#oVihtrfNa?C<$I92{5j+{y9+=f7L7cIZz*4b|v@dV?f3* zh-efna=C6m$HB*Y@mc+`e^x)DRqu7hP_dq$IDuZJ6&kLV-T38=G^K|6aK~yW=OA(% ztHFL+1oF5S(;vR04TMjb+w}|#TAl?bZ94|oCK6HgMynNve{gN&Zj7*T2zN=YZMEOpZqWddX*e2fFmx@(b-f-CEbYQGpO2GP~fSHaLl>a zTCtE)GD3o6uiu^%iV_$C?~85H%gT^fk%4fyiBc}MOO37vDL!A6Nf5+or9&Y#rc$0D zUT}I{JGrv6d0rkul*XvbJIdNcSWs8JQK*{6M5e_cA-#3!6greFEQh~1hoFT&tJBbM z_j#|25DXLvVxQtLy2>FVU%~u@z_92^G1mpJ(JWzM?}vAo`hL#x-Zf}NuxE+hBW3d( zY7D}({jl?NrKbZkn+>1VMw0KoNja0x4Ov|!*2s`ot<2C}%$JRtsdpcd;`Lp$q0%OV zK%TX*%NS205A8&Y*Bc7J=FpuqDGd_=j^big2r>j$JBd(J$|0;>~;15VE3T4w|G^Nj`eFH zj5c<2>@T=dKfre8Do8#Nn;^FL21vImTHqh&2R?E@cTI`Xaw zNpWlVSkp&WUT(nFIgg#~Of?q5DvP-a#)A)8Nf_0WSX^aa3hFn)d2IGSFf5#UFl|4le#|z23vgYaq_K$I;Fi~-0jjxJx z4By_sB^f0LtVuUU9NllYc)L*Ds3|5HhmvsjEntZ~?`XE?4hNZ*{1&h@Ko+`@k)3y^ z+4WvVrvhs^evLm-gW4J3QlfL!Ild4f?E*UJ`&jB&!zb;Go=6mvGw%dx85CndF)Be! z0y80s+88yHxvR9_?4aR_>luPLOyu>|Q09O3k66ih2XozNu&_vu z?t;cXd%^%bt#$E8Mq)&J(6S=U^JuQPoH-FOPQTUuZ6MIM>TPNx420s{eda*#ABF9V z|6EmS;gAnHSq}woPw>7~uUpW^aPK!?Vq4^QI0#A}#WKUK9T1iX%3%LoQvMVu&65!^ zcXcySrw^amxBQU)T~iuYE++l{G{5byUJMdxomQd?L+*CkpPw;h z!sepZ$N-+K(qxpa`jJ*_qy%OvNiziJU>=*<*McTB&OhmvIUIh=@-6`ZG5#kT=>Ic> zS^I(Wf5EfpP05Ek4A4nf*E$@>th=ok_CUmknTX*+w$DjIWR$oY1e8taE=n3L_iMNC zd6sLkTp>-Jzv5bDGN-xn;jjc&VR$505Lgi0B33TXO9*~i+&DFn190;~m(h`?e=<>N zd?KL*5{pw?Jj`7-|B=x5C8D9*P^9H6RR#e89C*TTvAi~r-EXe51F6n+u7~2|uaf*Q zO3_7|n~5^-KY8`#J*^gUE@X`nfd3j)!bns_^mStzr(fkihCacf*iEDLN6Y=eNCm3f zXqGZi{@IXIdmSi9fD^_~tKgftt!W@T8eoVlhEr*tg_JK7O0<%P7_=$`svYf+*SHxK z#;xh}a1$*)51=!0P~^s%_n9suC0P%av^^yv6q(?PX&T@8uZ#^?srlD^8cC1DCsSYQ z7=!veXA}p!0j4a~*2%(d=uXTB$w0$oWTUfeXJvEyzc;-^>mQmmlqs(Is`FI4=#@}$ z1Z>Ki4GmG2$o0i=e32w!)rpX1zEXmXzuF_%hZDpV3nrPDg%5g|08ISAKTwH-j!^Tt zU;x*K>g0KFaW@X~V>O?kR#sTYi&Wrl+;P??K&i=I&%+u@fT*w~4+a5EilbCcGAlHa zpz{GET;$qfo^7n_yVfDq5BFaTk6d*7HR-IcGgg88=8ar{?hei z-MkI7DQNrvX5G(Th0!~Jck2dCLnNlxr(3oHmZNmM_=S=t1HV!Qr|{kK7BRbSi;+3$ zD*+LP1x^9MeyXC7465D0Eb`9v;eU<>(5TY95b8n!$HnuPpB z?~fwd-UpHskO5~43)OLm!7Yu|)SA4-T2F-Q5}^+e)D}+GuUdf7%eHg&;kxX>Azj

7wENMPWpzV zMX%)iC1)5Aw9;!?UqW!3hwD|N+AGjn0p?HV8mXiS&6Jp@h1l0V!>K9gJIXQc48qxu z@3Q#R!}deSpc_$XSF6__jj&-(szRl9b&M=YNh}sjv$^=7K|6|E3S_1R7kCqz>33&uFQp8ZSN4Z zWt3n8D~h18=s-wD2etHua)Q$+wVFNs^h?USrE!Cd*`;SF#Nvq9B_n5%#hktpCI>_a zq1N=v326OH#}QE&3)K7~Vgp7$W8Gt!3v_Kyg*D=vY)@pBS&Gij#am8J|fpl2dzEw@6wWw`}P4>;7IdtMe z`?+{f9MnDl-p0HfY@8_%Vlsg(MC}*=7iN%=ctv@)DbvPWH@~{S(T>LI^vDbQ zRc3Q*OM&((CR{DG-y~rI9?s-^)GJ#XwJy)+0rcSdwh&JXh+VBMt5LE-Ru;^;Ed3 z(IQSx#AbWEkR?GJgPg;r_cFM@FOwMI)sNc0O*I#$A7(gO?)L1gF6b>fD^TwBKwG%& zcxDu>%%oZS(abWX&tMAwzCDCVkSASieyI+8clOTBGo`Fz2_$`6U`A%*?_f>2p^36* z+~EVpaE~}7>rTk_*rT6y3Y_S&Ds@1~h`;@<3FcDyTe{;g3W0#I%*RhG z;t3U`jtp3_i)YlJiOKPj(`9~Eo=D<@rz+1T%z@r9meeAzcbB{feY++9_W;N zq?hqrr>r+FJ5df%6Xt51Dm>}1e`^k7aCrZSWIw{6R-J-%4$N~IcuKGNqOm|ONKJ?A z0QqH$O7WHUbi4&&j4nUg4fT$~XoU{S+EC|JBN+j}q2G(K?AWpsCC z-&Ll>#ubuAf|r+}pLRCbxn+L$S-)YF4QOySZY}> zrT|5fb&p{6neqb$@qT)bq9KD0eQ=Mt&lBkf+T}A?Rr*I9pwdc}*T62m zKE?`X$8+Q^pjG4b#s0zqR}zkx76~P>beEg;bs8guuLPn*uSFG$srR}HPa*<8;s>`> z1Bai_+E{(A`ezAh-gi9a9r!~t>ML%-ebtjwfoX7m9KXP&HO{r>j5lFw1uF*n&n*0*IVht7v`#)bh*&DiQ(7*1a}KPZx{} zg#Wk_kIG4VY#|EX*9>t)QxH{J6ZMA&ODuQZD?24_&s3R@RJyKqBH5xo+jlQEXc0-V zA_2=Wa1rX<^0goC`gcr{^{b_wvX=ckShcMIcsX2K`Sn+|7udG~5@)8f)5c#vl3meA z1fgkzoWV7V`>W?JTEpvZq%365%#p*Xwz$%rrf_^7Y{d>681IUY@oS1iKxQdXB-!Fdz8IVROV6 zSDhQ^QL0oa+RU#V`irzgOd3(A4!dbgDw0PdU5IhIg2lClra=p)ie9V_$Hn>Y`+j!N zeyZOC&qpk$*QihbB2!3aN`g=G&j0p|kZLwA+J8x&`AJ5_GLg$OP1@7{GSDRbM6KY_ zwyqC9w&ZlYkP3mYy32H#R8h*!fGna+2W1y-g8pg*?rRe25^?=`rcLN3{&siuhfDEr z5<(#FCX2Br9#VL*C-{>2TJVwuHQ~SQ(VPodL<0H9<>%nzy_gl zYGCl>1yQw|qBUXLp^4c-tqU=wEwMwTXhZK5WnK+|zY?)k*HF^fhYC_*M)pno8*h03 z1Tf{jE=d`F`ON%x?!Kn=NSO6c1D;wIWOGmd{_NU+JSOkEw(nbgqFp9dBL8}SnteQP zbUZd+RWx+igFTm6<+%J>x2!5Y-TUihOdtwP?2}j5yw4O7w0PB8?Ofjh7$&{4BL=4@ z;WP}#5GLN}nMCZ7^Le=BE_6&EG#n5bWbu!sxz5EL-Q~O!J!0{WZsd00nPeTM(|1K0 z2EBeBh+^&)7d?k3P6dh_Gf!{UEc3?c1H$48F6-NU;nyqP*g2;U?biierlXQ6f9GVh zGBUTyw#N#+u(Zd!>MjNG796vA)Oaa?*`D#o$&@xsbDk-2yojYr7@caPgp2&}Dyzzv zy=uS2%z2KO+v9sGY0+FQ0d#U!++~S{V{tLVv3oWITQ=#m*~UeGorO!&(j#sG&9l#N z_4aHrjoi$h-rG~p_7UBKurhOvim|2WZ%|?uQ!{z8Pi2VfmN}enb@W^195v+P21bo-)NEizR)DdlkkpVVSIn1a_Q~4 z^e6LLCHFwj5v!R)`*mMl)pw|gjGF^}f;ruT_zHRV4+ihJT_kixd%Yfjh`WC0dkN_o z-_MlT)$y+C83D&O!YlvPpT(kOl2lDbxU&1`2uTvy!gIF1{>X{4FpR&GWqf?==>;g? zy(0@<5RlMjrrAHX!QCgvvAbfDZQv91(52)aNm$PFuUqoj8M?NoZ|Dl?BzKxIGCEZO zexjz(K!M@7;_eDm<{Uu|lE5gXR24CaYdu$SI$pq=eKM;ZC*_gH`auC(nGiOiKpxUv zHfm8UjTxD%8H=syn$8w;Ytil?Nk3u37+>TLt_-skJCpT19}^MLo1wV~9T?N7$NFlP;fXXj%^3L&qf)ysY%*+&-w^kdtGBI? znsj`^W0WdiyXx&(By&A%q-m&q4I>g#*jxK%3Gp1Hrn$%mvua2o8h6t=YEZ1>l=cXl zG|!w&p@Ig8pfJHi8$C*d7tX{=9bmU5XLlg`8rD3aEdSIOo-E44p}RA^;!B7FApf^(1mZ?c^Vc zNjDc2>Eb>hEFf3TOo)p^oYj*PAqCAjbQ-`ZeODSK@_UntRs7=@gW+(Dr9rONF?7`g zsu~#Mwa-n35m#_QWpQHWvd#=2mVe;Z-6>O z5&WPVY!bmB4+E*-*EP6wf_M@%KQ&T1QQ1pNlCbaV+b}M7dTIjFi%l}5$C=U<;*t%( zl(2taa;TQl_rBH4e<}r~8c%~#0VIgu`kuHg$(w)70I1JoqTjEm+~ocne-(YKKO%t) zZgi3EN6~1ToPwwvBBD$>evOc;L6ogjTyg_nN-P@2w66vo=>;-@gpA_74HucGHU^fO zp6ZRKo-Lc<`W)L>9u{2APFxVwM}uVOgd8+oU-JvtUWT=wvX?n)MRHIjQH)o={r@sQ zv}i!)r{}G0O!-)&lKx*L|F>0?z;x~a&QxN@R68n zY}km~rQxP@O8R?nadyRqCe)eDexOv+2_v(hi<(h|FJ|}VomL5pVmVQnAZb#GF*|?L z6zMAj~21>r@`y~Q!#Vb{qa9w42xVvJD>(~YoLzQ$WW;q8N@aX+$uAfj&Js|I#ll@trW(K-`x>qPSi~Wzh_nmJBO_}d z9q{|+X+@L?m@{I;Lsw;Z`o>Apu(qKK;8Jp`mFoojhW6EbM1^ZA?mAd@GL>Q49(Uq3 z{KMHh^F@_7P^kL7ku^!S~i(tT7NXg+M zuCvt)>zm#ReR=X2a@Kw@ry1V9Dl9{F%E_#_ie+)&P4=0)SBF97F)E9aUY+goBQQph zq>`_=|1*^&b$@ATxPvT9&fJybIpR02ShkhnM6S+37t-&WzTb56d5X4Vr|3+tshJ0n?9vw;VW$?bQ-x!n)r39WS=>*e4syOpZUjF@-FDg z^05mY4``o?po4|`r5(C6CVm%`9N&jHz3P`={pyRAyjuQH6x0&W#b#z#> z!sVs08&2}~HmH#DSube>IcghOs%(!%UKer-bc4_`Q|pfp z%&3^~TxW}1<=bSdr?}`$SaR`usNq5wnV8sGtd5v{}dL%ciAb{TfFWA#C%_j-q3+61qEVr_75| z@#frcdu2Exs85l8|8HagznaqATz1THU=Uq;`6}Q5O&&juxNs?IwYC~fc z|Cn_z#m{}r!TxKUS7hj32&|wl%)~OEJuXbJ`KvpRukrokf4Nl1#Eyor)kge~6nm&B z*E+o@Q7v3=51S?zhxF%!!7f;JcRZhay z|Ei&!`BhWJQu7M`BjwC6qcWSzh+wY2`~})q&bO>+cgfdf`u)kvT~{eol{3Aci`zat zbGoF*NSFcmep2S)&1)qs58` zht+UUAd@q(WX+X=(5E+pi36KtJLRmS>VNL9^+|C*oV2&pBWpg~> zuQHDm1oa0$xvq&}-T4@jgtzFfj5Z2zJF*9eXoK*9%NrbGru3H;4xxOXfQA|`I783K zcQFFrG-vhs+g=o2?Y3jw{W%F!wNIBTN@Hqbpotiv`8)1}8fOu^+xs4pkUTR@nJb8a zRKO9Q>a*3-1_Ll_E%g`L+rJT%ja}TkY5jiOJoP5rAfU$Ca1i!rOBT0x$4M>A0pb~g& z3<~#^@5iwO67Y%LSy?X$l;3KVsn@&Mm0+8UF!tcA_p}|C1?6@y1Q1nOUy-8O2ZR&Y zt`vI;&12&Vn(HQ{dpQBB*GnsI2ODlpAX8&s0Cf$<wfRivUTE+F|c|~SRAZd1VbUX#*!w8Ta???hB3%mvOuA2=@K&> ztDw}sWQi&4D&JFAFzGe@Xnzt6Dffpj%&0+Sj&C&&kz0`@WQyW4;x|lvazz5+YZbpk z=#HVW!luo4hbsaIzR!4jA)LCvA>n>Ncf=;`jHAMDz@Bb=y=m_J8V_U~e* z&lM03O@7xoP+G(|Fnc6P@z`XY8gy!R112QX=7pbu^Do5M1|$Br38$@kJ*jcwdc)9@2Z z+1&ik8|kBZK5D*zGnRjy*u&*_|$MmNw7+#ZQ|iZ*ZOD;{&OS6*>$CH za=;^l@qW|#_gdNa)7g;`0(xt!XO>o@eTaQnuvo};@~HQ9z1dt&k=u;6G|Dt7Qgj38N0Q!BGGQ2!P^Nv@{bR)%$9xw}QgYmI+f$lE`1=&Ot)hD9y1 zUb}bb({jrEG?ud;SN9 zDnOUVo3p?JCq`|Zv z>3$h)o6Id_rRaBWvjov=>6Jxme(&!1K~m(ru&KvgF*mgih-J>In^Zq1Lz;za~8MYcl@iRooNsU)TKvC;T~L zgI7A#h%a$O&7rbzXJz`M%0Iru5$S2g#t`y`eHmeI5XN}kHi?8;P?{t$ByN=h( zBc1ibCh(rf7DHVTNl2sX=72SgpGk)(f=#7g+;kh|-d*}a2tI1!tHKmQ_&ji@?oItZ$hbKxMfc9#f#dIn3b;-TJ9zK1xMW-rA;08y477Uy&3FF;9z>U z18r9F8$$aQ+Xs72^Qxl{zAH*iGmAnDpL(TSK^U7f5TFt*l z)GW74JP1Bel|&}fqKcz!)#@*lbP7wmy`Lv?K$derW9SE zc36S-LHN~~;DbPOviDqf%vN?{!}OFiuPh?E6L2kYAg%2~_j5a$GM9MBbNVBwCZ0ZH z+BTGiWXEYMb9e+VbD+1l1NW9DvKX*qHsvinwTBCswcW~j{e>I=u} zyRZ-gt$Ay(3k%5WrN*N)-rqpqTkBXo<M1%}s~6+8A`gAg5<;K(%JvYrubO4T8(+fx zqQWq4`vIFnv1_s<@q?-=K^{r>38l&<2sBR(a}A{9 z8@?i5?3nTA$?8l;cA99gw5dqlI_>kTD!gTR_#q-*n>x`r1|aNJ{#+Kh(b@V_>mTMd zrcUzm`~a2a=7;LhLBg?p!oyANUW6-O`=Zs8aoIjFea<6mc=~aioekNGJ5!P6s$W1n zHG1L+`o>}g!g(MFNaXW2Wrk%GtO&nKrT?6+IR3@pJORi@l+f1yg-FOL4NJ^9myG?n z?#}UUa`+d&koEEG3IGJblAD<4kG6r?PT$g!a!6qN_Upj;ccIcuP0h1;JA%aDWlS7r z*~FV$!99Y7J2)p=k3DyBjPsLc!W*Oxp}i*(<|3pu3dyA0b)n@u20Qg z({7)=X8gZBcLTK#A;pGJJG?K6yE=Zbzd4G;P_vlRe0;S7{^5~m!k}_r<8~ZL&_KAX zs_(_b69{P=uO9HK#2Z{Hl;ytUzuk#`TNv4W2<2DiLW%C)t#O}J>93L}I)PJ#q}9G^ z6J2P}jaJK_S53L#l{@SUEuv~i1(6liez8@=<)_W=Dc-3r#@r)U3=$Dy2#2XFCC}Ex z~qx{zl;gI|kb{^70P3mNC%*DvmS9XmeQ?xQ*c>B8h=kKg&P`i#L> zN+6RN^?pKGPnbWG|H7k{b%~53t)R$yAAlB~feic7`}>j%X4gp3ZB)@1XH5pW%ak2Q zJeAXaSAb%!mlW41P02XeX1#GCAHw{Ex^e z2EvD_@8e07@82KonEi@jjMq0Ibm=aoo=)0@L^ILZX7s~D85{`_`thYBr^lmA(D8dw zbDllL>;1UR0t-cb{zxKTBWhk;7LNhGCTjcfgn(iFR0Nyzq^aF5Pj``t z%qCY(0jr|WeZug#?|fTAWJe$I=$-BQHvvhW!<*xQiX++R;q-vTfrkC{5VzeDE$M3zQ1#Y^jj>6}E0j{BkcK)2He>mb^FCSc$Y7 zdag{xqob7PdTk29_4P_esf{*4IhTi~LGsd|dMSwq`4tawZr6SFHzcpxw5F_v?So#B zao_LO_Bv6giDo{#IdTe#jDXpTh=Ko@PyYzz5m;t0AKuPl&wU}#bLX5Ir?>7ddAMPJ zn|NZOqrkfww$&j%-DU^dP^Vt$sdDZavT&Do;^rpQ2x8nFUp13xVk(nY6;Nn=QyjHI z?37ohdX~$H_75As5`%o$_eFnT?u@!3g?B%8%vFu!UHI_>MEqI=f`(roG-AW?n?Ovh z@Kto$jQzE`yV_M-?8fn|krqFL1s?3H0BCY9`Ex;4uGUqeXWhH*=z3DtFxyv%($&`_ z&hA{WC*tnB8r=}{;%y^NIq?EA1SFxZ=sWZJ3{l(3sCIvP3>WxDKAT7&XJ0`rORttKo^KJFMn&$`@g%9^0EV;V8x@Vlbgxj9-+6ZIE zxF?Ab+mX9d0o}yfPjrLdvbmSml<#f$gU^6)WGXJYAWf8#2LSCrzi%`OTaDUHga^Y6 zIc0Gtse|N9>B9?R+95_#T5W~rpn8fJ)@?(7M9ktd9PC+wA1trXc>2FE_u#$Hm$&+V0X1UuPol?bgyQ6r|g8SFXaS6Y2Xu8CWt+ zJWSnZAg-gD{mmx?>)b~hsz2rx3&}t)5FRO`B=E4!MV3uBZ2wI05%(<&!l$20J2QHu zU1%i7zh`cD8LIIqAf#-w7Q^Ldon4mpNm7i%*tFI>8r;|26r+nnWnE+v z-ijzNP+_7mCQpsHbk6fwAL8f5>?7^*(RVC`XBrWsbFRlBa>Fr~E=_>-^hwo-O~!S- z^VM(c%o;_yt?#%Q*Ky|(hwO@6s8}6)H~oMoCT6etg@sJSk=XCUQ-4ZdY?is6>IlVO z&);3(F~3P{D0JVVlZcmV7GlFu$$rb&7edTg0np!f-?TORG}k%f7T&N>S#p2o4CbN> zq9&awO9NxUy8WOOu|f2rbLcC$_!C1u9$z%HrdhD9kELh_B5Pf9Tc>|idtQ7z8Ke1A zX1Zh;ZW&X*^OOQ&^tlanyxNc+sw>VH>d-Ej;yZ7;Sl~1)la%5PulvVP>k2Jyta61* z7HC*&qr(v~uEl7z<)h=FW)4hq?TMXkO=l?V&xj^yJ*B4=?~zp+M2YTWu}a|4*j*&P z;{aMZs?EHn#ofK%!{+ToyymJ{U)qvaa}nk<5f5l%>IRaO*WVl=W0gs4GDt_3cwng@ zsUl)b`c0w7yabi;Y-f>6gANuTF3wD`L%3Zv!uZl@b#|gbQ{z$ow0UUe+;q#;7qlP@ z^^Zt?%L7z^W2^rq!9?C4WI@k&%-Wv&4JuFe7E!tZFW~}To@&Pru#@DC!nXyEYEu(2 z*Tfk6qKqj;3>FgEs1hB26fEysG7}AUw}dLuY@Ya18c{~cTEJ|Dk1;17@HW zi2qGR*VfTWp))LW`_Uv>2#{Dl4fKe69SWbmZ$6CBG)qFMFcFvW#1tLvfE0Zco&)#T`^!mZfE899uzY3IL~T#k-I|r^ZS?wR88E&;TnP}xm1}hoA|}50Q9K|=~O?- zdEVpv4W%Wv6dv~j2TN1u_pbf{k#>uc<;i1%$`kV4K=B|Y3EmQM*5v20B6+#DF2{6c zp-XhxJEqK)r(3o3(VmNZ`F$YXtf(?e_910$Z-T+Z$oMmV_79_dJ#7o9<^cwlzmfz9q?{##~ypw`-R*@2}%+K+Iayv$!n{*3X1r5}i1CNlM!7 zj*6Juqd@Hi3r`hiEf+{Io#h?OKQ;Wd}> z)lU*+?0ZFeO%+s3V%Lwu5?SEtSqc@h{B%zUJP-Q{2J0c^-Cn+nf zQ>I~CTZU$A*oM|45A#}b6r z`o-X&tt?!qO^4|BoX2!3h|8Be2wn0{jSq;>Mm7L?Sjv@iOSirJ=lQXP!MqpL>xh^7 zUnS$rI5HcjWX`X+;q!Yb+e*d>2<0m288TdoMs7sb%nL>sAEycp|^)up0h3+=n`92|qm}#>5B43jJT?D+37=$CbIATTv>djkNQH>`Bhw z*}twE#6}1_77xu4J1uXZ3HLu$4ViYDTy+JOWi*ML_T}PQsaTTAc9|A$nGHEs^N)~$ zrdmAD&WrhT5^iUch1Y-|h3uZ5FSK}7C&-vY%3MFc?JP|fM;IyeSCG%cDfXuG@_cj- z@7GNZX55d2y5>1d?X5{De8tb~Txi8&SMV6T?9a3O?gvvU9Nq|D%@0C)b?8hr5D+KW^!G41cG9sXeEa*H%Sp zv>xF5j9Y0TRw_E>)mHPgr>f|%=6)>BSt(*~;FYPE75yn*Qx@iCkbEva?h?`n^C#RW zd=ALKoACrkDsvftlNc(A(IEDNK^3Y71=~*vIJ@IeTCZ)7}4xX2v6Yf{+f#Hnd1)h8dG%lbI2JT19@@(zTJCpe%lk@bmj zEmD< zWcc3N99?mHr+Cz^wT)LBZ+O*o*K;v`Q-eE6;xRB^Xl|)C|4W+u@ZPwA?k$R7HYH+Q zG)@&^%`A*G=cZH9> zK6Nlu7Lsr_f&HRmXCG9gbWe#AQy$mzikQ$HS?o>Djf}_%I;gg9;v!H*7u!2^*ieX- zARQ9TBquE;@`bKNEd!EpV8qRrg%yT%L*r>yM`JfxrJ^(0)jG|EUpM2KZNZ5j_OyeG zg|*2I772^<%WhS3F=LPMAL`{aYD-`%{_YyZb;^L04qqPN*h46tMFlp@O?R~J2eKM} zM!cQ~uH%KZ-IUwr=4L-Wa=70u>Eq&jrPkEOx{06%;nqdy$2Zsc_Ji_V_R)@tM;eqY zhCXM)hR$Pp2F{8pwi}OAl5Cbv%s*u#75aQg_g_;bAv5rPS)CpcFES2EHi$Pt_PjSD z_WuP|_7Ta486B|z_e4eorL|G9OMiB?#=s9YH@2}@=M2d2w*H4Z0RdY#>M~VJP4r|EZ%PhFu#xNSZnjXh(J}% zlJw!h&EfeL@E-Bh{O)G~;J)_xn~FFMU+#6@2`hqUAaISSF|~`*m8Mi1NlHb$&3miQ zk5Q@53;fwySawH<1P}T_VKSX4F}bedOB)2L*-C~+t+Nb)wG9mo3OXb8|HrQx0`Lp_ zQu)RGYrBcU28XNw)qVs;h)l>ioD^6+eNp&{*6{iMf<+1@9oMmnW(}UV)4fZxiBQEe z?^T;bi5GkHJcjO0wPXCixgojms#%REU#F(99pULAS6eQX<_b$_!9t>Q>#r2Z72J!l zJyQtd%{S>{HPf5Ueo%RwAaEfnl9YNxiSD#94t}*_(x$l`E_R=6a?&ExYH=2%?P2)W z_7r|_2nhsn3JN%7r2OIjOf zqz{;Xf+bWm^(q(o^K=?_(ZE87h{6Bs(wsjkh&?;^z2KR%M`flh{b)>F+myQt>KLp) zzN4QXw&2)^&rQW%P_-mYE$!aDt9qIFSqmfez9dsqhE|}3a5N~<&m%S2pSdf+%AcrU zUD03dB3ayRFAFM#g<{Bs*Tl`NwekJD{!io-HbJ_JvjpB>@m1wwRhOtAI7@06dZ;Gj z8iCL;ht%rzNrIzon~i+6I8djUK4x_=k_1FOtz$Tab~h06=(671S)WW5APUMrBsCD` z7>Yt$Dmj{)T)YQu&BRmYgKdl;rKGBEj7xz=Iq7YoDP-7?*++8_qE8N)wfSbCBLY|| zfuD93Z>#*Tsx5sBk=423UB%6K3>YF7Ifj>lWd+$~FjSjDa%p~Gv2^B6A5E9PDV*9$ z95zS)lbIXsBig0~ECZj+Pf`w7iujEtejJ+TR3hp(5v#&j!+(X%Z$0OHL4$oQ>}u_R zSkZi{r2Iwy$IdizD-Y(Ku8Ph9>gBr3n-HYA#nauqEt7ta*nhW>#{}O?q0Qch?1FKm zeB_5dOndjGLg=^NBJ}ayB5wwU{w7l-`E17IdK%E`w9K2qI&+y?8>pcV|-C z)KufBJh6RM)ho;~BG!lfW!xk#+a$FtLA+d>4~UN9pdi_+aIRLd@A9OSfT#@-uXt$k zX%=D~{W-S8B6dDy^@F{}dq?_O5V;kGt*GG}EtZsi^K#=)(BSxXWVF)Gi`@CBAT3be zg}UKEWIleVYsS*u#Wahp3df$+4)6JRXVmBmbkE{El}qv1oX|&dcC4zFV>o3dh?-2j zVCI{E+hENjj~*GYj52rMewPer(H=8KiL9>(-%=r|%%8kebVO>Dv5MM&-ID;$<>Q+} zClaO*Dq-(bFqU#7)89>)Al({eOcrc87IW*B*8HX?3XA%Bi5MP5Vr@%^K! zHWIWfr{S9EXcf|JO@y3eH?Or}7<9cuvvRBK!Lj9YV+>R#T^skqVmAk!6NK@Tciulf zmd7@xI>M}cWP^8teY57LG_jhiqGI06^ab~OX$*v(D(X#>@s(|TE?9E2En&Y&I6KeO zdLhjAU?9QAm&?uob*a?#%j*L@%*%*`@~d1sI_}NF*Fvt&1W|Fq7>X)Wgp6veLab9o z{sVV@=|fEMO`Gpq%sHlW@$#Z~RwhQ#qQ7oQLm^rgZ_SN%I(7vyVq;#!(A-67tUrp- zI1&}rtJNlX0nt0ZAGIH`7O?DviklyisgA|jnXR4nmgnI+B;T$L%Gb8yRG0)FT4zT- zl|7?*IyexO#ANfzSR?uRV_197vB-KmR9(N7q|mIcmbJTVnzH$-k9?PQArl&Oqvg*m zu!DPd>y?{F)g(vt8B!)G%1Yd(ZZd7m3H@aO0h|0r*^<4PM_=N zE3dxNc`=d@6|f37OU*AZjQ>Dg=^-r(^=z>&KgZZ$tVF(XXPS#YkZdp6{C>3!mEJN0 zZE?FF1NISZY(zq>N`RpU2Tq=8<+hVqyMsb)*HCok?-M&88RN@bhP z_sP}PSTKNXKdtztT3~(h=_NQI{m!iM%8G?+MaJ?O4!N}1wLAS>8}dun9-V!{Ycr^_ z%MW=>>*r5Rq8QG)v@SK_+x#i+?AiWl319iRsPas&Do zUaKGIlSclOy9%4=%dk@u^^A-m+ zDbgX2u-Er)FXg`MhQ6E3%*{xleFes^iC^0*w}3|sV=lu^Z(h`S1S5-9iINmoB!V0k z><3k_eY7L>lkXusokj{;>IuSSBZv{(^?lG$n6pLl%EEuevucvsLo!)S?E!+oOOtfVg zv0vEx-ozl$^o6X%dno-qE;%?F? z8IjN#@h^LH-hezauJYRxr@nmc?d@OH*EB93%`Wj!lsw}!0?v96cIhM9HZ?W!9bKhl z%a{|%6@|Q%Y+~g+J&@5NlWjGN$$vZ$;eIHLmtyy!V$2kDP|f&=QPqvGr0dwvGcPSR zmVWdWo~v+>Jt_e1?wxPM9f}*@=7ywUaUQVh)m$dQj_4cz36)s}ke4@bP>VeeDY zzZ7$Yzw9A7-_vh5ufBY&kQk|P@=5Ddj^3+qzDLW z0Xdc@GQhDS{V)kSA>_)c+S^ygz~$txXL5#(1vQLVQ|AJ(mJvJ*q2FD(o$PuTSpZ=f z=c#d|t<%Dx)W5>mjF*zp*!^%!wlK>>?cry!l6CKVPi7yv7~0K@AmStY0p6A2HeT;T z@zKk~93MuvDO9Lq8R5bY1gtpE2{P<%G>?%hZvpp@uR1)szCnCDak=9Vw}LNTNTd0ZcQ@c`9zZ*})%B`#x2IV+c#Y z89Zx~PF_ko9YwW3&>y=`7xqZR&WcKEXyU#~TG zLry#Tu0F20a2T}XizAGT8MzzXz_CY0riM8qG|c2g5?{+ztY}-G*oWs|hVLeG3*Zj# z6k)^mpiIz2RXYY4D;P>ZJgtnm5*vZ)WlS_YC|SyR1l#xMvlFG*^|}V` zN7h#`TPErU*q%Osfx0i-3|4tqi#qp-Z2H@Ey#!s>(rU7Z1l&yeZzdk6ZyzmSw;4CU zZi)?vBg($~JE?iYWLe|qGhbmeFAP<PGA4H0u7!$=rIE@YvQ;eR!fNxLN-9^3csrWTKfu!5tmM15;Je z3JwLvPPojB7HhSAIC%w}dZM84Y#5C~pr6f23`!zNvO7$MzBVbQ zUW*x2XBmE8IoshHus@E&bNCgS#%Xu6yvN+x)5O9FQknK@6n7xsp{LsTlcZ9_B`&k4 z#qP8|0wg|VfJ@Hb-@i2~1<1Y&O%S)6`eyR-NA|m|dBt?8)D-Rzh5}ajm2;K!1I)48 zGw#KI(oNv0-R5bup8X>^fBGj`)UFScoE5t=qI=0%C?9$2Q@Z|5ds2VW{cl&OGD2^s zyQO+08-j+WDv#-r3S{6iQg~uMZK~z&F+Kgvb>k%Mhk8jY(E&2SeMv8PugX2Mj}&jM zh~}ztl`ORyct&{=ZG_NL{dzuF|2!X!Wl$GwL*J=d$?Eye`;8<9PQ!&^YqFSM$TX$Z zR`iFetx2n>Y0vu&1E-lyM-m%O3~v!^?_raSXn!3hQejg*Z~K{Vg!krkcz_NXr_^sv zz4nuS&xM{Tf!*Z(&W#%u#Mf_FL|3&UpqYjS?p4fv#9t}x$$(CAdZSfpXW!dVT&>q()cCf!oP= z;tf_Uc9@7;<;$!P>~e3!J|yrSAvGGywJpxsrO@x7w;%AMqrr8}%lPZn^hp3m1Fo{q z@uKfS-cWtOz3<>f`8kBtr(Yie{NQws7a($u*I=wOgwf*Fzd_nu2x)O0q0{af%oz&K0Im&=?U$nm z!*QXu#;2+gWo1gd_Jm?g*d6<6=cfJdCERq5Y~DWQE-DI@=;|NzGRv!PPlNV}vvYB( zV!i%jc#s==@7FH5K-w&swe~5$O{eBbWq<%AkIu6(}woW*M*3Y|5CnF-S%!PKC zL))D_Zq`KJ-TfshUq`TS#2jd#(cgRlcre8F7^I}-CqK*O@l ziEMkgih4e)G8DF8{f(-;gN~oyn=C5p*^7a1GFEh4&D-cMil5j&Z`68F9ji?>F4b>3 z?WC`JJt=@(Qr+2tcJ4uXkuzv;&aeUY*E?r3soC2@7m#B?!FACSkMqu5v-bQHQ}7V%jF!iccaLY~e^*D;hD z@qJIDLlKkGPe{-`pGva_Xs3oQ0NY3Cn2Sw1(sa7{P( z0sWw|^w2Ysv@xG{?h zv#4Tck9ec?3Ji;1v;zji{5OuO^m3h6Q;O(6R>Ev919O3Ft|ssN4u)YXdD51u8@Z1P z+h&=JQxY97yUQ2fb1B}{;?g*?s`zY6?17TP<}>P;NZyt01>*GdL6kXcJS}!aJgOOZ zl!Bzm%@o$_b&5^A;t?ZdgqxuBtRLUTO^luBCpmB%UJBJ<|AaOrA2J$cuLi|BO@9%C4+j7OwEPD8r3mpcB5=8}{qo9Bb2B z3$v7v=*K)mVxvO3-N}%&s7HVq3cp9v1VrA^geW?k2J!8IaU8P(?n3X6Nz{Wq2N8yM ze~yZ}*e69Db2_0nkQ|T%Gv=#M-KLGS8Iw~H_{MtQIJF+bbh8zA?h3_6{%GF;yX@G> zoF_V-UE!_^`02@Q&&*z0xl2pI7Tw2;2B&AN&J_321@Z6amfqFcc)pi-wnOM)e+zZg zen*|o^{bjWztj}Z%s0=HjXH0quDNyCQzU6Xd9|29vf{Ij+WZ^aq1IWkq*RWWX||;p z^jq)jq7wE2goKVnhzW+djdVm@^K2km5*C?jUWDYYp)=ncsGNfgk zCX*LPX}CV0n!_M-H(>ANxq-BnHb-UvT2k=3-XU+aatGH`^wydc(^2s|>fum8wb{D* zrK(G2-~bZyfE z1(+XJaLtPmqh$pY!0LWOu<5mkSYW;bSm@UJX2U_N`}y@X_Zf3vCS=Em!b zY|nDYvZM8`C$p(|vlb*!W&Z1qf8Ej>fTVB@vA9&1x<_*--X2SA-+5yz4wG-8GIt`{ z98SZTQ*?``?TnQYr9Mh`FqQ4O7>`22A6K=~P&h8%w10M(MCM$zz}Ad}b@0i8S+axL zUtcU&#}%l27e=_2gr9~S+}sZwAKeNg9HhPRP9+@7`ZUffo3%n#1|3%N1)~-6&nBX6 zMn}k*c&t8QA)SqTsPwZNQJxkeUV^`y+D(1e4!r~qi!aYOj4gO6cgUNNovrVdJ)dEF zkD2&4vIq5j%CbmOhlwpnEJ8_%-@48E({&Kk0*VF^BD`gxA_i?ZxiJ3%@N|fX+Tg7( z9vZ2HRckWf7D5MvMQNf%IHtpGpI6S9;#BaQex{2ne?dXvWF&axJa~9*HLjc)ml#n@kcru>oT=k>i4wz-^cuN+WZ!ZJI1hNvRE|T5&uv z6cNb%dug)5W<|O2R*RQ*>&*l$W0q#iLdY3IJO2AE@jOg&e_tiisZHS3YM(2^ zY5&iQ{sT%jDVEcQhzF;-0Pt6o8n(O5=d9O17YDpupMIUh&y&uNs{f=26{+zk&lW-4 zO_`7SGALN|!&o|v0EP*(ZK5=#dw3q*Rv3a-KPjzhj|oD!>4qZ5&}VLN20frzEj>a< z?ef+i*)RUR^i{Azg0kFjYE?j(?@gfHz0KWm#0tuX2lrjwBk~nF>WXfH2i^FHhg!yv+#%m+#3?2U6H^i=4O!|{iTw8ij;WM}PsF@wq%{CTi|xEDDKqWsvEu)I uu2FO&e~v0jmmi@W-c^ciSO!rH?tsRSFyB@<5+HO0UYFH%)QVLsasLatu;Fk3 literal 0 HcmV?d00001 From dd05f9b3b03e4550de434b40c68d09e936dc3ea2 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Tue, 18 Jun 2024 19:08:46 -0500 Subject: [PATCH 22/81] sizing Concurrence enum --- src/EnergyPlus/DataSizing.hh | 89 ++++++++++++++++----------- src/EnergyPlus/OutputReportTabular.cc | 2 +- src/EnergyPlus/ReportCoilSelection.cc | 66 +++++++++----------- src/EnergyPlus/ReportCoilSelection.hh | 5 +- src/EnergyPlus/SimAirServingZones.cc | 20 +++--- src/EnergyPlus/SizingManager.cc | 11 ++-- 6 files changed, 103 insertions(+), 90 deletions(-) diff --git a/src/EnergyPlus/DataSizing.hh b/src/EnergyPlus/DataSizing.hh index e8084964c3a..394c973082e 100644 --- a/src/EnergyPlus/DataSizing.hh +++ b/src/EnergyPlus/DataSizing.hh @@ -117,11 +117,28 @@ namespace DataSizing { Num }; - // parameters for sizing + // parameters for sizing (keept this for now to avoid plant sizing output changes) constexpr int NonCoincident(1); constexpr int Coincident(2); constexpr int Combination(3); + // parameters for sizing concurrence method + enum class Concurrence + { + Invalid = -1, + NonCoincident, + Coincident, + Combination, + NA, + Num + }; + + constexpr std::array(Concurrence::Num)> ConcurrenceMethodNamesUC{ + "NonCoincident", "Coincident", "Combination", "NA"}; + + constexpr std::array(Concurrence::Num)> ConcurrenceMethodNames{ + "Non-Coincident", "Coincident", "Combination", "N/A"}; + // parameters for Cooling Peak Load Type enum class PeakLoad { @@ -767,23 +784,23 @@ namespace DataSizing { struct SystemSizingInputData { // Members - std::string AirPriLoopName; // name of an AirLoopHVAC object - int AirLoopNum = 0; // index number of air loop - LoadSizing loadSizingType = LoadSizing::Invalid; // type of load to size on sensible, latent, total, ventilation - int SizingOption = 0; // 1 = noncoincident, 2 = coincident - OAControl CoolOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for cooling sizing - OAControl HeatOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for heating sizing - Real64 DesOutAirVolFlow = 0.0; // design (minimum) outside air flow rate [m3/s] - Real64 SysAirMinFlowRat = 0.0; // minimum system air flow ratio for heating, Central Heating Maximum System Air Flow Ratio - bool SysAirMinFlowRatWasAutoSized = false; // true if central heating maximum system air flow ratio was autosize on input - Real64 PreheatTemp = 0.0; // preheat design set temperature [C] - Real64 PrecoolTemp = 0.0; // precool design set temperature [C] - Real64 PreheatHumRat = 0.0; // preheat design humidity ratio [kg water/kg dry air] - Real64 PrecoolHumRat = 0.0; // precool design humidity ratio [kg water/kg dry air] - Real64 CoolSupTemp = 0.0; // cooling design supply air temperature [C] - Real64 HeatSupTemp = 0.0; // heating design supply air temperature [C] - Real64 CoolSupHumRat = 0.0; // cooling design supply air humidity ratio [kg water/kg dry air] - Real64 HeatSupHumRat = 0.0; // heating design supply air humidity ratio [kg water/kg dry air] + std::string AirPriLoopName; // name of an AirLoopHVAC object + int AirLoopNum = 0; // index number of air loop + LoadSizing loadSizingType = LoadSizing::Invalid; // type of load to size on sensible, latent, total, ventilation + DataSizing::Concurrence concurrenceMethod = DataSizing::Concurrence::Invalid; // noncoincident, coincident + OAControl CoolOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for cooling sizing + OAControl HeatOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for heating sizing + Real64 DesOutAirVolFlow = 0.0; // design (minimum) outside air flow rate [m3/s] + Real64 SysAirMinFlowRat = 0.0; // minimum system air flow ratio for heating, Central Heating Maximum System Air Flow Ratio + bool SysAirMinFlowRatWasAutoSized = false; // true if central heating maximum system air flow ratio was autosize on input + Real64 PreheatTemp = 0.0; // preheat design set temperature [C] + Real64 PrecoolTemp = 0.0; // precool design set temperature [C] + Real64 PreheatHumRat = 0.0; // preheat design humidity ratio [kg water/kg dry air] + Real64 PrecoolHumRat = 0.0; // precool design humidity ratio [kg water/kg dry air] + Real64 CoolSupTemp = 0.0; // cooling design supply air temperature [C] + Real64 HeatSupTemp = 0.0; // heating design supply air temperature [C] + Real64 CoolSupHumRat = 0.0; // cooling design supply air humidity ratio [kg water/kg dry air] + Real64 HeatSupHumRat = 0.0; // heating design supply air humidity ratio [kg water/kg dry air] AirflowSizingMethod CoolAirDesMethod = AirflowSizingMethod::Invalid; // choice of how to get system cooling design air flow rates; // 1 = calc from des day simulation; 2=m3/s per system, user input Real64 DesCoolAirFlow = 0.0; // design system supply air flow rate for cooling[m3/s] @@ -819,24 +836,24 @@ namespace DataSizing { struct SystemSizingData // Contains data for system sizing { // Members - std::string AirPriLoopName; // name of an AirLoopHVAC object - std::string CoolDesDay; // name of a cooling design day - std::string HeatDesDay; // name of a heating design day - LoadSizing loadSizingType = LoadSizing::Invalid; // type of load to size on Sensible, Latent, Total, Ventilation - int SizingOption = 0; // 1 = noncoincident, 2 = coincident. - OAControl CoolOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for cooling sizing - OAControl HeatOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for heating sizing - Real64 DesOutAirVolFlow = 0.0; // design (minimum) outside air flow rate [m3/s] - Real64 SysAirMinFlowRat = 0.0; // minimum system air flow ratio for heating, Central Heating Maximum System Air Flow Ratio - bool SysAirMinFlowRatWasAutoSized = false; // true if central heating maximum system air flow ratio was autosize on input - Real64 PreheatTemp = 0.0; // preheat design set temperature - Real64 PrecoolTemp = 0.0; // precool design set temperature [C] - Real64 PreheatHumRat = 0.0; // preheat design humidity ratio [kg water/kg dry air] - Real64 PrecoolHumRat = 0.0; // precool design humidity ratio [kg water/kg dry air] - Real64 CoolSupTemp = 0.0; // cooling design supply air temperature [C] - Real64 HeatSupTemp = 0.0; // heating design supply air temperature[C] - Real64 CoolSupHumRat = 0.0; // cooling design supply air humidity ratio [kg water/kg dry air] - Real64 HeatSupHumRat = 0.0; // heating design supply air humidity ratio [kg water/kg dry air] + std::string AirPriLoopName; // name of an AirLoopHVAC object + std::string CoolDesDay; // name of a cooling design day + std::string HeatDesDay; // name of a heating design day + LoadSizing loadSizingType = LoadSizing::Invalid; // type of load to size on Sensible, Latent, Total, Ventilation + DataSizing::Concurrence concurrenceMethod = DataSizing::Concurrence::Invalid; // noncoincident, coincident. + OAControl CoolOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for cooling sizing + OAControl HeatOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for heating sizing + Real64 DesOutAirVolFlow = 0.0; // design (minimum) outside air flow rate [m3/s] + Real64 SysAirMinFlowRat = 0.0; // minimum system air flow ratio for heating, Central Heating Maximum System Air Flow Ratio + bool SysAirMinFlowRatWasAutoSized = false; // true if central heating maximum system air flow ratio was autosize on input + Real64 PreheatTemp = 0.0; // preheat design set temperature + Real64 PrecoolTemp = 0.0; // precool design set temperature [C] + Real64 PreheatHumRat = 0.0; // preheat design humidity ratio [kg water/kg dry air] + Real64 PrecoolHumRat = 0.0; // precool design humidity ratio [kg water/kg dry air] + Real64 CoolSupTemp = 0.0; // cooling design supply air temperature [C] + Real64 HeatSupTemp = 0.0; // heating design supply air temperature[C] + Real64 CoolSupHumRat = 0.0; // cooling design supply air humidity ratio [kg water/kg dry air] + Real64 HeatSupHumRat = 0.0; // heating design supply air humidity ratio [kg water/kg dry air] AirflowSizingMethod CoolAirDesMethod = AirflowSizingMethod::Invalid; // choice of how to get system design cooling air flow rates; // 1 = calc from des day simulation; 2=m3/s per system, user input AirflowSizingMethod HeatAirDesMethod = AirflowSizingMethod::Invalid; // choice of how to get system design heating air flow rates; diff --git a/src/EnergyPlus/OutputReportTabular.cc b/src/EnergyPlus/OutputReportTabular.cc index 0e7af812b51..54bec06f4ea 100644 --- a/src/EnergyPlus/OutputReportTabular.cc +++ b/src/EnergyPlus/OutputReportTabular.cc @@ -15351,7 +15351,7 @@ void WriteLoadComponentSummaryTables(EnergyPlusData &state) } for (int SysSizIndex = 1; SysSizIndex <= state.dataSize->NumSysSizInput; ++SysSizIndex) { if (state.dataSize->SysSizInput(SysSizIndex).AirLoopNum != iAirLoop) continue; - if (state.dataSize->SysSizInput(SysSizIndex).SizingOption == DataSizing::Coincident) { + if (state.dataSize->SysSizInput(SysSizIndex).concurrenceMethod == DataSizing::Concurrence::Coincident) { airLoopCoolTable.peakDesSensLoad = finalSysSizing.SysCoolCoinSpaceSens; airLoopCoolTable.designPeakLoad = finalSysSizing.SysDesCoolLoad; diff --git a/src/EnergyPlus/ReportCoilSelection.cc b/src/EnergyPlus/ReportCoilSelection.cc index 183aa090711..64eaa9d801b 100644 --- a/src/EnergyPlus/ReportCoilSelection.cc +++ b/src/EnergyPlus/ReportCoilSelection.cc @@ -81,20 +81,20 @@ void createCoilSelectionReportObj(EnergyPlusData &state) CoilSelectionData::CoilSelectionData( // constructor std::string const &coilName) : isCooling(false), isHeating(false), coilNum(-999), airloopNum(-999), oaControllerNum(-999), zoneEqNum(-999), oASysNum(-999), zoneHVACTypeNum(0), - zoneHVACIndex(0), typeof_Coil(-999), coilSizingMethodConcurrence(-999), coilSizingMethodCapacity(-999), coilSizingMethodAirFlow(-999), - isCoilSizingForTotalLoad(false), capIsAutosized(false), volFlowIsAutosized(false), coilWaterFlowUser(-999.0), oaPretreated(false), - isSupplementalHeater(false), coilTotCapFinal(-999.0), coilSensCapFinal(-999.0), coilRefAirVolFlowFinal(-999.0), - coilRefWaterVolFlowFinal(-999.0), coilTotCapAtPeak(-999.0), coilSensCapAtPeak(-999.0), coilDesMassFlow(-999.0), coilDesVolFlow(-999.0), - coilDesEntTemp(-999.0), coilDesEntWetBulb(-999.0), coilDesEntHumRat(-999.0), coilDesEntEnth(-999.0), coilDesLvgTemp(-999.0), - coilDesLvgWetBulb(-999.0), coilDesLvgHumRat(-999.0), coilDesLvgEnth(-999.0), coilDesWaterMassFlow(-999.0), coilDesWaterEntTemp(-999.0), - coilDesWaterLvgTemp(-999.0), coilDesWaterTempDiff(-999.0), pltSizNum(-999), waterLoopNum(-999), oaPeakTemp(-999.00), oaPeakHumRat(-999.0), - oaPeakWetBulb(-999.0), oaPeakVolFlow(-999.0), oaPeakVolFrac(-999.0), oaDoaTemp(-999.0), oaDoaHumRat(-999.0), raPeakTemp(-999.0), - raPeakHumRat(-999.0), rmPeakTemp(-999.0), rmPeakHumRat(-999.0), rmPeakRelHum(-999.0), rmSensibleAtPeak(-999.0), rmLatentAtPeak(0.0), - coilIdealSizCapOverSimPeakCap(-999.0), coilIdealSizCapUnderSimPeakCap(-999.0), reheatLoadMult(-999.0), minRatio(-999.0), maxRatio(-999.0), - cpMoistAir(-999.0), cpDryAir(-999.0), rhoStandAir(-999.0), rhoFluid(-999.0), cpFluid(-999.0), coilCapFTIdealPeak(1.0), coilRatedTotCap(-999.0), - coilRatedSensCap(-999.0), ratedAirMassFlow(-999.0), ratedCoilInDb(-999.0), ratedCoilInWb(-999.0), ratedCoilInHumRat(-999.0), - ratedCoilInEnth(-999.0), ratedCoilOutDb(-999.0), ratedCoilOutWb(-999.0), ratedCoilOutHumRat(-999.0), ratedCoilOutEnth(-999.0), - ratedCoilEff(-999.0), ratedCoilBpFactor(-999.0), ratedCoilAppDewPt(-999.0), ratedCoilOadbRef(-999.0), ratedCoilOawbRef(-999.0), + zoneHVACIndex(0), typeof_Coil(-999), coilSizingMethodCapacity(-999), coilSizingMethodAirFlow(-999), isCoilSizingForTotalLoad(false), + capIsAutosized(false), volFlowIsAutosized(false), coilWaterFlowUser(-999.0), oaPretreated(false), isSupplementalHeater(false), + coilTotCapFinal(-999.0), coilSensCapFinal(-999.0), coilRefAirVolFlowFinal(-999.0), coilRefWaterVolFlowFinal(-999.0), coilTotCapAtPeak(-999.0), + coilSensCapAtPeak(-999.0), coilDesMassFlow(-999.0), coilDesVolFlow(-999.0), coilDesEntTemp(-999.0), coilDesEntWetBulb(-999.0), + coilDesEntHumRat(-999.0), coilDesEntEnth(-999.0), coilDesLvgTemp(-999.0), coilDesLvgWetBulb(-999.0), coilDesLvgHumRat(-999.0), + coilDesLvgEnth(-999.0), coilDesWaterMassFlow(-999.0), coilDesWaterEntTemp(-999.0), coilDesWaterLvgTemp(-999.0), coilDesWaterTempDiff(-999.0), + pltSizNum(-999), waterLoopNum(-999), oaPeakTemp(-999.00), oaPeakHumRat(-999.0), oaPeakWetBulb(-999.0), oaPeakVolFlow(-999.0), + oaPeakVolFrac(-999.0), oaDoaTemp(-999.0), oaDoaHumRat(-999.0), raPeakTemp(-999.0), raPeakHumRat(-999.0), rmPeakTemp(-999.0), + rmPeakHumRat(-999.0), rmPeakRelHum(-999.0), rmSensibleAtPeak(-999.0), rmLatentAtPeak(0.0), coilIdealSizCapOverSimPeakCap(-999.0), + coilIdealSizCapUnderSimPeakCap(-999.0), reheatLoadMult(-999.0), minRatio(-999.0), maxRatio(-999.0), cpMoistAir(-999.0), cpDryAir(-999.0), + rhoStandAir(-999.0), rhoFluid(-999.0), cpFluid(-999.0), coilCapFTIdealPeak(1.0), coilRatedTotCap(-999.0), coilRatedSensCap(-999.0), + ratedAirMassFlow(-999.0), ratedCoilInDb(-999.0), ratedCoilInWb(-999.0), ratedCoilInHumRat(-999.0), ratedCoilInEnth(-999.0), + ratedCoilOutDb(-999.0), ratedCoilOutWb(-999.0), ratedCoilOutHumRat(-999.0), ratedCoilOutEnth(-999.0), ratedCoilEff(-999.0), + ratedCoilBpFactor(-999.0), ratedCoilAppDewPt(-999.0), ratedCoilOadbRef(-999.0), ratedCoilOawbRef(-999.0), supFanType(HVAC::FanType::Invalid), supFanNum(0), fanSizeMaxAirVolumeFlow(-999.0), fanSizeMaxAirMassFlow(-999.0), fanHeatGainIdealPeak(-999.0), coilAndFanNetTotalCapacityIdealPeak(-999.0), plantDesMaxMassFlowRate(-999.0), plantDesRetTemp(-999.0), plantDesSupTemp(-999.0), @@ -734,15 +734,7 @@ void ReportCoilSelection::doFinalProcessingOfCoilData(EnergyPlusData &state) c->oaPeakVolFrac = -999.0; } - if (c->coilSizingMethodConcurrence == DataSizing::NonCoincident) { - c->coilSizingMethodConcurrenceName = "Non-Coincident"; - } else if (c->coilSizingMethodConcurrence == DataSizing::Coincident) { - c->coilSizingMethodConcurrenceName = "Coincident"; - } else if (c->coilSizingMethodConcurrence == DataSizing::Combination) { - c->coilSizingMethodConcurrenceName = "Combination"; - } else { - c->coilSizingMethodConcurrenceName = "N/A"; - } + c->coilSizingMethodConcurrenceName = DataSizing::ConcurrenceMethodNames[(int)c->coilSizingMethodConcurrence]; if (c->coilSizingMethodCapacity == DataSizing::CoolingDesignCapacity) { c->coilSizingMethodCapacityName = "CoolingDesignCapacity"; @@ -1272,7 +1264,7 @@ void ReportCoilSelection::setCoilCoolingCapacity( c->oaPeakHumRat = finalSysSizing.OutHumRatAtCoolPeak; c->raPeakTemp = finalSysSizing.RetTempAtCoolPeak; c->raPeakHumRat = finalSysSizing.RetHumRatAtCoolPeak; - c->coilSizingMethodConcurrence = finalSysSizing.SizingOption; + c->coilSizingMethodConcurrence = finalSysSizing.concurrenceMethod; c->coilSizingMethodCapacity = finalSysSizing.CoolingCapMethod; c->coilSizingMethodAirFlow = finalSysSizing.ScaleCoolSAFMethod; // DesOutAirVolFlow @@ -1331,9 +1323,9 @@ void ReportCoilSelection::setCoilCoolingCapacity( c->rmPeakRelHum = -999.0; } - if (c->coilSizingMethodConcurrence == DataSizing::Coincident) { + if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::Coincident) { c->rmSensibleAtPeak = finalSysSizing.SysCoolCoinSpaceSens; - } else if (c->coilSizingMethodConcurrence == DataSizing::NonCoincident) { + } else if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::NonCoincident) { c->rmSensibleAtPeak = sumSensLoad; } else { // DataSizing::Combination or other c->rmSensibleAtPeak = sumSensLoad; @@ -1478,14 +1470,14 @@ void ReportCoilSelection::setCoilCoolingCapacity( state, c->coilDesLvgTemp, c->coilDesLvgHumRat, state.dataEnvrn->StdBaroPress, "ReportCoilSelection::setCoilCoolingCapacity"); c->coilDesLvgEnth = Psychrometrics::PsyHFnTdbW(c->coilDesLvgTemp, c->coilDesLvgHumRat); } - int sizMethod = 0; + DataSizing::Concurrence sizMethod = DataSizing::Concurrence::Invalid; bool sizMethodsAreTheSame = true; for (int airLoopNum = 0; airLoopNum < state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].NumOfAirLoops; ++airLoopNum) { int actualAirLoopNum = state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].m_AirLoopNum[airLoopNum]; if (airLoopNum == 0) { - sizMethod = state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption; + sizMethod = state.dataSize->FinalSysSizing(actualAirLoopNum).concurrenceMethod; } else { - if (sizMethod != state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption) { + if (sizMethod != state.dataSize->FinalSysSizing(actualAirLoopNum).concurrenceMethod) { sizMethodsAreTheSame = false; } } @@ -1493,7 +1485,7 @@ void ReportCoilSelection::setCoilCoolingCapacity( if (sizMethodsAreTheSame) { c->coilSizingMethodConcurrence = sizMethod; } else { - c->coilSizingMethodConcurrence = DataSizing::Combination; + c->coilSizingMethodConcurrence = DataSizing::Concurrence::Combination; } } } else { @@ -1541,7 +1533,7 @@ void ReportCoilSelection::setCoilHeatingCapacity( c->oaPeakVolFlow = finalSysSizing.DesOutAirVolFlow; c->raPeakTemp = finalSysSizing.HeatRetTemp; c->raPeakHumRat = finalSysSizing.HeatRetHumRat; - c->coilSizingMethodConcurrence = finalSysSizing.SizingOption; + c->coilSizingMethodConcurrence = finalSysSizing.concurrenceMethod; c->coilSizingMethodCapacity = finalSysSizing.HeatingCapMethod; c->coilSizingMethodAirFlow = finalSysSizing.ScaleHeatSAFMethod; @@ -1596,9 +1588,9 @@ void ReportCoilSelection::setCoilHeatingCapacity( c->rmPeakRelHum = -999.0; } - if (c->coilSizingMethodConcurrence == DataSizing::Coincident) { + if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::Coincident) { c->rmSensibleAtPeak = finalSysSizing.SysHeatCoinSpaceSens; - } else if (c->coilSizingMethodConcurrence == DataSizing::NonCoincident) { + } else if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::NonCoincident) { c->rmSensibleAtPeak = sumLoad; } @@ -1775,14 +1767,14 @@ void ReportCoilSelection::setCoilHeatingCapacity( state, c->coilDesLvgTemp, c->coilDesLvgHumRat, state.dataEnvrn->StdBaroPress, "ReportCoilSelection::setCoilHeatingCapacity"); c->coilDesLvgEnth = Psychrometrics::PsyHFnTdbW(c->coilDesLvgTemp, c->coilDesLvgHumRat); } - int sizMethod = 0; + DataSizing::Concurrence sizMethod = DataSizing::Concurrence::Invalid; bool sizMethodsAreTheSame = true; for (int airLoopNum = 0; airLoopNum < state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].NumOfAirLoops; ++airLoopNum) { int actualAirLoopNum = state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].m_AirLoopNum[airLoopNum]; if (airLoopNum == 0) { - sizMethod = state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption; + sizMethod = state.dataSize->FinalSysSizing(actualAirLoopNum).concurrenceMethod; } else { - if (sizMethod != state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption) { + if (sizMethod != state.dataSize->FinalSysSizing(actualAirLoopNum).concurrenceMethod) { sizMethodsAreTheSame = false; } } @@ -1790,7 +1782,7 @@ void ReportCoilSelection::setCoilHeatingCapacity( if (sizMethodsAreTheSame) { c->coilSizingMethodConcurrence = sizMethod; } else { - c->coilSizingMethodConcurrence = DataSizing::Combination; + c->coilSizingMethodConcurrence = DataSizing::Concurrence::Combination; } } } else { diff --git a/src/EnergyPlus/ReportCoilSelection.hh b/src/EnergyPlus/ReportCoilSelection.hh index 105b82899f7..d15bf87a2e0 100644 --- a/src/EnergyPlus/ReportCoilSelection.hh +++ b/src/EnergyPlus/ReportCoilSelection.hh @@ -56,6 +56,7 @@ // EnergyPlus Headers #include #include +#include #include namespace EnergyPlus { @@ -98,8 +99,8 @@ public: // data int typeof_Coil; // type of coil, e.g., PlantEquipmentType::CoilWaterSimpleHeating, PlantEquipmentType::CoilWaterDetailedFlatCooling, // PlantEquipmentType::CoilWaterCooling - int coilSizingMethodConcurrence; // 1 = noncoincident, 2 = coincident - std::string coilSizingMethodConcurrenceName; // string name of sizing method for concurrence + DataSizing::Concurrence coilSizingMethodConcurrence = DataSizing::Concurrence::NA; // non-coincident, coincident, combination, n/a + std::string coilSizingMethodConcurrenceName; // string name of sizing method for concurrence int coilSizingMethodCapacity; // 8=CoolingDesignCapacity, 9=HeatingDesignCapacity, 10=CapacityPerFloorArea, 11=FractionOfAutosizedCoolingCapacity, // 12=FractionOfAutosizedHeatingCapacity diff --git a/src/EnergyPlus/SimAirServingZones.cc b/src/EnergyPlus/SimAirServingZones.cc index d4f4fb9436e..20acbda6bee 100644 --- a/src/EnergyPlus/SimAirServingZones.cc +++ b/src/EnergyPlus/SimAirServingZones.cc @@ -4162,7 +4162,7 @@ void SetUpSysSizingArrays(EnergyPlusData &state) sysSizing.HeatSupTemp = sysSizInput.HeatSupTemp; sysSizing.CoolSupHumRat = sysSizInput.CoolSupHumRat; sysSizing.HeatSupHumRat = sysSizInput.HeatSupHumRat; - sysSizing.SizingOption = sysSizInput.SizingOption; + sysSizing.concurrenceMethod = sysSizInput.concurrenceMethod; if (primaryAirSystems.isAllOA) { sysSizing.CoolOAOption = OAControl::AllOA; sysSizing.HeatOAOption = OAControl::AllOA; @@ -4223,7 +4223,7 @@ void SetUpSysSizingArrays(EnergyPlusData &state) finalSysSizing.HeatSupTemp = sysSizInput.HeatSupTemp; finalSysSizing.CoolSupHumRat = sysSizInput.CoolSupHumRat; finalSysSizing.HeatSupHumRat = sysSizInput.HeatSupHumRat; - finalSysSizing.SizingOption = sysSizInput.SizingOption; + finalSysSizing.concurrenceMethod = sysSizInput.concurrenceMethod; finalSysSizing.CoolAirDesMethod = sysSizInput.CoolAirDesMethod; finalSysSizing.HeatAirDesMethod = sysSizInput.HeatAirDesMethod; finalSysSizing.ScaleCoolSAFMethod = sysSizInput.ScaleCoolSAFMethod; @@ -4270,7 +4270,7 @@ void SetUpSysSizingArrays(EnergyPlusData &state) calcSysSizing.HeatSupTemp = sysSizInput.HeatSupTemp; calcSysSizing.CoolSupHumRat = sysSizInput.CoolSupHumRat; calcSysSizing.HeatSupHumRat = sysSizInput.HeatSupHumRat; - calcSysSizing.SizingOption = sysSizInput.SizingOption; + calcSysSizing.concurrenceMethod = sysSizInput.concurrenceMethod; calcSysSizing.CoolAirDesMethod = sysSizInput.CoolAirDesMethod; calcSysSizing.HeatAirDesMethod = sysSizInput.HeatAirDesMethod; calcSysSizing.ScaleCoolSAFMethod = sysSizInput.ScaleCoolSAFMethod; @@ -5509,8 +5509,8 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn int NumZonesHeated = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated; auto &sysSizing = state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum); - switch (sysSizing.SizingOption) { - case Coincident: { + switch (sysSizing.concurrenceMethod) { + case DataSizing::Concurrence::Coincident: { if (finalSysSizing.SystemOAMethod == SysOAMethod::ZoneSum) { sysSizing.DesCoolVolFlow = sysSizing.CoinCoolMassFlow / state.dataEnvrn->StdRhoAir; sysSizing.DesHeatVolFlow = sysSizing.CoinHeatMassFlow / state.dataEnvrn->StdRhoAir; @@ -5841,7 +5841,7 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn sysSizing.DesMainVolFlow = max(sysSizing.DesCoolVolFlow, sysSizing.DesHeatVolFlow); // this should also be as least as big as is needed for Vot } break; - case NonCoincident: { + case DataSizing::Concurrence::NonCoincident: { if (finalSysSizing.SystemOAMethod == SysOAMethod::ZoneSum) { sysSizing.DesCoolVolFlow = sysSizing.NonCoinCoolMassFlow / state.dataEnvrn->StdRhoAir; sysSizing.DesHeatVolFlow = sysSizing.NonCoinHeatMassFlow / state.dataEnvrn->StdRhoAir; @@ -6540,7 +6540,7 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn } // move the noncoincident results into the system sizing array - if (state.dataSize->CalcSysSizing(AirLoopNum).SizingOption == NonCoincident) { + if (state.dataSize->CalcSysSizing(AirLoopNum).concurrenceMethod == DataSizing::Concurrence::NonCoincident) { // But first check to see if the noncoincident result is actually bigger than the coincident (for 100% outside air) if (!(state.dataSize->FinalSysSizing(AirLoopNum).CoolOAOption == OAControl::AllOA && SysSensCoolCap <= 0.0)) { // CoolOAOption = Yes 100% OA @@ -6761,7 +6761,8 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn ZoneOARatio = 0.0; } state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).scaleZoneCooling(ZoneOARatio); - } else if ((SysCoolSizingRat > 1.0) || (SysCoolSizingRat < 1.0 && finalSysSizing.SizingOption == NonCoincident)) { + } else if ((SysCoolSizingRat > 1.0) || + (SysCoolSizingRat < 1.0 && finalSysSizing.concurrenceMethod == DataSizing::Concurrence::NonCoincident)) { // size on user input system design flows state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).scaleZoneCooling(SysCoolSizingRat); } @@ -6821,7 +6822,8 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn ZoneOARatio = termUnitFinalZoneSizing.MinOA / max(termUnitFinalZoneSizing.DesHeatVolFlow, termUnitFinalZoneSizing.MinOA); ZoneOARatio *= (1.0 + state.dataSize->TermUnitSizing(TermUnitSizingIndex).InducRat); termUnitFinalZoneSizing.scaleZoneHeating(ZoneOARatio); - } else if ((SysHeatSizingRat > 1.0) || (SysHeatSizingRat < 1.0 && finalSysSizing.SizingOption == NonCoincident)) { + } else if ((SysHeatSizingRat > 1.0) || + (SysHeatSizingRat < 1.0 && finalSysSizing.concurrenceMethod == DataSizing::Concurrence::NonCoincident)) { // size on user input system design flows termUnitFinalZoneSizing.scaleZoneHeating(SysHeatSizingRat); } diff --git a/src/EnergyPlus/SizingManager.cc b/src/EnergyPlus/SizingManager.cc index 9d2c1b6f5f4..330dd875faa 100644 --- a/src/EnergyPlus/SizingManager.cc +++ b/src/EnergyPlus/SizingManager.cc @@ -1115,8 +1115,9 @@ void ManageSystemSizingAdjustments(EnergyPlusData &state) if (allocated(FinalSysSizing)) { // correct sizing design heating volume flow rate based on finalized air terminal unit operation - if (FinalSysSizing(AirLoopNum).SizingOption == - NonCoincident) { // If non-coincident sizing method for this air loop, the we can use these sum's from air terminals directly + if (FinalSysSizing(AirLoopNum).concurrenceMethod == + DataSizing::Concurrence::NonCoincident) { // If non-coincident sizing method for this air loop, the we can use these sum's from + // air terminals directly FinalSysSizing(AirLoopNum).DesHeatVolFlow = max(airLoopHeatingMaximumFlowRateSum, FinalSysSizing(AirLoopNum).DesHeatVolFlow); FinalSysSizing(AirLoopNum).DesMainVolFlow = max(airLoopMaxFlowRateSum, FinalSysSizing(AirLoopNum).DesMainVolFlow); if (FinalSysSizing(AirLoopNum).sysSizeCoolingDominant) { @@ -1126,7 +1127,7 @@ void ManageSystemSizingAdjustments(EnergyPlusData &state) FinalSysSizing(AirLoopNum).DesCoolVolFlow = max(airLoopHeatingMinimumFlowRateSum, FinalSysSizing(AirLoopNum).DesCoolVolFlow); FinalSysSizing(AirLoopNum).MassFlowAtCoolPeak = FinalSysSizing(AirLoopNum).DesCoolVolFlow * state.dataEnvrn->StdRhoAir; } - } else if (FinalSysSizing(AirLoopNum).SizingOption == Coincident) { + } else if (FinalSysSizing(AirLoopNum).concurrenceMethod == DataSizing::Concurrence::Coincident) { if (FinalSysSizing(AirLoopNum).sysSizeCoolingDominant) { // use minimum heating flow sum from air terminals // know that minimum heating flow is a hard minimum regardless of concurrence situation, so make sure that design is at @@ -3578,9 +3579,9 @@ void GetSystemSizingInput(EnergyPlusData &state) { std::string const &sizingOption = state.dataIPShortCut->cAlphaArgs(iSizingOptionAlphaNum); if (sizingOption == "COINCIDENT") { - SysSizInput(SysSizIndex).SizingOption = Coincident; + SysSizInput(SysSizIndex).concurrenceMethod = DataSizing::Concurrence::Coincident; } else if (sizingOption == "NONCOINCIDENT") { - SysSizInput(SysSizIndex).SizingOption = NonCoincident; + SysSizInput(SysSizIndex).concurrenceMethod = DataSizing::Concurrence::NonCoincident; } else { ShowSevereError(state, format("{}=\"{}\", invalid data.", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(iNameAlphaNum))); ShowContinueError(state, From c8aa4b3c68c71bd64660884af62175b6c451b9b4 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Wed, 19 Jun 2024 08:06:43 -0500 Subject: [PATCH 23/81] Fix and rollback --- src/EnergyPlus/DataSizing.hh | 30 +++++++++---------- src/EnergyPlus/OutputReportTabular.cc | 2 +- src/EnergyPlus/ReportCoilSelection.cc | 12 ++++---- src/EnergyPlus/SimAirServingZones.cc | 14 ++++----- src/EnergyPlus/SizingManager.cc | 8 ++--- .../unit/DesiccantDehumidifiers.unit.cc | 2 +- .../unit/OutputReportTabular.unit.cc | 7 ++--- 7 files changed, 36 insertions(+), 39 deletions(-) diff --git a/src/EnergyPlus/DataSizing.hh b/src/EnergyPlus/DataSizing.hh index 394c973082e..63d7d2a9e56 100644 --- a/src/EnergyPlus/DataSizing.hh +++ b/src/EnergyPlus/DataSizing.hh @@ -784,13 +784,13 @@ namespace DataSizing { struct SystemSizingInputData { // Members - std::string AirPriLoopName; // name of an AirLoopHVAC object - int AirLoopNum = 0; // index number of air loop - LoadSizing loadSizingType = LoadSizing::Invalid; // type of load to size on sensible, latent, total, ventilation - DataSizing::Concurrence concurrenceMethod = DataSizing::Concurrence::Invalid; // noncoincident, coincident - OAControl CoolOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for cooling sizing - OAControl HeatOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for heating sizing - Real64 DesOutAirVolFlow = 0.0; // design (minimum) outside air flow rate [m3/s] + std::string AirPriLoopName; // name of an AirLoopHVAC object + int AirLoopNum = 0; // index number of air loop + LoadSizing loadSizingType = LoadSizing::Invalid; // type of load to size on sensible, latent, total, ventilation + DataSizing::Concurrence SizingOption = DataSizing::Concurrence::NonCoincident; // noncoincident, coincident + OAControl CoolOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for cooling sizing + OAControl HeatOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for heating sizing + Real64 DesOutAirVolFlow = 0.0; // design (minimum) outside air flow rate [m3/s] Real64 SysAirMinFlowRat = 0.0; // minimum system air flow ratio for heating, Central Heating Maximum System Air Flow Ratio bool SysAirMinFlowRatWasAutoSized = false; // true if central heating maximum system air flow ratio was autosize on input Real64 PreheatTemp = 0.0; // preheat design set temperature [C] @@ -836,14 +836,14 @@ namespace DataSizing { struct SystemSizingData // Contains data for system sizing { // Members - std::string AirPriLoopName; // name of an AirLoopHVAC object - std::string CoolDesDay; // name of a cooling design day - std::string HeatDesDay; // name of a heating design day - LoadSizing loadSizingType = LoadSizing::Invalid; // type of load to size on Sensible, Latent, Total, Ventilation - DataSizing::Concurrence concurrenceMethod = DataSizing::Concurrence::Invalid; // noncoincident, coincident. - OAControl CoolOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for cooling sizing - OAControl HeatOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for heating sizing - Real64 DesOutAirVolFlow = 0.0; // design (minimum) outside air flow rate [m3/s] + std::string AirPriLoopName; // name of an AirLoopHVAC object + std::string CoolDesDay; // name of a cooling design day + std::string HeatDesDay; // name of a heating design day + LoadSizing loadSizingType = LoadSizing::Invalid; // type of load to size on Sensible, Latent, Total, Ventilation + DataSizing::Concurrence SizingOption = DataSizing::Concurrence::NonCoincident; // noncoincident, coincident. + OAControl CoolOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for cooling sizing + OAControl HeatOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for heating sizing + Real64 DesOutAirVolFlow = 0.0; // design (minimum) outside air flow rate [m3/s] Real64 SysAirMinFlowRat = 0.0; // minimum system air flow ratio for heating, Central Heating Maximum System Air Flow Ratio bool SysAirMinFlowRatWasAutoSized = false; // true if central heating maximum system air flow ratio was autosize on input Real64 PreheatTemp = 0.0; // preheat design set temperature diff --git a/src/EnergyPlus/OutputReportTabular.cc b/src/EnergyPlus/OutputReportTabular.cc index 54bec06f4ea..821fc171110 100644 --- a/src/EnergyPlus/OutputReportTabular.cc +++ b/src/EnergyPlus/OutputReportTabular.cc @@ -15351,7 +15351,7 @@ void WriteLoadComponentSummaryTables(EnergyPlusData &state) } for (int SysSizIndex = 1; SysSizIndex <= state.dataSize->NumSysSizInput; ++SysSizIndex) { if (state.dataSize->SysSizInput(SysSizIndex).AirLoopNum != iAirLoop) continue; - if (state.dataSize->SysSizInput(SysSizIndex).concurrenceMethod == DataSizing::Concurrence::Coincident) { + if (state.dataSize->SysSizInput(SysSizIndex).SizingOption == DataSizing::Concurrence::Coincident) { airLoopCoolTable.peakDesSensLoad = finalSysSizing.SysCoolCoinSpaceSens; airLoopCoolTable.designPeakLoad = finalSysSizing.SysDesCoolLoad; diff --git a/src/EnergyPlus/ReportCoilSelection.cc b/src/EnergyPlus/ReportCoilSelection.cc index 64eaa9d801b..50841801321 100644 --- a/src/EnergyPlus/ReportCoilSelection.cc +++ b/src/EnergyPlus/ReportCoilSelection.cc @@ -1264,7 +1264,7 @@ void ReportCoilSelection::setCoilCoolingCapacity( c->oaPeakHumRat = finalSysSizing.OutHumRatAtCoolPeak; c->raPeakTemp = finalSysSizing.RetTempAtCoolPeak; c->raPeakHumRat = finalSysSizing.RetHumRatAtCoolPeak; - c->coilSizingMethodConcurrence = finalSysSizing.concurrenceMethod; + c->coilSizingMethodConcurrence = finalSysSizing.SizingOption; c->coilSizingMethodCapacity = finalSysSizing.CoolingCapMethod; c->coilSizingMethodAirFlow = finalSysSizing.ScaleCoolSAFMethod; // DesOutAirVolFlow @@ -1475,9 +1475,9 @@ void ReportCoilSelection::setCoilCoolingCapacity( for (int airLoopNum = 0; airLoopNum < state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].NumOfAirLoops; ++airLoopNum) { int actualAirLoopNum = state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].m_AirLoopNum[airLoopNum]; if (airLoopNum == 0) { - sizMethod = state.dataSize->FinalSysSizing(actualAirLoopNum).concurrenceMethod; + sizMethod = state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption; } else { - if (sizMethod != state.dataSize->FinalSysSizing(actualAirLoopNum).concurrenceMethod) { + if (sizMethod != state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption) { sizMethodsAreTheSame = false; } } @@ -1533,7 +1533,7 @@ void ReportCoilSelection::setCoilHeatingCapacity( c->oaPeakVolFlow = finalSysSizing.DesOutAirVolFlow; c->raPeakTemp = finalSysSizing.HeatRetTemp; c->raPeakHumRat = finalSysSizing.HeatRetHumRat; - c->coilSizingMethodConcurrence = finalSysSizing.concurrenceMethod; + c->coilSizingMethodConcurrence = finalSysSizing.SizingOption; c->coilSizingMethodCapacity = finalSysSizing.HeatingCapMethod; c->coilSizingMethodAirFlow = finalSysSizing.ScaleHeatSAFMethod; @@ -1772,9 +1772,9 @@ void ReportCoilSelection::setCoilHeatingCapacity( for (int airLoopNum = 0; airLoopNum < state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].NumOfAirLoops; ++airLoopNum) { int actualAirLoopNum = state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].m_AirLoopNum[airLoopNum]; if (airLoopNum == 0) { - sizMethod = state.dataSize->FinalSysSizing(actualAirLoopNum).concurrenceMethod; + sizMethod = state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption; } else { - if (sizMethod != state.dataSize->FinalSysSizing(actualAirLoopNum).concurrenceMethod) { + if (sizMethod != state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption) { sizMethodsAreTheSame = false; } } diff --git a/src/EnergyPlus/SimAirServingZones.cc b/src/EnergyPlus/SimAirServingZones.cc index 20acbda6bee..494351d0478 100644 --- a/src/EnergyPlus/SimAirServingZones.cc +++ b/src/EnergyPlus/SimAirServingZones.cc @@ -4162,7 +4162,7 @@ void SetUpSysSizingArrays(EnergyPlusData &state) sysSizing.HeatSupTemp = sysSizInput.HeatSupTemp; sysSizing.CoolSupHumRat = sysSizInput.CoolSupHumRat; sysSizing.HeatSupHumRat = sysSizInput.HeatSupHumRat; - sysSizing.concurrenceMethod = sysSizInput.concurrenceMethod; + sysSizing.SizingOption = sysSizInput.SizingOption; if (primaryAirSystems.isAllOA) { sysSizing.CoolOAOption = OAControl::AllOA; sysSizing.HeatOAOption = OAControl::AllOA; @@ -4223,7 +4223,7 @@ void SetUpSysSizingArrays(EnergyPlusData &state) finalSysSizing.HeatSupTemp = sysSizInput.HeatSupTemp; finalSysSizing.CoolSupHumRat = sysSizInput.CoolSupHumRat; finalSysSizing.HeatSupHumRat = sysSizInput.HeatSupHumRat; - finalSysSizing.concurrenceMethod = sysSizInput.concurrenceMethod; + finalSysSizing.SizingOption = sysSizInput.SizingOption; finalSysSizing.CoolAirDesMethod = sysSizInput.CoolAirDesMethod; finalSysSizing.HeatAirDesMethod = sysSizInput.HeatAirDesMethod; finalSysSizing.ScaleCoolSAFMethod = sysSizInput.ScaleCoolSAFMethod; @@ -4270,7 +4270,7 @@ void SetUpSysSizingArrays(EnergyPlusData &state) calcSysSizing.HeatSupTemp = sysSizInput.HeatSupTemp; calcSysSizing.CoolSupHumRat = sysSizInput.CoolSupHumRat; calcSysSizing.HeatSupHumRat = sysSizInput.HeatSupHumRat; - calcSysSizing.concurrenceMethod = sysSizInput.concurrenceMethod; + calcSysSizing.SizingOption = sysSizInput.SizingOption; calcSysSizing.CoolAirDesMethod = sysSizInput.CoolAirDesMethod; calcSysSizing.HeatAirDesMethod = sysSizInput.HeatAirDesMethod; calcSysSizing.ScaleCoolSAFMethod = sysSizInput.ScaleCoolSAFMethod; @@ -5509,7 +5509,7 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn int NumZonesHeated = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated; auto &sysSizing = state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum); - switch (sysSizing.concurrenceMethod) { + switch (sysSizing.SizingOption) { case DataSizing::Concurrence::Coincident: { if (finalSysSizing.SystemOAMethod == SysOAMethod::ZoneSum) { sysSizing.DesCoolVolFlow = sysSizing.CoinCoolMassFlow / state.dataEnvrn->StdRhoAir; @@ -6540,7 +6540,7 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn } // move the noncoincident results into the system sizing array - if (state.dataSize->CalcSysSizing(AirLoopNum).concurrenceMethod == DataSizing::Concurrence::NonCoincident) { + if (state.dataSize->CalcSysSizing(AirLoopNum).SizingOption == DataSizing::Concurrence::NonCoincident) { // But first check to see if the noncoincident result is actually bigger than the coincident (for 100% outside air) if (!(state.dataSize->FinalSysSizing(AirLoopNum).CoolOAOption == OAControl::AllOA && SysSensCoolCap <= 0.0)) { // CoolOAOption = Yes 100% OA @@ -6762,7 +6762,7 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn } state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).scaleZoneCooling(ZoneOARatio); } else if ((SysCoolSizingRat > 1.0) || - (SysCoolSizingRat < 1.0 && finalSysSizing.concurrenceMethod == DataSizing::Concurrence::NonCoincident)) { + (SysCoolSizingRat < 1.0 && finalSysSizing.SizingOption == DataSizing::Concurrence::NonCoincident)) { // size on user input system design flows state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).scaleZoneCooling(SysCoolSizingRat); } @@ -6823,7 +6823,7 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn ZoneOARatio *= (1.0 + state.dataSize->TermUnitSizing(TermUnitSizingIndex).InducRat); termUnitFinalZoneSizing.scaleZoneHeating(ZoneOARatio); } else if ((SysHeatSizingRat > 1.0) || - (SysHeatSizingRat < 1.0 && finalSysSizing.concurrenceMethod == DataSizing::Concurrence::NonCoincident)) { + (SysHeatSizingRat < 1.0 && finalSysSizing.SizingOption == DataSizing::Concurrence::NonCoincident)) { // size on user input system design flows termUnitFinalZoneSizing.scaleZoneHeating(SysHeatSizingRat); } diff --git a/src/EnergyPlus/SizingManager.cc b/src/EnergyPlus/SizingManager.cc index 330dd875faa..8d5234b82bf 100644 --- a/src/EnergyPlus/SizingManager.cc +++ b/src/EnergyPlus/SizingManager.cc @@ -1115,7 +1115,7 @@ void ManageSystemSizingAdjustments(EnergyPlusData &state) if (allocated(FinalSysSizing)) { // correct sizing design heating volume flow rate based on finalized air terminal unit operation - if (FinalSysSizing(AirLoopNum).concurrenceMethod == + if (FinalSysSizing(AirLoopNum).SizingOption == DataSizing::Concurrence::NonCoincident) { // If non-coincident sizing method for this air loop, the we can use these sum's from // air terminals directly FinalSysSizing(AirLoopNum).DesHeatVolFlow = max(airLoopHeatingMaximumFlowRateSum, FinalSysSizing(AirLoopNum).DesHeatVolFlow); @@ -1127,7 +1127,7 @@ void ManageSystemSizingAdjustments(EnergyPlusData &state) FinalSysSizing(AirLoopNum).DesCoolVolFlow = max(airLoopHeatingMinimumFlowRateSum, FinalSysSizing(AirLoopNum).DesCoolVolFlow); FinalSysSizing(AirLoopNum).MassFlowAtCoolPeak = FinalSysSizing(AirLoopNum).DesCoolVolFlow * state.dataEnvrn->StdRhoAir; } - } else if (FinalSysSizing(AirLoopNum).concurrenceMethod == DataSizing::Concurrence::Coincident) { + } else if (FinalSysSizing(AirLoopNum).SizingOption == DataSizing::Concurrence::Coincident) { if (FinalSysSizing(AirLoopNum).sysSizeCoolingDominant) { // use minimum heating flow sum from air terminals // know that minimum heating flow is a hard minimum regardless of concurrence situation, so make sure that design is at @@ -3579,9 +3579,9 @@ void GetSystemSizingInput(EnergyPlusData &state) { std::string const &sizingOption = state.dataIPShortCut->cAlphaArgs(iSizingOptionAlphaNum); if (sizingOption == "COINCIDENT") { - SysSizInput(SysSizIndex).concurrenceMethod = DataSizing::Concurrence::Coincident; + SysSizInput(SysSizIndex).SizingOption = DataSizing::Concurrence::Coincident; } else if (sizingOption == "NONCOINCIDENT") { - SysSizInput(SysSizIndex).concurrenceMethod = DataSizing::Concurrence::NonCoincident; + SysSizInput(SysSizIndex).SizingOption = DataSizing::Concurrence::NonCoincident; } else { ShowSevereError(state, format("{}=\"{}\", invalid data.", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(iNameAlphaNum))); ShowContinueError(state, diff --git a/tst/EnergyPlus/unit/DesiccantDehumidifiers.unit.cc b/tst/EnergyPlus/unit/DesiccantDehumidifiers.unit.cc index 7b11550948c..56544d221fa 100644 --- a/tst/EnergyPlus/unit/DesiccantDehumidifiers.unit.cc +++ b/tst/EnergyPlus/unit/DesiccantDehumidifiers.unit.cc @@ -2898,7 +2898,7 @@ TEST_F(EnergyPlusFixture, DesiccantDehum_OnOASystemTest) auto &finalSysSizing = state->dataSize->FinalSysSizing(1); auto &sysSizPeakDDNum = state->dataSize->SysSizPeakDDNum(1); EXPECT_ENUM_EQ(finalSysSizing.coolingPeakLoad, DataSizing::PeakLoad::SensibleCooling); - EXPECT_EQ(finalSysSizing.SizingOption, DataSizing::NonCoincident); + EXPECT_ENUM_EQ(finalSysSizing.SizingOption, DataSizing::Concurrence::NonCoincident); EXPECT_EQ(sysSizPeakDDNum.SensCoolPeakDD, coolPeakDD); int timeStepIndexAtPeakCoolLoad = sysSizPeakDDNum.TimeStepAtSensCoolPk(coolPeakDD); EXPECT_EQ(sysSizPeakDDNum.TimeStepAtTotCoolPk(coolPeakDD), timeStepIndexAtPeakCoolLoad); diff --git a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc index 8f97d12ae42..122a0ec7450 100644 --- a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc +++ b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc @@ -7233,11 +7233,8 @@ TEST_F(SQLiteFixture, OutputReportTabular_WriteLoadComponentSummaryTables_AirLoo state->dataSize->NumSysSizInput = 1; state->dataSize->SysSizInput.allocate(state->dataSize->NumSysSizInput); state->dataSize->SysSizInput(1).AirLoopNum = 1; - state->dataSize->SysSizInput(1).SizingOption = DataSizing::NonCoincident; - auto degC_to_F = [](Real64 celsius) constexpr - { - return celsius * (9.0 / 5.0) + 32.0; - }; + state->dataSize->SysSizInput(1).SizingOption = DataSizing::Concurrence::NonCoincident; + auto degC_to_F = [](Real64 celsius) constexpr { return celsius * (9.0 / 5.0) + 32.0; }; constexpr Real64 coolMixTempSys = 26.2; constexpr Real64 coolMixTempSysIP = degC_to_F(coolMixTempSys); constexpr Real64 heatMixTempSys = -1.7; From 4449ccb435fc1f3c1a8ce7502a6cd553a93285fa Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Wed, 19 Jun 2024 08:19:12 -0500 Subject: [PATCH 24/81] Revert format disagreement --- tst/EnergyPlus/unit/OutputReportTabular.unit.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc index 122a0ec7450..31a772385eb 100644 --- a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc +++ b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc @@ -7234,7 +7234,10 @@ TEST_F(SQLiteFixture, OutputReportTabular_WriteLoadComponentSummaryTables_AirLoo state->dataSize->SysSizInput.allocate(state->dataSize->NumSysSizInput); state->dataSize->SysSizInput(1).AirLoopNum = 1; state->dataSize->SysSizInput(1).SizingOption = DataSizing::Concurrence::NonCoincident; - auto degC_to_F = [](Real64 celsius) constexpr { return celsius * (9.0 / 5.0) + 32.0; }; + auto degC_to_F = [](Real64 celsius) constexpr + { + return celsius * (9.0 / 5.0) + 32.0; + }; constexpr Real64 coolMixTempSys = 26.2; constexpr Real64 coolMixTempSysIP = degC_to_F(coolMixTempSys); constexpr Real64 heatMixTempSys = -1.7; From 62ef539ffebca1bff76224dfbff2e31f5c43114d Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Wed, 19 Jun 2024 09:06:58 -0500 Subject: [PATCH 25/81] Space IV-New Sizing:Zone coincidence input --- .../src/overview/group-design-objects.tex | 25 +++++++++++-------- idd/Energy+.idd.in | 8 +++++- src/EnergyPlus/DataSizing.hh | 8 +++--- src/EnergyPlus/SizingManager.cc | 2 ++ 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/doc/input-output-reference/src/overview/group-design-objects.tex b/doc/input-output-reference/src/overview/group-design-objects.tex index 0f96917a7b1..3160a6e470b 100644 --- a/doc/input-output-reference/src/overview/group-design-objects.tex +++ b/doc/input-output-reference/src/overview/group-design-objects.tex @@ -1287,11 +1287,15 @@ \subsubsection{Inputs}\label{inputs-4-008} Sizing Method = Sensible Load Only No Latent Load or a zone humidistat is present. A default of 50.0 will be used if no schedule is provided and no humidistat is associated with this zone. +\paragraph{Field: Type of Space Sum to Use}\label{field-type-of-space-sum-to-use} + +If the input is \emph{coincident} the zone equipment will be sized on the coincident zone load across all spaces in the zone. If the input is \emph{noncoincident} the zone equipment will be sized on the sum of the noncoincident space loads. The default is \emph{coincident}. This field is ignored unless \hyperref[zoneairheatbalancealgorithm]{ZoneAirHeatBalanceAlgorithm} ``Do Space Heat Balance for Sizing'' is Yes. + An IDF example: \begin{lstlisting} -Sizing:Zone, + Sizing:Zone, SPACE5-1, !- Name of a zone 14., !- Zone cooling design supply air temperature {C} 50., !- Zone heating design supply air temperature {C} @@ -1323,16 +1327,17 @@ \subsubsection{Inputs}\label{inputs-4-008} , !- Zone Humidification Design Supply Air Humidity Ratio 0.005, !- Zone Heating Design Supply Air Humidity Ratio Difference , !- Zone Humidistat Dehumidification Set Point Schedule Name - ; !- Zone Humidistat Humidification Set Point Schedule Name - + , !- Zone Humidistat Humidification Set Point Schedule Name + Coincident; !- Type of Space Sum to Use + DesignSpecification:OutdoorAir, - DSOA1, !- Name - SUM, !- Outdoor Air Method - 0.00236, !- Outdoor Air Flow per Person - 0.000305, !- Outdoor Air Flow per Zone Floor Area - 0.0, !- Outdoor Air Flow per Zone - 0.0, !- Outdoor Air Flow Air Changes per Hour - ; !- Outdoor Air Flow Rate Fraction Schedule Name + DSOA1, !- Name + SUM, !- Outdoor Air Method + 0.00236, !- Outdoor Air Flow per Person + 0.000305, !- Outdoor Air Flow per Zone Floor Area + 0.0, !- Outdoor Air Flow per Zone + 0.0, !- Outdoor Air Flow Air Changes per Hour + ; !- Outdoor Air Flow Rate Fraction Schedule Name DesignSpecification:ZoneAirDistribution, DSZADO1, !- Name diff --git a/idd/Energy+.idd.in b/idd/Energy+.idd.in index 466fc0a596b..85a5dfe2eb8 100644 --- a/idd/Energy+.idd.in +++ b/idd/Energy+.idd.in @@ -34374,7 +34374,7 @@ Sizing:Zone, \note no humidistat is associated with this zone. \type alpha \units percent - A14;\field Zone Humidistat Humidification Set Point Schedule Name + A14,\field Zone Humidistat Humidification Set Point Schedule Name \note Enter the zone relative humidity schedule used for zone latent \note heating calculations. \note A zone humidistat will take priority over this input. @@ -34384,6 +34384,12 @@ Sizing:Zone, \note no humidistat is associated with this zone. \type alpha \units percent + A15;\field Type of Space Sum to Use + \note NonCoincident is available only if Do Space Heat Balance for Sizing=Yes in ZoneAirHeatBalanceAlgorithm. + \type choice + \key Coincident + \key NonCoincident + \default Coincident DesignSpecification:ZoneHVAC:Sizing, \min-fields 1 diff --git a/src/EnergyPlus/DataSizing.hh b/src/EnergyPlus/DataSizing.hh index 63d7d2a9e56..a3c32ce7391 100644 --- a/src/EnergyPlus/DataSizing.hh +++ b/src/EnergyPlus/DataSizing.hh @@ -333,6 +333,7 @@ namespace DataSizing { DOASControl DOASControlStrategy = DOASControl::Invalid; // 0=neutral ventilation air; 1=neutral dehumidified ventilation air, 2 = cooled air; Real64 DOASLowSetpoint = 0.0; // Dedicated Outside Air Low Setpoint for Design [C] Real64 DOASHighSetpoint = 0.0; // Dedicated Outside Air High Setpoint for Design [C] + DataSizing::Concurrence spaceConcurrence = DataSizing::Concurrence::Coincident; // coincident or noncoincident space loads // zone latent sizing inputs bool zoneLatentSizing = false; @@ -458,9 +459,10 @@ namespace DataSizing { bool AccountForDOAS = false; // False: do nothing; True: calculate the effect of a DOA system on the zone sizing arrays DOASControl DOASControlStrategy = DOASControl::Invalid; // 0=neutral ventilation air; 1=neutral dehumidified ventilation air, 2 = cooled air; // 3=supply cold ventilation air - Real64 DOASLowSetpoint = 0.0; // Dedicated Outside Air Low Setpoint for Design [C] - Real64 DOASHighSetpoint = 0.0; // Dedicated Outside Air High Setpoint for Design [C] - bool EMSOverrideDesHeatMassOn = false; // true if EMS is acting on this structure + Real64 DOASLowSetpoint = 0.0; // Dedicated Outside Air Low Setpoint for Design [C] + Real64 DOASHighSetpoint = 0.0; // Dedicated Outside Air High Setpoint for Design [C] + DataSizing::Concurrence spaceConcurrence = DataSizing::Concurrence::Coincident; // coincident or noncoincident space loads + bool EMSOverrideDesHeatMassOn = false; // true if EMS is acting on this structure Real64 EMSValueDesHeatMassFlow = 0.0; // Value EMS directing to use for Design Heating air mass flow [kg/s] bool EMSOverrideDesCoolMassOn = false; // true if EMS is acting on this structure Real64 EMSValueDesCoolMassFlow = 0.0; // Value EMS directing to use for Design Cooling air mass flow [kg/s] diff --git a/src/EnergyPlus/SizingManager.cc b/src/EnergyPlus/SizingManager.cc index 8d5234b82bf..25d2294a30f 100644 --- a/src/EnergyPlus/SizingManager.cc +++ b/src/EnergyPlus/SizingManager.cc @@ -3280,6 +3280,8 @@ void GetZoneSizingInput(EnergyPlusData &state) ErrorsFound = true; } } + zoneSizingIndex.spaceConcurrence = + static_cast(getEnumValue(DataSizing::ConcurrenceMethodNamesUC, state.dataIPShortCut->cAlphaArgs(10))); zoneSizingIndex.zoneSizingMethod = static_cast(getEnumValue(DataSizing::ZoneSizingMethodNamesUC, state.dataIPShortCut->cAlphaArgs(10))); if (zoneSizingIndex.zoneSizingMethod != ZoneSizing::SensibleOnly) { From a93dc1cd2b0f73386b39174cb7e3d642fd8e7f4a Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Wed, 19 Jun 2024 09:24:23 -0500 Subject: [PATCH 26/81] Space IV-Revert scope creep --- src/EnergyPlus/DataSizing.hh | 2 +- src/EnergyPlus/ReportCoilSelection.cc | 66 +++++++++++++++------------ src/EnergyPlus/ReportCoilSelection.hh | 5 +- 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/EnergyPlus/DataSizing.hh b/src/EnergyPlus/DataSizing.hh index a3c32ce7391..2427fe288f7 100644 --- a/src/EnergyPlus/DataSizing.hh +++ b/src/EnergyPlus/DataSizing.hh @@ -117,7 +117,7 @@ namespace DataSizing { Num }; - // parameters for sizing (keept this for now to avoid plant sizing output changes) + // parameters for sizing (keep this for now to avoid plant sizing and coil selection output changes) constexpr int NonCoincident(1); constexpr int Coincident(2); constexpr int Combination(3); diff --git a/src/EnergyPlus/ReportCoilSelection.cc b/src/EnergyPlus/ReportCoilSelection.cc index 50841801321..506bc1325cc 100644 --- a/src/EnergyPlus/ReportCoilSelection.cc +++ b/src/EnergyPlus/ReportCoilSelection.cc @@ -81,20 +81,20 @@ void createCoilSelectionReportObj(EnergyPlusData &state) CoilSelectionData::CoilSelectionData( // constructor std::string const &coilName) : isCooling(false), isHeating(false), coilNum(-999), airloopNum(-999), oaControllerNum(-999), zoneEqNum(-999), oASysNum(-999), zoneHVACTypeNum(0), - zoneHVACIndex(0), typeof_Coil(-999), coilSizingMethodCapacity(-999), coilSizingMethodAirFlow(-999), isCoilSizingForTotalLoad(false), - capIsAutosized(false), volFlowIsAutosized(false), coilWaterFlowUser(-999.0), oaPretreated(false), isSupplementalHeater(false), - coilTotCapFinal(-999.0), coilSensCapFinal(-999.0), coilRefAirVolFlowFinal(-999.0), coilRefWaterVolFlowFinal(-999.0), coilTotCapAtPeak(-999.0), - coilSensCapAtPeak(-999.0), coilDesMassFlow(-999.0), coilDesVolFlow(-999.0), coilDesEntTemp(-999.0), coilDesEntWetBulb(-999.0), - coilDesEntHumRat(-999.0), coilDesEntEnth(-999.0), coilDesLvgTemp(-999.0), coilDesLvgWetBulb(-999.0), coilDesLvgHumRat(-999.0), - coilDesLvgEnth(-999.0), coilDesWaterMassFlow(-999.0), coilDesWaterEntTemp(-999.0), coilDesWaterLvgTemp(-999.0), coilDesWaterTempDiff(-999.0), - pltSizNum(-999), waterLoopNum(-999), oaPeakTemp(-999.00), oaPeakHumRat(-999.0), oaPeakWetBulb(-999.0), oaPeakVolFlow(-999.0), - oaPeakVolFrac(-999.0), oaDoaTemp(-999.0), oaDoaHumRat(-999.0), raPeakTemp(-999.0), raPeakHumRat(-999.0), rmPeakTemp(-999.0), - rmPeakHumRat(-999.0), rmPeakRelHum(-999.0), rmSensibleAtPeak(-999.0), rmLatentAtPeak(0.0), coilIdealSizCapOverSimPeakCap(-999.0), - coilIdealSizCapUnderSimPeakCap(-999.0), reheatLoadMult(-999.0), minRatio(-999.0), maxRatio(-999.0), cpMoistAir(-999.0), cpDryAir(-999.0), - rhoStandAir(-999.0), rhoFluid(-999.0), cpFluid(-999.0), coilCapFTIdealPeak(1.0), coilRatedTotCap(-999.0), coilRatedSensCap(-999.0), - ratedAirMassFlow(-999.0), ratedCoilInDb(-999.0), ratedCoilInWb(-999.0), ratedCoilInHumRat(-999.0), ratedCoilInEnth(-999.0), - ratedCoilOutDb(-999.0), ratedCoilOutWb(-999.0), ratedCoilOutHumRat(-999.0), ratedCoilOutEnth(-999.0), ratedCoilEff(-999.0), - ratedCoilBpFactor(-999.0), ratedCoilAppDewPt(-999.0), ratedCoilOadbRef(-999.0), ratedCoilOawbRef(-999.0), + zoneHVACIndex(0), typeof_Coil(-999), coilSizingMethodConcurrence(-999), coilSizingMethodCapacity(-999), coilSizingMethodAirFlow(-999), + isCoilSizingForTotalLoad(false), capIsAutosized(false), volFlowIsAutosized(false), coilWaterFlowUser(-999.0), oaPretreated(false), + isSupplementalHeater(false), coilTotCapFinal(-999.0), coilSensCapFinal(-999.0), coilRefAirVolFlowFinal(-999.0), + coilRefWaterVolFlowFinal(-999.0), coilTotCapAtPeak(-999.0), coilSensCapAtPeak(-999.0), coilDesMassFlow(-999.0), coilDesVolFlow(-999.0), + coilDesEntTemp(-999.0), coilDesEntWetBulb(-999.0), coilDesEntHumRat(-999.0), coilDesEntEnth(-999.0), coilDesLvgTemp(-999.0), + coilDesLvgWetBulb(-999.0), coilDesLvgHumRat(-999.0), coilDesLvgEnth(-999.0), coilDesWaterMassFlow(-999.0), coilDesWaterEntTemp(-999.0), + coilDesWaterLvgTemp(-999.0), coilDesWaterTempDiff(-999.0), pltSizNum(-999), waterLoopNum(-999), oaPeakTemp(-999.00), oaPeakHumRat(-999.0), + oaPeakWetBulb(-999.0), oaPeakVolFlow(-999.0), oaPeakVolFrac(-999.0), oaDoaTemp(-999.0), oaDoaHumRat(-999.0), raPeakTemp(-999.0), + raPeakHumRat(-999.0), rmPeakTemp(-999.0), rmPeakHumRat(-999.0), rmPeakRelHum(-999.0), rmSensibleAtPeak(-999.0), rmLatentAtPeak(0.0), + coilIdealSizCapOverSimPeakCap(-999.0), coilIdealSizCapUnderSimPeakCap(-999.0), reheatLoadMult(-999.0), minRatio(-999.0), maxRatio(-999.0), + cpMoistAir(-999.0), cpDryAir(-999.0), rhoStandAir(-999.0), rhoFluid(-999.0), cpFluid(-999.0), coilCapFTIdealPeak(1.0), coilRatedTotCap(-999.0), + coilRatedSensCap(-999.0), ratedAirMassFlow(-999.0), ratedCoilInDb(-999.0), ratedCoilInWb(-999.0), ratedCoilInHumRat(-999.0), + ratedCoilInEnth(-999.0), ratedCoilOutDb(-999.0), ratedCoilOutWb(-999.0), ratedCoilOutHumRat(-999.0), ratedCoilOutEnth(-999.0), + ratedCoilEff(-999.0), ratedCoilBpFactor(-999.0), ratedCoilAppDewPt(-999.0), ratedCoilOadbRef(-999.0), ratedCoilOawbRef(-999.0), supFanType(HVAC::FanType::Invalid), supFanNum(0), fanSizeMaxAirVolumeFlow(-999.0), fanSizeMaxAirMassFlow(-999.0), fanHeatGainIdealPeak(-999.0), coilAndFanNetTotalCapacityIdealPeak(-999.0), plantDesMaxMassFlowRate(-999.0), plantDesRetTemp(-999.0), plantDesSupTemp(-999.0), @@ -734,7 +734,15 @@ void ReportCoilSelection::doFinalProcessingOfCoilData(EnergyPlusData &state) c->oaPeakVolFrac = -999.0; } - c->coilSizingMethodConcurrenceName = DataSizing::ConcurrenceMethodNames[(int)c->coilSizingMethodConcurrence]; + if (c->coilSizingMethodConcurrence == DataSizing::NonCoincident) { + c->coilSizingMethodConcurrenceName = "Non-Coincident"; + } else if (c->coilSizingMethodConcurrence == DataSizing::Coincident) { + c->coilSizingMethodConcurrenceName = "Coincident"; + } else if (c->coilSizingMethodConcurrence == DataSizing::Combination) { + c->coilSizingMethodConcurrenceName = "Combination"; + } else { + c->coilSizingMethodConcurrenceName = "N/A"; + } if (c->coilSizingMethodCapacity == DataSizing::CoolingDesignCapacity) { c->coilSizingMethodCapacityName = "CoolingDesignCapacity"; @@ -1264,7 +1272,7 @@ void ReportCoilSelection::setCoilCoolingCapacity( c->oaPeakHumRat = finalSysSizing.OutHumRatAtCoolPeak; c->raPeakTemp = finalSysSizing.RetTempAtCoolPeak; c->raPeakHumRat = finalSysSizing.RetHumRatAtCoolPeak; - c->coilSizingMethodConcurrence = finalSysSizing.SizingOption; + c->coilSizingMethodConcurrence = (int)finalSysSizing.SizingOption; c->coilSizingMethodCapacity = finalSysSizing.CoolingCapMethod; c->coilSizingMethodAirFlow = finalSysSizing.ScaleCoolSAFMethod; // DesOutAirVolFlow @@ -1323,9 +1331,9 @@ void ReportCoilSelection::setCoilCoolingCapacity( c->rmPeakRelHum = -999.0; } - if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::Coincident) { + if (c->coilSizingMethodConcurrence == DataSizing::Coincident) { c->rmSensibleAtPeak = finalSysSizing.SysCoolCoinSpaceSens; - } else if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::NonCoincident) { + } else if (c->coilSizingMethodConcurrence == DataSizing::NonCoincident) { c->rmSensibleAtPeak = sumSensLoad; } else { // DataSizing::Combination or other c->rmSensibleAtPeak = sumSensLoad; @@ -1470,14 +1478,14 @@ void ReportCoilSelection::setCoilCoolingCapacity( state, c->coilDesLvgTemp, c->coilDesLvgHumRat, state.dataEnvrn->StdBaroPress, "ReportCoilSelection::setCoilCoolingCapacity"); c->coilDesLvgEnth = Psychrometrics::PsyHFnTdbW(c->coilDesLvgTemp, c->coilDesLvgHumRat); } - DataSizing::Concurrence sizMethod = DataSizing::Concurrence::Invalid; + int sizMethod = 0; bool sizMethodsAreTheSame = true; for (int airLoopNum = 0; airLoopNum < state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].NumOfAirLoops; ++airLoopNum) { int actualAirLoopNum = state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].m_AirLoopNum[airLoopNum]; if (airLoopNum == 0) { - sizMethod = state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption; + sizMethod = (int)state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption; } else { - if (sizMethod != state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption) { + if (sizMethod != (int)state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption) { sizMethodsAreTheSame = false; } } @@ -1485,7 +1493,7 @@ void ReportCoilSelection::setCoilCoolingCapacity( if (sizMethodsAreTheSame) { c->coilSizingMethodConcurrence = sizMethod; } else { - c->coilSizingMethodConcurrence = DataSizing::Concurrence::Combination; + c->coilSizingMethodConcurrence = DataSizing::Combination; } } } else { @@ -1533,7 +1541,7 @@ void ReportCoilSelection::setCoilHeatingCapacity( c->oaPeakVolFlow = finalSysSizing.DesOutAirVolFlow; c->raPeakTemp = finalSysSizing.HeatRetTemp; c->raPeakHumRat = finalSysSizing.HeatRetHumRat; - c->coilSizingMethodConcurrence = finalSysSizing.SizingOption; + c->coilSizingMethodConcurrence = (int)finalSysSizing.SizingOption; c->coilSizingMethodCapacity = finalSysSizing.HeatingCapMethod; c->coilSizingMethodAirFlow = finalSysSizing.ScaleHeatSAFMethod; @@ -1588,9 +1596,9 @@ void ReportCoilSelection::setCoilHeatingCapacity( c->rmPeakRelHum = -999.0; } - if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::Coincident) { + if (c->coilSizingMethodConcurrence == DataSizing::Coincident) { c->rmSensibleAtPeak = finalSysSizing.SysHeatCoinSpaceSens; - } else if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::NonCoincident) { + } else if (c->coilSizingMethodConcurrence == DataSizing::NonCoincident) { c->rmSensibleAtPeak = sumLoad; } @@ -1767,14 +1775,14 @@ void ReportCoilSelection::setCoilHeatingCapacity( state, c->coilDesLvgTemp, c->coilDesLvgHumRat, state.dataEnvrn->StdBaroPress, "ReportCoilSelection::setCoilHeatingCapacity"); c->coilDesLvgEnth = Psychrometrics::PsyHFnTdbW(c->coilDesLvgTemp, c->coilDesLvgHumRat); } - DataSizing::Concurrence sizMethod = DataSizing::Concurrence::Invalid; + int sizMethod = 0; bool sizMethodsAreTheSame = true; for (int airLoopNum = 0; airLoopNum < state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].NumOfAirLoops; ++airLoopNum) { int actualAirLoopNum = state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].m_AirLoopNum[airLoopNum]; if (airLoopNum == 0) { - sizMethod = state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption; + sizMethod = (int)state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption; } else { - if (sizMethod != state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption) { + if (sizMethod != (int)state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption) { sizMethodsAreTheSame = false; } } @@ -1782,7 +1790,7 @@ void ReportCoilSelection::setCoilHeatingCapacity( if (sizMethodsAreTheSame) { c->coilSizingMethodConcurrence = sizMethod; } else { - c->coilSizingMethodConcurrence = DataSizing::Concurrence::Combination; + c->coilSizingMethodConcurrence = DataSizing::Combination; } } } else { diff --git a/src/EnergyPlus/ReportCoilSelection.hh b/src/EnergyPlus/ReportCoilSelection.hh index d15bf87a2e0..105b82899f7 100644 --- a/src/EnergyPlus/ReportCoilSelection.hh +++ b/src/EnergyPlus/ReportCoilSelection.hh @@ -56,7 +56,6 @@ // EnergyPlus Headers #include #include -#include #include namespace EnergyPlus { @@ -99,8 +98,8 @@ public: // data int typeof_Coil; // type of coil, e.g., PlantEquipmentType::CoilWaterSimpleHeating, PlantEquipmentType::CoilWaterDetailedFlatCooling, // PlantEquipmentType::CoilWaterCooling - DataSizing::Concurrence coilSizingMethodConcurrence = DataSizing::Concurrence::NA; // non-coincident, coincident, combination, n/a - std::string coilSizingMethodConcurrenceName; // string name of sizing method for concurrence + int coilSizingMethodConcurrence; // 1 = noncoincident, 2 = coincident + std::string coilSizingMethodConcurrenceName; // string name of sizing method for concurrence int coilSizingMethodCapacity; // 8=CoolingDesignCapacity, 9=HeatingDesignCapacity, 10=CapacityPerFloorArea, 11=FractionOfAutosizedCoolingCapacity, // 12=FractionOfAutosizedHeatingCapacity From 1e66702a60b0f4d3e6a193bbbb3635ca2074eb97 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Wed, 19 Jun 2024 10:39:32 -0500 Subject: [PATCH 27/81] Revert "Space IV-Revert scope creep" This reverts commit a93dc1cd2b0f73386b39174cb7e3d642fd8e7f4a. --- src/EnergyPlus/DataSizing.hh | 2 +- src/EnergyPlus/ReportCoilSelection.cc | 66 ++++++++++++--------------- src/EnergyPlus/ReportCoilSelection.hh | 5 +- 3 files changed, 33 insertions(+), 40 deletions(-) diff --git a/src/EnergyPlus/DataSizing.hh b/src/EnergyPlus/DataSizing.hh index 2427fe288f7..a3c32ce7391 100644 --- a/src/EnergyPlus/DataSizing.hh +++ b/src/EnergyPlus/DataSizing.hh @@ -117,7 +117,7 @@ namespace DataSizing { Num }; - // parameters for sizing (keep this for now to avoid plant sizing and coil selection output changes) + // parameters for sizing (keept this for now to avoid plant sizing output changes) constexpr int NonCoincident(1); constexpr int Coincident(2); constexpr int Combination(3); diff --git a/src/EnergyPlus/ReportCoilSelection.cc b/src/EnergyPlus/ReportCoilSelection.cc index 506bc1325cc..50841801321 100644 --- a/src/EnergyPlus/ReportCoilSelection.cc +++ b/src/EnergyPlus/ReportCoilSelection.cc @@ -81,20 +81,20 @@ void createCoilSelectionReportObj(EnergyPlusData &state) CoilSelectionData::CoilSelectionData( // constructor std::string const &coilName) : isCooling(false), isHeating(false), coilNum(-999), airloopNum(-999), oaControllerNum(-999), zoneEqNum(-999), oASysNum(-999), zoneHVACTypeNum(0), - zoneHVACIndex(0), typeof_Coil(-999), coilSizingMethodConcurrence(-999), coilSizingMethodCapacity(-999), coilSizingMethodAirFlow(-999), - isCoilSizingForTotalLoad(false), capIsAutosized(false), volFlowIsAutosized(false), coilWaterFlowUser(-999.0), oaPretreated(false), - isSupplementalHeater(false), coilTotCapFinal(-999.0), coilSensCapFinal(-999.0), coilRefAirVolFlowFinal(-999.0), - coilRefWaterVolFlowFinal(-999.0), coilTotCapAtPeak(-999.0), coilSensCapAtPeak(-999.0), coilDesMassFlow(-999.0), coilDesVolFlow(-999.0), - coilDesEntTemp(-999.0), coilDesEntWetBulb(-999.0), coilDesEntHumRat(-999.0), coilDesEntEnth(-999.0), coilDesLvgTemp(-999.0), - coilDesLvgWetBulb(-999.0), coilDesLvgHumRat(-999.0), coilDesLvgEnth(-999.0), coilDesWaterMassFlow(-999.0), coilDesWaterEntTemp(-999.0), - coilDesWaterLvgTemp(-999.0), coilDesWaterTempDiff(-999.0), pltSizNum(-999), waterLoopNum(-999), oaPeakTemp(-999.00), oaPeakHumRat(-999.0), - oaPeakWetBulb(-999.0), oaPeakVolFlow(-999.0), oaPeakVolFrac(-999.0), oaDoaTemp(-999.0), oaDoaHumRat(-999.0), raPeakTemp(-999.0), - raPeakHumRat(-999.0), rmPeakTemp(-999.0), rmPeakHumRat(-999.0), rmPeakRelHum(-999.0), rmSensibleAtPeak(-999.0), rmLatentAtPeak(0.0), - coilIdealSizCapOverSimPeakCap(-999.0), coilIdealSizCapUnderSimPeakCap(-999.0), reheatLoadMult(-999.0), minRatio(-999.0), maxRatio(-999.0), - cpMoistAir(-999.0), cpDryAir(-999.0), rhoStandAir(-999.0), rhoFluid(-999.0), cpFluid(-999.0), coilCapFTIdealPeak(1.0), coilRatedTotCap(-999.0), - coilRatedSensCap(-999.0), ratedAirMassFlow(-999.0), ratedCoilInDb(-999.0), ratedCoilInWb(-999.0), ratedCoilInHumRat(-999.0), - ratedCoilInEnth(-999.0), ratedCoilOutDb(-999.0), ratedCoilOutWb(-999.0), ratedCoilOutHumRat(-999.0), ratedCoilOutEnth(-999.0), - ratedCoilEff(-999.0), ratedCoilBpFactor(-999.0), ratedCoilAppDewPt(-999.0), ratedCoilOadbRef(-999.0), ratedCoilOawbRef(-999.0), + zoneHVACIndex(0), typeof_Coil(-999), coilSizingMethodCapacity(-999), coilSizingMethodAirFlow(-999), isCoilSizingForTotalLoad(false), + capIsAutosized(false), volFlowIsAutosized(false), coilWaterFlowUser(-999.0), oaPretreated(false), isSupplementalHeater(false), + coilTotCapFinal(-999.0), coilSensCapFinal(-999.0), coilRefAirVolFlowFinal(-999.0), coilRefWaterVolFlowFinal(-999.0), coilTotCapAtPeak(-999.0), + coilSensCapAtPeak(-999.0), coilDesMassFlow(-999.0), coilDesVolFlow(-999.0), coilDesEntTemp(-999.0), coilDesEntWetBulb(-999.0), + coilDesEntHumRat(-999.0), coilDesEntEnth(-999.0), coilDesLvgTemp(-999.0), coilDesLvgWetBulb(-999.0), coilDesLvgHumRat(-999.0), + coilDesLvgEnth(-999.0), coilDesWaterMassFlow(-999.0), coilDesWaterEntTemp(-999.0), coilDesWaterLvgTemp(-999.0), coilDesWaterTempDiff(-999.0), + pltSizNum(-999), waterLoopNum(-999), oaPeakTemp(-999.00), oaPeakHumRat(-999.0), oaPeakWetBulb(-999.0), oaPeakVolFlow(-999.0), + oaPeakVolFrac(-999.0), oaDoaTemp(-999.0), oaDoaHumRat(-999.0), raPeakTemp(-999.0), raPeakHumRat(-999.0), rmPeakTemp(-999.0), + rmPeakHumRat(-999.0), rmPeakRelHum(-999.0), rmSensibleAtPeak(-999.0), rmLatentAtPeak(0.0), coilIdealSizCapOverSimPeakCap(-999.0), + coilIdealSizCapUnderSimPeakCap(-999.0), reheatLoadMult(-999.0), minRatio(-999.0), maxRatio(-999.0), cpMoistAir(-999.0), cpDryAir(-999.0), + rhoStandAir(-999.0), rhoFluid(-999.0), cpFluid(-999.0), coilCapFTIdealPeak(1.0), coilRatedTotCap(-999.0), coilRatedSensCap(-999.0), + ratedAirMassFlow(-999.0), ratedCoilInDb(-999.0), ratedCoilInWb(-999.0), ratedCoilInHumRat(-999.0), ratedCoilInEnth(-999.0), + ratedCoilOutDb(-999.0), ratedCoilOutWb(-999.0), ratedCoilOutHumRat(-999.0), ratedCoilOutEnth(-999.0), ratedCoilEff(-999.0), + ratedCoilBpFactor(-999.0), ratedCoilAppDewPt(-999.0), ratedCoilOadbRef(-999.0), ratedCoilOawbRef(-999.0), supFanType(HVAC::FanType::Invalid), supFanNum(0), fanSizeMaxAirVolumeFlow(-999.0), fanSizeMaxAirMassFlow(-999.0), fanHeatGainIdealPeak(-999.0), coilAndFanNetTotalCapacityIdealPeak(-999.0), plantDesMaxMassFlowRate(-999.0), plantDesRetTemp(-999.0), plantDesSupTemp(-999.0), @@ -734,15 +734,7 @@ void ReportCoilSelection::doFinalProcessingOfCoilData(EnergyPlusData &state) c->oaPeakVolFrac = -999.0; } - if (c->coilSizingMethodConcurrence == DataSizing::NonCoincident) { - c->coilSizingMethodConcurrenceName = "Non-Coincident"; - } else if (c->coilSizingMethodConcurrence == DataSizing::Coincident) { - c->coilSizingMethodConcurrenceName = "Coincident"; - } else if (c->coilSizingMethodConcurrence == DataSizing::Combination) { - c->coilSizingMethodConcurrenceName = "Combination"; - } else { - c->coilSizingMethodConcurrenceName = "N/A"; - } + c->coilSizingMethodConcurrenceName = DataSizing::ConcurrenceMethodNames[(int)c->coilSizingMethodConcurrence]; if (c->coilSizingMethodCapacity == DataSizing::CoolingDesignCapacity) { c->coilSizingMethodCapacityName = "CoolingDesignCapacity"; @@ -1272,7 +1264,7 @@ void ReportCoilSelection::setCoilCoolingCapacity( c->oaPeakHumRat = finalSysSizing.OutHumRatAtCoolPeak; c->raPeakTemp = finalSysSizing.RetTempAtCoolPeak; c->raPeakHumRat = finalSysSizing.RetHumRatAtCoolPeak; - c->coilSizingMethodConcurrence = (int)finalSysSizing.SizingOption; + c->coilSizingMethodConcurrence = finalSysSizing.SizingOption; c->coilSizingMethodCapacity = finalSysSizing.CoolingCapMethod; c->coilSizingMethodAirFlow = finalSysSizing.ScaleCoolSAFMethod; // DesOutAirVolFlow @@ -1331,9 +1323,9 @@ void ReportCoilSelection::setCoilCoolingCapacity( c->rmPeakRelHum = -999.0; } - if (c->coilSizingMethodConcurrence == DataSizing::Coincident) { + if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::Coincident) { c->rmSensibleAtPeak = finalSysSizing.SysCoolCoinSpaceSens; - } else if (c->coilSizingMethodConcurrence == DataSizing::NonCoincident) { + } else if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::NonCoincident) { c->rmSensibleAtPeak = sumSensLoad; } else { // DataSizing::Combination or other c->rmSensibleAtPeak = sumSensLoad; @@ -1478,14 +1470,14 @@ void ReportCoilSelection::setCoilCoolingCapacity( state, c->coilDesLvgTemp, c->coilDesLvgHumRat, state.dataEnvrn->StdBaroPress, "ReportCoilSelection::setCoilCoolingCapacity"); c->coilDesLvgEnth = Psychrometrics::PsyHFnTdbW(c->coilDesLvgTemp, c->coilDesLvgHumRat); } - int sizMethod = 0; + DataSizing::Concurrence sizMethod = DataSizing::Concurrence::Invalid; bool sizMethodsAreTheSame = true; for (int airLoopNum = 0; airLoopNum < state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].NumOfAirLoops; ++airLoopNum) { int actualAirLoopNum = state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].m_AirLoopNum[airLoopNum]; if (airLoopNum == 0) { - sizMethod = (int)state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption; + sizMethod = state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption; } else { - if (sizMethod != (int)state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption) { + if (sizMethod != state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption) { sizMethodsAreTheSame = false; } } @@ -1493,7 +1485,7 @@ void ReportCoilSelection::setCoilCoolingCapacity( if (sizMethodsAreTheSame) { c->coilSizingMethodConcurrence = sizMethod; } else { - c->coilSizingMethodConcurrence = DataSizing::Combination; + c->coilSizingMethodConcurrence = DataSizing::Concurrence::Combination; } } } else { @@ -1541,7 +1533,7 @@ void ReportCoilSelection::setCoilHeatingCapacity( c->oaPeakVolFlow = finalSysSizing.DesOutAirVolFlow; c->raPeakTemp = finalSysSizing.HeatRetTemp; c->raPeakHumRat = finalSysSizing.HeatRetHumRat; - c->coilSizingMethodConcurrence = (int)finalSysSizing.SizingOption; + c->coilSizingMethodConcurrence = finalSysSizing.SizingOption; c->coilSizingMethodCapacity = finalSysSizing.HeatingCapMethod; c->coilSizingMethodAirFlow = finalSysSizing.ScaleHeatSAFMethod; @@ -1596,9 +1588,9 @@ void ReportCoilSelection::setCoilHeatingCapacity( c->rmPeakRelHum = -999.0; } - if (c->coilSizingMethodConcurrence == DataSizing::Coincident) { + if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::Coincident) { c->rmSensibleAtPeak = finalSysSizing.SysHeatCoinSpaceSens; - } else if (c->coilSizingMethodConcurrence == DataSizing::NonCoincident) { + } else if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::NonCoincident) { c->rmSensibleAtPeak = sumLoad; } @@ -1775,14 +1767,14 @@ void ReportCoilSelection::setCoilHeatingCapacity( state, c->coilDesLvgTemp, c->coilDesLvgHumRat, state.dataEnvrn->StdBaroPress, "ReportCoilSelection::setCoilHeatingCapacity"); c->coilDesLvgEnth = Psychrometrics::PsyHFnTdbW(c->coilDesLvgTemp, c->coilDesLvgHumRat); } - int sizMethod = 0; + DataSizing::Concurrence sizMethod = DataSizing::Concurrence::Invalid; bool sizMethodsAreTheSame = true; for (int airLoopNum = 0; airLoopNum < state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].NumOfAirLoops; ++airLoopNum) { int actualAirLoopNum = state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].m_AirLoopNum[airLoopNum]; if (airLoopNum == 0) { - sizMethod = (int)state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption; + sizMethod = state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption; } else { - if (sizMethod != (int)state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption) { + if (sizMethod != state.dataSize->FinalSysSizing(actualAirLoopNum).SizingOption) { sizMethodsAreTheSame = false; } } @@ -1790,7 +1782,7 @@ void ReportCoilSelection::setCoilHeatingCapacity( if (sizMethodsAreTheSame) { c->coilSizingMethodConcurrence = sizMethod; } else { - c->coilSizingMethodConcurrence = DataSizing::Combination; + c->coilSizingMethodConcurrence = DataSizing::Concurrence::Combination; } } } else { diff --git a/src/EnergyPlus/ReportCoilSelection.hh b/src/EnergyPlus/ReportCoilSelection.hh index 105b82899f7..d15bf87a2e0 100644 --- a/src/EnergyPlus/ReportCoilSelection.hh +++ b/src/EnergyPlus/ReportCoilSelection.hh @@ -56,6 +56,7 @@ // EnergyPlus Headers #include #include +#include #include namespace EnergyPlus { @@ -98,8 +99,8 @@ public: // data int typeof_Coil; // type of coil, e.g., PlantEquipmentType::CoilWaterSimpleHeating, PlantEquipmentType::CoilWaterDetailedFlatCooling, // PlantEquipmentType::CoilWaterCooling - int coilSizingMethodConcurrence; // 1 = noncoincident, 2 = coincident - std::string coilSizingMethodConcurrenceName; // string name of sizing method for concurrence + DataSizing::Concurrence coilSizingMethodConcurrence = DataSizing::Concurrence::NA; // non-coincident, coincident, combination, n/a + std::string coilSizingMethodConcurrenceName; // string name of sizing method for concurrence int coilSizingMethodCapacity; // 8=CoolingDesignCapacity, 9=HeatingDesignCapacity, 10=CapacityPerFloorArea, 11=FractionOfAutosizedCoolingCapacity, // 12=FractionOfAutosizedHeatingCapacity From 5ffdf05e5737f0e79c0ab759f8b6df647ae43a60 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Wed, 19 Jun 2024 11:24:23 -0500 Subject: [PATCH 28/81] Space IV-YetAnotherEnum attempt --- src/EnergyPlus/DataSizing.hh | 103 ++++++++++-------- src/EnergyPlus/OutputReportTabular.cc | 2 +- src/EnergyPlus/ReportCoilSelection.cc | 26 ++--- src/EnergyPlus/ReportCoilSelection.hh | 5 +- src/EnergyPlus/SimAirServingZones.cc | 10 +- src/EnergyPlus/SizingManager.cc | 15 +-- .../unit/DesiccantDehumidifiers.unit.cc | 2 +- .../unit/OutputReportTabular.unit.cc | 2 +- 8 files changed, 87 insertions(+), 78 deletions(-) diff --git a/src/EnergyPlus/DataSizing.hh b/src/EnergyPlus/DataSizing.hh index a3c32ce7391..813ff4a4972 100644 --- a/src/EnergyPlus/DataSizing.hh +++ b/src/EnergyPlus/DataSizing.hh @@ -117,13 +117,23 @@ namespace DataSizing { Num }; - // parameters for sizing (keept this for now to avoid plant sizing output changes) + // parameters for sizing (keep this for now to avoid plant sizing output changes) constexpr int NonCoincident(1); constexpr int Coincident(2); - constexpr int Combination(3); - // parameters for sizing concurrence method - enum class Concurrence + // parameters for zone and system sizing concurrence method + enum class SizingConcurrence + { + Invalid = -1, + NonCoincident, + Coincident, + Num + }; + + constexpr std::array(SizingConcurrence::Num)> SizingConcurrenceNamesUC{"NonCoincident", "Coincident"}; + + // parameters for coil sizing concurrence method + enum class CoilSizingConcurrence { Invalid = -1, NonCoincident, @@ -133,10 +143,7 @@ namespace DataSizing { Num }; - constexpr std::array(Concurrence::Num)> ConcurrenceMethodNamesUC{ - "NonCoincident", "Coincident", "Combination", "NA"}; - - constexpr std::array(Concurrence::Num)> ConcurrenceMethodNames{ + constexpr std::array(CoilSizingConcurrence::Num)> CoilSizingConcurrenceNames{ "Non-Coincident", "Coincident", "Combination", "N/A"}; // parameters for Cooling Peak Load Type @@ -333,7 +340,7 @@ namespace DataSizing { DOASControl DOASControlStrategy = DOASControl::Invalid; // 0=neutral ventilation air; 1=neutral dehumidified ventilation air, 2 = cooled air; Real64 DOASLowSetpoint = 0.0; // Dedicated Outside Air Low Setpoint for Design [C] Real64 DOASHighSetpoint = 0.0; // Dedicated Outside Air High Setpoint for Design [C] - DataSizing::Concurrence spaceConcurrence = DataSizing::Concurrence::Coincident; // coincident or noncoincident space loads + DataSizing::SizingConcurrence spaceConcurrence = DataSizing::SizingConcurrence::Coincident; // coincident or noncoincident space loads // zone latent sizing inputs bool zoneLatentSizing = false; @@ -459,10 +466,10 @@ namespace DataSizing { bool AccountForDOAS = false; // False: do nothing; True: calculate the effect of a DOA system on the zone sizing arrays DOASControl DOASControlStrategy = DOASControl::Invalid; // 0=neutral ventilation air; 1=neutral dehumidified ventilation air, 2 = cooled air; // 3=supply cold ventilation air - Real64 DOASLowSetpoint = 0.0; // Dedicated Outside Air Low Setpoint for Design [C] - Real64 DOASHighSetpoint = 0.0; // Dedicated Outside Air High Setpoint for Design [C] - DataSizing::Concurrence spaceConcurrence = DataSizing::Concurrence::Coincident; // coincident or noncoincident space loads - bool EMSOverrideDesHeatMassOn = false; // true if EMS is acting on this structure + Real64 DOASLowSetpoint = 0.0; // Dedicated Outside Air Low Setpoint for Design [C] + Real64 DOASHighSetpoint = 0.0; // Dedicated Outside Air High Setpoint for Design [C] + DataSizing::SizingConcurrence spaceConcurrence = DataSizing::SizingConcurrence::Coincident; // coincident or noncoincident space loads + bool EMSOverrideDesHeatMassOn = false; // true if EMS is acting on this structure Real64 EMSValueDesHeatMassFlow = 0.0; // Value EMS directing to use for Design Heating air mass flow [kg/s] bool EMSOverrideDesCoolMassOn = false; // true if EMS is acting on this structure Real64 EMSValueDesCoolMassFlow = 0.0; // Value EMS directing to use for Design Cooling air mass flow [kg/s] @@ -786,23 +793,23 @@ namespace DataSizing { struct SystemSizingInputData { // Members - std::string AirPriLoopName; // name of an AirLoopHVAC object - int AirLoopNum = 0; // index number of air loop - LoadSizing loadSizingType = LoadSizing::Invalid; // type of load to size on sensible, latent, total, ventilation - DataSizing::Concurrence SizingOption = DataSizing::Concurrence::NonCoincident; // noncoincident, coincident - OAControl CoolOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for cooling sizing - OAControl HeatOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for heating sizing - Real64 DesOutAirVolFlow = 0.0; // design (minimum) outside air flow rate [m3/s] - Real64 SysAirMinFlowRat = 0.0; // minimum system air flow ratio for heating, Central Heating Maximum System Air Flow Ratio - bool SysAirMinFlowRatWasAutoSized = false; // true if central heating maximum system air flow ratio was autosize on input - Real64 PreheatTemp = 0.0; // preheat design set temperature [C] - Real64 PrecoolTemp = 0.0; // precool design set temperature [C] - Real64 PreheatHumRat = 0.0; // preheat design humidity ratio [kg water/kg dry air] - Real64 PrecoolHumRat = 0.0; // precool design humidity ratio [kg water/kg dry air] - Real64 CoolSupTemp = 0.0; // cooling design supply air temperature [C] - Real64 HeatSupTemp = 0.0; // heating design supply air temperature [C] - Real64 CoolSupHumRat = 0.0; // cooling design supply air humidity ratio [kg water/kg dry air] - Real64 HeatSupHumRat = 0.0; // heating design supply air humidity ratio [kg water/kg dry air] + std::string AirPriLoopName; // name of an AirLoopHVAC object + int AirLoopNum = 0; // index number of air loop + LoadSizing loadSizingType = LoadSizing::Invalid; // type of load to size on sensible, latent, total, ventilation + DataSizing::SizingConcurrence SizingOption = DataSizing::SizingConcurrence::NonCoincident; // noncoincident, coincident + OAControl CoolOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for cooling sizing + OAControl HeatOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for heating sizing + Real64 DesOutAirVolFlow = 0.0; // design (minimum) outside air flow rate [m3/s] + Real64 SysAirMinFlowRat = 0.0; // minimum system air flow ratio for heating, Central Heating Maximum System Air Flow Ratio + bool SysAirMinFlowRatWasAutoSized = false; // true if central heating maximum system air flow ratio was autosize on input + Real64 PreheatTemp = 0.0; // preheat design set temperature [C] + Real64 PrecoolTemp = 0.0; // precool design set temperature [C] + Real64 PreheatHumRat = 0.0; // preheat design humidity ratio [kg water/kg dry air] + Real64 PrecoolHumRat = 0.0; // precool design humidity ratio [kg water/kg dry air] + Real64 CoolSupTemp = 0.0; // cooling design supply air temperature [C] + Real64 HeatSupTemp = 0.0; // heating design supply air temperature [C] + Real64 CoolSupHumRat = 0.0; // cooling design supply air humidity ratio [kg water/kg dry air] + Real64 HeatSupHumRat = 0.0; // heating design supply air humidity ratio [kg water/kg dry air] AirflowSizingMethod CoolAirDesMethod = AirflowSizingMethod::Invalid; // choice of how to get system cooling design air flow rates; // 1 = calc from des day simulation; 2=m3/s per system, user input Real64 DesCoolAirFlow = 0.0; // design system supply air flow rate for cooling[m3/s] @@ -838,24 +845,24 @@ namespace DataSizing { struct SystemSizingData // Contains data for system sizing { // Members - std::string AirPriLoopName; // name of an AirLoopHVAC object - std::string CoolDesDay; // name of a cooling design day - std::string HeatDesDay; // name of a heating design day - LoadSizing loadSizingType = LoadSizing::Invalid; // type of load to size on Sensible, Latent, Total, Ventilation - DataSizing::Concurrence SizingOption = DataSizing::Concurrence::NonCoincident; // noncoincident, coincident. - OAControl CoolOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for cooling sizing - OAControl HeatOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for heating sizing - Real64 DesOutAirVolFlow = 0.0; // design (minimum) outside air flow rate [m3/s] - Real64 SysAirMinFlowRat = 0.0; // minimum system air flow ratio for heating, Central Heating Maximum System Air Flow Ratio - bool SysAirMinFlowRatWasAutoSized = false; // true if central heating maximum system air flow ratio was autosize on input - Real64 PreheatTemp = 0.0; // preheat design set temperature - Real64 PrecoolTemp = 0.0; // precool design set temperature [C] - Real64 PreheatHumRat = 0.0; // preheat design humidity ratio [kg water/kg dry air] - Real64 PrecoolHumRat = 0.0; // precool design humidity ratio [kg water/kg dry air] - Real64 CoolSupTemp = 0.0; // cooling design supply air temperature [C] - Real64 HeatSupTemp = 0.0; // heating design supply air temperature[C] - Real64 CoolSupHumRat = 0.0; // cooling design supply air humidity ratio [kg water/kg dry air] - Real64 HeatSupHumRat = 0.0; // heating design supply air humidity ratio [kg water/kg dry air] + std::string AirPriLoopName; // name of an AirLoopHVAC object + std::string CoolDesDay; // name of a cooling design day + std::string HeatDesDay; // name of a heating design day + LoadSizing loadSizingType = LoadSizing::Invalid; // type of load to size on Sensible, Latent, Total, Ventilation + DataSizing::SizingConcurrence SizingOption = DataSizing::SizingConcurrence::NonCoincident; // noncoincident, coincident. + OAControl CoolOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for cooling sizing + OAControl HeatOAOption = OAControl::Invalid; // 1 = use 100% outside air; 2 = use min OA; for heating sizing + Real64 DesOutAirVolFlow = 0.0; // design (minimum) outside air flow rate [m3/s] + Real64 SysAirMinFlowRat = 0.0; // minimum system air flow ratio for heating, Central Heating Maximum System Air Flow Ratio + bool SysAirMinFlowRatWasAutoSized = false; // true if central heating maximum system air flow ratio was autosize on input + Real64 PreheatTemp = 0.0; // preheat design set temperature + Real64 PrecoolTemp = 0.0; // precool design set temperature [C] + Real64 PreheatHumRat = 0.0; // preheat design humidity ratio [kg water/kg dry air] + Real64 PrecoolHumRat = 0.0; // precool design humidity ratio [kg water/kg dry air] + Real64 CoolSupTemp = 0.0; // cooling design supply air temperature [C] + Real64 HeatSupTemp = 0.0; // heating design supply air temperature[C] + Real64 CoolSupHumRat = 0.0; // cooling design supply air humidity ratio [kg water/kg dry air] + Real64 HeatSupHumRat = 0.0; // heating design supply air humidity ratio [kg water/kg dry air] AirflowSizingMethod CoolAirDesMethod = AirflowSizingMethod::Invalid; // choice of how to get system design cooling air flow rates; // 1 = calc from des day simulation; 2=m3/s per system, user input AirflowSizingMethod HeatAirDesMethod = AirflowSizingMethod::Invalid; // choice of how to get system design heating air flow rates; diff --git a/src/EnergyPlus/OutputReportTabular.cc b/src/EnergyPlus/OutputReportTabular.cc index 821fc171110..5b494d61448 100644 --- a/src/EnergyPlus/OutputReportTabular.cc +++ b/src/EnergyPlus/OutputReportTabular.cc @@ -15351,7 +15351,7 @@ void WriteLoadComponentSummaryTables(EnergyPlusData &state) } for (int SysSizIndex = 1; SysSizIndex <= state.dataSize->NumSysSizInput; ++SysSizIndex) { if (state.dataSize->SysSizInput(SysSizIndex).AirLoopNum != iAirLoop) continue; - if (state.dataSize->SysSizInput(SysSizIndex).SizingOption == DataSizing::Concurrence::Coincident) { + if (state.dataSize->SysSizInput(SysSizIndex).SizingOption == DataSizing::SizingConcurrence::Coincident) { airLoopCoolTable.peakDesSensLoad = finalSysSizing.SysCoolCoinSpaceSens; airLoopCoolTable.designPeakLoad = finalSysSizing.SysDesCoolLoad; diff --git a/src/EnergyPlus/ReportCoilSelection.cc b/src/EnergyPlus/ReportCoilSelection.cc index 50841801321..b3033365723 100644 --- a/src/EnergyPlus/ReportCoilSelection.cc +++ b/src/EnergyPlus/ReportCoilSelection.cc @@ -734,7 +734,7 @@ void ReportCoilSelection::doFinalProcessingOfCoilData(EnergyPlusData &state) c->oaPeakVolFrac = -999.0; } - c->coilSizingMethodConcurrenceName = DataSizing::ConcurrenceMethodNames[(int)c->coilSizingMethodConcurrence]; + c->coilSizingMethodConcurrenceName = DataSizing::CoilSizingConcurrenceNames[(int)c->coilSizingMethodConcurrence]; if (c->coilSizingMethodCapacity == DataSizing::CoolingDesignCapacity) { c->coilSizingMethodCapacityName = "CoolingDesignCapacity"; @@ -1264,7 +1264,7 @@ void ReportCoilSelection::setCoilCoolingCapacity( c->oaPeakHumRat = finalSysSizing.OutHumRatAtCoolPeak; c->raPeakTemp = finalSysSizing.RetTempAtCoolPeak; c->raPeakHumRat = finalSysSizing.RetHumRatAtCoolPeak; - c->coilSizingMethodConcurrence = finalSysSizing.SizingOption; + c->coilSizingMethodConcurrence = static_cast(finalSysSizing.SizingOption); c->coilSizingMethodCapacity = finalSysSizing.CoolingCapMethod; c->coilSizingMethodAirFlow = finalSysSizing.ScaleCoolSAFMethod; // DesOutAirVolFlow @@ -1323,9 +1323,9 @@ void ReportCoilSelection::setCoilCoolingCapacity( c->rmPeakRelHum = -999.0; } - if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::Coincident) { + if (c->coilSizingMethodConcurrence == DataSizing::CoilSizingConcurrence::Coincident) { c->rmSensibleAtPeak = finalSysSizing.SysCoolCoinSpaceSens; - } else if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::NonCoincident) { + } else if (c->coilSizingMethodConcurrence == DataSizing::CoilSizingConcurrence::NonCoincident) { c->rmSensibleAtPeak = sumSensLoad; } else { // DataSizing::Combination or other c->rmSensibleAtPeak = sumSensLoad; @@ -1470,7 +1470,7 @@ void ReportCoilSelection::setCoilCoolingCapacity( state, c->coilDesLvgTemp, c->coilDesLvgHumRat, state.dataEnvrn->StdBaroPress, "ReportCoilSelection::setCoilCoolingCapacity"); c->coilDesLvgEnth = Psychrometrics::PsyHFnTdbW(c->coilDesLvgTemp, c->coilDesLvgHumRat); } - DataSizing::Concurrence sizMethod = DataSizing::Concurrence::Invalid; + DataSizing::SizingConcurrence sizMethod = DataSizing::SizingConcurrence::Invalid; bool sizMethodsAreTheSame = true; for (int airLoopNum = 0; airLoopNum < state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].NumOfAirLoops; ++airLoopNum) { int actualAirLoopNum = state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].m_AirLoopNum[airLoopNum]; @@ -1483,9 +1483,9 @@ void ReportCoilSelection::setCoilCoolingCapacity( } } if (sizMethodsAreTheSame) { - c->coilSizingMethodConcurrence = sizMethod; + c->coilSizingMethodConcurrence = static_cast(sizMethod); } else { - c->coilSizingMethodConcurrence = DataSizing::Concurrence::Combination; + c->coilSizingMethodConcurrence = DataSizing::CoilSizingConcurrence::Combination; } } } else { @@ -1533,7 +1533,7 @@ void ReportCoilSelection::setCoilHeatingCapacity( c->oaPeakVolFlow = finalSysSizing.DesOutAirVolFlow; c->raPeakTemp = finalSysSizing.HeatRetTemp; c->raPeakHumRat = finalSysSizing.HeatRetHumRat; - c->coilSizingMethodConcurrence = finalSysSizing.SizingOption; + c->coilSizingMethodConcurrence = static_cast(finalSysSizing.SizingOption); c->coilSizingMethodCapacity = finalSysSizing.HeatingCapMethod; c->coilSizingMethodAirFlow = finalSysSizing.ScaleHeatSAFMethod; @@ -1588,9 +1588,9 @@ void ReportCoilSelection::setCoilHeatingCapacity( c->rmPeakRelHum = -999.0; } - if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::Coincident) { + if (c->coilSizingMethodConcurrence == DataSizing::CoilSizingConcurrence::Coincident) { c->rmSensibleAtPeak = finalSysSizing.SysHeatCoinSpaceSens; - } else if (c->coilSizingMethodConcurrence == DataSizing::Concurrence::NonCoincident) { + } else if (c->coilSizingMethodConcurrence == DataSizing::CoilSizingConcurrence::NonCoincident) { c->rmSensibleAtPeak = sumLoad; } @@ -1767,7 +1767,7 @@ void ReportCoilSelection::setCoilHeatingCapacity( state, c->coilDesLvgTemp, c->coilDesLvgHumRat, state.dataEnvrn->StdBaroPress, "ReportCoilSelection::setCoilHeatingCapacity"); c->coilDesLvgEnth = Psychrometrics::PsyHFnTdbW(c->coilDesLvgTemp, c->coilDesLvgHumRat); } - DataSizing::Concurrence sizMethod = DataSizing::Concurrence::Invalid; + DataSizing::SizingConcurrence sizMethod = DataSizing::SizingConcurrence::Invalid; bool sizMethodsAreTheSame = true; for (int airLoopNum = 0; airLoopNum < state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].NumOfAirLoops; ++airLoopNum) { int actualAirLoopNum = state.dataAirLoopHVACDOAS->airloopDOAS[DOASSysNum].m_AirLoopNum[airLoopNum]; @@ -1780,9 +1780,9 @@ void ReportCoilSelection::setCoilHeatingCapacity( } } if (sizMethodsAreTheSame) { - c->coilSizingMethodConcurrence = sizMethod; + c->coilSizingMethodConcurrence = static_cast(sizMethod); } else { - c->coilSizingMethodConcurrence = DataSizing::Concurrence::Combination; + c->coilSizingMethodConcurrence = DataSizing::CoilSizingConcurrence::Combination; } } } else { diff --git a/src/EnergyPlus/ReportCoilSelection.hh b/src/EnergyPlus/ReportCoilSelection.hh index d15bf87a2e0..b68d1b2c477 100644 --- a/src/EnergyPlus/ReportCoilSelection.hh +++ b/src/EnergyPlus/ReportCoilSelection.hh @@ -99,8 +99,9 @@ public: // data int typeof_Coil; // type of coil, e.g., PlantEquipmentType::CoilWaterSimpleHeating, PlantEquipmentType::CoilWaterDetailedFlatCooling, // PlantEquipmentType::CoilWaterCooling - DataSizing::Concurrence coilSizingMethodConcurrence = DataSizing::Concurrence::NA; // non-coincident, coincident, combination, n/a - std::string coilSizingMethodConcurrenceName; // string name of sizing method for concurrence + DataSizing::CoilSizingConcurrence coilSizingMethodConcurrence = + DataSizing::CoilSizingConcurrence::NA; // non-coincident, coincident, combination, n/a + std::string coilSizingMethodConcurrenceName; // string name of sizing method for concurrence int coilSizingMethodCapacity; // 8=CoolingDesignCapacity, 9=HeatingDesignCapacity, 10=CapacityPerFloorArea, 11=FractionOfAutosizedCoolingCapacity, // 12=FractionOfAutosizedHeatingCapacity diff --git a/src/EnergyPlus/SimAirServingZones.cc b/src/EnergyPlus/SimAirServingZones.cc index 494351d0478..7281b4e9abf 100644 --- a/src/EnergyPlus/SimAirServingZones.cc +++ b/src/EnergyPlus/SimAirServingZones.cc @@ -5510,7 +5510,7 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn auto &sysSizing = state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum); switch (sysSizing.SizingOption) { - case DataSizing::Concurrence::Coincident: { + case DataSizing::SizingConcurrence::Coincident: { if (finalSysSizing.SystemOAMethod == SysOAMethod::ZoneSum) { sysSizing.DesCoolVolFlow = sysSizing.CoinCoolMassFlow / state.dataEnvrn->StdRhoAir; sysSizing.DesHeatVolFlow = sysSizing.CoinHeatMassFlow / state.dataEnvrn->StdRhoAir; @@ -5841,7 +5841,7 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn sysSizing.DesMainVolFlow = max(sysSizing.DesCoolVolFlow, sysSizing.DesHeatVolFlow); // this should also be as least as big as is needed for Vot } break; - case DataSizing::Concurrence::NonCoincident: { + case DataSizing::SizingConcurrence::NonCoincident: { if (finalSysSizing.SystemOAMethod == SysOAMethod::ZoneSum) { sysSizing.DesCoolVolFlow = sysSizing.NonCoinCoolMassFlow / state.dataEnvrn->StdRhoAir; sysSizing.DesHeatVolFlow = sysSizing.NonCoinHeatMassFlow / state.dataEnvrn->StdRhoAir; @@ -6540,7 +6540,7 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn } // move the noncoincident results into the system sizing array - if (state.dataSize->CalcSysSizing(AirLoopNum).SizingOption == DataSizing::Concurrence::NonCoincident) { + if (state.dataSize->CalcSysSizing(AirLoopNum).SizingOption == DataSizing::SizingConcurrence::NonCoincident) { // But first check to see if the noncoincident result is actually bigger than the coincident (for 100% outside air) if (!(state.dataSize->FinalSysSizing(AirLoopNum).CoolOAOption == OAControl::AllOA && SysSensCoolCap <= 0.0)) { // CoolOAOption = Yes 100% OA @@ -6762,7 +6762,7 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn } state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).scaleZoneCooling(ZoneOARatio); } else if ((SysCoolSizingRat > 1.0) || - (SysCoolSizingRat < 1.0 && finalSysSizing.SizingOption == DataSizing::Concurrence::NonCoincident)) { + (SysCoolSizingRat < 1.0 && finalSysSizing.SizingOption == DataSizing::SizingConcurrence::NonCoincident)) { // size on user input system design flows state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).scaleZoneCooling(SysCoolSizingRat); } @@ -6823,7 +6823,7 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn ZoneOARatio *= (1.0 + state.dataSize->TermUnitSizing(TermUnitSizingIndex).InducRat); termUnitFinalZoneSizing.scaleZoneHeating(ZoneOARatio); } else if ((SysHeatSizingRat > 1.0) || - (SysHeatSizingRat < 1.0 && finalSysSizing.SizingOption == DataSizing::Concurrence::NonCoincident)) { + (SysHeatSizingRat < 1.0 && finalSysSizing.SizingOption == DataSizing::SizingConcurrence::NonCoincident)) { // size on user input system design flows termUnitFinalZoneSizing.scaleZoneHeating(SysHeatSizingRat); } diff --git a/src/EnergyPlus/SizingManager.cc b/src/EnergyPlus/SizingManager.cc index 25d2294a30f..2cd8bedbaed 100644 --- a/src/EnergyPlus/SizingManager.cc +++ b/src/EnergyPlus/SizingManager.cc @@ -1116,8 +1116,9 @@ void ManageSystemSizingAdjustments(EnergyPlusData &state) // correct sizing design heating volume flow rate based on finalized air terminal unit operation if (FinalSysSizing(AirLoopNum).SizingOption == - DataSizing::Concurrence::NonCoincident) { // If non-coincident sizing method for this air loop, the we can use these sum's from - // air terminals directly + DataSizing::SizingConcurrence::NonCoincident) { // If non-coincident sizing method for this air loop, the we can use these sum's + // from + // air terminals directly FinalSysSizing(AirLoopNum).DesHeatVolFlow = max(airLoopHeatingMaximumFlowRateSum, FinalSysSizing(AirLoopNum).DesHeatVolFlow); FinalSysSizing(AirLoopNum).DesMainVolFlow = max(airLoopMaxFlowRateSum, FinalSysSizing(AirLoopNum).DesMainVolFlow); if (FinalSysSizing(AirLoopNum).sysSizeCoolingDominant) { @@ -1127,7 +1128,7 @@ void ManageSystemSizingAdjustments(EnergyPlusData &state) FinalSysSizing(AirLoopNum).DesCoolVolFlow = max(airLoopHeatingMinimumFlowRateSum, FinalSysSizing(AirLoopNum).DesCoolVolFlow); FinalSysSizing(AirLoopNum).MassFlowAtCoolPeak = FinalSysSizing(AirLoopNum).DesCoolVolFlow * state.dataEnvrn->StdRhoAir; } - } else if (FinalSysSizing(AirLoopNum).SizingOption == DataSizing::Concurrence::Coincident) { + } else if (FinalSysSizing(AirLoopNum).SizingOption == DataSizing::SizingConcurrence::Coincident) { if (FinalSysSizing(AirLoopNum).sysSizeCoolingDominant) { // use minimum heating flow sum from air terminals // know that minimum heating flow is a hard minimum regardless of concurrence situation, so make sure that design is at @@ -3280,8 +3281,8 @@ void GetZoneSizingInput(EnergyPlusData &state) ErrorsFound = true; } } - zoneSizingIndex.spaceConcurrence = - static_cast(getEnumValue(DataSizing::ConcurrenceMethodNamesUC, state.dataIPShortCut->cAlphaArgs(10))); + zoneSizingIndex.spaceConcurrence = static_cast( + getEnumValue(DataSizing::SizingConcurrenceNamesUC, state.dataIPShortCut->cAlphaArgs(10))); zoneSizingIndex.zoneSizingMethod = static_cast(getEnumValue(DataSizing::ZoneSizingMethodNamesUC, state.dataIPShortCut->cAlphaArgs(10))); if (zoneSizingIndex.zoneSizingMethod != ZoneSizing::SensibleOnly) { @@ -3581,9 +3582,9 @@ void GetSystemSizingInput(EnergyPlusData &state) { std::string const &sizingOption = state.dataIPShortCut->cAlphaArgs(iSizingOptionAlphaNum); if (sizingOption == "COINCIDENT") { - SysSizInput(SysSizIndex).SizingOption = DataSizing::Concurrence::Coincident; + SysSizInput(SysSizIndex).SizingOption = DataSizing::SizingConcurrence::Coincident; } else if (sizingOption == "NONCOINCIDENT") { - SysSizInput(SysSizIndex).SizingOption = DataSizing::Concurrence::NonCoincident; + SysSizInput(SysSizIndex).SizingOption = DataSizing::SizingConcurrence::NonCoincident; } else { ShowSevereError(state, format("{}=\"{}\", invalid data.", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(iNameAlphaNum))); ShowContinueError(state, diff --git a/tst/EnergyPlus/unit/DesiccantDehumidifiers.unit.cc b/tst/EnergyPlus/unit/DesiccantDehumidifiers.unit.cc index 56544d221fa..ab90e93809e 100644 --- a/tst/EnergyPlus/unit/DesiccantDehumidifiers.unit.cc +++ b/tst/EnergyPlus/unit/DesiccantDehumidifiers.unit.cc @@ -2898,7 +2898,7 @@ TEST_F(EnergyPlusFixture, DesiccantDehum_OnOASystemTest) auto &finalSysSizing = state->dataSize->FinalSysSizing(1); auto &sysSizPeakDDNum = state->dataSize->SysSizPeakDDNum(1); EXPECT_ENUM_EQ(finalSysSizing.coolingPeakLoad, DataSizing::PeakLoad::SensibleCooling); - EXPECT_ENUM_EQ(finalSysSizing.SizingOption, DataSizing::Concurrence::NonCoincident); + EXPECT_ENUM_EQ(finalSysSizing.SizingOption, DataSizing::SizingConcurrence::NonCoincident); EXPECT_EQ(sysSizPeakDDNum.SensCoolPeakDD, coolPeakDD); int timeStepIndexAtPeakCoolLoad = sysSizPeakDDNum.TimeStepAtSensCoolPk(coolPeakDD); EXPECT_EQ(sysSizPeakDDNum.TimeStepAtTotCoolPk(coolPeakDD), timeStepIndexAtPeakCoolLoad); diff --git a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc index 31a772385eb..688f439840a 100644 --- a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc +++ b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc @@ -7233,7 +7233,7 @@ TEST_F(SQLiteFixture, OutputReportTabular_WriteLoadComponentSummaryTables_AirLoo state->dataSize->NumSysSizInput = 1; state->dataSize->SysSizInput.allocate(state->dataSize->NumSysSizInput); state->dataSize->SysSizInput(1).AirLoopNum = 1; - state->dataSize->SysSizInput(1).SizingOption = DataSizing::Concurrence::NonCoincident; + state->dataSize->SysSizInput(1).SizingOption = DataSizing::SizingConcurrence::NonCoincident; auto degC_to_F = [](Real64 celsius) constexpr { return celsius * (9.0 / 5.0) + 32.0; From 1c11d8931a7fd104bc315c0f7acd69ae64324add Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Fri, 28 Jun 2024 17:30:39 -0500 Subject: [PATCH 29/81] Streamline sizing peak timestamps plus etc --- src/EnergyPlus/ZoneEquipmentManager.cc | 62 +++++++++++++++----------- src/EnergyPlus/ZoneEquipmentManager.hh | 5 ++- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index cb1ea30e0f9..9c795aee378 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -1178,6 +1178,7 @@ void fillZoneSizingFromInput(EnergyPlusData &state, zoneSizing.DOASControlStrategy = zoneSizingInput.DOASControlStrategy; zoneSizing.DOASLowSetpoint = zoneSizingInput.DOASLowSetpoint; zoneSizing.DOASHighSetpoint = zoneSizingInput.DOASHighSetpoint; + zoneSizing.spaceConcurrence = zoneSizingInput.spaceConcurrence; zoneSizing.zoneSizingMethod = zoneSizingInput.zoneSizingMethod; zoneSizing.zoneLatentSizing = zoneSizingInput.zoneLatentSizing; zoneSizing.zoneRHDehumidifySetPoint = zoneSizingInput.zoneRHDehumidifySetPoint; @@ -1210,6 +1211,7 @@ void fillZoneSizingFromInput(EnergyPlusData &state, calcZoneSizing.DOASControlStrategy = zoneSizingInput.DOASControlStrategy; calcZoneSizing.DOASLowSetpoint = zoneSizingInput.DOASLowSetpoint; calcZoneSizing.DOASHighSetpoint = zoneSizingInput.DOASHighSetpoint; + calcZoneSizing.spaceConcurrence = zoneSizingInput.spaceConcurrence; calcZoneSizing.zoneSizingMethod = zoneSizingInput.zoneSizingMethod; calcZoneSizing.zoneLatentSizing = zoneSizingInput.zoneLatentSizing; calcZoneSizing.zoneRHDehumidifySetPoint = zoneSizingInput.zoneRHDehumidifySetPoint; @@ -1262,6 +1264,7 @@ void fillZoneSizingFromInput(EnergyPlusData &state, zsFinalSizing.ZoneADEffHeating = zoneSizingInput.ZoneADEffHeating; zsFinalSizing.ZoneSecondaryRecirculation = zoneSizingInput.ZoneSecondaryRecirculation; zsFinalSizing.ZoneVentilationEff = zoneSizingInput.ZoneVentilationEff; + zsFinalSizing.spaceConcurrence = zoneSizingInput.spaceConcurrence; zsFinalSizing.zoneSizingMethod = zoneSizingInput.zoneSizingMethod; zsFinalSizing.zoneLatentSizing = zoneSizingInput.zoneLatentSizing; zsFinalSizing.zoneRHDehumidifySetPoint = zoneSizingInput.zoneRHDehumidifySetPoint; @@ -1302,6 +1305,7 @@ void fillZoneSizingFromInput(EnergyPlusData &state, zsCalcFinalSizing.DOASHighSetpoint = zoneSizingInput.DOASHighSetpoint; zsCalcFinalSizing.ZoneADEffCooling = zoneSizingInput.ZoneADEffCooling; zsCalcFinalSizing.ZoneADEffHeating = zoneSizingInput.ZoneADEffHeating; + zsCalcFinalSizing.spaceConcurrence = zoneSizingInput.spaceConcurrence; zsCalcFinalSizing.zoneSizingMethod = zoneSizingInput.zoneSizingMethod; zsCalcFinalSizing.zoneLatentSizing = zoneSizingInput.zoneLatentSizing; zsCalcFinalSizing.zoneRHDehumidifySetPoint = zoneSizingInput.zoneRHDehumidifySetPoint; @@ -1958,21 +1962,27 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, DataSizing::ZoneS } } -void updateZoneSizingEndZoneSizingCalc2(DataSizing::ZoneSizingData &zsCalcSizing, int const timeStepIndex, int const hourPrint, int const minutes) +void updateZoneSizingEndZoneSizingCalc2(EnergyPlusData &state, DataSizing::ZoneSizingData &zsCalcSizing) { - // SpaceSizing TODO: There's gotta be a better place to set these timestamps - if (timeStepIndex == zsCalcSizing.TimeStepNumAtHeatMax) { - zsCalcSizing.HeatPeakDateHrMin = zsCalcSizing.cHeatDDDate + ' ' + format(PeakHrMinFmt, hourPrint, minutes); - } - if (timeStepIndex == zsCalcSizing.TimeStepNumAtCoolMax) { - zsCalcSizing.CoolPeakDateHrMin = zsCalcSizing.cCoolDDDate + ' ' + format(PeakHrMinFmt, hourPrint, minutes); - } - if (timeStepIndex == zsCalcSizing.TimeStepNumAtLatentHeatMax) { - zsCalcSizing.LatHeatPeakDateHrMin = zsCalcSizing.cLatentHeatDDDate + ' ' + format(PeakHrMinFmt, hourPrint, minutes); - } - if (timeStepIndex == zsCalcSizing.TimeStepNumAtLatentCoolMax) { - zsCalcSizing.LatCoolPeakDateHrMin = zsCalcSizing.cLatentCoolDDDate + ' ' + format(PeakHrMinFmt, hourPrint, minutes); - } + zsCalcSizing.HeatPeakDateHrMin = zsCalcSizing.cHeatDDDate + ' ' + sizingPeakTimeStamp(state, zsCalcSizing.TimeStepNumAtHeatMax); + + zsCalcSizing.CoolPeakDateHrMin = zsCalcSizing.cCoolDDDate + ' ' + sizingPeakTimeStamp(state, zsCalcSizing.TimeStepNumAtCoolMax); + + zsCalcSizing.LatHeatPeakDateHrMin = zsCalcSizing.cLatentHeatDDDate + ' ' + sizingPeakTimeStamp(state, zsCalcSizing.TimeStepNumAtLatentHeatMax); + + zsCalcSizing.LatCoolPeakDateHrMin = zsCalcSizing.cLatentCoolDDDate + ' ' + sizingPeakTimeStamp(state, zsCalcSizing.TimeStepNumAtLatentCoolMax); +} + +std::string sizingPeakTimeStamp(EnergyPlusData &state, int timeStepIndex) +{ + int constexpr minToSec = 60; + int hour = 0; + int minute = 0; + Real64 second = 0; + + Real64 timeInSeconds = timeStepIndex * state.dataGlobal->MinutesPerTimeStep * minToSec; + General::ParseTime(timeInSeconds, hour, minute, second); + return format(PeakHrMinFmt, hour, minute); } void updateZoneSizingEndZoneSizingCalc3(DataSizing::ZoneSizingData &zsCalcFinalSizing, @@ -2096,6 +2106,7 @@ void updateZoneSizingEndZoneSizingCalc3(DataSizing::ZoneSizingData &zsCalcFinalS } void updateZoneSizingEndZoneSizingCalc4(DataSizing::ZoneSizingData &zsSizing, DataSizing::ZoneSizingData const &zsCalcSizing) { + // Move data from Calc arrays to user modified arrays zsSizing.CoolDesDay = zsCalcSizing.CoolDesDay; zsSizing.HeatDesDay = zsCalcSizing.HeatDesDay; zsSizing.DesHeatDens = zsCalcSizing.DesHeatDens; @@ -2131,6 +2142,7 @@ void updateZoneSizingEndZoneSizingCalc4(DataSizing::ZoneSizingData &zsSizing, Da void updateZoneSizingEndZoneSizingCalc5(DataSizing::ZoneSizingData &zsFinalSizing, DataSizing::ZoneSizingData const &zsCalcFinalSizing) { + // Move data from CalcFinal arrays to user modified final arrays // SpaceSizing TODO: This is essentially the same as updateZoneSizingEndZoneSizingCalc4, except there are two extra fields copied here zsFinalSizing.CoolDesDay = zsCalcFinalSizing.CoolDesDay; zsFinalSizing.HeatDesDay = zsCalcFinalSizing.HeatDesDay; @@ -2765,6 +2777,16 @@ void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator const CallI ":Cooling Zone Relative Humidity [%]"); } + for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) { + if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue; + updateZoneSizingEndZoneSizingCalc2(state, state.dataSize->CalcFinalZoneSizing(CtrlZoneNum)); + if (state.dataHeatBal->doSpaceHeatBalanceSizing) { + for (int spaceNum : state.dataHeatBal->Zone(CtrlZoneNum).spaceIndexes) { + updateZoneSizingEndZoneSizingCalc2(state, state.dataSize->CalcFinalSpaceSizing(spaceNum)); + } + } + } + print(state.files.zsz, "\n"); // HourFrac = 0.0 int Minutes = 0; @@ -2778,16 +2800,6 @@ void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator const CallI Minutes = 0; HourPrint = HourCounter; } - for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) { - if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue; - updateZoneSizingEndZoneSizingCalc2(state.dataSize->CalcFinalZoneSizing(CtrlZoneNum), TimeStepIndex, HourPrint, Minutes); - if (state.dataHeatBal->doSpaceHeatBalanceSizing) { - for (int spaceNum : state.dataHeatBal->Zone(CtrlZoneNum).spaceIndexes) { - updateZoneSizingEndZoneSizingCalc2(state.dataSize->CalcFinalSpaceSizing(spaceNum), TimeStepIndex, HourPrint, Minutes); - } - } - } - static constexpr std::string_view ZSizeFmt20("{:02}:{:02}:00"); print(state.files.zsz, ZSizeFmt20, HourPrint, Minutes); for (int I = 1; I <= state.dataGlobal->NumOfZones; ++I) { @@ -2986,7 +2998,7 @@ void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator const CallI for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) { if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue; - // Yes, call updateZoneSizingEndZoneSizingCalc6 again here to copyd the same fields + // Yes, call updateZoneSizingEndZoneSizingCalc6 again here to copy the same fields updateZoneSizingEndZoneSizingCalc6(state.dataSize->FinalZoneSizing(CtrlZoneNum), state.dataSize->CalcFinalZoneSizing(CtrlZoneNum), state.dataZoneEquipmentManager->NumOfTimeStepInDay); diff --git a/src/EnergyPlus/ZoneEquipmentManager.hh b/src/EnergyPlus/ZoneEquipmentManager.hh index a58db51063a..16c53a10bc9 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.hh +++ b/src/EnergyPlus/ZoneEquipmentManager.hh @@ -142,8 +142,9 @@ namespace ZoneEquipmentManager { void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, DataSizing::ZoneSizingData const &zsCalcSizing); - void - updateZoneSizingEndZoneSizingCalc2(DataSizing::ZoneSizingData &zsCalcSizing, int const timeStepIndex, int const hourPrint, int const minutes); + void updateZoneSizingEndZoneSizingCalc2(EnergyPlusData &state, DataSizing::ZoneSizingData &zsCalcSizing); + + std::string sizingPeakTimeStamp(EnergyPlusData &state, int timeStepIndex); void updateZoneSizingEndZoneSizingCalc3(DataSizing::ZoneSizingData &zsCalcFinalSizing, Array2D &zsCalcSizing, From d68a756e5c840259db0649c9c82ab018dc093433 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Tue, 2 Jul 2024 16:58:50 -0500 Subject: [PATCH 30/81] Space IV-Add Spsz output --- idd/Energy+.idd.in | 51 +- scripts/RunEPlus.bat | 10 + src/EnergyPlus/CommandLineInterface.cc | 7 + src/EnergyPlus/Data/EnergyPlusData.cc | 1 + src/EnergyPlus/DataZoneEquipment.hh | 2 +- src/EnergyPlus/IOFiles.cc | 4 + src/EnergyPlus/IOFiles.hh | 6 + src/EnergyPlus/SizingManager.cc | 9 + src/EnergyPlus/ZoneEquipmentManager.cc | 473 +++++++++--------- src/EnergyPlus/ZoneEquipmentManager.hh | 7 + ...iumOfficeNew2004_Chicago_OutputControl.idf | 1 + .../unit/Fixtures/EnergyPlusFixture.cc | 2 + tst/EnergyPlus/unit/OutputFiles.unit.cc | 51 +- 13 files changed, 350 insertions(+), 274 deletions(-) diff --git a/idd/Energy+.idd.in b/idd/Energy+.idd.in index 6b3564b981a..f1fac315215 100644 --- a/idd/Energy+.idd.in +++ b/idd/Energy+.idd.in @@ -107173,117 +107173,122 @@ OutputControl:Files, \key Yes \key No \default Yes - A9 , \field Output Zone Sizing + A9 , \field Output Space Sizing \type choice \key Yes \key No \default Yes - A10, \field Output System Sizing + A10, \field Output Zone Sizing \type choice \key Yes \key No \default Yes - A11, \field Output DXF + A11, \field Output System Sizing \type choice \key Yes \key No \default Yes - A12, \field Output BND + A12, \field Output DXF \type choice \key Yes \key No \default Yes - A13, \field Output RDD + A13, \field Output BND \type choice \key Yes \key No \default Yes - A14, \field Output MDD + A14, \field Output RDD \type choice \key Yes \key No \default Yes - A15, \field Output MTD + A15, \field Output MDD \type choice \key Yes \key No \default Yes - A16, \field Output END + A16, \field Output MTD \type choice \key Yes \key No \default Yes - A17, \field Output SHD + A17, \field Output END \type choice \key Yes \key No \default Yes - A18, \field Output DFS + A18, \field Output SHD \type choice \key Yes \key No \default Yes - A19, \field Output GLHE + A19, \field Output DFS \type choice \key Yes \key No \default Yes - A20, \field Output DelightIn + A20, \field Output GLHE \type choice \key Yes \key No \default Yes - A21, \field Output DelightELdmp + A21, \field Output DelightIn \type choice \key Yes \key No \default Yes - A22, \field Output DelightDFdmp + A22, \field Output DelightELdmp \type choice \key Yes \key No \default Yes - A23, \field Output EDD + A23, \field Output DelightDFdmp \type choice \key Yes \key No \default Yes - A24, \field Output DBG + A24, \field Output EDD \type choice \key Yes \key No \default Yes - A25, \field Output PerfLog + A25, \field Output DBG \type choice \key Yes \key No \default Yes - A26, \field Output SLN + A26, \field Output PerfLog \type choice \key Yes \key No \default Yes - A27, \field Output SCI + A27, \field Output SLN \type choice \key Yes \key No \default Yes - A28, \field Output WRL + A28, \field Output SCI \type choice \key Yes \key No \default Yes - A29, \field Output Screen + A29, \field Output WRL \type choice \key Yes \key No \default Yes - A30, \field Output ExtShd + A30, \field Output Screen \type choice \key Yes \key No \default Yes - A31; \field Output Tarcog + A31, \field Output ExtShd + \type choice + \key Yes + \key No + \default Yes + A32; \field Output Tarcog \note Not Implemented Yet \type choice \key Yes diff --git a/scripts/RunEPlus.bat b/scripts/RunEPlus.bat index 142c045ea0b..8ec74d1a27a 100644 --- a/scripts/RunEPlus.bat +++ b/scripts/RunEPlus.bat @@ -86,6 +86,9 @@ IF EXIST eplusout.sln DEL eplusout.sln IF EXIST epluszsz.csv DEL epluszsz.csv IF EXIST epluszsz.tab DEL epluszsz.tab IF EXIST epluszsz.txt DEL epluszsz.txt +IF EXIST eplusspsz.csv DEL eplusspsz.csv +IF EXIST eplusspsz.tab DEL eplusspsz.tab +IF EXIST eplusspsz.txt DEL eplusspsz.txt IF EXIST eplusssz.csv DEL eplusssz.csv IF EXIST eplusssz.tab DEL eplusssz.tab IF EXIST eplusssz.txt DEL eplusssz.txt @@ -157,6 +160,10 @@ IF EXIST "%output_path%%~1.Zsz" DEL "%output_path%%~1.Zsz" IF EXIST "%output_path%%~1Zsz.csv" DEL "%output_path%%~1Zsz.csv" IF EXIST "%output_path%%~1Zsz.tab" DEL "%output_path%%~1Zsz.tab" IF EXIST "%output_path%%~1Zsz.txt" DEL "%output_path%%~1Zsz.txt" +IF EXIST "%output_path%%~1.Spsz" DEL "%output_path%%~1.Spsz" +IF EXIST "%output_path%%~1Spsz.csv" DEL "%output_path%%~1Spsz.csv" +IF EXIST "%output_path%%~1Spsz.tab" DEL "%output_path%%~1Spsz.tab" +IF EXIST "%output_path%%~1Spsz.txt" DEL "%output_path%%~1Spsz.txt" IF EXIST "%output_path%%~1.ssz" DEL "%output_path%%~1.ssz" IF EXIST "%output_path%%~1Ssz.csv" DEL "%output_path%%~1Ssz.csv" IF EXIST "%output_path%%~1Ssz.tab" DEL "%output_path%%~1Ssz.tab" @@ -339,6 +346,9 @@ IF EXIST eplusout.bnd %post_proc%HVAC-Diagram.exe IF EXIST epluszsz.csv MOVE epluszsz.csv "%output_path%%~1Zsz.csv" IF EXIST epluszsz.tab MOVE epluszsz.tab "%output_path%%~1Zsz.tab" IF EXIST epluszsz.txt MOVE epluszsz.txt "%output_path%%~1Zsz.txt" + IF EXIST eplusspsz.csv MOVE eplusspsz.csv "%output_path%%~1Spsz.csv" + IF EXIST eplusspsz.tab MOVE eplusspsz.tab "%output_path%%~1Spsz.tab" + IF EXIST eplusspsz.txt MOVE eplusspsz.txt "%output_path%%~1Spsz.txt" IF EXIST eplusssz.csv MOVE eplusssz.csv "%output_path%%~1Ssz.csv" IF EXIST eplusssz.tab MOVE eplusssz.tab "%output_path%%~1Ssz.tab" IF EXIST eplusssz.txt MOVE eplusssz.txt "%output_path%%~1Ssz.txt" diff --git a/src/EnergyPlus/CommandLineInterface.cc b/src/EnergyPlus/CommandLineInterface.cc index e54680f8a5b..d39a29a79b7 100644 --- a/src/EnergyPlus/CommandLineInterface.cc +++ b/src/EnergyPlus/CommandLineInterface.cc @@ -335,6 +335,7 @@ state.dataStrGlobals->inputFilePath='{}', std::string tableSuffix; std::string mapSuffix; std::string zszSuffix; + std::string spszSuffix; std::string sszSuffix; std::string meterSuffix; std::string sqliteSuffix; @@ -352,6 +353,7 @@ state.dataStrGlobals->inputFilePath='{}', tableSuffix = "tbl"; mapSuffix = "map"; zszSuffix = "zsz"; + spszSuffix = "spsz"; sszSuffix = "ssz"; meterSuffix = "mtr"; sqliteSuffix = "sqlite"; @@ -365,6 +367,7 @@ state.dataStrGlobals->inputFilePath='{}', tableSuffix = "-table"; mapSuffix = "-map"; zszSuffix = "-zsz"; + spszSuffix = "-spsz"; sszSuffix = "-ssz"; meterSuffix = "-meter"; sqliteSuffix = "-sqlite"; @@ -378,6 +381,7 @@ state.dataStrGlobals->inputFilePath='{}', tableSuffix = "Table"; mapSuffix = "Map"; zszSuffix = "Zsz"; + spszSuffix = "Spsz"; sszSuffix = "Ssz"; meterSuffix = "Meter"; sqliteSuffix = "Sqlite"; @@ -456,6 +460,9 @@ state.dataStrGlobals->inputFilePath='{}', state.files.outputZszCsvFilePath = composePath(zszSuffix + ".csv"); state.files.outputZszTabFilePath = composePath(zszSuffix + ".tab"); state.files.outputZszTxtFilePath = composePath(zszSuffix + ".txt"); + state.files.outputSpszCsvFilePath = composePath(spszSuffix + ".csv"); + state.files.outputSpszTabFilePath = composePath(spszSuffix + ".tab"); + state.files.outputSpszTxtFilePath = composePath(spszSuffix + ".txt"); state.files.outputSszCsvFilePath = composePath(sszSuffix + ".csv"); state.files.outputSszTabFilePath = composePath(sszSuffix + ".tab"); state.files.outputSszTxtFilePath = composePath(sszSuffix + ".txt"); diff --git a/src/EnergyPlus/Data/EnergyPlusData.cc b/src/EnergyPlus/Data/EnergyPlusData.cc index 03b30e7bfbb..28766d0df1d 100644 --- a/src/EnergyPlus/Data/EnergyPlusData.cc +++ b/src/EnergyPlus/Data/EnergyPlusData.cc @@ -566,6 +566,7 @@ void EnergyPlusData::clear_state() this->files.shade.close(); this->files.ssz.close(); this->files.zsz.close(); + this->files.spsz.close(); } void EnergyPlusData::init_state(EnergyPlusData &state) diff --git a/src/EnergyPlus/DataZoneEquipment.hh b/src/EnergyPlus/DataZoneEquipment.hh index 9688bf24682..a9621bd2b9f 100644 --- a/src/EnergyPlus/DataZoneEquipment.hh +++ b/src/EnergyPlus/DataZoneEquipment.hh @@ -614,7 +614,7 @@ struct DataZoneEquipmentData : BaseGlobalStruct int NumOfZoneEquipLists = 0; Array1D ZoneEquipAvail; Array1D ZoneEquipConfig; - EPVector spaceEquipConfig; + Array1D spaceEquipConfig; std::unordered_set UniqueZoneEquipListNames; Array1D ZoneEquipList; Array1D SupplyAirPath; diff --git a/src/EnergyPlus/IOFiles.cc b/src/EnergyPlus/IOFiles.cc index 614a27abcfd..d1be5d2e20c 100644 --- a/src/EnergyPlus/IOFiles.cc +++ b/src/EnergyPlus/IOFiles.cc @@ -376,6 +376,9 @@ void IOFiles::OutputControl::getInput(EnergyPlusData &state) { // "output_audit" audit = boolean_choice(find_input(fields, "output_audit")); } + { // "output_space_sizing" + spsz = boolean_choice(find_input(fields, "output_space_sizing")); + } { // "output_zone_sizing" zsz = boolean_choice(find_input(fields, "output_zone_sizing")); } @@ -484,6 +487,7 @@ void IOFiles::flushAll() eio.flush(); eso.flush(); zsz.flush(); + spsz.flush(); ssz.flush(); map.flush(); mtr.flush(); diff --git a/src/EnergyPlus/IOFiles.hh b/src/EnergyPlus/IOFiles.hh index d93b8b67978..c2ea2bc6dec 100644 --- a/src/EnergyPlus/IOFiles.hh +++ b/src/EnergyPlus/IOFiles.hh @@ -680,6 +680,7 @@ public: bool eso = true; bool eio = true; bool audit = true; + bool spsz = true; bool zsz = true; bool ssz = true; bool dxf = true; @@ -719,6 +720,11 @@ public: fs::path outputZszTabFilePath{"epluszsz.tab"}; fs::path outputZszTxtFilePath{"epluszsz.txt"}; + InputOutputFile spsz{""}; + fs::path outputSpszCsvFilePath{"eplusspsz.csv"}; + fs::path outputSpszTabFilePath{"eplusspsz.tab"}; + fs::path outputSpszTxtFilePath{"eplusspsz.txt"}; + InputOutputFile ssz{""}; fs::path outputSszCsvFilePath{"eplusssz.csv"}; fs::path outputSszTabFilePath{"eplusssz.tab"}; diff --git a/src/EnergyPlus/SizingManager.cc b/src/EnergyPlus/SizingManager.cc index 2cd8bedbaed..e728c220fbf 100644 --- a/src/EnergyPlus/SizingManager.cc +++ b/src/EnergyPlus/SizingManager.cc @@ -240,7 +240,16 @@ void ManageSizing(EnergyPlusData &state) state.files.zsz.filePath = state.files.outputZszTxtFilePath; } + if (state.dataSize->SizingFileColSep == CharComma) { + state.files.spsz.filePath = state.files.outputSpszCsvFilePath; + } else if (state.dataSize->SizingFileColSep == CharTab) { + state.files.spsz.filePath = state.files.outputSpszTabFilePath; + } else { + state.files.spsz.filePath = state.files.outputSpszTxtFilePath; + } + state.files.zsz.ensure_open(state, "ManageSizing", state.files.outputControl.zsz); + state.files.spsz.ensure_open(state, "ManageSizing", state.files.outputControl.spsz); ShowMessage(state, "Beginning Zone Sizing Calculations"); diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index 9c795aee378..80cb482861e 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -1985,6 +1985,239 @@ std::string sizingPeakTimeStamp(EnergyPlusData &state, int timeStepIndex) return format(PeakHrMinFmt, hour, minute); } +void writeZszSpsz(EnergyPlusData &state, + EnergyPlus::InputOutputFile &outputFile, + int const numSpacesOrZones, + Array1D const zsEquipConfig, + EPVector const &zsCalcFinalSizing, + Array2D const &zsCalcSizing) +{ + char const colSep = state.dataSize->SizingFileColSep; + print(outputFile, "Time"); + for (int i = 1; i <= numSpacesOrZones; ++i) { + if (!zsEquipConfig(i).IsControlled) continue; + auto &thisCalcFS = zsCalcFinalSizing(i); + + static constexpr std::string_view ZSizeFmt11("{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{" + "}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}"); + print(outputFile, + ZSizeFmt11, + colSep, + thisCalcFS.ZoneName, + thisCalcFS.HeatDesDay, + ":Des Heat Load [W]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.CoolDesDay, + ":Des Sens Cool Load [W]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.HeatDesDay, + ":Des Heat Mass Flow [kg/s]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.CoolDesDay, + ":Des Cool Mass Flow [kg/s]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.LatHeatDesDay, + ":Des Latent Heat Load [W]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.LatCoolDesDay, + ":Des Latent Cool Load [W]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.LatHeatDesDay, + ":Des Latent Heat Mass Flow [kg/s]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.LatCoolDesDay, + ":Des Latent Cool Mass Flow [kg/s]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.HeatNoDOASDesDay, + ":Des Heat Load No DOAS [W]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.CoolNoDOASDesDay, + ":Des Sens Cool Load No DOAS [W]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.LatHeatNoDOASDesDay, + ":Des Latent Heat Load No DOAS [W]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.LatCoolNoDOASDesDay, + ":Des Latent Cool Load No DOAS [W]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.HeatDesDay, + ":Heating Zone Temperature [C]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.HeatDesDay, + ":Heating Zone Relative Humidity [%]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.CoolDesDay, + ":Cooling Zone Temperature [C]", + colSep, + thisCalcFS.ZoneName, + thisCalcFS.CoolDesDay, + ":Cooling Zone Relative Humidity [%]"); + } + print(outputFile, "\n"); + // HourFrac = 0.0 + int Minutes = 0; + int TimeStepIndex = 0; + for (int HourCounter = 1; HourCounter <= 24; ++HourCounter) { + for (int TimeStepCounter = 1; TimeStepCounter <= state.dataGlobal->NumOfTimeStepInHour; ++TimeStepCounter) { + ++TimeStepIndex; + Minutes += state.dataGlobal->MinutesPerTimeStep; + int HourPrint = HourCounter - 1; + if (Minutes == 60) { + Minutes = 0; + HourPrint = HourCounter; + } + static constexpr std::string_view ZSizeFmt20("{:02}:{:02}:00"); + print(outputFile, ZSizeFmt20, HourPrint, Minutes); + for (int i = 1; i <= numSpacesOrZones; ++i) { + if (!zsEquipConfig(i).IsControlled) continue; + auto &thisCalcFS = zsCalcFinalSizing(i); + static constexpr std::string_view ZSizeFmt21("{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12." + "6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}"); + Real64 ZoneRHHeat = 0.0; + Real64 ZoneRHCool = 0.0; + Real64 ZoneTHeat = 0.0; + Real64 ZoneTCool = 0.0; + if (thisCalcFS.HeatDDNum > 0) { + ZoneTHeat = zsCalcSizing(thisCalcFS.HeatDDNum, i).HeatZoneTempSeq(TimeStepIndex); + ZoneRHHeat = Psychrometrics::PsyRhFnTdbWPb(state, + zsCalcSizing(thisCalcFS.HeatDDNum, i).HeatZoneTempSeq(TimeStepIndex), + zsCalcSizing(thisCalcFS.HeatDDNum, i).HeatZoneHumRatSeq(TimeStepIndex), + state.dataEnvrn->OutBaroPress) * + 100.0; + } + if (thisCalcFS.CoolDDNum > 0) { + ZoneTCool = zsCalcSizing(thisCalcFS.CoolDDNum, i).CoolZoneTempSeq(TimeStepIndex); + ZoneRHCool = Psychrometrics::PsyRhFnTdbWPb(state, + zsCalcSizing(thisCalcFS.CoolDDNum, i).CoolZoneTempSeq(TimeStepIndex), + zsCalcSizing(thisCalcFS.CoolDDNum, i).CoolZoneHumRatSeq(TimeStepIndex), + state.dataEnvrn->OutBaroPress) * + 100.0; + } + print(outputFile, + ZSizeFmt21, + colSep, + thisCalcFS.HeatLoadSeq(TimeStepIndex), + colSep, + thisCalcFS.CoolLoadSeq(TimeStepIndex), + colSep, + thisCalcFS.HeatFlowSeq(TimeStepIndex), + colSep, + thisCalcFS.CoolFlowSeq(TimeStepIndex), + colSep, + thisCalcFS.LatentHeatLoadSeq(TimeStepIndex), + colSep, + thisCalcFS.LatentCoolLoadSeq(TimeStepIndex), + colSep, + thisCalcFS.LatentHeatFlowSeq(TimeStepIndex), + colSep, + thisCalcFS.LatentCoolFlowSeq(TimeStepIndex), + colSep, + thisCalcFS.HeatLoadNoDOASSeq(TimeStepIndex), + colSep, + thisCalcFS.CoolLoadNoDOASSeq(TimeStepIndex), + colSep, + thisCalcFS.HeatLatentLoadNoDOASSeq(TimeStepIndex), + colSep, + thisCalcFS.CoolLatentLoadNoDOASSeq(TimeStepIndex), + colSep, + ZoneTHeat, + colSep, + ZoneRHHeat, + colSep, + ZoneTCool, + colSep, + ZoneRHCool); + } + print(outputFile, "\n"); + } + } + print(outputFile, "Peak"); + + for (int i = 1; i <= numSpacesOrZones; ++i) { + if (!zsEquipConfig(i).IsControlled) continue; + auto &thisCalcFS = zsCalcFinalSizing(i); + + static constexpr std::string_view ZSizeFmt31("{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12." + "6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{}{}{}"); + print(outputFile, + ZSizeFmt31, + colSep, + thisCalcFS.DesHeatLoad, + colSep, + thisCalcFS.DesCoolLoad, + colSep, + thisCalcFS.DesHeatMassFlow, + colSep, + thisCalcFS.DesCoolMassFlow, + colSep, + thisCalcFS.DesLatentHeatLoad, + colSep, + thisCalcFS.DesLatentCoolLoad, + colSep, + thisCalcFS.DesLatentHeatMassFlow, + colSep, + thisCalcFS.DesLatentCoolMassFlow, + colSep, + thisCalcFS.DesHeatLoadNoDOAS, + colSep, + thisCalcFS.DesCoolLoadNoDOAS, + colSep, + thisCalcFS.DesLatentHeatLoadNoDOAS, + colSep, + thisCalcFS.DesLatentCoolLoadNoDOAS, + colSep, + colSep, + colSep, + colSep); + } + print(outputFile, "\n"); + + print(outputFile, "\nPeak Vol Flow (m3/s)"); + for (int i = 1; i <= numSpacesOrZones; ++i) { + if (!zsEquipConfig(i).IsControlled) continue; + auto &thisCalcFS = zsCalcFinalSizing(i); + static constexpr std::string_view ZSizeFmt41("{}{}{}{:12.6E}{}{:12.6E}{}{}{}{:12.6E}{}{:12.6E}{}{}{}{}{}{}{}{}"); + print(outputFile, + ZSizeFmt41, + colSep, + colSep, + colSep, + thisCalcFS.DesHeatVolFlow, + colSep, + thisCalcFS.DesCoolVolFlow, + colSep, + colSep, + colSep, + thisCalcFS.DesLatentHeatVolFlow, + colSep, + thisCalcFS.DesLatentCoolVolFlow, + colSep, + colSep, + colSep, + colSep, + colSep, + colSep, + colSep, + colSep); + } + print(outputFile, "\n"); + outputFile.close(); +} + void updateZoneSizingEndZoneSizingCalc3(DataSizing::ZoneSizingData &zsCalcFinalSizing, Array2D &zsCalcSizing, bool &anyLatentLoad, @@ -2701,82 +2934,6 @@ void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator const CallI } } - // SpaceSizing TODO: For now only write zone-level zsz - print(state.files.zsz, "Time"); - for (int I = 1; I <= state.dataGlobal->NumOfZones; ++I) { - if (!state.dataZoneEquip->ZoneEquipConfig(I).IsControlled) continue; - auto &calcFinalZoneSizing = state.dataSize->CalcFinalZoneSizing(I); - - static constexpr std::string_view ZSizeFmt11("{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{" - "}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}"); - print(state.files.zsz, - ZSizeFmt11, - state.dataSize->SizingFileColSep, - state.dataSize->CalcFinalZoneSizing(I).ZoneName, - state.dataSize->CalcFinalZoneSizing(I).HeatDesDay, - ":Des Heat Load [W]", - state.dataSize->SizingFileColSep, - state.dataSize->CalcFinalZoneSizing(I).ZoneName, - state.dataSize->CalcFinalZoneSizing(I).CoolDesDay, - ":Des Sens Cool Load [W]", - state.dataSize->SizingFileColSep, - state.dataSize->CalcFinalZoneSizing(I).ZoneName, - state.dataSize->CalcFinalZoneSizing(I).HeatDesDay, - ":Des Heat Mass Flow [kg/s]", - state.dataSize->SizingFileColSep, - state.dataSize->CalcFinalZoneSizing(I).ZoneName, - state.dataSize->CalcFinalZoneSizing(I).CoolDesDay, - ":Des Cool Mass Flow [kg/s]", - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.ZoneName, - calcFinalZoneSizing.LatHeatDesDay, - ":Des Latent Heat Load [W]", - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.ZoneName, - calcFinalZoneSizing.LatCoolDesDay, - ":Des Latent Cool Load [W]", - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.ZoneName, - calcFinalZoneSizing.LatHeatDesDay, - ":Des Latent Heat Mass Flow [kg/s]", - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.ZoneName, - calcFinalZoneSizing.LatCoolDesDay, - ":Des Latent Cool Mass Flow [kg/s]", - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.ZoneName, - calcFinalZoneSizing.HeatNoDOASDesDay, - ":Des Heat Load No DOAS [W]", - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.ZoneName, - calcFinalZoneSizing.CoolNoDOASDesDay, - ":Des Sens Cool Load No DOAS [W]", - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.ZoneName, - calcFinalZoneSizing.LatHeatNoDOASDesDay, - ":Des Latent Heat Load No DOAS [W]", - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.ZoneName, - calcFinalZoneSizing.LatCoolNoDOASDesDay, - ":Des Latent Cool Load No DOAS [W]", - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.ZoneName, - calcFinalZoneSizing.HeatDesDay, - ":Heating Zone Temperature [C]", - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.ZoneName, - calcFinalZoneSizing.HeatDesDay, - ":Heating Zone Relative Humidity [%]", - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.ZoneName, - calcFinalZoneSizing.CoolDesDay, - ":Cooling Zone Temperature [C]", - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.ZoneName, - calcFinalZoneSizing.CoolDesDay, - ":Cooling Zone Relative Humidity [%]"); - } - for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) { if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue; updateZoneSizingEndZoneSizingCalc2(state, state.dataSize->CalcFinalZoneSizing(CtrlZoneNum)); @@ -2787,158 +2944,20 @@ void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator const CallI } } - print(state.files.zsz, "\n"); - // HourFrac = 0.0 - int Minutes = 0; - int TimeStepIndex = 0; - for (int HourCounter = 1; HourCounter <= 24; ++HourCounter) { - for (int TimeStepCounter = 1; TimeStepCounter <= state.dataGlobal->NumOfTimeStepInHour; ++TimeStepCounter) { - ++TimeStepIndex; - Minutes += state.dataGlobal->MinutesPerTimeStep; - int HourPrint = HourCounter - 1; - if (Minutes == 60) { - Minutes = 0; - HourPrint = HourCounter; - } - static constexpr std::string_view ZSizeFmt20("{:02}:{:02}:00"); - print(state.files.zsz, ZSizeFmt20, HourPrint, Minutes); - for (int I = 1; I <= state.dataGlobal->NumOfZones; ++I) { - if (!state.dataZoneEquip->ZoneEquipConfig(I).IsControlled) continue; - auto &calcFinalZoneSizing = state.dataSize->CalcFinalZoneSizing(I); - static constexpr std::string_view ZSizeFmt21( - "{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12." - "6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}"); - Real64 ZoneRHHeat = 0.0; - Real64 ZoneRHCool = 0.0; - Real64 ZoneTHeat = 0.0; - Real64 ZoneTCool = 0.0; - if (calcFinalZoneSizing.HeatDDNum > 0) { - ZoneTHeat = state.dataSize->CalcZoneSizing(calcFinalZoneSizing.HeatDDNum, I).HeatZoneTempSeq(TimeStepIndex); - ZoneRHHeat = Psychrometrics::PsyRhFnTdbWPb( - state, - state.dataSize->CalcZoneSizing(calcFinalZoneSizing.HeatDDNum, I).HeatZoneTempSeq(TimeStepIndex), - state.dataSize->CalcZoneSizing(calcFinalZoneSizing.HeatDDNum, I).HeatZoneHumRatSeq(TimeStepIndex), - state.dataEnvrn->OutBaroPress) * - 100.0; - } - if (calcFinalZoneSizing.CoolDDNum > 0) { - ZoneTCool = state.dataSize->CalcZoneSizing(calcFinalZoneSizing.CoolDDNum, I).CoolZoneTempSeq(TimeStepIndex); - ZoneRHCool = Psychrometrics::PsyRhFnTdbWPb( - state, - state.dataSize->CalcZoneSizing(calcFinalZoneSizing.CoolDDNum, I).CoolZoneTempSeq(TimeStepIndex), - state.dataSize->CalcZoneSizing(calcFinalZoneSizing.CoolDDNum, I).CoolZoneHumRatSeq(TimeStepIndex), - state.dataEnvrn->OutBaroPress) * - 100.0; - } - print(state.files.zsz, - ZSizeFmt21, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.HeatLoadSeq(TimeStepIndex), - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.CoolLoadSeq(TimeStepIndex), - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.HeatFlowSeq(TimeStepIndex), - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.CoolFlowSeq(TimeStepIndex), - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.LatentHeatLoadSeq(TimeStepIndex), - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.LatentCoolLoadSeq(TimeStepIndex), - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.LatentHeatFlowSeq(TimeStepIndex), - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.LatentCoolFlowSeq(TimeStepIndex), - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.HeatLoadNoDOASSeq(TimeStepIndex), - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.CoolLoadNoDOASSeq(TimeStepIndex), - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.HeatLatentLoadNoDOASSeq(TimeStepIndex), - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.CoolLatentLoadNoDOASSeq(TimeStepIndex), - state.dataSize->SizingFileColSep, - ZoneTHeat, - state.dataSize->SizingFileColSep, - ZoneRHHeat, - state.dataSize->SizingFileColSep, - ZoneTCool, - state.dataSize->SizingFileColSep, - ZoneRHCool); - } - print(state.files.zsz, "\n"); - } + writeZszSpsz(state, + state.files.zsz, + state.dataGlobal->NumOfZones, + state.dataZoneEquip->ZoneEquipConfig, + state.dataSize->CalcFinalZoneSizing, + state.dataSize->CalcZoneSizing); + if (state.dataHeatBal->doSpaceHeatBalanceSizing) { + writeZszSpsz(state, + state.files.spsz, + state.dataGlobal->numSpaces, + state.dataZoneEquip->spaceEquipConfig, + state.dataSize->CalcFinalSpaceSizing, + state.dataSize->CalcSpaceSizing); } - print(state.files.zsz, "Peak"); - - for (int I = 1; I <= state.dataGlobal->NumOfZones; ++I) { - if (!state.dataZoneEquip->ZoneEquipConfig(I).IsControlled) continue; - auto &calcFinalZoneSizing = state.dataSize->CalcFinalZoneSizing(I); - - static constexpr std::string_view ZSizeFmt31("{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12." - "6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{}{}{}"); - print(state.files.zsz, - ZSizeFmt31, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesHeatLoad, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesCoolLoad, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesHeatMassFlow, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesCoolMassFlow, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesLatentHeatLoad, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesLatentCoolLoad, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesLatentHeatMassFlow, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesLatentCoolMassFlow, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesHeatLoadNoDOAS, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesCoolLoadNoDOAS, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesLatentHeatLoadNoDOAS, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesLatentCoolLoadNoDOAS, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep); - } - print(state.files.zsz, "\n"); - - print(state.files.zsz, "\nPeak Vol Flow (m3/s)"); - for (int I = 1; I <= state.dataGlobal->NumOfZones; ++I) { - if (!state.dataZoneEquip->ZoneEquipConfig(I).IsControlled) continue; - auto &calcFinalZoneSizing = state.dataSize->CalcFinalZoneSizing(I); - static constexpr std::string_view ZSizeFmt41("{}{}{}{:12.6E}{}{:12.6E}{}{}{}{:12.6E}{}{:12.6E}{}{}{}{}{}{}{}{}"); - print(state.files.zsz, - ZSizeFmt41, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesHeatVolFlow, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesCoolVolFlow, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesLatentHeatVolFlow, - state.dataSize->SizingFileColSep, - calcFinalZoneSizing.DesLatentCoolVolFlow, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep, - state.dataSize->SizingFileColSep); - } - print(state.files.zsz, "\n"); - state.files.zsz.close(); } if (!state.dataGlobal->isPulseZoneSizing) { diff --git a/src/EnergyPlus/ZoneEquipmentManager.hh b/src/EnergyPlus/ZoneEquipmentManager.hh index 16c53a10bc9..563cba75d07 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.hh +++ b/src/EnergyPlus/ZoneEquipmentManager.hh @@ -144,6 +144,13 @@ namespace ZoneEquipmentManager { void updateZoneSizingEndZoneSizingCalc2(EnergyPlusData &state, DataSizing::ZoneSizingData &zsCalcSizing); + void writeZszSpsz(EnergyPlusData &state, + EnergyPlus::InputOutputFile &outputFile, + int const numSpacesOrZones, + Array1D const zsEquipConfig, + EPVector const &zsCalcFinalSizing, + Array2D const &zsCalcSizing); + std::string sizingPeakTimeStamp(EnergyPlusData &state, int timeStepIndex); void updateZoneSizingEndZoneSizingCalc3(DataSizing::ZoneSizingData &zsCalcFinalSizing, diff --git a/testfiles/RefBldgMediumOfficeNew2004_Chicago_OutputControl.idf b/testfiles/RefBldgMediumOfficeNew2004_Chicago_OutputControl.idf index b7a0ca050ce..b89feeb9c58 100644 --- a/testfiles/RefBldgMediumOfficeNew2004_Chicago_OutputControl.idf +++ b/testfiles/RefBldgMediumOfficeNew2004_Chicago_OutputControl.idf @@ -7875,6 +7875,7 @@ No, !- Output SQLite No, !- Output JSON No, !- Output AUDIT + No, !- Output Space Sizing No, !- Output Zone Sizing No, !- Output System Sizing No, !- Output DXF diff --git a/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.cc b/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.cc index 43e61139917..be2ba42c515 100644 --- a/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.cc +++ b/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.cc @@ -90,6 +90,7 @@ void EnergyPlusFixture::openOutputFiles(EnergyPlusData &state) state.files.mtd.open_as_stringstream(); state.files.edd.open_as_stringstream(); state.files.zsz.open_as_stringstream(); + state.files.spsz.open_as_stringstream(); state.files.ssz.open_as_stringstream(); } @@ -130,6 +131,7 @@ void EnergyPlusFixture::TearDown() state->files.eio.del(); state->files.debug.del(); state->files.zsz.del(); + state->files.spsz.del(); state->files.ssz.del(); state->files.mtr.del(); state->files.bnd.del(); diff --git a/tst/EnergyPlus/unit/OutputFiles.unit.cc b/tst/EnergyPlus/unit/OutputFiles.unit.cc index 6d04767db4b..f2c56dd994f 100644 --- a/tst/EnergyPlus/unit/OutputFiles.unit.cc +++ b/tst/EnergyPlus/unit/OutputFiles.unit.cc @@ -294,6 +294,7 @@ OutputControl:Files, {sqlite}, !- Output SQLite {json}, !- Output JSON {audit}, !- Output AUDIT + {spsz}, !- Output Space Sizing {zsz}, !- Output Zone Sizing {ssz}, !- Output System Sizing {dxf}, !- Output DXF @@ -330,29 +331,30 @@ OutputControl:Files, bool sqlite = (i == 5); bool json = (i == 6); bool audit = (i == 7); - bool zsz = (i == 8); - bool ssz = (i == 9); - bool dxf = (i == 10); - bool bnd = (i == 11); - bool rdd = (i == 12); - bool mdd = (i == 13); - bool mtd = (i == 14); - bool end = (i == 15); - bool shd = (i == 16); - bool dfs = (i == 17); - bool glhe = (i == 18); - bool delightin = (i == 19); - bool delighteldmp = (i == 20); - bool delightdfdmp = (i == 21); - bool edd = (i == 22); - bool dbg = (i == 23); - bool perflog = (i == 24); - bool sln = (i == 25); - bool sci = (i == 26); - bool wrl = (i == 27); - bool screen = (i == 28); - bool extshd = (i == 29); - bool tarcog = (i == 30); + bool spsz = (i == 8); + bool zsz = (i == 9); + bool ssz = (i == 10); + bool dxf = (i == 11); + bool bnd = (i == 12); + bool rdd = (i == 13); + bool mdd = (i == 14); + bool mtd = (i == 15); + bool end = (i == 16); + bool shd = (i == 17); + bool dfs = (i == 18); + bool glhe = (i == 19); + bool delightin = (i == 20); + bool delighteldmp = (i == 21); + bool delightdfdmp = (i == 22); + bool edd = (i == 23); + bool dbg = (i == 24); + bool perflog = (i == 25); + bool sln = (i == 26); + bool sci = (i == 27); + bool wrl = (i == 28); + bool screen = (i == 29); + bool extshd = (i == 30); + bool tarcog = (i == 31); std::string const idf_objects = fmt::format(idf_objects_fmt, fmt::arg("csv", boolToString(csv)), @@ -363,6 +365,7 @@ OutputControl:Files, fmt::arg("sqlite", boolToString(sqlite)), fmt::arg("json", boolToString(json)), fmt::arg("audit", boolToString(audit)), + fmt::arg("spsz", boolToString(spsz)), fmt::arg("zsz", boolToString(zsz)), fmt::arg("ssz", boolToString(ssz)), fmt::arg("dxf", boolToString(dxf)), @@ -399,6 +402,7 @@ OutputControl:Files, EXPECT_EQ(sqlite, state->files.outputControl.sqlite); EXPECT_EQ(json, state->files.outputControl.json); EXPECT_EQ(audit, state->files.outputControl.audit); + EXPECT_EQ(spsz, state->files.outputControl.spsz); EXPECT_EQ(zsz, state->files.outputControl.zsz); EXPECT_EQ(ssz, state->files.outputControl.ssz); EXPECT_EQ(dxf, state->files.outputControl.dxf); @@ -433,6 +437,7 @@ OutputControl:Files, state->files.outputControl.sqlite = false; state->files.outputControl.json = false; state->files.outputControl.audit = false; + state->files.outputControl.spsz = false; state->files.outputControl.zsz = false; state->files.outputControl.ssz = false; state->files.outputControl.dxf = false; From 1a07c51671bdd3b9b668a114e40efab4714f6016 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Mon, 8 Jul 2024 11:24:25 -0700 Subject: [PATCH 31/81] change varname to fanRunTimeFraction, add comments to this arg this argument is only used in VRFFluidTCtrl model, not regular VAV --- src/EnergyPlus/Fans.cc | 14 +++++++++----- src/EnergyPlus/Fans.hh | 24 +++++++++++++----------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/EnergyPlus/Fans.cc b/src/EnergyPlus/Fans.cc index bc337c1cb8e..3f5cca1da63 100644 --- a/src/EnergyPlus/Fans.cc +++ b/src/EnergyPlus/Fans.cc @@ -103,7 +103,9 @@ void FanBase::simulate(EnergyPlusData &state, // the legacy speed ratio that was used with SimulateFanComponents. ObjexxFCL::Optional _pressureRise, // Pressure difference to use for DeltaPress, for rating DX coils at a ObjexxFCL::Optional _flowFraction, // when used, this directs the fan to set the flow at this flow fraction - ObjexxFCL::Optional _onOffFanPartLoadFraction, // to control for cycling in VAV fan in VRFFluidTCtrl + ObjexxFCL::Optional + _fanRunTimeFraction, // This argument is only used in the variable volume fan in + // VRFFluidTCtrl model to control for fan cycling. Please do not use it in normal VAV model. // different pressure without entire duct system ObjexxFCL::Optional _massFlowRate1, // Mass flow rate in operating mode 1 [kg/s] ObjexxFCL::Optional _runTimeFraction1, // Run time fraction in operating mode 1 @@ -139,7 +141,7 @@ void FanBase::simulate(EnergyPlusData &state, _thisFan->simulateConstant(state); } break; case HVAC::FanType::VAV: { - _thisFan->simulateVAV(state, _pressureRise, _onOffFanPartLoadFraction); + _thisFan->simulateVAV(state, _pressureRise, _fanRunTimeFraction); } break; case HVAC::FanType::OnOff: { _thisFan->simulateOnOff(state, _speedRatio); @@ -1703,7 +1705,9 @@ void FanComponent::simulateConstant(EnergyPlusData &state) void FanComponent::simulateVAV(EnergyPlusData &state, ObjexxFCL::Optional _pressureRise, - ObjexxFCL::Optional _onOffFanPartLoadFraction) + // This argument is only used in the variable volume fan in + // VRFFluidTCtrl model to control for fan cycling. Please do not use it in normal VAV model. + ObjexxFCL::Optional _fanRunTimeFraction) { // SUBROUTINE INFORMATION: @@ -1869,8 +1873,8 @@ void FanComponent::simulateVAV(EnergyPlusData &state, massFlowRateMaxAvail = 0.0; massFlowRateMinAvail = 0.0; } - if (present(_onOffFanPartLoadFraction)) { - totalPower *= _onOffFanPartLoadFraction; + if (present(_fanRunTimeFraction)) { + totalPower *= _fanRunTimeFraction; } } // FanComponent::SimVAV() diff --git a/src/EnergyPlus/Fans.hh b/src/EnergyPlus/Fans.hh index a84ec8d1af5..9086cadde83 100644 --- a/src/EnergyPlus/Fans.hh +++ b/src/EnergyPlus/Fans.hh @@ -97,15 +97,16 @@ namespace Fans { virtual void init(EnergyPlusData &state) = 0; virtual void simulate(EnergyPlusData &state, bool const FirstHVACIteration, - ObjexxFCL::Optional speedRatio = _, // Flow fraction in operating mode 1 - ObjexxFCL::Optional pressureRise = _, // Pressure difference to use for DeltaPress - ObjexxFCL::Optional flowFraction = _, // Flow fraction in operating mode 1 - ObjexxFCL::Optional onOffFanPartLoadFraction = 1.0, // to control for cycling in VAV fan in VRFFluidTCtrl - ObjexxFCL::Optional massFlowRate1 = _, // Mass flow rate in operating mode 1 [kg/s] - ObjexxFCL::Optional runTimeFraction1 = _, // Run time fraction in operating mode 1 - ObjexxFCL::Optional massFlowRate2 = _, // Mass flow rate in operating mode 2 [kg/s] - ObjexxFCL::Optional runTimeFraction2 = _, // Run time fraction in operating mode 2 - ObjexxFCL::Optional pressureRise2 = _ // Pressure difference to use for operating mode 2 + ObjexxFCL::Optional speedRatio = _, // Flow fraction in operating mode 1 + ObjexxFCL::Optional pressureRise = _, // Pressure difference to use for DeltaPress + ObjexxFCL::Optional flowFraction = _, // Flow fraction in operating mode 1 + ObjexxFCL::Optional fanRuntimeFraction = 1.0, // This argument is only used in the variable volume fan in + // VRFFluidTCtrl model to control for fan cycling. Please do not use it in normal VAV model. + ObjexxFCL::Optional massFlowRate1 = _, // Mass flow rate in operating mode 1 [kg/s] + ObjexxFCL::Optional runTimeFraction1 = _, // Run time fraction in operating mode 1 + ObjexxFCL::Optional massFlowRate2 = _, // Mass flow rate in operating mode 2 [kg/s] + ObjexxFCL::Optional runTimeFraction2 = _, // Run time fraction in operating mode 2 + ObjexxFCL::Optional pressureRise2 = _ // Pressure difference to use for operating mode 2 ); virtual void update(EnergyPlusData &state) = 0; @@ -229,8 +230,9 @@ namespace Fans { void simulateVAV(EnergyPlusData &state, ObjexxFCL::Optional PressureRise = _, - // to control for cycling in VAV fan in VRFFluidTCtrl - ObjexxFCL::Optional OnOffFanPartLoadFraction = 1.0); + // This argument is only used in the variable volume fan in + // VRFFluidTCtrl model to control for fan cycling. Please do not use it in normal VAV model. + ObjexxFCL::Optional fanRuntimeFraction = 1.0); void simulateOnOff(EnergyPlusData &state, ObjexxFCL::Optional SpeedRatio = _); From 733ec7ea190a9a1e1a77627869a667f293748fad Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Mon, 15 Jul 2024 17:44:28 -0700 Subject: [PATCH 32/81] use SystemModel for fan object in VRFFluidTCtrl TU --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 5 +- ...US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf | 64 ++++++++++++++----- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 79e475f5dfb..c2fd71961dd 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -12865,8 +12865,7 @@ void VRFTerminalUnitEquipment::CalcVRF_FluidTCtrl(EnergyPlusData &state, } Real64 OnOffFanPartLoadFraction = 1.0; - if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Cycling && - state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::VAV) { + if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Cycling) { OnOffFanPartLoadFraction = state.dataHVACGlobal->OnOffFanPartLoadFraction; } // if draw through, simulate coils then fan @@ -12874,7 +12873,7 @@ void VRFTerminalUnitEquipment::CalcVRF_FluidTCtrl(EnergyPlusData &state, auto *fan = state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex); if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::SystemModel) { if (OnOffAirFlowRatio > 0.0) { - fan->simulate(state, FirstHVACIteration, _, _); + fan->simulate(state, FirstHVACIteration, _, _, _, _, fan->inletAirMassFlowRate, OnOffFanPartLoadFraction, 0, 0, _); } else { fan->simulate(state, FirstHVACIteration, _, _, PartLoadRatio); } diff --git a/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf b/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf index 91ddad35a01..3a82696c3c0 100644 --- a/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf +++ b/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf @@ -482,7 +482,7 @@ 0, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanModeSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU1 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU1 OA Mixer, !- Outside Air Mixer Object Name @@ -530,25 +530,57 @@ OutdoorAir:NodeList, Outside Air Inlet Node 1;!- Node or NodeList Name 1 - Fan:VariableVolume, + !- Fan:VariableVolume, + !- TU1 VRF Supply Fan, !- Name + !- VRFAvailSched, !- Availability Schedule Name + !- 0.5, !- Fan Total Efficiency + !- 400, !- Pressure Rise {Pa} + !- 0.595, !- Maximum Flow Rate {m3/s} + !- FixedFlowRate, !- Fan Power Minimum Flow Rate Input Method + !- 0, !- Fan Power Minimum Flow Fraction + !- 0.415, !- Fan Power Minimum Air Flow Rate {m3/s} + !- 0.9, !- Motor Efficiency + !- 1, !- Motor In Airstream Fraction + !- 0.09, !- Fan Power Coefficient 1 + !- 0, !- Fan Power Coefficient 2 + !- 0, !- Fan Power Coefficient 3 + !- 0.91, !- Fan Power Coefficient 4 + !- 0, !- Fan Power Coefficient 5 + !- TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name + !- TU1 VRF Fan Outlet Node, !- Air Outlet Node Name + !- General; !- End-Use Subcategory + + Fan:SystemModel, TU1 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.5, !- Fan Total Efficiency - 400, !- Pressure Rise {Pa} - 0.595, !- Maximum Flow Rate {m3/s} - FixedFlowRate, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0.415, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.09, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.91, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU1 VRF Fan Outlet Node, !- Air Outlet Node Name - General; !- End-Use Subcategory + 0.595, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.415, !- Electric Power Minimum Flow Rate Fraction + 400, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1.0, !- Motor In Air Stream Fraction + 476, !- Design Electric Power Consumption {W} + , !- 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.5, !- Fan Total Efficiency + Fan Power Curve; !- Electric Power Function of Flow Fraction Curve Name + + Curve:Quartic, + Fan Power Curve , !- Name + 0.09, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.91, !- Coefficient4 x**3 + 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 !- =========== ALL OBJECTS IN CLASS: COIL:COOLING:DX:VARIABLEREFRIGERANTFLOW:FLUIDTEMPERATURECONTROL =========== From 63196565209945f5565c6e5f2fc8629df2875d1f Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Mon, 15 Jul 2024 18:01:20 -0700 Subject: [PATCH 33/81] relax curve output range and fix min x Fan:SystemModel --- testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf b/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf index 3a82696c3c0..09900d222ef 100644 --- a/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf +++ b/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf @@ -575,10 +575,10 @@ 0, !- Coefficient3 x**2 0.91, !- Coefficient4 x**3 0, !- Coefficient5 x**4 - 0.0, !- Minimum Value of x + 0.6975, !- Minimum Value of x 1.0, !- Maximum Value of x 0.0, !- Minimum Curve Output - 1.0, !- Maximum Curve Output + 5.0, !- Maximum Curve Output Dimensionless, !- Input Unit Type for X Dimensionless; !- Output Unit Type From 324f1fc796f7f6f7286920b3fe85faefa25ca809 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Tue, 16 Jul 2024 09:33:05 -0500 Subject: [PATCH 34/81] Space IV-Non-coincident 1 --- src/EnergyPlus/ZoneEquipmentManager.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index 80cb482861e..7410d7ba8e9 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -1865,6 +1865,12 @@ void updateZoneSizingEndDay(DataSizing::ZoneSizingData &zsCalcSizing, } void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, DataSizing::ZoneSizingData const &zsCalcSizing) +{ + // Use this to set or override finalzonesizing data for non-coincident sizing + return; +} + +void updateZoneSizingEndZoneSizingCalc2(EnergyPlusData &state, DataSizing::ZoneSizingData &zsCalcSizing) { if (std::abs(zsCalcSizing.DesCoolLoad) <= 1.e-8) { ShowWarningError(state, format("Calculated design cooling load for zone={} is zero.", zsCalcSizing.ZoneName)); @@ -1960,10 +1966,6 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, DataSizing::ZoneS "flow calculations"); } } -} - -void updateZoneSizingEndZoneSizingCalc2(EnergyPlusData &state, DataSizing::ZoneSizingData &zsCalcSizing) -{ zsCalcSizing.HeatPeakDateHrMin = zsCalcSizing.cHeatDDDate + ' ' + sizingPeakTimeStamp(state, zsCalcSizing.TimeStepNumAtHeatMax); zsCalcSizing.CoolPeakDateHrMin = zsCalcSizing.cCoolDDDate + ' ' + sizingPeakTimeStamp(state, zsCalcSizing.TimeStepNumAtCoolMax); From 79a0810cd1bdbac5be8e46045d98910f7dbb1cbe Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 17 Jul 2024 10:24:50 -0700 Subject: [PATCH 35/81] transition code Fan:VariableVolume to Fan:SystemModel --- .../CreateNewIDFUsingRulesV24_2_0.f90 | 156 ++++++++++++++++++ .../InputRulesFiles/Rules24-1-0-to-24-2-0.md | 8 + 2 files changed, 164 insertions(+) diff --git a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 index 78900861161..9fc4ceeb14a 100644 --- a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 +++ b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 @@ -124,6 +124,40 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile ! I N S E R T L O C A L V A R I A B L E S H E R E ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ! used in transition code for changing fan in ZoneHVAC:TerminalUnit:VariableRefrigerantFlow from VariableVolume to SystemModel + LOGICAL :: isVariableVolume + REAL :: fanTotalEff + REAL :: pressureRise + REAL :: maxAirFlow + REAL :: minAirFlowFrac + REAL :: fanPowerMinAirFlow + INTEGER :: NumFanVariableVolume = 0 + INTEGER :: NumOldFanVO = 0 + INTEGER :: Num3 + CHARACTER(len=MaxNameLength) :: sysFanName + CHARACTER(len=MaxNameLength) :: vavFanName + + TYPE FanVOTransitionInfo + CHARACTER(len=MaxNameLength) :: oldFanName + CHARACTER(len=MaxNameLength) :: availSchedule + CHARACTER(len=MaxNameLength) :: fanTotalEff_str + CHARACTER(len=MaxNameLength) :: pressureRise_str + CHARACTER(len=MaxNameLength) :: maxAirFlow_str + CHARACTER(len=MaxNameLength) :: minFlowInputMethod + CHARACTER(len=MaxNameLength) :: minAirFlowFrac_str + CHARACTER(len=MaxNameLength) :: fanPowerMinAirFlow_str + CHARACTER(len=MaxNameLength) :: motorEfficiency + CHARACTER(len=MaxNameLength) :: motorInAirStreamFrac + CHARACTER(len=MaxNameLength) :: coeff1 !- Coefficient1 Constant + CHARACTER(len=MaxNameLength) :: coeff2 !- Coefficient2 x + CHARACTER(len=MaxNameLength) :: coeff3 !- Coefficient3 x**2 + CHARACTER(len=MaxNameLength) :: coeff4 !- Coefficient4 x**3 + CHARACTER(len=MaxNameLength) :: coeff5 !- Coefficient5 x**4 + CHARACTER(len=MaxNameLength) :: inletAirNodeName + CHARACTER(len=MaxNameLength) :: outletAirNodeName + CHARACTER(len=MaxNameLength) :: endUseSubCat + END TYPE FanVOTransitionInfo + TYPE(FanVOTransitionInfo), ALLOCATABLE, DIMENSION(:) :: OldFanVO INTEGER :: TotSPMs = 0 INTEGER :: spmNum = 0 @@ -317,6 +351,37 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile ENDDO ENDDO + ! accumulate info on VAV fans + NumFanVariableVolume = GetNumObjectsFound('FAN:VARIABLEVOLUME') + IF (ALLOCATED(OldFanVO)) DEALLOCATE(OldFanVO) + ALLOCATE(OldFanVO(NumFanVariableVolume)) + NumOldFanVO = 0 + DO Num = 1, NumIDFRecords + SELECT CASE (MakeUPPERCase(IDFRecords(Num)%Name)) + CASE ('FAN:VARIABLEVOLUME') + NumOldFanVO = NumOldFanVO + 1 + ! debug print + PRINT *, "Alphas", TRIM(IDFRecords(Num)%Alphas(1)), TRIM(IDFRecords(Num)%Alphas(6)) + OldFanVO(NumOldFanVO)%oldFanName = TRIM(IDFRecords(Num)%Alphas(1)) + OldFanVO(NumOldFanVO)%availSchedule = TRIM(IDFRecords(Num)%Alphas(2)) + OldFanVO(NumOldFanVO)%fanTotalEff_str = TRIM(IDFRecords(Num)%Numbers(1)) + OldFanVO(NumOldFanVO)%pressureRise_str = TRIM(IDFRecords(Num)%Numbers(2)) + OldFanVO(NumOldFanVO)%maxAirFlow_str = TRIM(IDFRecords(Num)%Numbers(3)) + OldFanVO(NumOldFanVO)%minFlowInputMethod = TRIM(IDFRecords(Num)%Alphas(3)) + OldFanVO(NumOldFanVO)%minAirFlowFrac_str = TRIM(IDFRecords(Num)%Numbers(4)) + OldFanVO(NumOldFanVO)%fanPowerMinAirFlow_str = TRIM(IDFRecords(Num)%Numbers(5)) + OldFanVO(NumOldFanVO)%motorEfficiency = TRIM(IDFRecords(Num)%Numbers(6)) + OldFanVO(NumOldFanVO)%motorInAirStreamFrac = TRIM(IDFRecords(Num)%Numbers(7)) + OldFanVO(NumOldFanVO)%coeff1 = TRIM(IDFRecords(Num)%Numbers(8)) !- Coefficient1 Constant + OldFanVO(NumOldFanVO)%coeff2 = TRIM(IDFRecords(Num)%Numbers(9)) !- Coefficient2 x + OldFanVO(NumOldFanVO)%coeff3 = TRIM(IDFRecords(Num)%Numbers(10)) !- Coefficient3 x**2 + OldFanVO(NumOldFanVO)%coeff4 = TRIM(IDFRecords(Num)%Numbers(11)) !- Coefficient4 x**3 + OldFanVO(NumOldFanVO)%coeff5 = TRIM(IDFRecords(Num)%Numbers(12)) !- Coefficient5 x**4 + OldFanVO(NumOldFanVO)%inletAirNodeName = TRIM(IDFRecords(Num)%Alphas(4)) + OldFanVO(NumOldFanVO)%outletAirNodeName = TRIM(IDFRecords(Num)%Alphas(5)) + OldFanVO(NumOldFanVO)%endUseSubCat = TRIM(IDFRecords(Num)%Alphas(6)) + END SELECT + END DO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! P R O C E S S I N G ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -485,6 +550,97 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile ! If your original object starts with Z, insert the rules here +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + CASE('ZONEHVAC:TERMINALUNIT:VARIABLEREFRIGERANTFLOW') + isVariableVolume = .FALSE. + CALL GetNewObjectDefInIDD(ObjectName, NwNumArgs, NwAorN, NwReqFld, NwObjMinFlds, NwFldNames, NwFldDefaults, NwFldUnits) + nodiff = .false. + OutArgs(1:13) = InArgs(1:13) + IF (SameString(InArgs(14), 'FAN:VARIABLEVOLUME')) THEN + isVariableVolume = .TRUE. + OutArgs(14) = 'FAN:SYSTEMMODEL' + ! create a new fan object with a new name + OutArgs(15) = TRIM(InArgs(15)) // '_sysModel' + sysFanName = TRIM(InArgs(15)) // '_sysModel' + vavFanName = TRIM(InArgs(15)) + ELSE + OutArgs(14:15) = InArgs(14:15) + ENDIF + OutArgs(16:CurArgs) = InArgs(16:CurArgs) + CALL WriteOutIDFLines(DifLfn, 'ZONEHVAC:TERMINALUNIT:VARIABLEREFRIGERANTFLOW', CurArgs, OutArgs, NwFldNames, NwFldUnits) + + IF (isVariableVolume) THEN + ! create fan system model object + ObjectName = 'Fan:SystemModel' + DO Num3 = 1, NumFanVariableVolume + IF (SameString(OldFanVO(Num3)%oldFanName, vavFanName)) THEN + CALL GetNewObjectDefInIDD(ObjectName, NwNumArgs, NwAorN, NwReqFld, NwObjMinFlds, NwFldNames, NwFldDefaults, NwFldUnits) + OutArgs(1) = TRIM(sysFanName) + OutArgs(2) = OldFanVO(Num3)%availSchedule + OutArgs(3) = OldFanVO(Num3)%inletAirNodeName + OutArgs(4) = OldFanVO(Num3)%outletAirNodeName + OutArgs(5) = OldFanVO(Num3)%maxAirFlow_str + OutArgs(6) = 'Continuous' !- Speed Control Method + IF (SameString(OldFanVO(Num3)%minFlowInputMethod, "FixedFlowRate")) THEN + OutArgs(7) = OldFanVO(Num3)%maxAirFlow_str + ELSE ! input method is "Fraction" + READ(OldFanVO(Num3)%minAirFlowFrac_str, '(F15.5)') minAirFlowFrac + IF (minAirFlowFrac == 0.0) THEN + OutArgs(7) = '0.0' + ELSE + IF (.NOT. SameString(OldFanVO(Num3)%maxAirFlow_str, "AUTOSIZE")) THEN + READ(OldFanVO(Num3)%maxAirFlow_str, '(F15.5)') maxAirFlow + WRITE(OutArgs(7), '(F15.5)') (maxAirFlow * minAirFlowFrac) + ELSE ! don't know how to multiply fraction with autosize + OutArgs(7) = '' + ENDIF + ENDIF + ENDIF + OutArgs(8) = OldFanVO(Num3)%pressureRise_str !- Design Pressure Rise {Pa} + OutArgs(9) = OldFanVO(Num3)%motorEfficiency !- Motor Efficiency + OutArgs(10) = OldFanVO(Num3)%motorInAirStreamFrac !- Motor In Air Stream Fraction + IF (.NOT. SameString(OldFanVO(Num3)%maxAirFlow_str, "AUTOSIZE")) THEN + READ(OldFanVO(Num3)%maxAirFlow_str, '(F15.5)') maxAirFlow + READ(OldFanVO(Num3)%pressureRise_str, '(F15.5)') pressureRise + READ(OldFanVO(Num3)%fanTotalEff_str, '(F15.5)') fanTotalEff + WRITE(OutArgs(11), '(F15.5)') (maxAirFlow * pressureRise / fanTotalEff) !- Design Electric Power Consumption {W} + ELSE + OutArgs(11) = 'autosize' + OutArgs(12) = 'TotalEfficiencyAndPressure' ! chose this becuase power per flow or per pressure are unknown + ENDIF + OutArgs(13) = '' !- Electric Power Per Unit Flow Rate {W/(m3/s)} + OutArgs(14) = '' !- Electric Power Per Unit Flow Rate Per Unit Pressure {W/((m3/s)-Pa)} + OutArgs(15) = OldFanVO(Num3)%fanTotalEff_str !- Fan Total Efficiency + OutArgs(16) = TRIM(sysFanName) // '_curve' !- Electric Power Function of Flow Fraction Curve Name + OutArgs(17) = '' + OutArgs(18) = '' + OutArgs(19) = '' + OutArgs(20) = '' + OutArgs(21) = OldFanVO(Num3)%endUseSubCat !- End-Use Subcategory + CurArgs = 21 !- Design Electric Power Consumption {W} + CALL WriteOutIDFLines(DifLfn, ObjectName, CurArgs, OutArgs, NwFldNames, NwFldUnits) + + ! create curve object + ObjectName = 'Curve:Quartic' + CALL GetNewObjectDefInIDD(ObjectName, NwNumArgs, NwAorN, NwReqFld, NwObjMinFlds, NwFldNames, NwFldDefaults, NwFldUnits) + OutArgs(1) = TRIM(sysFanName) // '_curve' + OutArgs(2) = OldFanVO(Num3)%coeff1 !- Coefficient1 Constant + OutArgs(3) = OldFanVO(Num3)%coeff2 !- Coefficient2 x + OutArgs(4) = OldFanVO(Num3)%coeff3 !- Coefficient3 x**2 + OutArgs(5) = OldFanVO(Num3)%coeff4 !- Coefficient4 x**3 + OutArgs(6) = OldFanVO(Num3)%coeff5 !- Coefficient5 x**4 + READ(OldFanVO(Num3)%fanPowerMinAirFlow_str, '(F15.5)') fanPowerMinAirFlow + WRITE(OutArgs(7), '(F10.7)') (fanPowerMinAirFlow / maxAirFlow) !- Minimum Value of x + OutArgs(8) = '1.0' !- Maximum Value of x + OutArgs(9) = '0.0' !- Minimum Curve Output + OutArgs(10) = '5.0' !- Maximum Curve Output + OutArgs(11) = 'Dimensionless' !- Input Unit Type for X + OutArgs(12) = 'Dimensionless' !- Output Unit Type + CurArgs = 12 + ENDIF + ENDDO + ENDIF + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Changes for report variables, meters, tables -- update names ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/src/Transition/InputRulesFiles/Rules24-1-0-to-24-2-0.md b/src/Transition/InputRulesFiles/Rules24-1-0-to-24-2-0.md index dd4cf24cda0..073f46274a4 100644 --- a/src/Transition/InputRulesFiles/Rules24-1-0-to-24-2-0.md +++ b/src/Transition/InputRulesFiles/Rules24-1-0-to-24-2-0.md @@ -73,3 +73,11 @@ There are three new optional heat recovery fields at the end which transition wi # Object Change: ObjectStartsWithY # Object Change: ObjectStartsWithZ +## "ZoneHVAC:TerminalUnit:VariableRefrigerantFlow" +If field "Supply Air Fan Object Type" (A7, the 14th field) in +"ZoneHVAC:TerminalUnit:VariableRefrigerantFlow" is "Fan:VariableVolume", it +needs to be changed to "Fan:SystemModel". A "Fan:SystemModel" object need to be +created based on the former "Fan:VariableVolume" object. A fan power curve will +be created as well that holds the "Fan Power Coefficient i" in Fan:VariableVolume. + +See PR https://github.com/NREL/EnergyPlus/pull/10341 From 289d5cc4642f0d7c04c52ea817423bc86e9b58d6 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 17 Jul 2024 14:44:32 -0700 Subject: [PATCH 36/81] update idd and doc to remove vav fan Fan:VariableVolume is not allowed in the ZoneHVAC:TerminalUnit:VariableRefrigerantFlow any more. The previous VariableVolume one used in the FluidTCtrl model is converted to Fan:SystemModel --- .../src/overview/group-zone-forced-air-units.tex | 2 +- idd/Energy+.idd.in | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/input-output-reference/src/overview/group-zone-forced-air-units.tex b/doc/input-output-reference/src/overview/group-zone-forced-air-units.tex index 2daad751ecc..43f2e9f2f5e 100644 --- a/doc/input-output-reference/src/overview/group-zone-forced-air-units.tex +++ b/doc/input-output-reference/src/overview/group-zone-forced-air-units.tex @@ -4060,7 +4060,7 @@ \subsubsection{Inputs}\label{inputs-14-018} \paragraph{Field: Supply Air Fan Object Type}\label{field-supply-air-fan-object-type-8} -This choice field contains the identifying type of supply air fan specified for the furnace. Fan type must be \textit{\hyperref[fanonoff]{Fan:OnOff}}, \textit{\hyperref[fanconstantvolume]{Fan:ConstantVolume}}, \textit{\hyperref[fansystemmodel]{Fan:SystemModel}} or \textit{\hyperref[fanvariablevolume]{Fan:VariableVolume}}. The Supply Air Fan Object Type must be \hyperref[fansystemmodel]{Fan:SystemModel}, \hyperref[fanonoff]{Fan:OnOff}, or \hyperref[fanconstantvolume]{Fan:ConstantVolume} if \hyperref[airconditionervariablerefrigerantflow]{AirConditioner:VariableRefrigerantFlow} is used to model the VRF outdoor unit. The Supply Air Fan Object Type must be \hyperref[fansystemmodel]{Fan:SystemModel} or \hyperref[fanvariablevolume]{Fan:VariableVolume} if AirConditioner:VariableRefrigerantFlow:\-FluidTemperatureControl or AirConditioner:VariableRefrigerantFlow:\-FluidTemperatureControl:HR is used to model the VRF outdoor unit. +This choice field contains the identifying type of supply air fan specified for the furnace. Fan type must be \textit{\hyperref[fanonoff]{Fan:OnOff}}, \textit{\hyperref[fanconstantvolume]{Fan:ConstantVolume}}, \textit{\hyperref[fansystemmodel]{Fan:SystemModel}}. The Supply Air Fan Object Type must be \hyperref[fansystemmodel]{Fan:SystemModel}, \hyperref[fanonoff]{Fan:OnOff}, or \hyperref[fanconstantvolume]{Fan:ConstantVolume} if \hyperref[airconditionervariablerefrigerantflow]{AirConditioner:VariableRefrigerantFlow} is used to model the VRF outdoor unit. The Supply Air Fan Object Type must be \hyperref[fansystemmodel]{Fan:SystemModel} if AirConditioner:VariableRefrigerantFlow:\-FluidTemperatureControl or AirConditioner:VariableRefrigerantFlow:\-FluidTemperatureControl:HR is used to model the VRF outdoor unit. \hyperref[fanconstantvolume]{Fan:ConstantVolume} is used when the Supply Air Fan Operating Mode Schedule values are never 0 and the fan operates continuously. \hyperref[fanonoff]{Fan:OnOff} is used when the fan cycles on and off with the cooling or heating coil (i.e.~Supply Air Fan Operating Mode Schedule values are at times 0). The \hyperref[fansystemmodel]{Fan:SystemModel} may be used to model either of these fan operating characteristics. diff --git a/idd/Energy+.idd.in b/idd/Energy+.idd.in index 0193d450215..8ecca331289 100644 --- a/idd/Energy+.idd.in +++ b/idd/Energy+.idd.in @@ -42464,11 +42464,10 @@ ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, \key Fan:SystemModel \key Fan:OnOff \key Fan:ConstantVolume - \key Fan:VariableVolume \default Fan:ConstantVolume \note Supply Air Fan Object Type must be Fan:SystemModel, Fan:OnOff, or Fan:ConstantVolume \note if AirConditioner:VariableRefrigerantFlow is used to model VRF outdoor unit - \note Supply Air Fan Object Type must be Fan:SystemModel or Fan:VariableVolume if + \note Supply Air Fan Object Type must be Fan:SystemModel if \note AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl or \note AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl:HR \note is used to model VRF outdoor unit From 4f6b6777e65b25497972eeec9469674ba9edb1c9 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Wed, 17 Jul 2024 17:32:17 -0500 Subject: [PATCH 37/81] Space IV-Non-coincident 2 --- src/EnergyPlus/ZoneEquipmentManager.cc | 221 +++++++++++++++++++++++-- src/EnergyPlus/ZoneEquipmentManager.hh | 2 +- 2 files changed, 211 insertions(+), 12 deletions(-) diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index 7410d7ba8e9..997ce4ab31d 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -1864,9 +1864,212 @@ void updateZoneSizingEndDay(DataSizing::ZoneSizingData &zsCalcSizing, } } -void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, DataSizing::ZoneSizingData const &zsCalcSizing) +void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum) { - // Use this to set or override finalzonesizing data for non-coincident sizing + // Set or override finalzonesizing data for non-coincident sizing + auto &zoneCFS = state.dataSize->CalcFinalZoneSizing(zoneNum); + if (zoneCFS.spaceConcurrence == DataSizing::SizingConcurrence::Coincident) return; + // Zero out simple sums and averages + zoneCFS.DesHeatVolFlow = 0.0; + zoneCFS.DesHeatLoad = 0.0; + zoneCFS.DesHeatMassFlow = 0.0; + zoneCFS.DesHeatLoadNoDOAS = 0.0; + zoneCFS.DesCoolVolFlow = 0.0; + zoneCFS.DesCoolLoad = 0.0; + zoneCFS.DesCoolMassFlow = 0.0; + zoneCFS.DesCoolLoadNoDOAS = 0.0; + + // Weighted averages + zoneCFS.DesHeatDens = 0.0; + zoneCFS.ZoneTempAtHeatPeak = 0.0; + zoneCFS.OutTempAtHeatPeak = 0.0; + zoneCFS.ZoneRetTempAtHeatPeak = 0.0; + zoneCFS.ZoneHumRatAtHeatPeak = 0.0; + zoneCFS.OutHumRatAtHeatPeak = 0.0; + zoneCFS.DesHeatCoilInTemp = 0.0; + zoneCFS.DesHeatCoilInHumRat = 0.0; + zoneCFS.DesCoolDens = 0.0; + zoneCFS.ZoneTempAtCoolPeak = 0.0; + zoneCFS.OutTempAtCoolPeak = 0.0; + zoneCFS.ZoneRetTempAtCoolPeak = 0.0; + zoneCFS.ZoneHumRatAtCoolPeak = 0.0; + zoneCFS.OutHumRatAtCoolPeak = 0.0; + zoneCFS.DesCoolCoilInTemp = 0.0; + zoneCFS.DesCoolCoilInHumRat = 0.0; + + // Zero out ime-series sums + for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) { + zoneCFS.HeatFlowSeq(ts) = 0.0; + zoneCFS.HeatLoadSeq(ts) = 0.0; + zoneCFS.HeatZoneTempSeq(ts) = 0.0; + zoneCFS.HeatOutTempSeq(ts) = 0.0; + zoneCFS.HeatZoneRetTempSeq(ts) = 0.0; + zoneCFS.HeatZoneHumRatSeq(ts) = 0.0; + zoneCFS.HeatOutHumRatSeq(ts) = 0.0; + zoneCFS.HeatLoadNoDOASSeq(ts) = 0.0; + zoneCFS.CoolFlowSeq(ts) = 0.0; + zoneCFS.CoolLoadSeq(ts) = 0.0; + zoneCFS.CoolZoneTempSeq(ts) = 0.0; + zoneCFS.CoolOutTempSeq(ts) = 0.0; + zoneCFS.CoolZoneRetTempSeq(ts) = 0.0; + zoneCFS.CoolZoneHumRatSeq(ts) = 0.0; + zoneCFS.CoolOutHumRatSeq(ts) = 0.0; + zoneCFS.CoolLoadNoDOASSeq(ts) = 0.0; + } + if (zoneCFS.zoneLatentSizing) { + // Simple sums + zoneCFS.DesLatentHeatVolFlow = 0.0; + zoneCFS.DesLatentHeatMassFlow = 0.0; + zoneCFS.DesLatentHeatLoad = 0.0; + zoneCFS.DesLatentHeatLoadNoDOAS = 0.0; + zoneCFS.DesLatentCoolVolFlow = 0.0; + zoneCFS.DesLatentCoolMassFlow = 0.0; + zoneCFS.DesLatentCoolLoad = 0.0; + zoneCFS.DesLatentCoolLoadNoDOAS = 0.0; + + // Weighted averages + zoneCFS.ZoneTempAtLatentHeatPeak = 0.0; + zoneCFS.ZoneHumRatAtLatentHeatPeak = 0.0; + zoneCFS.ZoneRetTempAtLatentHeatPeak = 0.0; + zoneCFS.DesLatentHeatCoilInTemp = 0.0; + zoneCFS.DesLatentHeatCoilInHumRat = 0.0; + zoneCFS.ZoneTempAtLatentCoolPeak = 0.0; + zoneCFS.ZoneHumRatAtLatentCoolPeak = 0.0; + zoneCFS.ZoneRetTempAtLatentCoolPeak = 0.0; + zoneCFS.DesLatentCoolCoilInTemp = 0.0; + zoneCFS.DesLatentCoolCoilInHumRat = 0.0; + + // Time-series sums + for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) { + zoneCFS.LatentHeatLoadSeq(ts) = 0.0; + zoneCFS.LatentHeatFlowSeq(ts) = 0.0; + zoneCFS.HeatLatentLoadNoDOASSeq(ts) = 0.0; + zoneCFS.LatentCoolLoadSeq(ts) = 0.0; + zoneCFS.LatentCoolFlowSeq(ts) = 0.0; + zoneCFS.CoolLatentLoadNoDOASSeq(ts) = 0.0; + } + } + + int numSpaces = 0; // Track this for averages later + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &spaceCFS = state.dataSize->CalcFinalSpaceSizing(spaceNum); + if (!state.dataZoneEquip->spaceEquipConfig(spaceNum).IsControlled) continue; + ++numSpaces; + + // Simple sums + zoneCFS.DesHeatVolFlow += spaceCFS.DesHeatVolFlow; + zoneCFS.DesHeatLoad += spaceCFS.DesHeatLoad; + zoneCFS.DesHeatMassFlow += spaceCFS.DesHeatMassFlow; + zoneCFS.DesHeatLoadNoDOAS += spaceCFS.DesHeatLoadNoDOAS; + zoneCFS.DesCoolVolFlow += spaceCFS.DesCoolVolFlow; + zoneCFS.DesCoolLoad += spaceCFS.DesCoolLoad; + zoneCFS.DesCoolMassFlow += spaceCFS.DesCoolMassFlow; + zoneCFS.DesCoolLoadNoDOAS += spaceCFS.DesCoolLoadNoDOAS; + + // Weighted averages + zoneCFS.DesHeatDens += spaceCFS.DesHeatDens; + zoneCFS.ZoneTempAtHeatPeak += spaceCFS.ZoneTempAtHeatPeak; + zoneCFS.OutTempAtHeatPeak += spaceCFS.OutTempAtHeatPeak; + zoneCFS.ZoneRetTempAtHeatPeak += spaceCFS.ZoneRetTempAtHeatPeak; + zoneCFS.ZoneHumRatAtHeatPeak += spaceCFS.ZoneHumRatAtHeatPeak; + zoneCFS.OutHumRatAtHeatPeak += spaceCFS.OutHumRatAtHeatPeak; + zoneCFS.DesHeatCoilInTemp += spaceCFS.DesHeatCoilInTemp; + zoneCFS.DesHeatCoilInHumRat += spaceCFS.DesHeatCoilInHumRat; + zoneCFS.DesCoolDens += spaceCFS.DesCoolDens; + zoneCFS.ZoneTempAtCoolPeak += spaceCFS.ZoneTempAtCoolPeak; + zoneCFS.OutTempAtCoolPeak += spaceCFS.OutTempAtCoolPeak; + zoneCFS.ZoneRetTempAtCoolPeak += spaceCFS.ZoneRetTempAtCoolPeak; + zoneCFS.ZoneHumRatAtCoolPeak += spaceCFS.ZoneHumRatAtCoolPeak; + zoneCFS.OutHumRatAtCoolPeak += spaceCFS.OutHumRatAtCoolPeak; + zoneCFS.DesCoolCoilInTemp += spaceCFS.DesCoolCoilInTemp; + zoneCFS.DesCoolCoilInHumRat += spaceCFS.DesCoolCoilInHumRat; + + // Time-series sums + for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) { + zoneCFS.HeatFlowSeq(ts) += spaceCFS.HeatFlowSeq(ts); + zoneCFS.HeatLoadSeq(ts) += spaceCFS.HeatLoadSeq(ts); + zoneCFS.HeatZoneTempSeq(ts) += spaceCFS.HeatZoneTempSeq(ts); + zoneCFS.HeatOutTempSeq(ts) += spaceCFS.HeatOutTempSeq(ts); + zoneCFS.HeatZoneRetTempSeq(ts) += spaceCFS.HeatZoneRetTempSeq(ts); + zoneCFS.HeatZoneHumRatSeq(ts) += spaceCFS.HeatZoneHumRatSeq(ts); + zoneCFS.HeatOutHumRatSeq(ts) += spaceCFS.HeatOutHumRatSeq(ts); + zoneCFS.HeatLoadNoDOASSeq(ts) += spaceCFS.HeatLoadNoDOASSeq(ts); + zoneCFS.CoolFlowSeq(ts) += spaceCFS.CoolFlowSeq(ts); + zoneCFS.CoolLoadSeq(ts) += spaceCFS.CoolLoadSeq(ts); + zoneCFS.CoolZoneTempSeq(ts) += spaceCFS.CoolZoneTempSeq(ts); + zoneCFS.CoolOutTempSeq(ts) += spaceCFS.CoolOutTempSeq(ts); + zoneCFS.CoolZoneRetTempSeq(ts) += spaceCFS.CoolZoneRetTempSeq(ts); + zoneCFS.CoolZoneHumRatSeq(ts) += spaceCFS.CoolZoneHumRatSeq(ts); + zoneCFS.CoolOutHumRatSeq(ts) += spaceCFS.CoolOutHumRatSeq(ts); + zoneCFS.CoolLoadNoDOASSeq(ts) += spaceCFS.CoolLoadNoDOASSeq(ts); + } + + // Other + // zoneCFS.HeatDesDay = spaceCFS.HeatDesDay; + // zoneCFS.HeatDDNum = spaceCFS.HeatDDNum; + // zoneCFS.cHeatDDDate = desDayWeath.DateString; + // zoneCFS.TimeStepNumAtHeatMax = spaceCFS.TimeStepNumAtHeatMax; + // zoneCFS.HeatNoDOASDDNum = spaceCFS.HeatNoDOASDDNum; + // zoneCFS.HeatNoDOASDesDay = spaceCFS.HeatNoDOASDesDay; + // zoneCFS.TimeStepNumAtHeatNoDOASMax = spaceCFS.TimeStepNumAtHeatNoDOASMax; + // zoneCFS.LatentHeatNoDOASDDNum = spaceCFS.LatentHeatNoDOASDDNum; + // zoneCFS.LatHeatNoDOASDesDay = spaceCFS.LatHeatNoDOASDesDay; + // zoneCFS.TimeStepNumAtLatentHeatNoDOASMax = spaceCFS.TimeStepNumAtLatentHeatNoDOASMax; + // zoneCFS.CoolDesDay = spaceCFS.CoolDesDay; + // zoneCFS.CoolDDNum = spaceCFS.CoolDDNum; + // zoneCFS.cCoolDDDate = desDayWeath.DateString; + // zoneCFS.TimeStepNumAtCoolMax = spaceCFS.TimeStepNumAtCoolMax; + + if (spaceCFS.zoneLatentSizing) { + // Simple sums + zoneCFS.DesLatentHeatVolFlow += spaceCFS.DesLatentHeatVolFlow; + zoneCFS.DesLatentHeatMassFlow += spaceCFS.ZoneHeatLatentMassFlow; + zoneCFS.DesLatentHeatLoad += spaceCFS.DesLatentHeatLoad; + zoneCFS.DesLatentHeatLoadNoDOAS += spaceCFS.DesLatentHeatLoadNoDOAS; + zoneCFS.DesLatentCoolVolFlow += spaceCFS.DesLatentCoolVolFlow; + zoneCFS.DesLatentCoolMassFlow += spaceCFS.DesLatentCoolMassFlow; + zoneCFS.DesLatentCoolLoad += spaceCFS.DesLatentCoolLoad; + zoneCFS.DesLatentCoolLoadNoDOAS += spaceCFS.DesLatentCoolLoadNoDOAS; + + // Weighted averages + zoneCFS.ZoneTempAtLatentHeatPeak += spaceCFS.ZoneTempAtLatentHeatPeak; + zoneCFS.ZoneHumRatAtLatentHeatPeak += spaceCFS.ZoneHumRatAtLatentHeatPeak; + zoneCFS.ZoneRetTempAtLatentHeatPeak += spaceCFS.ZoneRetTempAtLatentHeatPeak; + zoneCFS.DesLatentHeatCoilInTemp += spaceCFS.DesLatentHeatCoilInTemp; + zoneCFS.DesLatentHeatCoilInHumRat += spaceCFS.DesLatentHeatCoilInHumRat; + zoneCFS.ZoneTempAtLatentCoolPeak += spaceCFS.ZoneTempAtLatentCoolPeak; + zoneCFS.ZoneHumRatAtLatentCoolPeak += spaceCFS.ZoneHumRatAtLatentCoolPeak; + zoneCFS.ZoneRetTempAtLatentCoolPeak += spaceCFS.ZoneRetTempAtLatentCoolPeak; + zoneCFS.DesLatentCoolCoilInTemp += spaceCFS.DesLatentCoolCoilInTemp; + zoneCFS.DesLatentCoolCoilInHumRat += spaceCFS.DesLatentCoolCoilInHumRat; + + // Other + // zoneCFS.LatHeatDesDay = spaceCFS.LatHeatDesDay; + // zoneCFS.cLatentHeatDDDate = desDayWeath.DateString; + // zoneCFS.LatentHeatDDNum = spaceCFS.LatentHeatDDNum; + // zoneCFS.TimeStepNumAtLatentHeatMax = spaceCFS.TimeStepNumAtLatentHeatMax; + // zoneCFS.LatCoolDesDay = spaceCFS.LatCoolDesDay; + // zoneCFS.cLatentCoolDDDate = desDayWeath.DateString; + // zoneCFS.LatentCoolDDNum = spaceCFS.LatentCoolDDNum; + // zoneCFS.TimeStepNumAtLatentCoolMax = spaceCFS.TimeStepNumAtLatentCoolMax; + // zoneCFS.CoolNoDOASDDNum = spaceCFS.CoolNoDOASDDNum; + // zoneCFS.CoolNoDOASDesDay = spaceCFS.CoolNoDOASDesDay; + // zoneCFS.TimeStepNumAtCoolNoDOASMax = spaceCFS.TimeStepNumAtCoolNoDOASMax; + // zoneCFS.LatentCoolNoDOASDDNum = spaceCFS.LatentCoolNoDOASDDNum; + // zoneCFS.LatCoolNoDOASDesDay = spaceCFS.LatCoolNoDOASDesDay; + // zoneCFS.TimeStepNumAtLatentCoolNoDOASMax = spaceCFS.TimeStepNumAtLatentCoolNoDOASMax; + + // Time-series sums + for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) { + zoneCFS.LatentHeatLoadSeq(ts) += spaceCFS.LatentHeatLoadSeq(ts); + zoneCFS.LatentHeatFlowSeq(ts) += spaceCFS.LatentHeatFlowSeq(ts); + zoneCFS.HeatLatentLoadNoDOASSeq(ts) += spaceCFS.HeatLatentLoadNoDOASSeq(ts); + zoneCFS.LatentCoolLoadSeq(ts) += spaceCFS.LatentCoolLoadSeq(ts); + zoneCFS.LatentCoolFlowSeq(ts) += spaceCFS.LatentCoolFlowSeq(ts); + zoneCFS.CoolLatentLoadNoDOASSeq(ts) += spaceCFS.CoolLatentLoadNoDOASSeq(ts); + } + } + } return; } @@ -2926,13 +3129,11 @@ void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator const CallI if (!state.dataGlobal->isPulseZoneSizing) { - for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) { - if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue; - updateZoneSizingEndZoneSizingCalc1(state, state.dataSize->CalcFinalZoneSizing(CtrlZoneNum)); - if (state.dataHeatBal->doSpaceHeatBalanceSizing) { - for (int spaceNum : state.dataHeatBal->Zone(CtrlZoneNum).spaceIndexes) { - updateZoneSizingEndZoneSizingCalc1(state, state.dataSize->CalcFinalSpaceSizing(spaceNum)); - } + // Apply non-coincident zone sizing - only if space sizing is active + if (state.dataHeatBal->doSpaceHeatBalanceSizing) { + for (int ctrlZoneNum = 1; ctrlZoneNum <= state.dataGlobal->NumOfZones; ++ctrlZoneNum) { + if (!state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).IsControlled) continue; + updateZoneSizingEndZoneSizingCalc1(state, ctrlZoneNum); } } @@ -2960,9 +3161,7 @@ void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator const CallI state.dataSize->CalcFinalSpaceSizing, state.dataSize->CalcSpaceSizing); } - } - if (!state.dataGlobal->isPulseZoneSizing) { // Move sizing data into final sizing array according to sizing method for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { if (!state.dataZoneEquip->ZoneEquipConfig(zoneNum).IsControlled) continue; diff --git a/src/EnergyPlus/ZoneEquipmentManager.hh b/src/EnergyPlus/ZoneEquipmentManager.hh index 563cba75d07..25e10c8b2f2 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.hh +++ b/src/EnergyPlus/ZoneEquipmentManager.hh @@ -140,7 +140,7 @@ namespace ZoneEquipmentManager { DataSizing::DesDayWeathData const &desDayWeath, Real64 const stdRhoAir); - void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, DataSizing::ZoneSizingData const &zsCalcSizing); + void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum); void updateZoneSizingEndZoneSizingCalc2(EnergyPlusData &state, DataSizing::ZoneSizingData &zsCalcSizing); From 6e791434c07e09590fbf3b7a7084ca7f16320b52 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 17 Jul 2024 18:02:51 -0700 Subject: [PATCH 38/81] add transition to delete old VAV fan objects --- .../CreateNewIDFUsingRulesV24_2_0.f90 | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 index 9fc4ceeb14a..e158c7eac6b 100644 --- a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 +++ b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 @@ -131,11 +131,14 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile REAL :: maxAirFlow REAL :: minAirFlowFrac REAL :: fanPowerMinAirFlow - INTEGER :: NumFanVariableVolume = 0 - INTEGER :: NumOldFanVO = 0 - INTEGER :: Num3 + INTEGER :: NumFanVariableVolume + INTEGER :: NumOldFanVO = 1 + INTEGER :: NumVRFTU = 1 + INTEGER :: Num3 = 1 + INTEGER :: VRFTU_i = 1 CHARACTER(len=MaxNameLength) :: sysFanName CHARACTER(len=MaxNameLength) :: vavFanName + CHARACTER(len=MaxNameLength), ALLOCATABLE, DIMENSION(:) :: vavFanNameToDelete TYPE FanVOTransitionInfo CHARACTER(len=MaxNameLength) :: oldFanName @@ -351,17 +354,30 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile ENDDO ENDDO + ! collect old VAV fans to be deleted + NumVRFTU = GetNumObjectsFound('ZONEHVAC:TERMINALUNIT:VARIABLEREFRIGERANTFLOW') + IF(ALLOCATED(vavFanNameToDelete)) DEALLOCATE(vavFanNameToDelete) + ALLOCATE(vavFanNameToDelete(NumVRFTU)) + DO Num = 1, NumIDFRecords + SELECT CASE (MakeUPPERCase(IDFRecords(Num)%Name)) + CASE('ZONEHVAC:TERMINALUNIT:VARIABLEREFRIGERANTFLOW') + IF (SameString(TRIM(IDFRecords(Num)%Alphas(7)), 'FAN:VARIABLEVOLUME')) THEN + vavFanNameToDelete(VRFTU_i) =TRIM(IDFRecords(Num)%Alphas(8)) + ELSE + vavFanNameToDelete(VRFTU_i) = '' + ENDIF + VRFTU_i = VRFTU_i + 1 + END SELECT + END DO + ! accumulate info on VAV fans NumFanVariableVolume = GetNumObjectsFound('FAN:VARIABLEVOLUME') IF (ALLOCATED(OldFanVO)) DEALLOCATE(OldFanVO) ALLOCATE(OldFanVO(NumFanVariableVolume)) - NumOldFanVO = 0 + NumOldFanVO = 1 DO Num = 1, NumIDFRecords SELECT CASE (MakeUPPERCase(IDFRecords(Num)%Name)) CASE ('FAN:VARIABLEVOLUME') - NumOldFanVO = NumOldFanVO + 1 - ! debug print - PRINT *, "Alphas", TRIM(IDFRecords(Num)%Alphas(1)), TRIM(IDFRecords(Num)%Alphas(6)) OldFanVO(NumOldFanVO)%oldFanName = TRIM(IDFRecords(Num)%Alphas(1)) OldFanVO(NumOldFanVO)%availSchedule = TRIM(IDFRecords(Num)%Alphas(2)) OldFanVO(NumOldFanVO)%fanTotalEff_str = TRIM(IDFRecords(Num)%Numbers(1)) @@ -380,8 +396,13 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile OldFanVO(NumOldFanVO)%inletAirNodeName = TRIM(IDFRecords(Num)%Alphas(4)) OldFanVO(NumOldFanVO)%outletAirNodeName = TRIM(IDFRecords(Num)%Alphas(5)) OldFanVO(NumOldFanVO)%endUseSubCat = TRIM(IDFRecords(Num)%Alphas(6)) + IF (FindItemInList(TRIM(IDFRecords(Num)%Alphas(1)), vavFanNameToDelete, NumVRFTU) /= 0) THEN + DeleteThisRecord(Num) = .TRUE. + ENDIF + NumOldFanVO = NumOldFanVO + 1 END SELECT END DO + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! P R O C E S S I N G ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! From f0a18f4051758dd1b71a9aafd2d5133ba2740c46 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 17 Jul 2024 18:08:40 -0700 Subject: [PATCH 39/81] Revert "change varname to fanRunTimeFraction, add comments to this arg" This reverts commit 1a07c51671bdd3b9b668a114e40efab4714f6016. --- src/EnergyPlus/Fans.cc | 14 +++++--------- src/EnergyPlus/Fans.hh | 24 +++++++++++------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/EnergyPlus/Fans.cc b/src/EnergyPlus/Fans.cc index e1a0ff5fae0..1e4a4c2f15c 100644 --- a/src/EnergyPlus/Fans.cc +++ b/src/EnergyPlus/Fans.cc @@ -104,9 +104,7 @@ void FanBase::simulate(EnergyPlusData &state, // the legacy speed ratio that was used with SimulateFanComponents. ObjexxFCL::Optional _pressureRise, // Pressure difference to use for DeltaPress, for rating DX coils at a ObjexxFCL::Optional _flowFraction, // when used, this directs the fan to set the flow at this flow fraction - ObjexxFCL::Optional - _fanRunTimeFraction, // This argument is only used in the variable volume fan in - // VRFFluidTCtrl model to control for fan cycling. Please do not use it in normal VAV model. + ObjexxFCL::Optional _onOffFanPartLoadFraction, // to control for cycling in VAV fan in VRFFluidTCtrl // different pressure without entire duct system ObjexxFCL::Optional _massFlowRate1, // Mass flow rate in operating mode 1 [kg/s] ObjexxFCL::Optional _runTimeFraction1, // Run time fraction in operating mode 1 @@ -142,7 +140,7 @@ void FanBase::simulate(EnergyPlusData &state, _thisFan->simulateConstant(state); } break; case HVAC::FanType::VAV: { - _thisFan->simulateVAV(state, _pressureRise, _fanRunTimeFraction); + _thisFan->simulateVAV(state, _pressureRise, _onOffFanPartLoadFraction); } break; case HVAC::FanType::OnOff: { _thisFan->simulateOnOff(state, _speedRatio); @@ -1716,9 +1714,7 @@ void FanComponent::simulateConstant(EnergyPlusData &state) void FanComponent::simulateVAV(EnergyPlusData &state, ObjexxFCL::Optional _pressureRise, - // This argument is only used in the variable volume fan in - // VRFFluidTCtrl model to control for fan cycling. Please do not use it in normal VAV model. - ObjexxFCL::Optional _fanRunTimeFraction) + ObjexxFCL::Optional _onOffFanPartLoadFraction) { // SUBROUTINE INFORMATION: @@ -1884,8 +1880,8 @@ void FanComponent::simulateVAV(EnergyPlusData &state, massFlowRateMaxAvail = 0.0; massFlowRateMinAvail = 0.0; } - if (present(_fanRunTimeFraction)) { - totalPower *= _fanRunTimeFraction; + if (present(_onOffFanPartLoadFraction)) { + totalPower *= _onOffFanPartLoadFraction; } } // FanComponent::SimVAV() diff --git a/src/EnergyPlus/Fans.hh b/src/EnergyPlus/Fans.hh index 411dd9093eb..fce7296764e 100644 --- a/src/EnergyPlus/Fans.hh +++ b/src/EnergyPlus/Fans.hh @@ -97,16 +97,15 @@ namespace Fans { virtual void init(EnergyPlusData &state) = 0; virtual void simulate(EnergyPlusData &state, bool const FirstHVACIteration, - ObjexxFCL::Optional speedRatio = _, // Flow fraction in operating mode 1 - ObjexxFCL::Optional pressureRise = _, // Pressure difference to use for DeltaPress - ObjexxFCL::Optional flowFraction = _, // Flow fraction in operating mode 1 - ObjexxFCL::Optional fanRuntimeFraction = 1.0, // This argument is only used in the variable volume fan in - // VRFFluidTCtrl model to control for fan cycling. Please do not use it in normal VAV model. - ObjexxFCL::Optional massFlowRate1 = _, // Mass flow rate in operating mode 1 [kg/s] - ObjexxFCL::Optional runTimeFraction1 = _, // Run time fraction in operating mode 1 - ObjexxFCL::Optional massFlowRate2 = _, // Mass flow rate in operating mode 2 [kg/s] - ObjexxFCL::Optional runTimeFraction2 = _, // Run time fraction in operating mode 2 - ObjexxFCL::Optional pressureRise2 = _ // Pressure difference to use for operating mode 2 + ObjexxFCL::Optional speedRatio = _, // Flow fraction in operating mode 1 + ObjexxFCL::Optional pressureRise = _, // Pressure difference to use for DeltaPress + ObjexxFCL::Optional flowFraction = _, // Flow fraction in operating mode 1 + ObjexxFCL::Optional onOffFanPartLoadFraction = 1.0, // to control for cycling in VAV fan in VRFFluidTCtrl + ObjexxFCL::Optional massFlowRate1 = _, // Mass flow rate in operating mode 1 [kg/s] + ObjexxFCL::Optional runTimeFraction1 = _, // Run time fraction in operating mode 1 + ObjexxFCL::Optional massFlowRate2 = _, // Mass flow rate in operating mode 2 [kg/s] + ObjexxFCL::Optional runTimeFraction2 = _, // Run time fraction in operating mode 2 + ObjexxFCL::Optional pressureRise2 = _ // Pressure difference to use for operating mode 2 ); virtual void update(EnergyPlusData &state) = 0; @@ -231,9 +230,8 @@ namespace Fans { void simulateVAV(EnergyPlusData &state, ObjexxFCL::Optional PressureRise = _, - // This argument is only used in the variable volume fan in - // VRFFluidTCtrl model to control for fan cycling. Please do not use it in normal VAV model. - ObjexxFCL::Optional fanRuntimeFraction = 1.0); + // to control for cycling in VAV fan in VRFFluidTCtrl + ObjexxFCL::Optional OnOffFanPartLoadFraction = 1.0); void simulateOnOff(EnergyPlusData &state, ObjexxFCL::Optional SpeedRatio = _); From b5fa9ea8ed4e826f36a363feef24a83f303689cd Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 17 Jul 2024 18:09:41 -0700 Subject: [PATCH 40/81] Revert "fix unit and integration tests from optional arg addition" This reverts commit 5bb21f0b853489ac315df1d16d35666107a9ea6d. --- src/EnergyPlus/Fans.cc | 4 +--- tst/EnergyPlus/unit/HVACFan.unit.cc | 30 ++++++++++++++--------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/EnergyPlus/Fans.cc b/src/EnergyPlus/Fans.cc index 1e4a4c2f15c..45da3b366f7 100644 --- a/src/EnergyPlus/Fans.cc +++ b/src/EnergyPlus/Fans.cc @@ -1880,9 +1880,7 @@ void FanComponent::simulateVAV(EnergyPlusData &state, massFlowRateMaxAvail = 0.0; massFlowRateMinAvail = 0.0; } - if (present(_onOffFanPartLoadFraction)) { - totalPower *= _onOffFanPartLoadFraction; - } + totalPower *= _onOffFanPartLoadFraction; } // FanComponent::SimVAV() void FanComponent::simulateOnOff(EnergyPlusData &state, ObjexxFCL::Optional _speedRatio) diff --git a/tst/EnergyPlus/unit/HVACFan.unit.cc b/tst/EnergyPlus/unit/HVACFan.unit.cc index 19d6712f71c..5303e1b3be6 100644 --- a/tst/EnergyPlus/unit/HVACFan.unit.cc +++ b/tst/EnergyPlus/unit/HVACFan.unit.cc @@ -345,7 +345,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc3) Real64 massFlow2 = designMassFlowRate; Real64 runTimeFrac1 = 0.5; Real64 runTimeFrac2 = 0.5; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); Real64 locFanElecPower = fanSystem->totalPower; Real64 locExpectPower = (runTimeFrac1 * 0.125 * 100.0) + (runTimeFrac2 * 1.0 * 100.0); EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -355,7 +355,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc3) massFlow2 = 0.75 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 1.0; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; // locExpectPower expect the same power as the previous case EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -365,7 +365,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc3) massFlow2 = 1.0 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 1.0; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; locExpectPower = fanSystem->designElecPower; // expect full power EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -375,13 +375,13 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc3) massFlow2 = 1.0 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 0.85; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; locExpectPower = 0.85 * fanSystem->designElecPower; // expect 85% of full power EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); // reverse the 1 and 2 arguments, expect the same result - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow2, runTimeFrac2, massFlow1, runTimeFrac1); + fanSystem->simulate(*state, false, _, _, _, massFlow2, runTimeFrac2, massFlow1, runTimeFrac1); locFanElecPower = fanSystem->totalPower; EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); } @@ -445,7 +445,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc4) Real64 massFlow2 = designMassFlowRate; Real64 runTimeFrac1 = 0.5; Real64 runTimeFrac2 = 0.5; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); Real64 locFanElecPower = fanSystem->totalPower; Real64 locExpectPower = (0.5 * pow(0.5, 3) + 0.5 * 1.0) * fanSystem->designElecPower; EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -455,7 +455,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc4) massFlow2 = 0.75 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 1.0; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; locExpectPower = pow(0.75, 3) * fanSystem->designElecPower; EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -465,7 +465,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc4) massFlow2 = 1.0 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 1.0; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; locExpectPower = fanSystem->designElecPower; // expect full power EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -475,7 +475,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_TwoSpeedFanPowerCalc4) massFlow2 = 1.0 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 0.85; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; locExpectPower = 0.85 * fanSystem->designElecPower; // expect 85% of full power EXPECT_NEAR(locFanElecPower, locExpectPower, 0.01); @@ -606,7 +606,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_DiscreteMode_noPowerFFlowCurve) Real64 massFlow2 = designMassFlowRate; Real64 runTimeFrac1 = 0.5; Real64 runTimeFrac2 = 0.5; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); Real64 locFanElecPower = fanSystem->totalPower; // uses flow weighted power calculation. 50% of time at 50% flow and 50% of time at 100% flow Real64 locExpectPower = (0.5 * 0.5 + 0.5 * 1.0) * fanSystem->designElecPower; // expect 75% of power @@ -617,7 +617,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_DiscreteMode_noPowerFFlowCurve) massFlow2 = 0.75 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 1.0; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; // uses flow weighted power calculation. 0% of time at 0% flow and 100% of time at 75% flow locExpectPower = (0.0 * 0.0 + 1.0 * 0.75) * fanSystem->designElecPower; // expect 75% of power @@ -628,7 +628,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_DiscreteMode_noPowerFFlowCurve) massFlow2 = 1.0 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 1.0; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; // uses flow weighted power calculation. 0% of time at 0% flow and 100% of time at 100% flow locExpectPower = (0.0 * 0.0 + 1.0 * 1.0) * fanSystem->designElecPower; // expect full power @@ -639,7 +639,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_DiscreteMode_noPowerFFlowCurve) massFlow2 = 1.0 * designMassFlowRate; runTimeFrac1 = 0.0; runTimeFrac2 = 0.85; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; // uses flow weighted power calculation. 0% of time at 0% flow and 85% of time at 100% flow locExpectPower = (0.0 * 0.25 + 0.85 * 1.0) * fanSystem->designElecPower; // expect 85% of full power @@ -712,7 +712,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_DiscreteMode_EMSPressureRiseResetTest) Real64 massFlow2 = designMassFlowRate; Real64 runTimeFrac1 = 0.5; Real64 runTimeFrac2 = 0.5; - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); Real64 locFanElecPower = fanSystem->totalPower; // uses flow weighted power calculation. 50% of time at 50% flow and 50% of time at 100% flow Real64 locExpectPower = (0.5 * 0.5 + 0.5 * 1.0) * fanSystem->designElecPower; // expect 75% of power @@ -724,7 +724,7 @@ TEST_F(EnergyPlusFixture, SystemFanObj_DiscreteMode_EMSPressureRiseResetTest) EMSManager::ManageEMS(*state, EMSManager::EMSCallFrom::BeginTimestepBeforePredictor, anyRan, ObjexxFCL::Optional_int_const()); EXPECT_TRUE(anyRan); // simulate the fan with -100.0 Pa fan pressure rise - fanSystem->simulate(*state, false, _, _, _, 1.0, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); + fanSystem->simulate(*state, false, _, _, _, massFlow1, runTimeFrac1, massFlow2, runTimeFrac2); locFanElecPower = fanSystem->totalPower; // negative fan pressure rise results in zero fan power locExpectPower = 0.0; From 340cc89e8b4a3da6f460523ac76bf0a815f6c8b4 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Thu, 18 Jul 2024 10:15:47 -0500 Subject: [PATCH 41/81] Space IV-Non-coincident 3 repairs --- src/EnergyPlus/DataSizing.hh | 2 +- src/EnergyPlus/SizingManager.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EnergyPlus/DataSizing.hh b/src/EnergyPlus/DataSizing.hh index 4bc28877441..ef4f8e2e07f 100644 --- a/src/EnergyPlus/DataSizing.hh +++ b/src/EnergyPlus/DataSizing.hh @@ -130,7 +130,7 @@ namespace DataSizing { Num }; - constexpr std::array(SizingConcurrence::Num)> SizingConcurrenceNamesUC{"NonCoincident", "Coincident"}; + constexpr std::array(SizingConcurrence::Num)> SizingConcurrenceNamesUC{"NONCOINCIDENT", "COINCIDENT"}; // parameters for coil sizing concurrence method enum class CoilSizingConcurrence diff --git a/src/EnergyPlus/SizingManager.cc b/src/EnergyPlus/SizingManager.cc index 1af5dc10eab..9c830da768a 100644 --- a/src/EnergyPlus/SizingManager.cc +++ b/src/EnergyPlus/SizingManager.cc @@ -3291,7 +3291,7 @@ void GetZoneSizingInput(EnergyPlusData &state) } } zoneSizingIndex.spaceConcurrence = static_cast( - getEnumValue(DataSizing::SizingConcurrenceNamesUC, state.dataIPShortCut->cAlphaArgs(10))); + getEnumValue(DataSizing::SizingConcurrenceNamesUC, state.dataIPShortCut->cAlphaArgs(15))); zoneSizingIndex.zoneSizingMethod = static_cast(getEnumValue(DataSizing::ZoneSizingMethodNamesUC, state.dataIPShortCut->cAlphaArgs(10))); if (zoneSizingIndex.zoneSizingMethod != ZoneSizing::SensibleOnly) { From 4c834c7d0e172287608dd9e022071dab4dc38ba6 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Thu, 18 Jul 2024 10:16:29 -0700 Subject: [PATCH 42/81] Revert "use optional arg in SimulateVAV to control for cycling" This reverts commit 9de83a18a2dc02f4b9a180a76a45fd3f5dda19bd. also resolves conflicts fan->simulate(state, FirstHVACIteration, _, _, _, fan->inletAirMassFlowRate, OnOffFanPartLoadFraction, 0, 0, _); --- src/EnergyPlus/Fans.cc | 8 ++----- src/EnergyPlus/Fans.hh | 22 ++++++++----------- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 4 ++-- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/EnergyPlus/Fans.cc b/src/EnergyPlus/Fans.cc index 45da3b366f7..7b2e137eea4 100644 --- a/src/EnergyPlus/Fans.cc +++ b/src/EnergyPlus/Fans.cc @@ -104,7 +104,6 @@ void FanBase::simulate(EnergyPlusData &state, // the legacy speed ratio that was used with SimulateFanComponents. ObjexxFCL::Optional _pressureRise, // Pressure difference to use for DeltaPress, for rating DX coils at a ObjexxFCL::Optional _flowFraction, // when used, this directs the fan to set the flow at this flow fraction - ObjexxFCL::Optional _onOffFanPartLoadFraction, // to control for cycling in VAV fan in VRFFluidTCtrl // different pressure without entire duct system ObjexxFCL::Optional _massFlowRate1, // Mass flow rate in operating mode 1 [kg/s] ObjexxFCL::Optional _runTimeFraction1, // Run time fraction in operating mode 1 @@ -140,7 +139,7 @@ void FanBase::simulate(EnergyPlusData &state, _thisFan->simulateConstant(state); } break; case HVAC::FanType::VAV: { - _thisFan->simulateVAV(state, _pressureRise, _onOffFanPartLoadFraction); + _thisFan->simulateVAV(state, _pressureRise); } break; case HVAC::FanType::OnOff: { _thisFan->simulateOnOff(state, _speedRatio); @@ -1712,9 +1711,7 @@ void FanComponent::simulateConstant(EnergyPlusData &state) } } // FanComponent::simulateConstant -void FanComponent::simulateVAV(EnergyPlusData &state, - ObjexxFCL::Optional _pressureRise, - ObjexxFCL::Optional _onOffFanPartLoadFraction) +void FanComponent::simulateVAV(EnergyPlusData &state, ObjexxFCL::Optional _pressureRise) { // SUBROUTINE INFORMATION: @@ -1880,7 +1877,6 @@ void FanComponent::simulateVAV(EnergyPlusData &state, massFlowRateMaxAvail = 0.0; massFlowRateMinAvail = 0.0; } - totalPower *= _onOffFanPartLoadFraction; } // FanComponent::SimVAV() void FanComponent::simulateOnOff(EnergyPlusData &state, ObjexxFCL::Optional _speedRatio) diff --git a/src/EnergyPlus/Fans.hh b/src/EnergyPlus/Fans.hh index fce7296764e..e78811ef0b3 100644 --- a/src/EnergyPlus/Fans.hh +++ b/src/EnergyPlus/Fans.hh @@ -97,15 +97,14 @@ namespace Fans { virtual void init(EnergyPlusData &state) = 0; virtual void simulate(EnergyPlusData &state, bool const FirstHVACIteration, - ObjexxFCL::Optional speedRatio = _, // Flow fraction in operating mode 1 - ObjexxFCL::Optional pressureRise = _, // Pressure difference to use for DeltaPress - ObjexxFCL::Optional flowFraction = _, // Flow fraction in operating mode 1 - ObjexxFCL::Optional onOffFanPartLoadFraction = 1.0, // to control for cycling in VAV fan in VRFFluidTCtrl - ObjexxFCL::Optional massFlowRate1 = _, // Mass flow rate in operating mode 1 [kg/s] - ObjexxFCL::Optional runTimeFraction1 = _, // Run time fraction in operating mode 1 - ObjexxFCL::Optional massFlowRate2 = _, // Mass flow rate in operating mode 2 [kg/s] - ObjexxFCL::Optional runTimeFraction2 = _, // Run time fraction in operating mode 2 - ObjexxFCL::Optional pressureRise2 = _ // Pressure difference to use for operating mode 2 + ObjexxFCL::Optional speedRatio = _, // Flow fraction in operating mode 1 + ObjexxFCL::Optional pressureRise = _, // Pressure difference to use for DeltaPress + ObjexxFCL::Optional flowFraction = _, // Flow fraction in operating mode 1 + ObjexxFCL::Optional massFlowRate1 = _, // Mass flow rate in operating mode 1 [kg/s] + ObjexxFCL::Optional runTimeFraction1 = _, // Run time fraction in operating mode 1 + ObjexxFCL::Optional massFlowRate2 = _, // Mass flow rate in operating mode 2 [kg/s] + ObjexxFCL::Optional runTimeFraction2 = _, // Run time fraction in operating mode 2 + ObjexxFCL::Optional pressureRise2 = _ // Pressure difference to use for operating mode 2 ); virtual void update(EnergyPlusData &state) = 0; @@ -228,10 +227,7 @@ namespace Fans { void simulateConstant(EnergyPlusData &state); - void simulateVAV(EnergyPlusData &state, - ObjexxFCL::Optional PressureRise = _, - // to control for cycling in VAV fan in VRFFluidTCtrl - ObjexxFCL::Optional OnOffFanPartLoadFraction = 1.0); + void simulateVAV(EnergyPlusData &state, ObjexxFCL::Optional PressureRise = _); void simulateOnOff(EnergyPlusData &state, ObjexxFCL::Optional SpeedRatio = _); diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index d68031510f1..e63773481b7 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -12865,12 +12865,12 @@ void VRFTerminalUnitEquipment::CalcVRF_FluidTCtrl(EnergyPlusData &state, auto *fan = state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex); if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::SystemModel) { if (OnOffAirFlowRatio > 0.0) { - fan->simulate(state, FirstHVACIteration, _, _, _, _, fan->inletAirMassFlowRate, OnOffFanPartLoadFraction, 0, 0, _); + fan->simulate(state, FirstHVACIteration, _, _, _, fan->inletAirMassFlowRate, OnOffFanPartLoadFraction, 0, 0, _); } else { fan->simulate(state, FirstHVACIteration, _, _, PartLoadRatio); } } else { - fan->simulate(state, FirstHVACIteration, state.dataHVACVarRefFlow->FanSpeedRatio, _, _, OnOffFanPartLoadFraction); + fan->simulate(state, FirstHVACIteration, state.dataHVACVarRefFlow->FanSpeedRatio); } } From 49e82a05736544a82477aa013286b0d5e1f924b4 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Thu, 18 Jul 2024 10:41:54 -0700 Subject: [PATCH 43/81] use old fan name in transition after VAV fans are deleted --- src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 index e158c7eac6b..9a8a0a90218 100644 --- a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 +++ b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 @@ -137,7 +137,6 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile INTEGER :: Num3 = 1 INTEGER :: VRFTU_i = 1 CHARACTER(len=MaxNameLength) :: sysFanName - CHARACTER(len=MaxNameLength) :: vavFanName CHARACTER(len=MaxNameLength), ALLOCATABLE, DIMENSION(:) :: vavFanNameToDelete TYPE FanVOTransitionInfo @@ -580,10 +579,8 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile IF (SameString(InArgs(14), 'FAN:VARIABLEVOLUME')) THEN isVariableVolume = .TRUE. OutArgs(14) = 'FAN:SYSTEMMODEL' - ! create a new fan object with a new name - OutArgs(15) = TRIM(InArgs(15)) // '_sysModel' - sysFanName = TRIM(InArgs(15)) // '_sysModel' - vavFanName = TRIM(InArgs(15)) + OutArgs(15) = TRIM(InArgs(15)) + sysFanName = TRIM(InArgs(15)) ELSE OutArgs(14:15) = InArgs(14:15) ENDIF @@ -594,7 +591,7 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile ! create fan system model object ObjectName = 'Fan:SystemModel' DO Num3 = 1, NumFanVariableVolume - IF (SameString(OldFanVO(Num3)%oldFanName, vavFanName)) THEN + IF (SameString(OldFanVO(Num3)%oldFanName, sysFanName)) THEN CALL GetNewObjectDefInIDD(ObjectName, NwNumArgs, NwAorN, NwReqFld, NwObjMinFlds, NwFldNames, NwFldDefaults, NwFldUnits) OutArgs(1) = TRIM(sysFanName) OutArgs(2) = OldFanVO(Num3)%availSchedule From 6e5166afb792aec3d65ffb9c3abffcfee75dd191 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Thu, 18 Jul 2024 11:22:35 -0700 Subject: [PATCH 44/81] remove unused inititialization --- tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index 6e719d90e3e..b392f7abf46 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -18163,9 +18163,6 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_SupplementalHtgCoilTest) GetVRFInput(*state); state->dataHVACVarRefFlow->GetVRFInputFlag = false; - state->dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; - state->dataHVACVarRefFlow->VRF(VRFCond).VRFCondCyclingRatio = 1.0; - state->dataScheduleMgr->Schedule(state->dataHVACVarRefFlow->VRF(VRFCond).SchedPtr).CurrentValue = 1.0; VRFTUNum = zone_num_TU1; state->dataScheduleMgr->Schedule(state->dataHVACVarRefFlow->VRFTU(VRFTUNum).SchedPtr).CurrentValue = 1.0; From 0c5b4ba06195b3e1463ce9d45a2729d69d433fac Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Thu, 18 Jul 2024 15:20:18 -0500 Subject: [PATCH 45/81] Space IV-Non-coincident 4 --- src/EnergyPlus/ZoneEquipmentManager.cc | 153 +++++++++++++++++-------- 1 file changed, 106 insertions(+), 47 deletions(-) diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index 997ce4ab31d..b459e11ae07 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -1869,7 +1869,7 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum // Set or override finalzonesizing data for non-coincident sizing auto &zoneCFS = state.dataSize->CalcFinalZoneSizing(zoneNum); if (zoneCFS.spaceConcurrence == DataSizing::SizingConcurrence::Coincident) return; - // Zero out simple sums and averages + // Zero out simple sums zoneCFS.DesHeatVolFlow = 0.0; zoneCFS.DesHeatLoad = 0.0; zoneCFS.DesHeatMassFlow = 0.0; @@ -1879,7 +1879,7 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum zoneCFS.DesCoolMassFlow = 0.0; zoneCFS.DesCoolLoadNoDOAS = 0.0; - // Weighted averages + // Zero out weighted averages zoneCFS.DesHeatDens = 0.0; zoneCFS.ZoneTempAtHeatPeak = 0.0; zoneCFS.OutTempAtHeatPeak = 0.0; @@ -1897,7 +1897,7 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum zoneCFS.DesCoolCoilInTemp = 0.0; zoneCFS.DesCoolCoilInHumRat = 0.0; - // Zero out ime-series sums + // Zero out time-series sums and averages for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) { zoneCFS.HeatFlowSeq(ts) = 0.0; zoneCFS.HeatLoadSeq(ts) = 0.0; @@ -1917,7 +1917,7 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum zoneCFS.CoolLoadNoDOASSeq(ts) = 0.0; } if (zoneCFS.zoneLatentSizing) { - // Simple sums + // Zero out latent simple sums zoneCFS.DesLatentHeatVolFlow = 0.0; zoneCFS.DesLatentHeatMassFlow = 0.0; zoneCFS.DesLatentHeatLoad = 0.0; @@ -1927,7 +1927,7 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum zoneCFS.DesLatentCoolLoad = 0.0; zoneCFS.DesLatentCoolLoadNoDOAS = 0.0; - // Weighted averages + // Zero out latent weighted averages zoneCFS.ZoneTempAtLatentHeatPeak = 0.0; zoneCFS.ZoneHumRatAtLatentHeatPeak = 0.0; zoneCFS.ZoneRetTempAtLatentHeatPeak = 0.0; @@ -1939,7 +1939,7 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum zoneCFS.DesLatentCoolCoilInTemp = 0.0; zoneCFS.DesLatentCoolCoilInHumRat = 0.0; - // Time-series sums + // Zero out latent time-series sums for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) { zoneCFS.LatentHeatLoadSeq(ts) = 0.0; zoneCFS.LatentHeatFlowSeq(ts) = 0.0; @@ -1953,7 +1953,6 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum int numSpaces = 0; // Track this for averages later for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { auto &spaceCFS = state.dataSize->CalcFinalSpaceSizing(spaceNum); - if (!state.dataZoneEquip->spaceEquipConfig(spaceNum).IsControlled) continue; ++numSpaces; // Simple sums @@ -1967,41 +1966,43 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum zoneCFS.DesCoolLoadNoDOAS += spaceCFS.DesCoolLoadNoDOAS; // Weighted averages - zoneCFS.DesHeatDens += spaceCFS.DesHeatDens; - zoneCFS.ZoneTempAtHeatPeak += spaceCFS.ZoneTempAtHeatPeak; - zoneCFS.OutTempAtHeatPeak += spaceCFS.OutTempAtHeatPeak; - zoneCFS.ZoneRetTempAtHeatPeak += spaceCFS.ZoneRetTempAtHeatPeak; - zoneCFS.ZoneHumRatAtHeatPeak += spaceCFS.ZoneHumRatAtHeatPeak; - zoneCFS.OutHumRatAtHeatPeak += spaceCFS.OutHumRatAtHeatPeak; - zoneCFS.DesHeatCoilInTemp += spaceCFS.DesHeatCoilInTemp; - zoneCFS.DesHeatCoilInHumRat += spaceCFS.DesHeatCoilInHumRat; - zoneCFS.DesCoolDens += spaceCFS.DesCoolDens; - zoneCFS.ZoneTempAtCoolPeak += spaceCFS.ZoneTempAtCoolPeak; - zoneCFS.OutTempAtCoolPeak += spaceCFS.OutTempAtCoolPeak; - zoneCFS.ZoneRetTempAtCoolPeak += spaceCFS.ZoneRetTempAtCoolPeak; - zoneCFS.ZoneHumRatAtCoolPeak += spaceCFS.ZoneHumRatAtCoolPeak; - zoneCFS.OutHumRatAtCoolPeak += spaceCFS.OutHumRatAtCoolPeak; - zoneCFS.DesCoolCoilInTemp += spaceCFS.DesCoolCoilInTemp; - zoneCFS.DesCoolCoilInHumRat += spaceCFS.DesCoolCoilInHumRat; - - // Time-series sums + zoneCFS.DesHeatDens += spaceCFS.DesHeatDens * spaceCFS.DesHeatMassFlow; + zoneCFS.ZoneTempAtHeatPeak += spaceCFS.ZoneTempAtHeatPeak * spaceCFS.DesHeatMassFlow; + zoneCFS.OutTempAtHeatPeak += spaceCFS.OutTempAtHeatPeak * spaceCFS.DesHeatMassFlow; + zoneCFS.ZoneRetTempAtHeatPeak += spaceCFS.ZoneRetTempAtHeatPeak * spaceCFS.DesHeatMassFlow; + zoneCFS.ZoneHumRatAtHeatPeak += spaceCFS.ZoneHumRatAtHeatPeak * spaceCFS.DesHeatMassFlow; + zoneCFS.OutHumRatAtHeatPeak += spaceCFS.OutHumRatAtHeatPeak * spaceCFS.DesHeatMassFlow; + zoneCFS.DesHeatCoilInTemp += spaceCFS.DesHeatCoilInTemp * spaceCFS.DesHeatMassFlow; + zoneCFS.DesHeatCoilInHumRat += spaceCFS.DesHeatCoilInHumRat * spaceCFS.DesHeatMassFlow; + zoneCFS.DesCoolDens += spaceCFS.DesCoolDens * spaceCFS.DesCoolMassFlow; + zoneCFS.ZoneTempAtCoolPeak += spaceCFS.ZoneTempAtCoolPeak * spaceCFS.DesCoolMassFlow; + zoneCFS.OutTempAtCoolPeak += spaceCFS.OutTempAtCoolPeak * spaceCFS.DesCoolMassFlow; + zoneCFS.ZoneRetTempAtCoolPeak += spaceCFS.ZoneRetTempAtCoolPeak * spaceCFS.DesCoolMassFlow; + zoneCFS.ZoneHumRatAtCoolPeak += spaceCFS.ZoneHumRatAtCoolPeak * spaceCFS.DesCoolMassFlow; + zoneCFS.OutHumRatAtCoolPeak += spaceCFS.OutHumRatAtCoolPeak * spaceCFS.DesCoolMassFlow; + zoneCFS.DesCoolCoilInTemp += spaceCFS.DesCoolCoilInTemp * spaceCFS.DesCoolMassFlow; + zoneCFS.DesCoolCoilInHumRat += spaceCFS.DesCoolCoilInHumRat * spaceCFS.DesCoolMassFlow; + for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) { + // Time-series sums zoneCFS.HeatFlowSeq(ts) += spaceCFS.HeatFlowSeq(ts); zoneCFS.HeatLoadSeq(ts) += spaceCFS.HeatLoadSeq(ts); - zoneCFS.HeatZoneTempSeq(ts) += spaceCFS.HeatZoneTempSeq(ts); - zoneCFS.HeatOutTempSeq(ts) += spaceCFS.HeatOutTempSeq(ts); - zoneCFS.HeatZoneRetTempSeq(ts) += spaceCFS.HeatZoneRetTempSeq(ts); - zoneCFS.HeatZoneHumRatSeq(ts) += spaceCFS.HeatZoneHumRatSeq(ts); - zoneCFS.HeatOutHumRatSeq(ts) += spaceCFS.HeatOutHumRatSeq(ts); zoneCFS.HeatLoadNoDOASSeq(ts) += spaceCFS.HeatLoadNoDOASSeq(ts); zoneCFS.CoolFlowSeq(ts) += spaceCFS.CoolFlowSeq(ts); zoneCFS.CoolLoadSeq(ts) += spaceCFS.CoolLoadSeq(ts); - zoneCFS.CoolZoneTempSeq(ts) += spaceCFS.CoolZoneTempSeq(ts); - zoneCFS.CoolOutTempSeq(ts) += spaceCFS.CoolOutTempSeq(ts); - zoneCFS.CoolZoneRetTempSeq(ts) += spaceCFS.CoolZoneRetTempSeq(ts); - zoneCFS.CoolZoneHumRatSeq(ts) += spaceCFS.CoolZoneHumRatSeq(ts); - zoneCFS.CoolOutHumRatSeq(ts) += spaceCFS.CoolOutHumRatSeq(ts); zoneCFS.CoolLoadNoDOASSeq(ts) += spaceCFS.CoolLoadNoDOASSeq(ts); + + // Time-series weighted averages + zoneCFS.HeatZoneTempSeq(ts) += spaceCFS.HeatZoneTempSeq(ts) * spaceCFS.HeatFlowSeq(ts); + zoneCFS.HeatOutTempSeq(ts) += spaceCFS.HeatOutTempSeq(ts) * spaceCFS.HeatFlowSeq(ts); + zoneCFS.HeatZoneRetTempSeq(ts) += spaceCFS.HeatZoneRetTempSeq(ts) * spaceCFS.HeatFlowSeq(ts); + zoneCFS.HeatZoneHumRatSeq(ts) += spaceCFS.HeatZoneHumRatSeq(ts) * spaceCFS.HeatFlowSeq(ts); + zoneCFS.HeatOutHumRatSeq(ts) += spaceCFS.HeatOutHumRatSeq(ts) * spaceCFS.HeatFlowSeq(ts); + zoneCFS.CoolZoneTempSeq(ts) += spaceCFS.CoolZoneTempSeq(ts) * spaceCFS.CoolFlowSeq(ts); + zoneCFS.CoolOutTempSeq(ts) += spaceCFS.CoolOutTempSeq(ts) * spaceCFS.CoolFlowSeq(ts); + zoneCFS.CoolZoneRetTempSeq(ts) += spaceCFS.CoolZoneRetTempSeq(ts) * spaceCFS.CoolFlowSeq(ts); + zoneCFS.CoolZoneHumRatSeq(ts) += spaceCFS.CoolZoneHumRatSeq(ts) * spaceCFS.CoolFlowSeq(ts); + zoneCFS.CoolOutHumRatSeq(ts) += spaceCFS.CoolOutHumRatSeq(ts) * spaceCFS.CoolFlowSeq(ts); } // Other @@ -2020,7 +2021,7 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum // zoneCFS.cCoolDDDate = desDayWeath.DateString; // zoneCFS.TimeStepNumAtCoolMax = spaceCFS.TimeStepNumAtCoolMax; - if (spaceCFS.zoneLatentSizing) { + if (zoneCFS.zoneLatentSizing) { // Simple sums zoneCFS.DesLatentHeatVolFlow += spaceCFS.DesLatentHeatVolFlow; zoneCFS.DesLatentHeatMassFlow += spaceCFS.ZoneHeatLatentMassFlow; @@ -2032,16 +2033,16 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum zoneCFS.DesLatentCoolLoadNoDOAS += spaceCFS.DesLatentCoolLoadNoDOAS; // Weighted averages - zoneCFS.ZoneTempAtLatentHeatPeak += spaceCFS.ZoneTempAtLatentHeatPeak; - zoneCFS.ZoneHumRatAtLatentHeatPeak += spaceCFS.ZoneHumRatAtLatentHeatPeak; - zoneCFS.ZoneRetTempAtLatentHeatPeak += spaceCFS.ZoneRetTempAtLatentHeatPeak; - zoneCFS.DesLatentHeatCoilInTemp += spaceCFS.DesLatentHeatCoilInTemp; - zoneCFS.DesLatentHeatCoilInHumRat += spaceCFS.DesLatentHeatCoilInHumRat; - zoneCFS.ZoneTempAtLatentCoolPeak += spaceCFS.ZoneTempAtLatentCoolPeak; - zoneCFS.ZoneHumRatAtLatentCoolPeak += spaceCFS.ZoneHumRatAtLatentCoolPeak; - zoneCFS.ZoneRetTempAtLatentCoolPeak += spaceCFS.ZoneRetTempAtLatentCoolPeak; - zoneCFS.DesLatentCoolCoilInTemp += spaceCFS.DesLatentCoolCoilInTemp; - zoneCFS.DesLatentCoolCoilInHumRat += spaceCFS.DesLatentCoolCoilInHumRat; + zoneCFS.ZoneTempAtLatentHeatPeak += spaceCFS.ZoneTempAtLatentHeatPeak * spaceCFS.ZoneHeatLatentMassFlow; + zoneCFS.ZoneHumRatAtLatentHeatPeak += spaceCFS.ZoneHumRatAtLatentHeatPeak * spaceCFS.ZoneHeatLatentMassFlow; + zoneCFS.ZoneRetTempAtLatentHeatPeak += spaceCFS.ZoneRetTempAtLatentHeatPeak * spaceCFS.ZoneHeatLatentMassFlow; + zoneCFS.DesLatentHeatCoilInTemp += spaceCFS.DesLatentHeatCoilInTemp * spaceCFS.ZoneHeatLatentMassFlow; + zoneCFS.DesLatentHeatCoilInHumRat += spaceCFS.DesLatentHeatCoilInHumRat * spaceCFS.ZoneHeatLatentMassFlow; + zoneCFS.ZoneTempAtLatentCoolPeak += spaceCFS.ZoneTempAtLatentCoolPeak * spaceCFS.DesLatentCoolVolFlow; + zoneCFS.ZoneHumRatAtLatentCoolPeak += spaceCFS.ZoneHumRatAtLatentCoolPeak * spaceCFS.DesLatentCoolVolFlow; + zoneCFS.ZoneRetTempAtLatentCoolPeak += spaceCFS.ZoneRetTempAtLatentCoolPeak * spaceCFS.DesLatentCoolVolFlow; + zoneCFS.DesLatentCoolCoilInTemp += spaceCFS.DesLatentCoolCoilInTemp * spaceCFS.DesLatentCoolVolFlow; + zoneCFS.DesLatentCoolCoilInHumRat += spaceCFS.DesLatentCoolCoilInHumRat * spaceCFS.DesLatentCoolVolFlow; // Other // zoneCFS.LatHeatDesDay = spaceCFS.LatHeatDesDay; @@ -2070,6 +2071,63 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum } } } + + // Compute weighted averages + if (zoneCFS.DesHeatMassFlow > 0) { + zoneCFS.DesHeatDens /= zoneCFS.DesHeatMassFlow; + zoneCFS.ZoneTempAtHeatPeak /= zoneCFS.DesHeatMassFlow; + zoneCFS.OutTempAtHeatPeak /= zoneCFS.DesHeatMassFlow; + zoneCFS.ZoneRetTempAtHeatPeak /= zoneCFS.DesHeatMassFlow; + zoneCFS.ZoneHumRatAtHeatPeak /= zoneCFS.DesHeatMassFlow; + zoneCFS.OutHumRatAtHeatPeak /= zoneCFS.DesHeatMassFlow; + zoneCFS.DesHeatCoilInTemp /= zoneCFS.DesHeatMassFlow; + zoneCFS.DesHeatCoilInHumRat /= zoneCFS.DesHeatMassFlow; + } + if (zoneCFS.DesCoolMassFlow > 0) { + zoneCFS.DesCoolDens /= zoneCFS.DesCoolMassFlow; + zoneCFS.ZoneTempAtCoolPeak /= zoneCFS.DesCoolMassFlow; + zoneCFS.OutTempAtCoolPeak /= zoneCFS.DesCoolMassFlow; + zoneCFS.ZoneRetTempAtCoolPeak /= zoneCFS.DesCoolMassFlow; + zoneCFS.ZoneHumRatAtCoolPeak /= zoneCFS.DesCoolMassFlow; + zoneCFS.OutHumRatAtCoolPeak /= zoneCFS.DesCoolMassFlow; + zoneCFS.DesCoolCoilInTemp /= zoneCFS.DesCoolMassFlow; + zoneCFS.DesCoolCoilInHumRat /= zoneCFS.DesCoolMassFlow; + } + for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) { + if (zoneCFS.HeatFlowSeq(ts) > 0) { + zoneCFS.HeatZoneTempSeq(ts) /= zoneCFS.HeatFlowSeq(ts); + zoneCFS.HeatOutTempSeq(ts) /= zoneCFS.HeatFlowSeq(ts); + zoneCFS.HeatZoneRetTempSeq(ts) /= zoneCFS.HeatFlowSeq(ts); + zoneCFS.HeatZoneHumRatSeq(ts) /= zoneCFS.HeatFlowSeq(ts); + zoneCFS.HeatOutHumRatSeq(ts) /= zoneCFS.HeatFlowSeq(ts); + zoneCFS.HeatLoadNoDOASSeq(ts) /= zoneCFS.HeatFlowSeq(ts); + } + if (zoneCFS.CoolFlowSeq(ts) > 0) { + zoneCFS.CoolZoneTempSeq(ts) /= zoneCFS.CoolFlowSeq(ts); + zoneCFS.CoolOutTempSeq(ts) /= zoneCFS.CoolFlowSeq(ts); + zoneCFS.CoolZoneRetTempSeq(ts) /= zoneCFS.CoolFlowSeq(ts); + zoneCFS.CoolZoneHumRatSeq(ts) /= zoneCFS.CoolFlowSeq(ts); + zoneCFS.CoolOutHumRatSeq(ts) /= zoneCFS.CoolFlowSeq(ts); + zoneCFS.CoolLoadNoDOASSeq(ts) /= zoneCFS.CoolFlowSeq(ts); + } + } + if (zoneCFS.zoneLatentSizing) { + if (zoneCFS.DesLatentHeatMassFlow > 0) { + zoneCFS.ZoneTempAtLatentHeatPeak /= zoneCFS.DesLatentHeatMassFlow; + zoneCFS.ZoneHumRatAtLatentHeatPeak /= zoneCFS.DesLatentHeatMassFlow; + zoneCFS.ZoneRetTempAtLatentHeatPeak /= zoneCFS.DesLatentHeatMassFlow; + zoneCFS.DesLatentHeatCoilInTemp /= zoneCFS.DesLatentHeatMassFlow; + zoneCFS.DesLatentHeatCoilInHumRat /= zoneCFS.DesLatentHeatMassFlow; + } + if (zoneCFS.DesLatentCoolMassFlow > 0) { + zoneCFS.ZoneTempAtLatentCoolPeak /= zoneCFS.DesLatentCoolMassFlow; + zoneCFS.ZoneHumRatAtLatentCoolPeak /= zoneCFS.DesLatentCoolMassFlow; + zoneCFS.ZoneRetTempAtLatentCoolPeak /= zoneCFS.DesLatentCoolMassFlow; + zoneCFS.DesLatentCoolCoilInTemp /= zoneCFS.DesLatentCoolMassFlow; + zoneCFS.DesLatentCoolCoilInHumRat /= zoneCFS.DesLatentCoolMassFlow; + } + } + return; } @@ -3129,10 +3187,11 @@ void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator const CallI if (!state.dataGlobal->isPulseZoneSizing) { - // Apply non-coincident zone sizing - only if space sizing is active + // Apply non-coincident zone sizing - only if space sizing is active, and only if there is more than one space in the zone if (state.dataHeatBal->doSpaceHeatBalanceSizing) { for (int ctrlZoneNum = 1; ctrlZoneNum <= state.dataGlobal->NumOfZones; ++ctrlZoneNum) { if (!state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).IsControlled) continue; + if (state.dataHeatBal->Zone(ctrlZoneNum).numSpaces == 1) continue; updateZoneSizingEndZoneSizingCalc1(state, ctrlZoneNum); } } From c1a23960ed169e3191ed260194e6c6e15f21f7f1 Mon Sep 17 00:00:00 2001 From: Edwin Lee Date: Thu, 18 Jul 2024 15:56:11 -0500 Subject: [PATCH 46/81] Add API endpoints to access EMS global variables --- src/EnergyPlus/api/datatransfer.cc | 44 +++++++++++++++ src/EnergyPlus/api/datatransfer.h | 36 +++++++++++- src/EnergyPlus/api/datatransfer.py | 88 ++++++++++++++++++++++++++++-- 3 files changed, 161 insertions(+), 7 deletions(-) diff --git a/src/EnergyPlus/api/datatransfer.cc b/src/EnergyPlus/api/datatransfer.cc index 196f1e2b406..fd8a303e07d 100644 --- a/src/EnergyPlus/api/datatransfer.cc +++ b/src/EnergyPlus/api/datatransfer.cc @@ -573,6 +573,50 @@ Real64 getInternalVariableValue(EnergyPlusState state, int handle) return 0; } +int getEMSGlobalVariableHandle(EnergyPlusState state, const char *name) +{ + auto *thisState = static_cast(state); + int index = 0; + for (auto const &erlVar : thisState->dataRuntimeLang->ErlVariable) { + index++; + if (EnergyPlus::Util::SameString(name, erlVar.Name)) { + return index; + } + } + return 0; +} + +Real64 getEMSGlobalVariableValue(EnergyPlusState state, int handle) +{ + auto *thisState = static_cast(state); + if (handle < 0 || handle > thisState->dataRuntimeLang->NumErlVariables) { + // need to fatal out once the process is done + // throw an error, set the fatal flag, and then return 0 + EnergyPlus::ShowSevereError( + *thisState, fmt::format("Data Exchange API: Problem -- index error in getEMSGlobalVariableValue; received handle: {}", handle)); + EnergyPlus::ShowContinueError( + *thisState, "The getEMSGlobalVariableValue function will return 0 for now to allow the process to finish, then EnergyPlus will abort"); + thisState->dataPluginManager->apiErrorFlag = true; + return 0; + } + return thisState->dataRuntimeLang->ErlVariable(handle).Value.Number; +} + +void setEMSGlobalVariableValue(EnergyPlusState state, int handle, Real64 value) +{ + auto *thisState = static_cast(state); + if (handle < 0 || handle > thisState->dataRuntimeLang->NumErlVariables) { + // need to fatal out once the plugin is done + // throw an error, set the fatal flag, and then return + EnergyPlus::ShowSevereError( + *thisState, fmt::format("Data Exchange API: Problem -- index error in setEMSGlobalVariableValue; received handle: {}", handle)); + EnergyPlus::ShowContinueError(*thisState, + "The setEMSGlobalVariableValue function will return to allow the plugin to finish, then EnergyPlus will abort"); + thisState->dataPluginManager->apiErrorFlag = true; + } + thisState->dataRuntimeLang->ErlVariable(handle).Value.Number = value; +} + int getPluginGlobalVariableHandle(EnergyPlusState state, const char *name) { auto *thisState = static_cast(state); diff --git a/src/EnergyPlus/api/datatransfer.h b/src/EnergyPlus/api/datatransfer.h index ae45b8fc5c8..11bee4ce75b 100644 --- a/src/EnergyPlus/api/datatransfer.h +++ b/src/EnergyPlus/api/datatransfer.h @@ -149,7 +149,7 @@ ENERGYPLUSLIB_API void freeAPIData(const struct APIDataEntry *data, unsigned int ENERGYPLUSLIB_API char **getObjectNames(EnergyPlusState state, const char *objectType, unsigned int *resultingSize); /// \brief Clears an object names array allocation /// \details This function frees an instance of the object names array, which is returned from getObjectNames -/// \param[in] data An array (pointer) of const char * as returned from the getObjectNames function +/// \param[in] objectNames An array (pointer) of char * as returned from the getObjectNames function /// \param[in] arraySize The size of the object name array, which is known after the call to getObjectNames. /// \return Nothing, this simply frees the memory ENERGYPLUSLIB_API void freeObjectNames(char **objectNames, unsigned int arraySize); @@ -297,6 +297,40 @@ ENERGYPLUSLIB_API int getInternalVariableHandle(EnergyPlusState state, const cha /// \see getInternalVariableHandle ENERGYPLUSLIB_API Real64 getInternalVariableValue(EnergyPlusState state, int handle); +// ----- FUNCTIONS RELATED TO EMS GLOBAL VARIABLES (FOR CORNER CASES WHERE PLUGIN/API BLENDS WITH EMS PROGRAMS) +/// \brief Gets a handle to an EMS "Global" variable +/// \details When using EMS, it is sometimes necessary to share data between programs. +/// EMS global variables are declared in the input file and used in EMS programs. +/// EMS global variables are identified by name only. This function returns -1 if a match is not found. +/// \param[in] state An active EnergyPlusState instance created with `stateNew`. +/// \param[in] name The name of the EMS global variable, which is declared in the EnergyPlus input file +/// \return The integer handle to an EMS global variable, or -1 if a match is not found. +/// \remark The behavior of this function is not well-defined until the `apiDataFullyReady` function returns true. +/// \see apiDataFullyReady +ENERGYPLUSLIB_API int getEMSGlobalVariableHandle(EnergyPlusState state, const char *name); +/// \brief Gets the current value of an EMS "Global" variable +/// \details When using EMS, the value of the shared "global" variables can change at any time. +/// This function returns the current value of the variable. +/// \param[in] state An active EnergyPlusState instance created with `stateNew`. +/// \param[in] handle The handle id to an EMS "Global" variable, which can be retrieved using the `getEMSGlobalVariableHandle` function. +/// \remark The behavior of this function is not well-defined until the `apiDataFullyReady` function returns true. +/// \return The current value of the variable, in floating point form, or zero if a handle problem is encountered. If a zero +/// is returned, use the `apiErrorFlag` function to disambiguate the return value. +/// \see apiDataFullyReady +/// \see getEMSGlobalVariableHandle +ENERGYPLUSLIB_API Real64 getEMSGlobalVariableValue(EnergyPlusState state, int handle); +/// \brief Sets the value of an EMS "Global" variable +/// \details When using EMS, the value of the shared "global" variables can change at any time. +/// This function sets the variable to a new value. +/// \param[in] state An active EnergyPlusState instance created with `stateNew`. +/// \param[in] handle The handle id to an EMS "Global" variable, which can be retrieved using the `getEMSGlobalVariableHandle` function. +/// \param[in] value The floating point value to be assigned to the global variable +/// \remark The behavior of this function is not well-defined until the `apiDataFullyReady` function returns true. +/// \remark A handle index or other problem will return 0 and set a flag to cause EnergyPlus to terminate once Python completes. +/// \see apiDataFullyReady +/// \see getEMSGlobalVariableHandle +ENERGYPLUSLIB_API void setEMSGlobalVariableValue(EnergyPlusState state, int handle, Real64 value); + // ----- FUNCTIONS RELATED TO PYTHON PLUGIN GLOBAL VARIABLES (ONLY USED FOR PYTHON PLUGIN SYSTEM) /// \brief Gets a handle to a Python Plugin "Global" variable diff --git a/src/EnergyPlus/api/datatransfer.py b/src/EnergyPlus/api/datatransfer.py index 3b154108d38..bee6023f1f9 100644 --- a/src/EnergyPlus/api/datatransfer.py +++ b/src/EnergyPlus/api/datatransfer.py @@ -201,6 +201,12 @@ def __init__(self, api: cdll, running_as_python_plugin: bool = False): self.api.currentEnvironmentNum.restype = c_int self.api.warmupFlag.argtypes = [c_void_p] self.api.warmupFlag.restype = c_int + self.api.getEMSGlobalVariableHandle.argtypes = [c_void_p, c_char_p] + self.api.getEMSGlobalVariableHandle.restype = c_int + self.api.getEMSGlobalVariableValue.argtypes = [c_void_p, c_int] + self.api.getEMSGlobalVariableValue.restype = RealEP + self.api.setEMSGlobalVariableValue.argtypes = [c_void_p, c_int, RealEP] + self.api.setEMSGlobalVariableValue.restype = c_void_p self.api.getPluginGlobalVariableHandle.argtypes = [c_void_p, c_char_p] self.api.getPluginGlobalVariableHandle.restype = c_int self.api.getPluginGlobalVariableValue.argtypes = [c_void_p, c_int] @@ -698,6 +704,82 @@ def get_construction_handle(self, state: c_void_p, var_name: Union[str, bytes]) "'{}'".format(var_name)) return self.api.getConstructionHandle(state, var_name) + def get_ems_global_handle(self, state: c_void_p, var_name: Union[str, bytes]) -> int: + """ + Get a handle to an EMS global variable in a running simulation. + + EMS global variables are used as a way to share data between running EMS programs. First a global variable must + be declared in the input file using the EnergyManagementSystem:GlobalVariable object. Once a name has been + declared, it can be accessed by EMS programs by name, and through the Python API. For API usage, the client + should get a handle to the variable using this get_global_handle function, then + using the get_ems_global_value and set_ems_global_value functions as needed. Note all global variables are + floating point values. + + The arguments passed into this function do not need to be a particular case, as the EnergyPlus API + automatically converts values to upper-case when finding matches to internal variables in the simulation. + + Note also that the arguments passed in here can be either strings or bytes, as this wrapper handles conversion + as needed. + + :param state: An active EnergyPlus "state" that is returned from a call to `api.state_manager.new_state()`. + :param var_name: The name of the EMS global variable to retrieve, this name must be listed in an IDF object: + `EnergyManagementSystem:GlobalVariable` + :return: An integer ID for this EMS global variable, or -1 if one could not be found. + """ + if isinstance(var_name, str): + var_name = var_name.encode('utf-8') + elif not isinstance(var_name, bytes): + raise EnergyPlusException( + "`get_ems_global_handle` expects `component_type` as a `str` or UTF-8 encoded `bytes`, not " + "'{}'".format(var_name)) + return self.api.getEMSGlobalVariableHandle(state, var_name) + + def get_ems_global_value(self, state: c_void_p, handle: int) -> float: + """ + Get the current value of an EMS global variable in a running simulation. + + EMS global variables are used as a way to share data between running EMS programs. First a global variable must + be declared in the input file using the EnergyManagementSystem:GlobalVariable object. Once a name has been + declared, it can be accessed by EMS programs by name, and through the Python API. For API usage, the client + should get a handle to the variable using this get_global_handle function, then + using the get_ems_global_value and set_ems_global_value functions as needed. Note all global variables are + floating point values. + + :param state: An active EnergyPlus "state" that is returned from a call to `api.state_manager.new_state()`. + :param handle: An integer returned from the `get_ems_global_handle` function. + :return: Floating point representation of the EMS global variable value + """ + if not is_number(handle): + raise EnergyPlusException( + "`get_ems_global_value` expects `handle` as an `int`, not " + "'{}'".format(handle)) + return self.api.getEMSGlobalVariableValue(state, handle) + + def set_ems_global_value(self, state: c_void_p, handle: int, value: float) -> None: + """ + Set the current value of an EMS global variable in a running simulation. + + EMS global variables are used as a way to share data between running EMS programs. First a global variable must + be declared in the input file using the EnergyManagementSystem:GlobalVariable object. Once a name has been + declared, it can be accessed by EMS programs by name, and through the Python API. For API usage, the client + should get a handle to the variable using this get_global_handle function, then + using the get_ems_global_value and set_ems_global_value functions as needed. Note all global variables are + floating point values. + + :param state: An active EnergyPlus "state" that is returned from a call to `api.state_manager.new_state()`. + :param handle: An integer returned from the `get_ems_global_handle` function. + :param value: Floating point value to assign to the EMS global variable + """ + if not is_number(handle): + raise EnergyPlusException( + "`set_ems_global_value` expects `variable_handle` as an `int`, not " + "'{}'".format(handle)) + if not is_number(value): + raise EnergyPlusException( + "`set_ems_global_value` expects `value` as a `float`, not " + "'{}'".format(value)) + self.api.setEMSGlobalVariableValue(state, handle, value) + def get_global_handle(self, state: c_void_p, var_name: Union[str, bytes]) -> int: """ Get a handle to a global variable in a running simulation. This is only used for Python Plugin applications! @@ -740,12 +822,6 @@ def get_global_value(self, state: c_void_p, handle: int) -> float: using this get_global_value and the set_global_value functions as needed. Note all global variables are floating point values. - The arguments passed into this function do not need to be a particular case, as the EnergyPlus API - automatically converts values to upper-case when finding matches to internal variables in the simulation. - - Note also that the arguments passed in here can be either strings or bytes, as this wrapper handles conversion - as needed. - :param state: An active EnergyPlus "state" that is returned from a call to `api.state_manager.new_state()`. :param handle: An integer returned from the `get_global_handle` function. :return: Floating point representation of the global variable value From 5d4c91148c2dae1ef5467eb8c29746ee9e32cd7b Mon Sep 17 00:00:00 2001 From: Edwin Lee Date: Fri, 19 Jul 2024 12:46:21 -0500 Subject: [PATCH 47/81] Add API endpoint for accecssing the specified IDF path --- src/EnergyPlus/api/datatransfer.cc | 9 +++++++++ src/EnergyPlus/api/datatransfer.h | 6 ++++++ src/EnergyPlus/api/datatransfer.py | 13 +++++++++++++ tst/EnergyPlus/api/TestDataTransfer.c | 7 ++++++- 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/EnergyPlus/api/datatransfer.cc b/src/EnergyPlus/api/datatransfer.cc index fd8a303e07d..fa6d83bdad3 100644 --- a/src/EnergyPlus/api/datatransfer.cc +++ b/src/EnergyPlus/api/datatransfer.cc @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -239,6 +240,14 @@ void resetErrorFlag(EnergyPlusState state) thisState->dataPluginManager->apiErrorFlag = false; } +char *inputFilePath(EnergyPlusState state) +{ + const auto *thisState = static_cast(state); + char *p = new char[std::strlen(thisState->dataStrGlobals->inputFilePath.c_str()) + 1]; + std::strcpy(p, thisState->dataStrGlobals->inputFilePath.c_str()); + return p; +} + char **getObjectNames(EnergyPlusState state, const char *objectType, unsigned int *resultingSize) { const auto *thisState = static_cast(state); diff --git a/src/EnergyPlus/api/datatransfer.h b/src/EnergyPlus/api/datatransfer.h index 11bee4ce75b..6ab69306286 100644 --- a/src/EnergyPlus/api/datatransfer.h +++ b/src/EnergyPlus/api/datatransfer.h @@ -121,6 +121,12 @@ ENERGYPLUSLIB_API int apiErrorFlag(EnergyPlusState state); /// a calculation to continue, this function can reset the flag. /// \param[in] state An active EnergyPlusState instance created with `stateNew`. ENERGYPLUSLIB_API void resetErrorFlag(EnergyPlusState state); +/// \brief Provides the input file path back to the user +/// \details In most circumstances the client will know the path to the input file, but there are some cases where code +/// is generalized in unexpected workflows. Users have requested a way to get the input file path back from the running instance. +/// \param[in] state An active EnergyPlusState instance created with `stateNew`. +/// \return A char * of the input file path. This allocates a new char *, and calling clients must free this when done with it! +ENERGYPLUSLIB_API char *inputFilePath(EnergyPlusState state); // ----- DATA TRANSFER HELPER FUNCTIONS diff --git a/src/EnergyPlus/api/datatransfer.py b/src/EnergyPlus/api/datatransfer.py index bee6023f1f9..312da6c0a3b 100644 --- a/src/EnergyPlus/api/datatransfer.py +++ b/src/EnergyPlus/api/datatransfer.py @@ -139,6 +139,8 @@ def __init__(self, api: cdll, running_as_python_plugin: bool = False): self.api.apiErrorFlag.restype = c_int self.api.resetErrorFlag.argtypes = [c_void_p] self.api.resetErrorFlag.restype = c_void_p + self.api.inputFilePath.argtypes = [c_void_p] + self.api.inputFilePath.restype = c_char_p self.api.requestVariable.argtypes = [c_void_p, c_char_p, c_char_p] self.api.getNumNodesInCondFDSurfaceLayer.argtypes = [c_void_p, c_char_p, c_char_p] self.api.requestVariable.restype = c_void_p @@ -359,6 +361,17 @@ def reset_api_error_flag(self, state: c_void_p) -> None: """ self.api.resetErrorFlag(state) + def get_input_file_path(self, state: c_void_p) -> bytes: + """ + Provides the input file path back to the client. In most circumstances the client will know the path to the + input file, but there are some cases where code is generalized in unexpected workflows. Users have requested + a way to get the input file path back from the running instance. + + :param state: An active EnergyPlus "state" that is returned from a call to `api.state_manager.new_state()`. + :return: Returns a raw bytes representation of the input file path + """ + return self.api.inputFilePath(state) + def get_object_names(self, state: c_void_p, object_type_name: Union[str, bytes]) -> List[str]: """ Gets the instance names for a given object type in the current input file diff --git a/tst/EnergyPlus/api/TestDataTransfer.c b/tst/EnergyPlus/api/TestDataTransfer.c index 3980ba06440..ccd767010b0 100644 --- a/tst/EnergyPlus/api/TestDataTransfer.c +++ b/tst/EnergyPlus/api/TestDataTransfer.c @@ -95,7 +95,7 @@ void afterZoneTimeStepHandler(EnergyPlusState state) freeAPIData(data, arraySize); freeObjectNames(surfaceNames, arraySize); - printf("Got handles %d, %d, %d, %d, %d, %d", + printf("Got handles %d, %d, %d, %d, %d, %d\n", outdoorDewPointActuator, outdoorTempSensor, outdoorDewPointSensor, @@ -106,6 +106,11 @@ void afterZoneTimeStepHandler(EnergyPlusState state) wallConstruction == -1 || floorConstruction == -1) { exit(1); } + + char * filePath = inputFilePath(state); + printf("Input file path accessed via API: %s\n", filePath); + free(filePath); + handlesRetrieved = 1; } setActuatorValue(state, outdoorDewPointActuator, -25.0); From cf3b3c52b2b7bd228a0dd41a52ed8a27d29056ca Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Mon, 22 Jul 2024 16:30:35 -0700 Subject: [PATCH 48/81] transition testfiles to use Fan:SystemModel --- ...riableRefrigerantFlow_FluidTCtrl_5Zone.idf | 235 ++++++++++++------ ...bleRefrigerantFlow_FluidTCtrl_HR_5Zone.idf | 235 ++++++++++++------ ...erantFlow_FluidTCtrl_wSuppHeater_5Zone.idf | 235 ++++++++++++------ 3 files changed, 480 insertions(+), 225 deletions(-) diff --git a/testfiles/VariableRefrigerantFlow_FluidTCtrl_5Zone.idf b/testfiles/VariableRefrigerantFlow_FluidTCtrl_5Zone.idf index d766ef40844..877b1e884fa 100644 --- a/testfiles/VariableRefrigerantFlow_FluidTCtrl_5Zone.idf +++ b/testfiles/VariableRefrigerantFlow_FluidTCtrl_5Zone.idf @@ -320,7 +320,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU1 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU1 OA Mixer, !- Outside Air Mixer Object Name @@ -351,7 +351,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU2 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU2 OA Mixer, !- Outside Air Mixer Object Name @@ -382,7 +382,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU3 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU3 OA Mixer, !- Outside Air Mixer Object Name @@ -413,7 +413,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU4 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU4 OA Mixer, !- Outside Air Mixer Object Name @@ -444,7 +444,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU5 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU5 OA Mixer, !- Outside Air Mixer Object Name @@ -505,106 +505,191 @@ Relief Air Outlet Node 5,!- Relief Air Stream Node Name TU5 Inlet Node; !- Return Air Stream Node Name - Fan:VariableVolume, + Fan:SystemModel, TU1 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU1 Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU1 VRF Supply 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 General; !- End-Use Subcategory - Fan:VariableVolume, + Curve:Quartic, + TU1 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + + Fan:SystemModel, TU2 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU2 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU2 Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU2 VRF Supply 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 General; !- End-Use Subcategory - Fan:VariableVolume, + Curve:Quartic, + TU2 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + + Fan:SystemModel, TU3 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU3 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU3 Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU3 VRF Supply 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 General; !- End-Use Subcategory - Fan:VariableVolume, + Curve:Quartic, + TU3 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + + Fan:SystemModel, TU4 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU4 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU4 Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU4 VRF Supply 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 General; !- End-Use Subcategory - Fan:VariableVolume, + Curve:Quartic, + TU4 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + + Fan:SystemModel, TU5 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU5 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU5 Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU5 VRF Supply 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 General; !- End-Use Subcategory + Curve:Quartic, + TU5 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + !- =========== ALL OBJECTS IN CLASS: COIL:COOLING:DX:VARIABLEREFRIGERANTFLOW:FLUIDTEMPERATURECONTROL =========== Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, diff --git a/testfiles/VariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf b/testfiles/VariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf index 31458c8e19f..423639c97d9 100644 --- a/testfiles/VariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf +++ b/testfiles/VariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf @@ -339,7 +339,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU1 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU1 OA Mixer, !- Outside Air Mixer Object Name @@ -370,7 +370,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU2 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU2 OA Mixer, !- Outside Air Mixer Object Name @@ -401,7 +401,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU3 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU3 OA Mixer, !- Outside Air Mixer Object Name @@ -432,7 +432,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU4 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU4 OA Mixer, !- Outside Air Mixer Object Name @@ -463,7 +463,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU5 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU5 OA Mixer, !- Outside Air Mixer Object Name @@ -524,106 +524,191 @@ Relief Air Outlet Node 5,!- Relief Air Stream Node Name TU5 Inlet Node; !- Return Air Stream Node Name - Fan:VariableVolume, + Fan:SystemModel, TU1 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU1 Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU1 VRF Supply 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 General; !- End-Use Subcategory - Fan:VariableVolume, + Curve:Quartic, + TU1 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + + Fan:SystemModel, TU2 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU2 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU2 Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU2 VRF Supply 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 General; !- End-Use Subcategory - Fan:VariableVolume, + Curve:Quartic, + TU2 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + + Fan:SystemModel, TU3 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU3 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU3 Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU3 VRF Supply 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 General; !- End-Use Subcategory - Fan:VariableVolume, + Curve:Quartic, + TU3 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + + Fan:SystemModel, TU4 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU4 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU4 Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU4 VRF Supply 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 General; !- End-Use Subcategory - Fan:VariableVolume, + Curve:Quartic, + TU4 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + + Fan:SystemModel, TU5 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU5 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU5 Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU5 VRF Supply 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 General; !- End-Use Subcategory + Curve:Quartic, + TU5 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + !- =========== ALL OBJECTS IN CLASS: COIL:COOLING:DX:VARIABLEREFRIGERANTFLOW:FLUIDTEMPERATURECONTROL =========== Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, diff --git a/testfiles/VariableRefrigerantFlow_FluidTCtrl_wSuppHeater_5Zone.idf b/testfiles/VariableRefrigerantFlow_FluidTCtrl_wSuppHeater_5Zone.idf index d5a19ad2e8d..611e87422c2 100644 --- a/testfiles/VariableRefrigerantFlow_FluidTCtrl_wSuppHeater_5Zone.idf +++ b/testfiles/VariableRefrigerantFlow_FluidTCtrl_wSuppHeater_5Zone.idf @@ -2207,7 +2207,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU1 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU1 OA Mixer, !- Outside Air Mixer Object Name @@ -2238,7 +2238,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU2 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU2 OA Mixer, !- Outside Air Mixer Object Name @@ -2269,7 +2269,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU3 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU3 OA Mixer, !- Outside Air Mixer Object Name @@ -2300,7 +2300,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU4 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU4 OA Mixer, !- Outside Air Mixer Object Name @@ -2331,7 +2331,7 @@ autosize, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:VariableVolume, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU5 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU5 OA Mixer, !- Outside Air Mixer Object Name @@ -2444,106 +2444,191 @@ !- =========== ALL OBJECTS IN CLASS: FAN:VARIABLEVOLUME =========== - Fan:VariableVolume, + Fan:SystemModel, TU1 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU1 VRF Fan Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU1 VRF Supply 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 General; !- End-Use Subcategory - Fan:VariableVolume, + Curve:Quartic, + TU1 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + + Fan:SystemModel, TU2 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU2 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU2 VRF Fan Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU2 VRF Supply 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 General; !- End-Use Subcategory - Fan:VariableVolume, + Curve:Quartic, + TU2 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + + Fan:SystemModel, TU3 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU3 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU3 VRF Fan Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU3 VRF Supply 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 General; !- End-Use Subcategory - Fan:VariableVolume, + Curve:Quartic, + TU3 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + + Fan:SystemModel, TU4 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU4 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU4 VRF Fan Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU4 VRF Supply 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 General; !- End-Use Subcategory - Fan:VariableVolume, + Curve:Quartic, + TU4 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + + Fan:SystemModel, TU5 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name - 0.7, !- Fan Total Efficiency - 600, !- Pressure Rise {Pa} - autosize, !- Maximum Flow Rate {m3/s} - Fraction, !- Fan Power Minimum Flow Rate Input Method - 0, !- Fan Power Minimum Flow Fraction - 0, !- Fan Power Minimum Air Flow Rate {m3/s} - 0.9, !- Motor Efficiency - 1, !- Motor In Airstream Fraction - 0.059, !- Fan Power Coefficient 1 - 0, !- Fan Power Coefficient 2 - 0, !- Fan Power Coefficient 3 - 0.928, !- Fan Power Coefficient 4 - 0, !- Fan Power Coefficient 5 TU5 VRF DX HCoil Outlet Node, !- Air Inlet Node Name TU5 VRF Fan Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU5 VRF Supply 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 General; !- End-Use Subcategory + Curve:Quartic, + TU5 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + !- =========== ALL OBJECTS IN CLASS: COIL:COOLING:DX:VARIABLEREFRIGERANTFLOW:FLUIDTEMPERATURECONTROL =========== Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, From 7dd6720cd02f6a8dd88c27f5f9113a74f84eb3df Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Tue, 23 Jul 2024 08:27:51 -0700 Subject: [PATCH 49/81] change all-upper case to pascal-case --- src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 index 9a8a0a90218..59fbe7b5d11 100644 --- a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 +++ b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 @@ -578,14 +578,14 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile OutArgs(1:13) = InArgs(1:13) IF (SameString(InArgs(14), 'FAN:VARIABLEVOLUME')) THEN isVariableVolume = .TRUE. - OutArgs(14) = 'FAN:SYSTEMMODEL' + OutArgs(14) = 'Fan:SystemModel' OutArgs(15) = TRIM(InArgs(15)) sysFanName = TRIM(InArgs(15)) ELSE OutArgs(14:15) = InArgs(14:15) ENDIF OutArgs(16:CurArgs) = InArgs(16:CurArgs) - CALL WriteOutIDFLines(DifLfn, 'ZONEHVAC:TERMINALUNIT:VARIABLEREFRIGERANTFLOW', CurArgs, OutArgs, NwFldNames, NwFldUnits) + CALL WriteOutIDFLines(DifLfn, 'ZoneHVAC:TerminalUnit:VariableRefrigerantFlow', CurArgs, OutArgs, NwFldNames, NwFldUnits) IF (isVariableVolume) THEN ! create fan system model object From 9cfd98853b4581ace4c67fdbf88d9078f72fbda6 Mon Sep 17 00:00:00 2001 From: Edwin Lee Date: Tue, 23 Jul 2024 15:33:05 -0500 Subject: [PATCH 50/81] Use fs::path::string method to get windows compiling --- src/EnergyPlus/api/datatransfer.cc | 2 +- tst/EnergyPlus/api/TestDataTransfer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EnergyPlus/api/datatransfer.cc b/src/EnergyPlus/api/datatransfer.cc index fa6d83bdad3..ff98d413d0e 100644 --- a/src/EnergyPlus/api/datatransfer.cc +++ b/src/EnergyPlus/api/datatransfer.cc @@ -243,7 +243,7 @@ void resetErrorFlag(EnergyPlusState state) char *inputFilePath(EnergyPlusState state) { const auto *thisState = static_cast(state); - char *p = new char[std::strlen(thisState->dataStrGlobals->inputFilePath.c_str()) + 1]; + char *p = new char[std::strlen(thisState->dataStrGlobals->inputFilePath.string().c_str()) + 1]; std::strcpy(p, thisState->dataStrGlobals->inputFilePath.c_str()); return p; } diff --git a/tst/EnergyPlus/api/TestDataTransfer.c b/tst/EnergyPlus/api/TestDataTransfer.c index ccd767010b0..5544756772d 100644 --- a/tst/EnergyPlus/api/TestDataTransfer.c +++ b/tst/EnergyPlus/api/TestDataTransfer.c @@ -107,7 +107,7 @@ void afterZoneTimeStepHandler(EnergyPlusState state) exit(1); } - char * filePath = inputFilePath(state); + char *filePath = inputFilePath(state); printf("Input file path accessed via API: %s\n", filePath); free(filePath); From 125f244fa66e4e1b8424a9885afd0407de341d80 Mon Sep 17 00:00:00 2001 From: Edwin Lee Date: Wed, 24 Jul 2024 08:18:02 -0500 Subject: [PATCH 51/81] Add string() method on fs::path, location 2 --- src/EnergyPlus/api/datatransfer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EnergyPlus/api/datatransfer.cc b/src/EnergyPlus/api/datatransfer.cc index ff98d413d0e..066e0ccfb6e 100644 --- a/src/EnergyPlus/api/datatransfer.cc +++ b/src/EnergyPlus/api/datatransfer.cc @@ -244,7 +244,7 @@ char *inputFilePath(EnergyPlusState state) { const auto *thisState = static_cast(state); char *p = new char[std::strlen(thisState->dataStrGlobals->inputFilePath.string().c_str()) + 1]; - std::strcpy(p, thisState->dataStrGlobals->inputFilePath.c_str()); + std::strcpy(p, thisState->dataStrGlobals->inputFilePath.string().c_str()); return p; } From 19c4aae751f39f0c8428d9fc0b62ad20edce5de3 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 24 Jul 2024 14:29:45 -0700 Subject: [PATCH 52/81] fix unit test Fan:VariableVolume to Fan:SystemModel transition --- .../unit/AirTerminalSingleDuctMixer.unit.cc | 102 ++++-- .../unit/HVACVariableRefrigerantFlow.unit.cc | 317 +++++++++++------- 2 files changed, 268 insertions(+), 151 deletions(-) diff --git a/tst/EnergyPlus/unit/AirTerminalSingleDuctMixer.unit.cc b/tst/EnergyPlus/unit/AirTerminalSingleDuctMixer.unit.cc index 6fb85c4a598..752ccc73f3b 100644 --- a/tst/EnergyPlus/unit/AirTerminalSingleDuctMixer.unit.cc +++ b/tst/EnergyPlus/unit/AirTerminalSingleDuctMixer.unit.cc @@ -3405,7 +3405,7 @@ TEST_F(EnergyPlusFixture, AirTerminalSingleDuctMixer_SimVRFfluidCntrl_ATMInletSi " 0, !- Outdoor Air Flow Rate When No Cooling or Heating is Needed {m3/s}", " VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name", " drawthrough, !- Supply Air Fan Placement", - " Fan:VariableVolume, !- Supply Air Fan Object Type", + " Fan:SystemModel, !- Supply Air Fan Object Type", " TU1 VRF Supply Fan, !- Supply Air Fan Object Name", " , !- Outside Air Mixer Object Type", " , !- Outside Air Mixer Object Name", @@ -3416,26 +3416,43 @@ TEST_F(EnergyPlusFixture, AirTerminalSingleDuctMixer_SimVRFfluidCntrl_ATMInletSi " 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W}", " 20; !- Zone Terminal Unit Off Parasitic Electric Energy Use {W}", - " Fan:VariableVolume,", + " Fan:SystemModel,", " TU1 VRF Supply Fan, !- Name", " VRFAvailSched, !- Availability Schedule Name", - " 0.7, !- Fan Total Efficiency", - " 600, !- Pressure Rise {Pa}", - " 0.500, !- Maximum Flow Rate {m3/s}", - " Fraction, !- Fan Power Minimum Flow Rate Input Method", - " 0, !- Fan Power Minimum Flow Fraction", - " 0, !- Fan Power Minimum Air Flow Rate {m3/s}", - " 0.9, !- Motor Efficiency", - " 1, !- Motor In Airstream Fraction", - " 0.059, !- Fan Power Coefficient 1", - " 0, !- Fan Power Coefficient 2", - " 0, !- Fan Power Coefficient 3", - " 0.928, !- Fan Power Coefficient 4", - " 0, !- Fan Power Coefficient 5", " TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name", " TU1 Outlet Node, !- Air Outlet Node Name", + " 0.500, !- Design Maximum Air Flow Rate {m3/s}", + " Continuous, !- Speed Control Method", + " 0.0, !- Electric Power Minimum Flow Rate Fraction", + " 600, !- 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", + " TU1 Fan Power Curve, !- Electric Power Function of Flow Fraction Curve Name", + " ,", + " ,", + " ,", + " ,", " General; !- End-Use Subcategory", + " Curve:Quartic,", + " TU1 Fan Power Curve , !- Name", + " 0.059, !- Coefficient1 Constant", + " 0, !- Coefficient2 x ", + " 0, !- Coefficient3 x**2 ", + " 0.928, !- Coefficient4 x**3 ", + " 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", + " Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl,", " TU1 VRF DX Heating Coil, !- Name", " VRFAvailSched, !- Availability Schedule", @@ -5063,6 +5080,8 @@ TEST_F(EnergyPlusFixture, AirTerminalSingleDuctMixer_SimVRFfluidCntrl_ATMInletSi // set secondary air mass flow rate to zero state->dataLoopNodes->Node(state->dataSingleDuct->SysATMixer(1).SecInNode).MassFlowRate = 0.0; + state->dataFans->fans(1)->set_size(*state); // add sizing + state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio = 1.0; // Simulate zoneHVAC equipment (VRF terminal unit) SimVRF(*state, VRFTUNum, FirstHVACIteration, OnOffAirFlowRatio, QUnitOutVRFTU, LatOutputProvided, QZnReq); @@ -5164,7 +5183,7 @@ TEST_F(EnergyPlusFixture, AirTerminalSingleDuctMixer_SimVRFfluidCntrl_ATMSupplyS " 0, !- Outdoor Air Flow Rate When No Cooling or Heating is Needed {m3/s}", " VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name", " drawthrough, !- Supply Air Fan Placement", - " Fan:VariableVolume, !- Supply Air Fan Object Type", + " Fan:SystemModel, !- Supply Air Fan Object Type", " TU1 VRF Supply Fan, !- Supply Air Fan Object Name", " , !- Outside Air Mixer Object Type", " , !- Outside Air Mixer Object Name", @@ -5175,26 +5194,43 @@ TEST_F(EnergyPlusFixture, AirTerminalSingleDuctMixer_SimVRFfluidCntrl_ATMSupplyS " 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W}", " 20; !- Zone Terminal Unit Off Parasitic Electric Energy Use {W}", - " Fan:VariableVolume,", + " Fan:SystemModel,", " TU1 VRF Supply Fan, !- Name", " VRFAvailSched, !- Availability Schedule Name", - " 0.7, !- Fan Total Efficiency", - " 600, !- Pressure Rise {Pa}", - " 0.500, !- Maximum Flow Rate {m3/s}", - " Fraction, !- Fan Power Minimum Flow Rate Input Method", - " 0, !- Fan Power Minimum Flow Fraction", - " 0, !- Fan Power Minimum Air Flow Rate {m3/s}", - " 0.9, !- Motor Efficiency", - " 1, !- Motor In Airstream Fraction", - " 0.059, !- Fan Power Coefficient 1", - " 0, !- Fan Power Coefficient 2", - " 0, !- Fan Power Coefficient 3", - " 0.928, !- Fan Power Coefficient 4", - " 0, !- Fan Power Coefficient 5", " TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name", " SPACE1-1 AIR TERMINAL MIXER SECONDARY INLET, !- Air Outlet Node Name", + " 0.500, !- Design Maximum Air Flow Rate {m3/s}", + " Continuous, !- Speed Control Method", + " 0.0, !- Electric Power Minimum Flow Rate Fraction", + " 600, !- 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", + " TU1 Fan Power Curve, !- Electric Power Function of Flow Fraction Curve Name", + " ,", + " ,", + " ,", + " ,", " General; !- End-Use Subcategory", + " Curve:Quartic,", + " TU1 Fan Power Curve , !- Name", + " 0.059, !- Coefficient1 Constant", + " 0, !- Coefficient2 x ", + " 0, !- Coefficient3 x**2 ", + " 0.928, !- Coefficient4 x**3 ", + " 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", + " Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl,", " TU1 VRF DX Heating Coil, !- Name", " VRFAvailSched, !- Availability Schedule", @@ -6817,6 +6853,8 @@ TEST_F(EnergyPlusFixture, AirTerminalSingleDuctMixer_SimVRFfluidCntrl_ATMSupplyS state->dataScheduleMgr->Schedule(state->dataHVACVarRefFlow->VRFTU(VRFTUNum).SchedPtr).CurrentValue = 1.0; // unit is always available state->dataScheduleMgr->Schedule(state->dataHVACVarRefFlow->VRFTU(VRFTUNum).FanAvailSchedPtr).CurrentValue = 1.0; // fan is always available + state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio = 1.0; + state->dataFans->fans(1)->set_size(*state); // add fan sizing // set secondary air mass flow rate to zero state->dataLoopNodes->Node(state->dataSingleDuct->SysATMixer(1).SecInNode).MassFlowRate = 0.0; @@ -6829,8 +6867,8 @@ TEST_F(EnergyPlusFixture, AirTerminalSingleDuctMixer_SimVRFfluidCntrl_ATMSupplyS // check the terminal air mixer outlet flow rate must be equal to the mass flow rate of VRFTU + the primary air ATMixerOutletMassFlowRate = SecondaryAirMassFlowRate + PrimaryAirMassFlowRate; ASSERT_EQ(ATMixerOutletMassFlowRate, state->dataSingleDuct->SysATMixer(1).MixedAirMassFlowRate); - // check the cooling output delivered is within 2.0 Watt of zone cooling load - ASSERT_NEAR(QZnReq, QUnitOutVRFTU, 2.0); + // changed the threshold from 2 to 3 as the fan was changed from hard-sized to autosize, a little more error is expected + ASSERT_NEAR(QZnReq, QUnitOutVRFTU, 3.0); } TEST_F(EnergyPlusFixture, AirTerminalSingleDuctMixer_SimUnitVent_ATMInletSide) diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index b392f7abf46..5e04826e9a2 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -11785,7 +11785,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_ReportOutputVerificationTest) " 0, !- Outdoor Air Flow Rate When No Cooling or Heating is Needed {m3/s}", " VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name", " drawthrough, !- Supply Air Fan Placement", - " Fan:VariableVolume, !- Supply Air Fan Object Type", + " Fan:SystemModel, !- Supply Air Fan Object Type", " TU1 VRF Supply Fan, !- Supply Air Fan Object Name", " , !- Outside Air Mixer Object Type", " , !- Outside Air Mixer Object Name", @@ -11857,26 +11857,43 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_ReportOutputVerificationTest) " Temperature, !- Input Unit Type for X", " Temperature; !- Output Unit Type", - " Fan:VariableVolume,", + " Fan:SystemModel,", " TU1 VRF Supply Fan, !- Name", " VRFAvailSched, !- Availability Schedule Name", - " 0.7, !- Fan Total Efficiency", - " 600, !- Pressure Rise {Pa}", - " autosize, !- Maximum Flow Rate {m3/s}", - " Fraction, !- Fan Power Minimum Flow Rate Input Method", - " 0, !- Fan Power Minimum Flow Fraction", - " 0, !- Fan Power Minimum Air Flow Rate {m3/s}", - " 0.9, !- Motor Efficiency", - " 1, !- Motor In Airstream Fraction", - " 0.059, !- Fan Power Coefficient 1", - " 0, !- Fan Power Coefficient 2", - " 0, !- Fan Power Coefficient 3", - " 0.928, !- Fan Power Coefficient 4", - " 0, !- Fan Power Coefficient 5", " TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name", " TU1 Outlet Node, !- Air Outlet Node Name", + " autosize, !- Design Maximum Air Flow Rate {m3/s}", + " Continuous, !- Speed Control Method", + " 0.0, !- Electric Power Minimum Flow Rate Fraction", + " 600, !- 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", + " TU1 Fan Power Curve, !- Electric Power Function of Flow Fraction Curve Name", + " ,", + " ,", + " ,", + " ,", " General; !- End-Use Subcategory", + " Curve:Quartic,", + " TU1 Fan Power Curve , !- Name", + " 0.059, !- Coefficient1 Constant", + " 0, !- Coefficient2 x ", + " 0, !- Coefficient3 x**2 ", + " 0.928, !- Coefficient4 x**3 ", + " 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", + " !- =========== ALL OBJECTS IN CLASS: FLUIDPROPERTIES:NAME =========== ", " ", " FluidProperties:Name, ", @@ -16302,7 +16319,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_SupplementalHtgCoilTest) " 0, !- No Load Outdoor Air Flow Rate {m3/s}", " VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name", " drawthrough, !- Supply Air Fan Placement", - " Fan:VariableVolume, !- Supply Air Fan Object Type", + " Fan:SystemModel, !- Supply Air Fan Object Type", " TU1 VRF Supply Fan, !- Supply Air Fan Object Name", " OutdoorAir:Mixer, !- Outside Air Mixer Object Type", " TU1 OA Mixer, !- Outside Air Mixer Object Name", @@ -16333,7 +16350,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_SupplementalHtgCoilTest) " 0, !- No Load Outdoor Air Flow Rate {m3/s}", " VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name", " drawthrough, !- Supply Air Fan Placement", - " Fan:VariableVolume, !- Supply Air Fan Object Type", + " Fan:SystemModel, !- Supply Air Fan Object Type", " TU2 VRF Supply Fan, !- Supply Air Fan Object Name", " OutdoorAir:Mixer, !- Outside Air Mixer Object Type", " TU2 OA Mixer, !- Outside Air Mixer Object Name", @@ -16386,44 +16403,64 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_SupplementalHtgCoilTest) " SPACE2-1 Node, !- Zone Air Node Name", " SPACE2-1 Out Node; !- Zone Return Air Node or NodeList Name", - "Fan:VariableVolume,", + " Fan:SystemModel,", " TU1 VRF Supply Fan, !- Name", " VRFAvailSched, !- Availability Schedule Name", - " 0.7, !- Fan Total Efficiency", - " 600, !- Pressure Rise {Pa}", - " autosize, !- Maximum Flow Rate {m3/s}", - " Fraction, !- Fan Power Minimum Flow Rate Input Method", - " 0, !- Fan Power Minimum Flow Fraction", - " 0, !- Fan Power Minimum Air Flow Rate {m3/s}", - " 0.9, !- Motor Efficiency", - " 1, !- Motor In Airstream Fraction", - " 0.059, !- Fan Power Coefficient 1", - " 0, !- Fan Power Coefficient 2", - " 0, !- Fan Power Coefficient 3", - " 0.928, !- Fan Power Coefficient 4", - " 0, !- Fan Power Coefficient 5", " TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name", - " TU1 VRF Fan Outlet Node, !- Air Outlet Node Name", + " TU1 VRF Fan Outlet Node, !- Air Outlet Node Name", + " autosize, !- Design Maximum Air Flow Rate {m3/s}", + " Continuous, !- Speed Control Method", + " 0.0, !- Electric Power Minimum Flow Rate Fraction", + " 600, !- 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", + " TU Fan Power Curve, !- Electric Power Function of Flow Fraction Curve Name", + " ,", + " ,", + " ,", + " ,", " General; !- End-Use Subcategory", - "Fan:VariableVolume,", + " Curve:Quartic,", + " TU Fan Power Curve , !- Name", + " 0.059, !- Coefficient1 Constant", + " 0, !- Coefficient2 x ", + " 0, !- Coefficient3 x**2 ", + " 0.928, !- Coefficient4 x**3 ", + " 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", + + " Fan:SystemModel,", " TU2 VRF Supply Fan, !- Name", " VRFAvailSched, !- Availability Schedule Name", - " 0.7, !- Fan Total Efficiency", - " 600, !- Pressure Rise {Pa}", - " autosize, !- Maximum Flow Rate {m3/s}", - " Fraction, !- Fan Power Minimum Flow Rate Input Method", - " 0, !- Fan Power Minimum Flow Fraction", - " 0, !- Fan Power Minimum Air Flow Rate {m3/s}", - " 0.9, !- Motor Efficiency", - " 1, !- Motor In Airstream Fraction", - " 0.059, !- Fan Power Coefficient 1", - " 0, !- Fan Power Coefficient 2", - " 0, !- Fan Power Coefficient 3", - " 0.928, !- Fan Power Coefficient 4", - " 0, !- Fan Power Coefficient 5", " TU2 VRF DX HCoil Outlet Node, !- Air Inlet Node Name", - " TU2 VRF Fan Outlet Node, !- Air Outlet Node Name", + " TU2 VRF Fan Outlet Node, !- Air Outlet Node Name", + " autosize, !- Design Maximum Air Flow Rate {m3/s}", + " Continuous, !- Speed Control Method", + " 0.0, !- Electric Power Minimum Flow Rate Fraction", + " 600, !- 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", + " TU Fan Power Curve, !- Electric Power Function of Flow Fraction Curve Name", + " ,", + " ,", + " ,", + " ,", " General; !- End-Use Subcategory", "Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl,", @@ -18263,6 +18300,8 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_SupplementalHtgCoilTest) state->dataHVACVarRefFlow->HeatingLoad(VRFCond) = false; state->dataHVACVarRefFlow->TerminalUnitList(1).IsSimulated = true; + state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio = 1.0; + QZnReq = state->dataZoneEnergyDemand->ZoneSysEnergyDemand(zone_num_TU1).RemainingOutputRequired; SimVRF(*state, VRFTUNum, FirstHVACIteration, OnOffAirFlowRatio, SysOutputProvided, LatOutputProvided, QZnReq); ReportVRFTerminalUnit(*state, VRFTUNum); @@ -18415,7 +18454,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_offSupplementalHtgCoilTest) " 0, !- No Load Outdoor Air Flow Rate {m3/s}", " VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name", " drawthrough, !- Supply Air Fan Placement", - " Fan:VariableVolume, !- Supply Air Fan Object Type", + " Fan:SystemModel, !- Supply Air Fan Object Type", " TU1 VRF Supply Fan, !- Supply Air Fan Object Name", " OutdoorAir:Mixer, !- Outside Air Mixer Object Type", " TU1 OA Mixer, !- Outside Air Mixer Object Name", @@ -18446,7 +18485,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_offSupplementalHtgCoilTest) " 0, !- No Load Outdoor Air Flow Rate {m3/s}", " VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name", " drawthrough, !- Supply Air Fan Placement", - " Fan:VariableVolume, !- Supply Air Fan Object Type", + " Fan:SystemModel, !- Supply Air Fan Object Type", " TU2 VRF Supply Fan, !- Supply Air Fan Object Name", " OutdoorAir:Mixer, !- Outside Air Mixer Object Type", " TU2 OA Mixer, !- Outside Air Mixer Object Name", @@ -18499,44 +18538,64 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_offSupplementalHtgCoilTest) " SPACE2-1 Node, !- Zone Air Node Name", " SPACE2-1 Out Node; !- Zone Return Air Node or NodeList Name", - "Fan:VariableVolume,", + " Fan:SystemModel,", " TU1 VRF Supply Fan, !- Name", " VRFAvailSched, !- Availability Schedule Name", - " 0.7, !- Fan Total Efficiency", - " 600, !- Pressure Rise {Pa}", - " autosize, !- Maximum Flow Rate {m3/s}", - " Fraction, !- Fan Power Minimum Flow Rate Input Method", - " 0, !- Fan Power Minimum Flow Fraction", - " 0, !- Fan Power Minimum Air Flow Rate {m3/s}", - " 0.9, !- Motor Efficiency", - " 1, !- Motor In Airstream Fraction", - " 0.059, !- Fan Power Coefficient 1", - " 0, !- Fan Power Coefficient 2", - " 0, !- Fan Power Coefficient 3", - " 0.928, !- Fan Power Coefficient 4", - " 0, !- Fan Power Coefficient 5", " TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name", - " TU1 VRF Fan Outlet Node, !- Air Outlet Node Name", + " TU1 VRF Fan Outlet Node, !- Air Outlet Node Name", + " autosize, !- Design Maximum Air Flow Rate {m3/s}", + " Continuous, !- Speed Control Method", + " 0.0, !- Electric Power Minimum Flow Rate Fraction", + " 600, !- 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", + " TU Fan Power Curve, !- Electric Power Function of Flow Fraction Curve Name", + " ,", + " ,", + " ,", + " ,", " General; !- End-Use Subcategory", - "Fan:VariableVolume,", + " Curve:Quartic,", + " TU Fan Power Curve , !- Name", + " 0.059, !- Coefficient1 Constant", + " 0, !- Coefficient2 x ", + " 0, !- Coefficient3 x**2 ", + " 0.928, !- Coefficient4 x**3 ", + " 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", + + " Fan:SystemModel,", " TU2 VRF Supply Fan, !- Name", " VRFAvailSched, !- Availability Schedule Name", - " 0.7, !- Fan Total Efficiency", - " 600, !- Pressure Rise {Pa}", - " autosize, !- Maximum Flow Rate {m3/s}", - " Fraction, !- Fan Power Minimum Flow Rate Input Method", - " 0, !- Fan Power Minimum Flow Fraction", - " 0, !- Fan Power Minimum Air Flow Rate {m3/s}", - " 0.9, !- Motor Efficiency", - " 1, !- Motor In Airstream Fraction", - " 0.059, !- Fan Power Coefficient 1", - " 0, !- Fan Power Coefficient 2", - " 0, !- Fan Power Coefficient 3", - " 0.928, !- Fan Power Coefficient 4", - " 0, !- Fan Power Coefficient 5", " TU2 VRF DX HCoil Outlet Node, !- Air Inlet Node Name", - " TU2 VRF Fan Outlet Node, !- Air Outlet Node Name", + " TU2 VRF Fan Outlet Node, !- Air Outlet Node Name", + " autosize, !- Design Maximum Air Flow Rate {m3/s}", + " Continuous, !- Speed Control Method", + " 0.0, !- Electric Power Minimum Flow Rate Fraction", + " 600, !- 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", + " TU Fan Power Curve, !- Electric Power Function of Flow Fraction Curve Name", + " ,", + " ,", + " ,", + " ,", " General; !- End-Use Subcategory", "Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl,", @@ -20524,7 +20583,7 @@ TEST_F(EnergyPlusFixture, VRF_MixedTypes) " 0, !- Outdoor Air Flow Rate When No Cooling or Heating is Needed {m3/s}", " VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name", " drawthrough, !- Supply Air Fan Placement", - " Fan:VariableVolume, !- Supply Air Fan Object Type", + " Fan:SystemModel, !- Supply Air Fan Object Type", " TU1 VRF Supply Fan, !- Supply Air Fan Object Name", " , !- Outside Air Mixer Object Type", " , !- Outside Air Mixer Object Name", @@ -20556,25 +20615,28 @@ TEST_F(EnergyPlusFixture, VRF_MixedTypes) " IUCondTempCurve; !- Indoor Unit Condensing Temperature Function of Subcooling Curve Name", "", "", - "Fan:VariableVolume,", - " TU1 VRF Supply Fan, !- Name", - " VRFAvailSched, !- Availability Schedule Name", - " 0.7, !- Fan Total Efficiency", - " 600, !- Pressure Rise {Pa}", - " autosize, !- Maximum Flow Rate {m3/s}", - " Fraction, !- Fan Power Minimum Flow Rate Input Method", - " 0, !- Fan Power Minimum Flow Fraction", - " 0, !- Fan Power Minimum Air Flow Rate {m3/s}", - " 0.9, !- Motor Efficiency", - " 1, !- Motor In Airstream Fraction", - " 0.059, !- Fan Power Coefficient 1", - " 0, !- Fan Power Coefficient 2", - " 0, !- Fan Power Coefficient 3", - " 0.928, !- Fan Power Coefficient 4", - " 0, !- Fan Power Coefficient 5", - " TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name", - " TU1 Outlet Node, !- Air Outlet Node Name", - " General; !- End-Use Subcategory", + " Fan:SystemModel,", + " TU1 VRF Supply Fan, !- Name", + " VRFAvailSched, !- Availability Schedule Name", + " TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name", + " TU1 Outlet Node, !- Air Outlet Node Name", + " autosize, !- Design Maximum Air Flow Rate {m3/s}", + " Continuous, !- Speed Control Method", + " 0.0, !- Electric Power Minimum Flow Rate Fraction", + " 600, !- Design Pressure Rise {Pa}", + " 0.9, !- Motor Efficiency", + " 1.0, !- Motor In Air Stream Fraction", + " autosize, !- Design Electric Power Consumption {W}", + " , !- 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", + " TU Fan Power Curve, !- Electric Power Function of Flow Fraction Curve Name", + " ,", + " ,", + " ,", + " ,", + " General; !- End-Use Subcategory", }); std::string const vrfFluidCtrl_HR = delimited_string({ @@ -20692,7 +20754,7 @@ TEST_F(EnergyPlusFixture, VRF_MixedTypes) " 0, !- Outdoor Air Flow Rate When No Cooling or Heating is Needed {m3/s}", " VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name", " drawthrough, !- Supply Air Fan Placement", - " Fan:VariableVolume, !- Supply Air Fan Object Type", + " Fan:SystemModel, !- Supply Air Fan Object Type", " TU2 VRF Supply Fan, !- Supply Air Fan Object Name", " , !- Outside Air Mixer Object Type", " , !- Outside Air Mixer Object Name", @@ -20724,28 +20786,45 @@ TEST_F(EnergyPlusFixture, VRF_MixedTypes) " IUCondTempCurve; !- Indoor Unit Condensing Temperature Function of Subcooling Curve Name", "", "", - "Fan:VariableVolume,", - " TU2 VRF Supply Fan, !- Name", - " VRFAvailSched, !- Availability Schedule Name", - " 0.7, !- Fan Total Efficiency", - " 600, !- Pressure Rise {Pa}", - " autosize, !- Maximum Flow Rate {m3/s}", - " Fraction, !- Fan Power Minimum Flow Rate Input Method", - " 0, !- Fan Power Minimum Flow Fraction", - " 0, !- Fan Power Minimum Air Flow Rate {m3/s}", - " 0.9, !- Motor Efficiency", - " 1, !- Motor In Airstream Fraction", - " 0.059, !- Fan Power Coefficient 1", - " 0, !- Fan Power Coefficient 2", - " 0, !- Fan Power Coefficient 3", - " 0.928, !- Fan Power Coefficient 4", - " 0, !- Fan Power Coefficient 5", - " TU2 VRF DX HCoil Outlet Node, !- Air Inlet Node Name", - " TU2 Outlet Node, !- Air Outlet Node Name", - " General; !- End-Use Subcategory", + " Fan:SystemModel,", + " TU2 VRF Supply Fan, !- Name", + " VRFAvailSched, !- Availability Schedule Name", + " TU2 VRF DX HCoil Outlet Node, !- Air Inlet Node Name", + " TU2 Outlet Node, !- Air Outlet Node Name", + " autosize, !- Design Maximum Air Flow Rate {m3/s}", + " Continuous, !- Speed Control Method", + " 0.0, !- Electric Power Minimum Flow Rate Fraction", + " 600, !- Design Pressure Rise {Pa}", + " 0.9, !- Motor Efficiency", + " 1.0, !- Motor In Air Stream Fraction", + " autosize, !- Design Electric Power Consumption {W}", + " , !- 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", + " TU Fan Power Curve, !- Electric Power Function of Flow Fraction Curve Name", + " ,", + " ,", + " ,", + " ,", + " General; !- End-Use Subcategory", }); std::string const commonCurvesAndFansForFluidCtrlAndHR = delimited_string({ + " Curve:Quartic,", + " TU Fan Power Curve , !- Name", + " 0.059, !- Coefficient1 Constant", + " 0, !- Coefficient2 x ", + " 0, !- Coefficient3 x**2 ", + " 0.928, !- Coefficient4 x**3 ", + " 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", + "Curve:Quadratic,", " OUEvapTempCurve, !- Name", " 0, !- Coefficient1 Constant", From 3870cef41949884f01bb79714e04543463d4ba62 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Thu, 25 Jul 2024 15:53:38 -0500 Subject: [PATCH 53/81] Fix unit test fail on windows --- src/EnergyPlus/FluidProperties.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EnergyPlus/FluidProperties.cc b/src/EnergyPlus/FluidProperties.cc index a27751e06b6..540cb65ab1c 100644 --- a/src/EnergyPlus/FluidProperties.cc +++ b/src/EnergyPlus/FluidProperties.cc @@ -2849,7 +2849,7 @@ namespace FluidProperties { static constexpr std::string_view routineName = "RefrigProps::getSatTemperature"; // FUNCTION LOCAL VARIABLE DECLARATIONS: - bool ErrorFlag; // error flag for current call + bool ErrorFlag = false; // error flag for current call auto &df = state.dataFluidProps; From a246dffbb7875c5ef5b6458209362dceb742cbfd Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Thu, 25 Jul 2024 15:54:22 -0500 Subject: [PATCH 54/81] Space IV-Non-coincident 5 --- src/EnergyPlus/ZoneEquipmentManager.cc | 163 ++++++++++++++++++------- 1 file changed, 120 insertions(+), 43 deletions(-) diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index b459e11ae07..6c4089019e1 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -1916,6 +1916,7 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum zoneCFS.CoolOutHumRatSeq(ts) = 0.0; zoneCFS.CoolLoadNoDOASSeq(ts) = 0.0; } + if (zoneCFS.zoneLatentSizing) { // Zero out latent simple sums zoneCFS.DesLatentHeatVolFlow = 0.0; @@ -1950,7 +1951,45 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum } } + // Other - Initialize to first space values (clear later if not all the same) + int firstSpace = state.dataHeatBal->Zone(zoneNum).spaceIndexes[0]; + auto &firstSpaceCFS = state.dataSize->CalcFinalSpaceSizing(firstSpace); + zoneCFS.HeatDesDay = firstSpaceCFS.HeatDesDay; + zoneCFS.HeatDDNum = firstSpaceCFS.HeatDDNum; + zoneCFS.cHeatDDDate = firstSpaceCFS.cHeatDDDate; + zoneCFS.TimeStepNumAtHeatMax = firstSpaceCFS.TimeStepNumAtHeatMax; + zoneCFS.HeatNoDOASDDNum = firstSpaceCFS.HeatNoDOASDDNum; + zoneCFS.HeatNoDOASDesDay = firstSpaceCFS.HeatNoDOASDesDay; + zoneCFS.TimeStepNumAtHeatNoDOASMax = firstSpaceCFS.TimeStepNumAtHeatNoDOASMax; + zoneCFS.CoolDesDay = firstSpaceCFS.CoolDesDay; + zoneCFS.CoolDDNum = firstSpaceCFS.CoolDDNum; + zoneCFS.cCoolDDDate = firstSpaceCFS.cCoolDDDate; + zoneCFS.TimeStepNumAtCoolMax = firstSpaceCFS.TimeStepNumAtCoolMax; + if (zoneCFS.zoneLatentSizing) { + zoneCFS.LatHeatDesDay = firstSpaceCFS.LatHeatDesDay; + zoneCFS.cLatentHeatDDDate = firstSpaceCFS.cLatentHeatDDDate; + zoneCFS.LatentHeatDDNum = firstSpaceCFS.LatentHeatDDNum; + zoneCFS.TimeStepNumAtLatentHeatMax = firstSpaceCFS.TimeStepNumAtLatentHeatMax; + zoneCFS.LatentHeatNoDOASDDNum = firstSpaceCFS.LatentHeatNoDOASDDNum; + zoneCFS.LatHeatNoDOASDesDay = firstSpaceCFS.LatHeatNoDOASDesDay; + zoneCFS.TimeStepNumAtLatentHeatNoDOASMax = firstSpaceCFS.TimeStepNumAtLatentHeatNoDOASMax; + zoneCFS.LatCoolDesDay = firstSpaceCFS.LatCoolDesDay; + zoneCFS.cLatentCoolDDDate = firstSpaceCFS.cLatentCoolDDDate; + zoneCFS.LatentCoolDDNum = firstSpaceCFS.LatentCoolDDNum; + zoneCFS.TimeStepNumAtLatentCoolMax = firstSpaceCFS.TimeStepNumAtLatentCoolMax; + zoneCFS.CoolNoDOASDDNum = firstSpaceCFS.CoolNoDOASDDNum; + zoneCFS.CoolNoDOASDesDay = firstSpaceCFS.CoolNoDOASDesDay; + zoneCFS.TimeStepNumAtCoolNoDOASMax = firstSpaceCFS.TimeStepNumAtCoolNoDOASMax; + zoneCFS.LatentCoolNoDOASDDNum = firstSpaceCFS.LatentCoolNoDOASDDNum; + zoneCFS.LatCoolNoDOASDesDay = firstSpaceCFS.LatCoolNoDOASDesDay; + zoneCFS.TimeStepNumAtLatentCoolNoDOASMax = firstSpaceCFS.TimeStepNumAtLatentCoolNoDOASMax; + } + int numSpaces = 0; // Track this for averages later + bool heatDDNumAllSame = true; + bool coolDDNumAllSame = true; + int priorHeatDDNum = 0; + int priorCoolDDNum = 0; for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { auto &spaceCFS = state.dataSize->CalcFinalSpaceSizing(spaceNum); ++numSpaces; @@ -2006,20 +2045,24 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum } // Other - // zoneCFS.HeatDesDay = spaceCFS.HeatDesDay; - // zoneCFS.HeatDDNum = spaceCFS.HeatDDNum; - // zoneCFS.cHeatDDDate = desDayWeath.DateString; - // zoneCFS.TimeStepNumAtHeatMax = spaceCFS.TimeStepNumAtHeatMax; - // zoneCFS.HeatNoDOASDDNum = spaceCFS.HeatNoDOASDDNum; - // zoneCFS.HeatNoDOASDesDay = spaceCFS.HeatNoDOASDesDay; - // zoneCFS.TimeStepNumAtHeatNoDOASMax = spaceCFS.TimeStepNumAtHeatNoDOASMax; - // zoneCFS.LatentHeatNoDOASDDNum = spaceCFS.LatentHeatNoDOASDDNum; - // zoneCFS.LatHeatNoDOASDesDay = spaceCFS.LatHeatNoDOASDesDay; - // zoneCFS.TimeStepNumAtLatentHeatNoDOASMax = spaceCFS.TimeStepNumAtLatentHeatNoDOASMax; - // zoneCFS.CoolDesDay = spaceCFS.CoolDesDay; - // zoneCFS.CoolDDNum = spaceCFS.CoolDDNum; - // zoneCFS.cCoolDDDate = desDayWeath.DateString; - // zoneCFS.TimeStepNumAtCoolMax = spaceCFS.TimeStepNumAtCoolMax; + if ((zoneCFS.HeatDDNum != 0) && (zoneCFS.HeatDDNum != spaceCFS.HeatDDNum)) { + zoneCFS.HeatDesDay = "n/a"; + zoneCFS.HeatDDNum = 0; + zoneCFS.cHeatDDDate = ""; + } + if ((zoneCFS.HeatNoDOASDDNum != 0) && (zoneCFS.HeatNoDOASDDNum != spaceCFS.HeatNoDOASDDNum)) { + zoneCFS.HeatNoDOASDDNum = 0; + zoneCFS.HeatNoDOASDesDay = "n/a"; + } + if ((zoneCFS.CoolDDNum != 0) && (zoneCFS.CoolDDNum != spaceCFS.CoolDDNum)) { + zoneCFS.CoolDesDay = "n/a"; + zoneCFS.CoolDDNum = 0; + zoneCFS.cCoolDDDate = ""; + } + if ((zoneCFS.CoolNoDOASDDNum != 0) && (zoneCFS.CoolNoDOASDDNum != spaceCFS.CoolNoDOASDDNum)) { + zoneCFS.CoolNoDOASDDNum = 0; + zoneCFS.CoolNoDOASDesDay = "n/a"; + } if (zoneCFS.zoneLatentSizing) { // Simple sums @@ -2045,20 +2088,24 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum zoneCFS.DesLatentCoolCoilInHumRat += spaceCFS.DesLatentCoolCoilInHumRat * spaceCFS.DesLatentCoolVolFlow; // Other - // zoneCFS.LatHeatDesDay = spaceCFS.LatHeatDesDay; - // zoneCFS.cLatentHeatDDDate = desDayWeath.DateString; - // zoneCFS.LatentHeatDDNum = spaceCFS.LatentHeatDDNum; - // zoneCFS.TimeStepNumAtLatentHeatMax = spaceCFS.TimeStepNumAtLatentHeatMax; - // zoneCFS.LatCoolDesDay = spaceCFS.LatCoolDesDay; - // zoneCFS.cLatentCoolDDDate = desDayWeath.DateString; - // zoneCFS.LatentCoolDDNum = spaceCFS.LatentCoolDDNum; - // zoneCFS.TimeStepNumAtLatentCoolMax = spaceCFS.TimeStepNumAtLatentCoolMax; - // zoneCFS.CoolNoDOASDDNum = spaceCFS.CoolNoDOASDDNum; - // zoneCFS.CoolNoDOASDesDay = spaceCFS.CoolNoDOASDesDay; - // zoneCFS.TimeStepNumAtCoolNoDOASMax = spaceCFS.TimeStepNumAtCoolNoDOASMax; - // zoneCFS.LatentCoolNoDOASDDNum = spaceCFS.LatentCoolNoDOASDDNum; - // zoneCFS.LatCoolNoDOASDesDay = spaceCFS.LatCoolNoDOASDesDay; - // zoneCFS.TimeStepNumAtLatentCoolNoDOASMax = spaceCFS.TimeStepNumAtLatentCoolNoDOASMax; + if ((zoneCFS.LatentHeatDDNum != 0) && (zoneCFS.LatentHeatDDNum != spaceCFS.LatentHeatDDNum)) { + zoneCFS.LatHeatDesDay = "n/a"; + zoneCFS.cLatentHeatDDDate = ""; + zoneCFS.LatentHeatDDNum = 0; + } + if ((zoneCFS.LatentHeatNoDOASDDNum != 0) && (zoneCFS.LatentHeatNoDOASDDNum != spaceCFS.LatentHeatNoDOASDDNum)) { + zoneCFS.LatentHeatNoDOASDDNum = 0; + zoneCFS.LatHeatNoDOASDesDay = "n/a"; + } + if ((zoneCFS.LatentCoolDDNum != 0) && (zoneCFS.LatentCoolDDNum != spaceCFS.LatentCoolDDNum)) { + zoneCFS.LatCoolDesDay = "n/a"; + zoneCFS.cLatentCoolDDDate = ""; + zoneCFS.LatentCoolDDNum = 0; + } + if ((zoneCFS.LatentCoolNoDOASDDNum != 0) && (zoneCFS.LatentCoolNoDOASDDNum != spaceCFS.LatentCoolNoDOASDDNum)) { + zoneCFS.LatentCoolNoDOASDDNum = 0; + zoneCFS.LatCoolNoDOASDesDay = "n/a"; + } // Time-series sums for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) { @@ -2093,24 +2140,39 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum zoneCFS.DesCoolCoilInTemp /= zoneCFS.DesCoolMassFlow; zoneCFS.DesCoolCoilInHumRat /= zoneCFS.DesCoolMassFlow; } + // Timestep at max + zoneCFS.TimeStepNumAtHeatMax = 0; + zoneCFS.TimeStepNumAtHeatNoDOASMax = 0; + zoneCFS.TimeStepNumAtCoolMax = 0; + zoneCFS.TimeStepNumAtHeatNoDOASMax = 0; + Real64 maxHeatLoad = 0.0; + Real64 maxHeatLoadNoDOAS = 0.0; + Real64 maxCoolLoad = 0.0; + Real64 maxCoolLoadNoDOAS = 0.0; for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) { - if (zoneCFS.HeatFlowSeq(ts) > 0) { - zoneCFS.HeatZoneTempSeq(ts) /= zoneCFS.HeatFlowSeq(ts); - zoneCFS.HeatOutTempSeq(ts) /= zoneCFS.HeatFlowSeq(ts); - zoneCFS.HeatZoneRetTempSeq(ts) /= zoneCFS.HeatFlowSeq(ts); - zoneCFS.HeatZoneHumRatSeq(ts) /= zoneCFS.HeatFlowSeq(ts); - zoneCFS.HeatOutHumRatSeq(ts) /= zoneCFS.HeatFlowSeq(ts); - zoneCFS.HeatLoadNoDOASSeq(ts) /= zoneCFS.HeatFlowSeq(ts); - } - if (zoneCFS.CoolFlowSeq(ts) > 0) { - zoneCFS.CoolZoneTempSeq(ts) /= zoneCFS.CoolFlowSeq(ts); - zoneCFS.CoolOutTempSeq(ts) /= zoneCFS.CoolFlowSeq(ts); - zoneCFS.CoolZoneRetTempSeq(ts) /= zoneCFS.CoolFlowSeq(ts); - zoneCFS.CoolZoneHumRatSeq(ts) /= zoneCFS.CoolFlowSeq(ts); - zoneCFS.CoolOutHumRatSeq(ts) /= zoneCFS.CoolFlowSeq(ts); - zoneCFS.CoolLoadNoDOASSeq(ts) /= zoneCFS.CoolFlowSeq(ts); + Real64 tsHeatFlow = zoneCFS.HeatFlowSeq(ts); + if (tsHeatFlow > 0) { + zoneCFS.HeatZoneTempSeq(ts) /= tsHeatFlow; + zoneCFS.HeatOutTempSeq(ts) /= tsHeatFlow; + zoneCFS.HeatZoneRetTempSeq(ts) /= tsHeatFlow; + zoneCFS.HeatZoneHumRatSeq(ts) /= tsHeatFlow; + zoneCFS.HeatOutHumRatSeq(ts) /= tsHeatFlow; + } + if (zoneCFS.HeatLoadSeq(ts) > maxHeatLoad) zoneCFS.TimeStepNumAtHeatMax = ts; + if (zoneCFS.HeatLoadNoDOASSeq(ts) > maxHeatLoadNoDOAS) zoneCFS.TimeStepNumAtHeatNoDOASMax = ts; + + Real64 tsCoolFlow = zoneCFS.CoolFlowSeq(ts); + if (tsCoolFlow > 0) { + zoneCFS.CoolZoneTempSeq(ts) /= tsCoolFlow; + zoneCFS.CoolOutTempSeq(ts) /= tsCoolFlow; + zoneCFS.CoolZoneRetTempSeq(ts) /= tsCoolFlow; + zoneCFS.CoolZoneHumRatSeq(ts) /= tsCoolFlow; + zoneCFS.CoolOutHumRatSeq(ts) /= tsCoolFlow; } + if (zoneCFS.CoolLoadSeq(ts) > maxCoolLoad) zoneCFS.TimeStepNumAtCoolMax = ts; + if (zoneCFS.CoolLoadNoDOASSeq(ts) > maxCoolLoadNoDOAS) zoneCFS.TimeStepNumAtCoolNoDOASMax = ts; } + if (zoneCFS.zoneLatentSizing) { if (zoneCFS.DesLatentHeatMassFlow > 0) { zoneCFS.ZoneTempAtLatentHeatPeak /= zoneCFS.DesLatentHeatMassFlow; @@ -2126,6 +2188,21 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum zoneCFS.DesLatentCoolCoilInTemp /= zoneCFS.DesLatentCoolMassFlow; zoneCFS.DesLatentCoolCoilInHumRat /= zoneCFS.DesLatentCoolMassFlow; } + // Timestep at max + zoneCFS.TimeStepNumAtLatentHeatMax = 0; + zoneCFS.TimeStepNumAtLatentHeatNoDOASMax = 0; + zoneCFS.TimeStepNumAtLatentCoolMax = 0; + zoneCFS.TimeStepNumAtLatentCoolNoDOASMax = 0; + Real64 maxLatHeatLoad = 0.0; + Real64 maxLatHeatLoadNoDOAS = 0.0; + Real64 maxLatCoolLoad = 0.0; + Real64 maxLatCoolLoadNoDOAS = 0.0; + for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) { + if (zoneCFS.LatentHeatFlowSeq(ts) > maxLatHeatLoad) zoneCFS.TimeStepNumAtLatentHeatMax = ts; + if (zoneCFS.HeatLatentLoadNoDOASSeq(ts) > maxLatHeatLoadNoDOAS) zoneCFS.TimeStepNumAtLatentHeatNoDOASMax = ts; + if (zoneCFS.LatentCoolLoadSeq(ts) > maxLatCoolLoad) zoneCFS.TimeStepNumAtLatentCoolMax = ts; + if (zoneCFS.CoolLatentLoadNoDOASSeq(ts) > maxLatCoolLoadNoDOAS) zoneCFS.TimeStepNumAtLatentCoolNoDOASMax = ts; + } } return; From 4e56d25dd89dd21a5bed484e0ba39ca5a82f05e2 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Mon, 29 Jul 2024 17:45:06 -0500 Subject: [PATCH 55/81] Space IV-Non-coincident 6 --- src/EnergyPlus/OutputReportTabular.cc | 2 +- src/EnergyPlus/SimAirServingZones.cc | 32 ++++++++++++++++++++++----- src/EnergyPlus/SizingManager.cc | 10 +++++++++ 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/EnergyPlus/OutputReportTabular.cc b/src/EnergyPlus/OutputReportTabular.cc index e3171047cf7..bbf5530f5bc 100644 --- a/src/EnergyPlus/OutputReportTabular.cc +++ b/src/EnergyPlus/OutputReportTabular.cc @@ -15970,7 +15970,7 @@ void CollectPeakZoneConditions( if (isCooling) { // Time of Peak Load - if ((size_t)desDaySelected <= state.dataWeather->DesDayInput.size()) { + if ((desDaySelected > 0) && ((size_t)desDaySelected <= state.dataWeather->DesDayInput.size())) { compLoad.peakDateHrMin = format("{}/{} {}", state.dataWeather->DesDayInput(desDaySelected).Month, state.dataWeather->DesDayInput(desDaySelected).DayOfMonth, diff --git a/src/EnergyPlus/SimAirServingZones.cc b/src/EnergyPlus/SimAirServingZones.cc index 8284166804c..5a8ccc20e53 100644 --- a/src/EnergyPlus/SimAirServingZones.cc +++ b/src/EnergyPlus/SimAirServingZones.cc @@ -6426,8 +6426,14 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn (1.0 + termUnitSizing.InducRat); CoolDDNum = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).CoolDDNum; CoolTimeStepNum = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).TimeStepNumAtCoolMax; - OutAirTemp += state.dataSize->DesDayWeath(CoolDDNum).Temp(CoolTimeStepNum) * coolMassFlow / (1.0 + termUnitSizing.InducRat); - OutAirHumRat += state.dataSize->DesDayWeath(CoolDDNum).HumRat(CoolTimeStepNum) * coolMassFlow / (1.0 + termUnitSizing.InducRat); + if (CoolDDNum == 0) { + auto &zoneCFS = state.dataSize->CalcFinalZoneSizing(state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneNum); + OutAirTemp += zoneCFS.CoolOutTemp * coolMassFlow / (1.0 + termUnitSizing.InducRat); + OutAirHumRat += zoneCFS.CoolOutHumRat * coolMassFlow / (1.0 + termUnitSizing.InducRat); + } else { + OutAirTemp += state.dataSize->DesDayWeath(CoolDDNum).Temp(CoolTimeStepNum) * coolMassFlow / (1.0 + termUnitSizing.InducRat); + OutAirHumRat += state.dataSize->DesDayWeath(CoolDDNum).HumRat(CoolTimeStepNum) * coolMassFlow / (1.0 + termUnitSizing.InducRat); + } } if (state.dataSize->CalcSysSizing(AirLoopNum).NonCoinCoolMassFlow > 0.0) { SysCoolRetTemp /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinCoolMassFlow; @@ -6490,8 +6496,15 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn (1.0 + termUnitSizing.InducRat); HeatDDNum = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).HeatDDNum; HeatTimeStepNum = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).TimeStepNumAtHeatMax; - OutAirTemp += state.dataSize->DesDayWeath(HeatDDNum).Temp(HeatTimeStepNum) * heatMassFlow / (1.0 + termUnitSizing.InducRat); - OutAirHumRat += state.dataSize->DesDayWeath(HeatDDNum).HumRat(HeatTimeStepNum) * heatMassFlow / (1.0 + termUnitSizing.InducRat); + if (HeatDDNum == 0) { + auto &zoneCFS = state.dataSize->CalcFinalZoneSizing(state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneNum); + OutAirTemp += zoneCFS.HeatOutTemp * heatMassFlow / (1.0 + termUnitSizing.InducRat); + OutAirHumRat += zoneCFS.HeatOutHumRat * heatMassFlow / (1.0 + termUnitSizing.InducRat); + } else { + OutAirTemp += state.dataSize->DesDayWeath(HeatDDNum).Temp(HeatTimeStepNum) * heatMassFlow / (1.0 + termUnitSizing.InducRat); + OutAirHumRat += + state.dataSize->DesDayWeath(HeatDDNum).HumRat(HeatTimeStepNum) * heatMassFlow / (1.0 + termUnitSizing.InducRat); + } } if (state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow > 0.0) { SysHeatRetTemp /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow; @@ -6537,8 +6550,15 @@ void UpdateSysSizing(EnergyPlusData &state, Constant::CallIndicator const CallIn (1.0 + termUnitSizing.InducRat); HeatDDNum = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).HeatDDNum; HeatTimeStepNum = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).TimeStepNumAtHeatMax; - OutAirTemp += state.dataSize->DesDayWeath(HeatDDNum).Temp(HeatTimeStepNum) * heatMassFlow / (1.0 + termUnitSizing.InducRat); - OutAirHumRat += state.dataSize->DesDayWeath(HeatDDNum).HumRat(HeatTimeStepNum) * heatMassFlow / (1.0 + termUnitSizing.InducRat); + if (HeatDDNum == 0) { + auto &zoneCFS = state.dataSize->CalcFinalZoneSizing(state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneNum); + OutAirTemp += zoneCFS.HeatOutTemp * heatMassFlow / (1.0 + termUnitSizing.InducRat); + OutAirHumRat += zoneCFS.HeatOutHumRat * heatMassFlow / (1.0 + termUnitSizing.InducRat); + } else { + OutAirTemp += state.dataSize->DesDayWeath(HeatDDNum).Temp(HeatTimeStepNum) * heatMassFlow / (1.0 + termUnitSizing.InducRat); + OutAirHumRat += + state.dataSize->DesDayWeath(HeatDDNum).HumRat(HeatTimeStepNum) * heatMassFlow / (1.0 + termUnitSizing.InducRat); + } } if (state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow > 0.0) { SysHeatRetTemp /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow; diff --git a/src/EnergyPlus/SizingManager.cc b/src/EnergyPlus/SizingManager.cc index 9c830da768a..0b76cbd122e 100644 --- a/src/EnergyPlus/SizingManager.cc +++ b/src/EnergyPlus/SizingManager.cc @@ -4283,6 +4283,11 @@ void reportZoneSizing(EnergyPlusData &state, HumRatAtPeak = state.dataSize->DesDayWeath(DDNum).HumRat(TimeStepAtPeak); DOASHeatGainRateAtClPk = zsCalcSizing(DDNum, thisNum).DOASHeatAddSeq(TimeStepAtPeak); TStatSetPtAtPk = zSizing(DDNum, thisNum).CoolTstatTempSeq(TimeStepAtPeak); + } else { + TempAtPeak = zsCalcFinalSizing.OutTempAtCoolPeak; + HumRatAtPeak = zsCalcFinalSizing.OutHumRatAtCoolPeak; + DOASHeatGainRateAtClPk = zsCalcFinalSizing.DOASCoolLoad; + TStatSetPtAtPk = zsCalcFinalSizing.ZoneTempAtCoolPeak; } reportZoneSizingEio(state, zsFinalSizing.ZoneName, @@ -4351,6 +4356,11 @@ void reportZoneSizing(EnergyPlusData &state, HumRatAtPeak = state.dataSize->DesDayWeath(DDNum).HumRat(TimeStepAtPeak); DOASHeatGainRateAtHtPk = zsCalcSizing(DDNum, thisNum).DOASHeatAddSeq(TimeStepAtPeak); TStatSetPtAtPk = zSizing(DDNum, thisNum).HeatTstatTempSeq(TimeStepAtPeak); + } else { + TempAtPeak = zsCalcFinalSizing.OutTempAtHeatPeak; + HumRatAtPeak = zsCalcFinalSizing.OutHumRatAtHeatPeak; + DOASHeatGainRateAtHtPk = zsCalcFinalSizing.DOASHeatLoad; + TStatSetPtAtPk = zsCalcFinalSizing.ZoneTempAtHeatPeak; } reportZoneSizingEio(state, zsFinalSizing.ZoneName, From a19c99063cb59032f6903e71ad3af0971c5b951d Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 31 Jul 2024 10:35:36 -0700 Subject: [PATCH 56/81] change ElecPowerMinFlowRateFrac calc, autosize DesignElecPower to compute "Electric Power Minimum Flow Rate Fraction", use the following logic This field in Fan:SystemModel is "Electric Power Minimum Flow Rate Fraction", so if the old fan is FixedFlowRate then the new field should be old fanPowerMinAirFlow_str / maxAirFlow_str If maxAirFlow_str is autosize, and fanPowerMinAirFlow_str` is > 0, then throw a warning and set this field to 0 if the old fan is Fraction, then this field = old fan minAirFlowFrac_str. For "Design Electric Power Consumption", directly make it autosize and use TotalEfficiencyAndPressure in the sizing method. This way also ensures the "_localTotalEff" variable in the code to use inputs from "Fan Total Efficiency" in Fan:SystemModel --- .../CreateNewIDFUsingRulesV24_2_0.f90 | 35 +- ...US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf | 114 ++--- ...riableRefrigerantFlow_FluidTCtrl_5Zone.idf | 443 ++++++++-------- ...bleRefrigerantFlow_FluidTCtrl_HR_5Zone.idf | 441 ++++++++-------- ...erantFlow_FluidTCtrl_wSuppHeater_5Zone.idf | 479 ++++++++++-------- 5 files changed, 807 insertions(+), 705 deletions(-) diff --git a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 index 59fbe7b5d11..67a848f7a97 100644 --- a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 +++ b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 @@ -600,32 +600,27 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile OutArgs(5) = OldFanVO(Num3)%maxAirFlow_str OutArgs(6) = 'Continuous' !- Speed Control Method IF (SameString(OldFanVO(Num3)%minFlowInputMethod, "FixedFlowRate")) THEN - OutArgs(7) = OldFanVO(Num3)%maxAirFlow_str - ELSE ! input method is "Fraction" - READ(OldFanVO(Num3)%minAirFlowFrac_str, '(F15.5)') minAirFlowFrac - IF (minAirFlowFrac == 0.0) THEN + IF (.NOT. SameString(OldFanVO(Num3)%maxAirFlow_str, "AUTOSIZE")) THEN + READ(OldFanVO(Num3)%fanPowerMinAirFlow_str, '(F15.5)') fanPowerMinAirFlow + READ(OldFanVO(Num3)%maxAirFlow_str, '(F15.5)') maxAirFlow + WRITE(OutArgs(7), '(F15.5)') (fanPowerMinAirFlow / maxAirFlow) + ELSE ! maxAirFlow_stris autosize + READ(OldFanVO(Num3)%fanPowerMinAirFlow_str, '(F15.5)') fanPowerMinAirFlow + IF (.NOT. fanPowerMinAirFlow == 0) THEN ! don't know how to do division with autosize + CALL writePreprocessorObject(DifLfn, PrognameConversion, 'Warning', & + 'Cannot calculate Electric Power Minimum Flow Rate Fraction for' // sysFanName // & + 'when Maximum Flow Rate is autosize and Fan Power Minimum Air Flow Rate is non-zero') + END IF OutArgs(7) = '0.0' - ELSE - IF (.NOT. SameString(OldFanVO(Num3)%maxAirFlow_str, "AUTOSIZE")) THEN - READ(OldFanVO(Num3)%maxAirFlow_str, '(F15.5)') maxAirFlow - WRITE(OutArgs(7), '(F15.5)') (maxAirFlow * minAirFlowFrac) - ELSE ! don't know how to multiply fraction with autosize - OutArgs(7) = '' - ENDIF ENDIF + ELSE ! input method is "Fraction" + OutArgs(7) = OldFanVO(Num3)%minAirFlowFrac_str ENDIF OutArgs(8) = OldFanVO(Num3)%pressureRise_str !- Design Pressure Rise {Pa} OutArgs(9) = OldFanVO(Num3)%motorEfficiency !- Motor Efficiency OutArgs(10) = OldFanVO(Num3)%motorInAirStreamFrac !- Motor In Air Stream Fraction - IF (.NOT. SameString(OldFanVO(Num3)%maxAirFlow_str, "AUTOSIZE")) THEN - READ(OldFanVO(Num3)%maxAirFlow_str, '(F15.5)') maxAirFlow - READ(OldFanVO(Num3)%pressureRise_str, '(F15.5)') pressureRise - READ(OldFanVO(Num3)%fanTotalEff_str, '(F15.5)') fanTotalEff - WRITE(OutArgs(11), '(F15.5)') (maxAirFlow * pressureRise / fanTotalEff) !- Design Electric Power Consumption {W} - ELSE - OutArgs(11) = 'autosize' - OutArgs(12) = 'TotalEfficiencyAndPressure' ! chose this becuase power per flow or per pressure are unknown - ENDIF + OutArgs(11) = 'autosize' + OutArgs(12) = 'TotalEfficiencyAndPressure' ! chose this becuase power per flow or per pressure are unknown OutArgs(13) = '' !- Electric Power Per Unit Flow Rate {W/(m3/s)} OutArgs(14) = '' !- Electric Power Per Unit Flow Rate Per Unit Pressure {W/((m3/s)-Pa)} OutArgs(15) = OldFanVO(Num3)%fanTotalEff_str !- Fan Total Efficiency diff --git a/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf b/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf index 09900d222ef..2a21a3cbc47 100644 --- a/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf +++ b/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf @@ -482,7 +482,7 @@ 0, !- No Load Outdoor Air Flow Rate {m3/s} VRFFanModeSchedule, !- Supply Air Fan Operating Mode Schedule Name drawthrough, !- Supply Air Fan Placement - Fan:SystemModel, !- Supply Air Fan Object Type + Fan:SystemModel, !- Supply Air Fan Object Type TU1 VRF Supply Fan, !- Supply Air Fan Object Name OutdoorAir:Mixer, !- Outside Air Mixer Object Type TU1 OA Mixer, !- Outside Air Mixer Object Name @@ -497,7 +497,45 @@ , !- Design Specification ZoneHVAC Sizing Object Name Coil:Heating:Electric, !- Supplemental Heating Coil Object Type TU1 Supp Heating Coil, !- Supplemental Heating Coil Name - 50; !- Maximum Supply Air Temperature from Supplemental Heater {C} + 50, !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + + Fan:SystemModel, + TU1 VRF Supply Fan, !- Name + VRFAvailSched, !- Availability Schedule Name + TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name + TU1 VRF Fan Outlet Node, !- Air Outlet Node Name + 0.595, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0.69748, !- Electric Power Minimum Flow Rate Fraction + 400, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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.5, !- Fan Total Efficiency + TU1 VRF Supply 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 + General; !- End-Use Subcategory + + Curve:Quartic, + TU1 VRF Supply Fan_curve,!- Name + 0.09, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.91, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.6974790, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type !- =========== ALL OBJECTS IN CLASS: COIL:HEATING:ELECTRIC =========== @@ -530,58 +568,6 @@ OutdoorAir:NodeList, Outside Air Inlet Node 1;!- Node or NodeList Name 1 - !- Fan:VariableVolume, - !- TU1 VRF Supply Fan, !- Name - !- VRFAvailSched, !- Availability Schedule Name - !- 0.5, !- Fan Total Efficiency - !- 400, !- Pressure Rise {Pa} - !- 0.595, !- Maximum Flow Rate {m3/s} - !- FixedFlowRate, !- Fan Power Minimum Flow Rate Input Method - !- 0, !- Fan Power Minimum Flow Fraction - !- 0.415, !- Fan Power Minimum Air Flow Rate {m3/s} - !- 0.9, !- Motor Efficiency - !- 1, !- Motor In Airstream Fraction - !- 0.09, !- Fan Power Coefficient 1 - !- 0, !- Fan Power Coefficient 2 - !- 0, !- Fan Power Coefficient 3 - !- 0.91, !- Fan Power Coefficient 4 - !- 0, !- Fan Power Coefficient 5 - !- TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name - !- TU1 VRF Fan Outlet Node, !- Air Outlet Node Name - !- General; !- End-Use Subcategory - - Fan:SystemModel, - TU1 VRF Supply Fan, !- Name - VRFAvailSched, !- Availability Schedule Name - TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name - TU1 VRF Fan Outlet Node, !- Air Outlet Node Name - 0.595, !- Design Maximum Air Flow Rate {m3/s} - Continuous, !- Speed Control Method - 0.415, !- Electric Power Minimum Flow Rate Fraction - 400, !- Design Pressure Rise {Pa} - 0.9, !- Motor Efficiency - 1.0, !- Motor In Air Stream Fraction - 476, !- Design Electric Power Consumption {W} - , !- 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.5, !- Fan Total Efficiency - Fan Power Curve; !- Electric Power Function of Flow Fraction Curve Name - - Curve:Quartic, - Fan Power Curve , !- Name - 0.09, !- Coefficient1 Constant - 0, !- Coefficient2 x - 0, !- Coefficient3 x**2 - 0.91, !- Coefficient4 x**3 - 0, !- Coefficient5 x**4 - 0.6975, !- Minimum Value of x - 1.0, !- Maximum Value of x - 0.0, !- Minimum Curve Output - 5.0, !- Maximum Curve Output - Dimensionless, !- Input Unit Type for X - Dimensionless; !- Output Unit Type - !- =========== ALL OBJECTS IN CLASS: COIL:COOLING:DX:VARIABLEREFRIGERANTFLOW:FLUIDTEMPERATURECONTROL =========== Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, @@ -4727,7 +4713,7 @@ DishWasher, !- Schedule Name EquipmentLevel, !- Design Level Calculation Method 65.698787492023, !- Design Level {W} - , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.15, !- Fraction Latent 0.6, !- Fraction Radiant @@ -4740,7 +4726,7 @@ Refrigerator, !- Schedule Name EquipmentLevel, !- Design Level Calculation Method 91.0575745202123, !- Design Level {W} - , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 1, !- Fraction Radiant @@ -4753,7 +4739,7 @@ ClothesWasher, !- Schedule Name EquipmentLevel, !- Design Level Calculation Method 28.4784377542718, !- Design Level {W} - , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.8, !- Fraction Radiant @@ -4766,7 +4752,7 @@ ClothesDryer, !- Schedule Name EquipmentLevel, !- Design Level Calculation Method 213.064557285022, !- Design Level {W} - , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.05, !- Fraction Latent 0.15, !- Fraction Radiant @@ -4779,7 +4765,7 @@ CookingRange, !- Schedule Name EquipmentLevel, !- Design Level Calculation Method 248.154224774405, !- Design Level {W} - , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.3, !- Fraction Latent 0.4, !- Fraction Radiant @@ -4792,7 +4778,7 @@ InteriorLighting, !- Schedule Name EquipmentLevel, !- Design Level Calculation Method 0, !- Design Level {W} - , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 1, !- Fraction Radiant @@ -4805,7 +4791,7 @@ MiscPlugLoad, !- Schedule Name EquipmentLevel, !- Design Level Calculation Method 567.464237516869, !- Design Level {W} - , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.06, !- Fraction Latent 0.69, !- Fraction Radiant @@ -4818,7 +4804,7 @@ MiscPlugLoad, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 1.54356736989469, !- Watts per Zone Floor Area {W/m2} + 1.54356736989469, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0624390461422629, !- Fraction Latent 0.41190936353998, !- Fraction Radiant @@ -6387,7 +6373,7 @@ InteriorLightingHE, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 1.91387072900558, !- Watts per Zone Floor Area {W/m2} + 1.91387072900558, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Return Air Fraction 0.6, !- Fraction Radiant @@ -6400,7 +6386,7 @@ InteriorLightingHE, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 0.478467682251396, !- Watts per Zone Floor Area {W/m2} + 0.478467682251396, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Return Air Fraction 0.6, !- Fraction Radiant diff --git a/testfiles/VariableRefrigerantFlow_FluidTCtrl_5Zone.idf b/testfiles/VariableRefrigerantFlow_FluidTCtrl_5Zone.idf index 877b1e884fa..e674841ad1f 100644 --- a/testfiles/VariableRefrigerantFlow_FluidTCtrl_5Zone.idf +++ b/testfiles/VariableRefrigerantFlow_FluidTCtrl_5Zone.idf @@ -335,175 +335,8 @@ , !- Design Specification ZoneHVAC Sizing Object Name , !- Supplemental Heating Coil Object Type , !- Supplemental Heating Coil Name - ; !- Maximum Supply Air Temperature from Supplemental Heater {C} - - ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, - TU2, !- Zone Terminal Unit Name - VRFAvailSched, !- Terminal Unit Availability Schedule - TU2 Inlet Node, !- Terminal Unit Air Inlet Node Name - TU2 Outlet Node, !- Terminal Unit Air Outlet Node Name - autosize, !- Cooling Supply Air Flow Rate {m3/s} - autosize, !- No Cooling Supply Air Flow Rate {m3/s} - autosize, !- Heating Supply Air Flow Rate {m3/s} - autosize, !- No Heating Supply Air Flow Rate {m3/s} - autosize, !- Cooling Outdoor Air Flow Rate {m3/s} - autosize, !- Heating Outdoor Air Flow Rate {m3/s} - autosize, !- No Load Outdoor Air Flow Rate {m3/s} - VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name - drawthrough, !- Supply Air Fan Placement - Fan:SystemModel, !- Supply Air Fan Object Type - TU2 VRF Supply Fan, !- Supply Air Fan Object Name - OutdoorAir:Mixer, !- Outside Air Mixer Object Type - TU2 OA Mixer, !- Outside Air Mixer Object Name - Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type - TU2 VRF DX Cooling Coil, !- Cooling Coil Object Name - COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type - TU2 VRF DX Heating Coil, !- Heating Coil Object Name - 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} - 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} - , !- Rated Heating Capacity Sizing Ratio {W/W} - , !- Availability Manager List Name - , !- Design Specification ZoneHVAC Sizing Object Name - , !- Supplemental Heating Coil Object Type - , !- Supplemental Heating Coil Name - ; !- Maximum Supply Air Temperature from Supplemental Heater {C} - - ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, - TU3, !- Zone Terminal Unit Name - VRFAvailSched, !- Terminal Unit Availability Schedule - TU3 Inlet Node, !- Terminal Unit Air Inlet Node Name - TU3 Outlet Node, !- Terminal Unit Air Outlet Node Name - autosize, !- Cooling Supply Air Flow Rate {m3/s} - autosize, !- No Cooling Supply Air Flow Rate {m3/s} - autosize, !- Heating Supply Air Flow Rate {m3/s} - autosize, !- No Heating Supply Air Flow Rate {m3/s} - autosize, !- Cooling Outdoor Air Flow Rate {m3/s} - autosize, !- Heating Outdoor Air Flow Rate {m3/s} - autosize, !- No Load Outdoor Air Flow Rate {m3/s} - VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name - drawthrough, !- Supply Air Fan Placement - Fan:SystemModel, !- Supply Air Fan Object Type - TU3 VRF Supply Fan, !- Supply Air Fan Object Name - OutdoorAir:Mixer, !- Outside Air Mixer Object Type - TU3 OA Mixer, !- Outside Air Mixer Object Name - Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type - TU3 VRF DX Cooling Coil, !- Cooling Coil Object Name - COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type - TU3 VRF DX Heating Coil, !- Heating Coil Object Name - 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} - 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} - , !- Rated Heating Capacity Sizing Ratio {W/W} - , !- Availability Manager List Name - , !- Design Specification ZoneHVAC Sizing Object Name - , !- Supplemental Heating Coil Object Type - , !- Supplemental Heating Coil Name - ; !- Maximum Supply Air Temperature from Supplemental Heater {C} - - ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, - TU4, !- Zone Terminal Unit Name - VRFAvailSched, !- Terminal Unit Availability Schedule - TU4 Inlet Node, !- Terminal Unit Air Inlet Node Name - TU4 Outlet Node, !- Terminal Unit Air Outlet Node Name - autosize, !- Cooling Supply Air Flow Rate {m3/s} - autosize, !- No Cooling Supply Air Flow Rate {m3/s} - autosize, !- Heating Supply Air Flow Rate {m3/s} - autosize, !- No Heating Supply Air Flow Rate {m3/s} - autosize, !- Cooling Outdoor Air Flow Rate {m3/s} - autosize, !- Heating Outdoor Air Flow Rate {m3/s} - autosize, !- No Load Outdoor Air Flow Rate {m3/s} - VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name - drawthrough, !- Supply Air Fan Placement - Fan:SystemModel, !- Supply Air Fan Object Type - TU4 VRF Supply Fan, !- Supply Air Fan Object Name - OutdoorAir:Mixer, !- Outside Air Mixer Object Type - TU4 OA Mixer, !- Outside Air Mixer Object Name - Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type - TU4 VRF DX Cooling Coil, !- Cooling Coil Object Name - COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type - TU4 VRF DX Heating Coil, !- Heating Coil Object Name - 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} - 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} - , !- Rated Heating Capacity Sizing Ratio {W/W} - , !- Availability Manager List Name - , !- Design Specification ZoneHVAC Sizing Object Name - , !- Supplemental Heating Coil Object Type - , !- Supplemental Heating Coil Name - ; !- Maximum Supply Air Temperature from Supplemental Heater {C} - - ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, - TU5, !- Zone Terminal Unit Name - VRFAvailSched, !- Terminal Unit Availability Schedule - TU5 Inlet Node, !- Terminal Unit Air Inlet Node Name - TU5 Outlet Node, !- Terminal Unit Air Outlet Node Name - autosize, !- Cooling Supply Air Flow Rate {m3/s} - autosize, !- No Cooling Supply Air Flow Rate {m3/s} - autosize, !- Heating Supply Air Flow Rate {m3/s} - autosize, !- No Heating Supply Air Flow Rate {m3/s} - autosize, !- Cooling Outdoor Air Flow Rate {m3/s} - autosize, !- Heating Outdoor Air Flow Rate {m3/s} - autosize, !- No Load Outdoor Air Flow Rate {m3/s} - VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name - drawthrough, !- Supply Air Fan Placement - Fan:SystemModel, !- Supply Air Fan Object Type - TU5 VRF Supply Fan, !- Supply Air Fan Object Name - OutdoorAir:Mixer, !- Outside Air Mixer Object Type - TU5 OA Mixer, !- Outside Air Mixer Object Name - Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type - TU5 VRF DX Cooling Coil, !- Cooling Coil Object Name - COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type - TU5 VRF DX Heating Coil, !- Heating Coil Object Name - 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} - 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} - , !- Rated Heating Capacity Sizing Ratio {W/W} - , !- Availability Manager List Name - , !- Design Specification ZoneHVAC Sizing Object Name - , !- Supplemental Heating Coil Object Type - , !- Supplemental Heating Coil Name - ; !- Maximum Supply Air Temperature from Supplemental Heater {C} - - Schedule:Compact, - VRFFanSchedule, !- Name - Any Number, !- Schedule Type Limits Name - Through: 12/31, !- Field 1 - For: AllDays, !- Field 2 - Until: 7:00,1.0, !- Field 3 - Until: 18:00,1.0, !- Field 5 - Until: 24:00,1.0; !- Field 7 - - OutdoorAir:Mixer, - TU1 OA Mixer, !- Name - TU1 VRF DX CCoil Inlet Node, !- Mixed Air Node Name - Outside Air Inlet Node 1,!- Outdoor Air Stream Node Name - Relief Air Outlet Node 1,!- Relief Air Stream Node Name - TU1 Inlet Node; !- Return Air Stream Node Name - - OutdoorAir:Mixer, - TU2 OA Mixer, !- Name - TU2 VRF DX CCoil Inlet Node, !- Mixed Air Node Name - Outside Air Inlet Node 2,!- Outdoor Air Stream Node Name - Relief Air Outlet Node 2,!- Relief Air Stream Node Name - TU2 Inlet Node; !- Return Air Stream Node Name - - OutdoorAir:Mixer, - TU3 OA Mixer, !- Name - TU3 VRF DX CCoil Inlet Node, !- Mixed Air Node Name - Outside Air Inlet Node 3,!- Outdoor Air Stream Node Name - Relief Air Outlet Node 3,!- Relief Air Stream Node Name - TU3 Inlet Node; !- Return Air Stream Node Name - - OutdoorAir:Mixer, - TU4 OA Mixer, !- Name - TU4 VRF DX CCoil Inlet Node, !- Mixed Air Node Name - Outside Air Inlet Node 4,!- Outdoor Air Stream Node Name - Relief Air Outlet Node 4,!- Relief Air Stream Node Name - TU4 Inlet Node; !- Return Air Stream Node Name - - OutdoorAir:Mixer, - TU5 OA Mixer, !- Name - TU5 VRF DX CCoil Inlet Node, !- Mixed Air Node Name - Outside Air Inlet Node 5,!- Outdoor Air Stream Node Name - Relief Air Outlet Node 5,!- Relief Air Stream Node Name - TU5 Inlet Node; !- Return Air Stream Node Name + , !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} Fan:SystemModel, TU1 VRF Supply Fan, !- Name @@ -512,7 +345,7 @@ TU1 Outlet Node, !- Air Outlet Node Name autosize, !- Design Maximum Air Flow Rate {m3/s} Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction + 0, !- Electric Power Minimum Flow Rate Fraction 600, !- Design Pressure Rise {Pa} 0.9, !- Motor Efficiency 1, !- Motor In Air Stream Fraction @@ -542,6 +375,38 @@ Dimensionless, !- Input Unit Type for X Dimensionless; !- Output Unit Type + ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, + TU2, !- Zone Terminal Unit Name + VRFAvailSched, !- Terminal Unit Availability Schedule + TU2 Inlet Node, !- Terminal Unit Air Inlet Node Name + TU2 Outlet Node, !- Terminal Unit Air Outlet Node Name + autosize, !- Cooling Supply Air Flow Rate {m3/s} + autosize, !- No Cooling Supply Air Flow Rate {m3/s} + autosize, !- Heating Supply Air Flow Rate {m3/s} + autosize, !- No Heating Supply Air Flow Rate {m3/s} + autosize, !- Cooling Outdoor Air Flow Rate {m3/s} + autosize, !- Heating Outdoor Air Flow Rate {m3/s} + autosize, !- No Load Outdoor Air Flow Rate {m3/s} + VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name + drawthrough, !- Supply Air Fan Placement + Fan:SystemModel, !- Supply Air Fan Object Type + TU2 VRF Supply Fan, !- Supply Air Fan Object Name + OutdoorAir:Mixer, !- Outside Air Mixer Object Type + TU2 OA Mixer, !- Outside Air Mixer Object Name + Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type + TU2 VRF DX Cooling Coil, !- Cooling Coil Object Name + COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type + TU2 VRF DX Heating Coil, !- Heating Coil Object Name + 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} + 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} + , !- Rated Heating Capacity Sizing Ratio {W/W} + , !- Availability Manager List Name + , !- Design Specification ZoneHVAC Sizing Object Name + , !- Supplemental Heating Coil Object Type + , !- Supplemental Heating Coil Name + , !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + Fan:SystemModel, TU2 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name @@ -549,7 +414,7 @@ TU2 Outlet Node, !- Air Outlet Node Name autosize, !- Design Maximum Air Flow Rate {m3/s} Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction + 0, !- Electric Power Minimum Flow Rate Fraction 600, !- Design Pressure Rise {Pa} 0.9, !- Motor Efficiency 1, !- Motor In Air Stream Fraction @@ -579,6 +444,38 @@ Dimensionless, !- Input Unit Type for X Dimensionless; !- Output Unit Type + ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, + TU3, !- Zone Terminal Unit Name + VRFAvailSched, !- Terminal Unit Availability Schedule + TU3 Inlet Node, !- Terminal Unit Air Inlet Node Name + TU3 Outlet Node, !- Terminal Unit Air Outlet Node Name + autosize, !- Cooling Supply Air Flow Rate {m3/s} + autosize, !- No Cooling Supply Air Flow Rate {m3/s} + autosize, !- Heating Supply Air Flow Rate {m3/s} + autosize, !- No Heating Supply Air Flow Rate {m3/s} + autosize, !- Cooling Outdoor Air Flow Rate {m3/s} + autosize, !- Heating Outdoor Air Flow Rate {m3/s} + autosize, !- No Load Outdoor Air Flow Rate {m3/s} + VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name + drawthrough, !- Supply Air Fan Placement + Fan:SystemModel, !- Supply Air Fan Object Type + TU3 VRF Supply Fan, !- Supply Air Fan Object Name + OutdoorAir:Mixer, !- Outside Air Mixer Object Type + TU3 OA Mixer, !- Outside Air Mixer Object Name + Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type + TU3 VRF DX Cooling Coil, !- Cooling Coil Object Name + COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type + TU3 VRF DX Heating Coil, !- Heating Coil Object Name + 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} + 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} + , !- Rated Heating Capacity Sizing Ratio {W/W} + , !- Availability Manager List Name + , !- Design Specification ZoneHVAC Sizing Object Name + , !- Supplemental Heating Coil Object Type + , !- Supplemental Heating Coil Name + , !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + Fan:SystemModel, TU3 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name @@ -586,7 +483,7 @@ TU3 Outlet Node, !- Air Outlet Node Name autosize, !- Design Maximum Air Flow Rate {m3/s} Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction + 0, !- Electric Power Minimum Flow Rate Fraction 600, !- Design Pressure Rise {Pa} 0.9, !- Motor Efficiency 1, !- Motor In Air Stream Fraction @@ -616,6 +513,38 @@ Dimensionless, !- Input Unit Type for X Dimensionless; !- Output Unit Type + ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, + TU4, !- Zone Terminal Unit Name + VRFAvailSched, !- Terminal Unit Availability Schedule + TU4 Inlet Node, !- Terminal Unit Air Inlet Node Name + TU4 Outlet Node, !- Terminal Unit Air Outlet Node Name + autosize, !- Cooling Supply Air Flow Rate {m3/s} + autosize, !- No Cooling Supply Air Flow Rate {m3/s} + autosize, !- Heating Supply Air Flow Rate {m3/s} + autosize, !- No Heating Supply Air Flow Rate {m3/s} + autosize, !- Cooling Outdoor Air Flow Rate {m3/s} + autosize, !- Heating Outdoor Air Flow Rate {m3/s} + autosize, !- No Load Outdoor Air Flow Rate {m3/s} + VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name + drawthrough, !- Supply Air Fan Placement + Fan:SystemModel, !- Supply Air Fan Object Type + TU4 VRF Supply Fan, !- Supply Air Fan Object Name + OutdoorAir:Mixer, !- Outside Air Mixer Object Type + TU4 OA Mixer, !- Outside Air Mixer Object Name + Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type + TU4 VRF DX Cooling Coil, !- Cooling Coil Object Name + COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type + TU4 VRF DX Heating Coil, !- Heating Coil Object Name + 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} + 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} + , !- Rated Heating Capacity Sizing Ratio {W/W} + , !- Availability Manager List Name + , !- Design Specification ZoneHVAC Sizing Object Name + , !- Supplemental Heating Coil Object Type + , !- Supplemental Heating Coil Name + , !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + Fan:SystemModel, TU4 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name @@ -623,7 +552,7 @@ TU4 Outlet Node, !- Air Outlet Node Name autosize, !- Design Maximum Air Flow Rate {m3/s} Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction + 0, !- Electric Power Minimum Flow Rate Fraction 600, !- Design Pressure Rise {Pa} 0.9, !- Motor Efficiency 1, !- Motor In Air Stream Fraction @@ -653,6 +582,38 @@ Dimensionless, !- Input Unit Type for X Dimensionless; !- Output Unit Type + ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, + TU5, !- Zone Terminal Unit Name + VRFAvailSched, !- Terminal Unit Availability Schedule + TU5 Inlet Node, !- Terminal Unit Air Inlet Node Name + TU5 Outlet Node, !- Terminal Unit Air Outlet Node Name + autosize, !- Cooling Supply Air Flow Rate {m3/s} + autosize, !- No Cooling Supply Air Flow Rate {m3/s} + autosize, !- Heating Supply Air Flow Rate {m3/s} + autosize, !- No Heating Supply Air Flow Rate {m3/s} + autosize, !- Cooling Outdoor Air Flow Rate {m3/s} + autosize, !- Heating Outdoor Air Flow Rate {m3/s} + autosize, !- No Load Outdoor Air Flow Rate {m3/s} + VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name + drawthrough, !- Supply Air Fan Placement + Fan:SystemModel, !- Supply Air Fan Object Type + TU5 VRF Supply Fan, !- Supply Air Fan Object Name + OutdoorAir:Mixer, !- Outside Air Mixer Object Type + TU5 OA Mixer, !- Outside Air Mixer Object Name + Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type + TU5 VRF DX Cooling Coil, !- Cooling Coil Object Name + COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type + TU5 VRF DX Heating Coil, !- Heating Coil Object Name + 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} + 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} + , !- Rated Heating Capacity Sizing Ratio {W/W} + , !- Availability Manager List Name + , !- Design Specification ZoneHVAC Sizing Object Name + , !- Supplemental Heating Coil Object Type + , !- Supplemental Heating Coil Name + , !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + Fan:SystemModel, TU5 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name @@ -660,7 +621,7 @@ TU5 Outlet Node, !- Air Outlet Node Name autosize, !- Design Maximum Air Flow Rate {m3/s} Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction + 0, !- Electric Power Minimum Flow Rate Fraction 600, !- Design Pressure Rise {Pa} 0.9, !- Motor Efficiency 1, !- Motor In Air Stream Fraction @@ -683,13 +644,57 @@ 0, !- Coefficient3 x**2 0.928, !- Coefficient4 x**3 0, !- Coefficient5 x**4 - 0.0000000, !- Minimum Value of x + 0.0000000, !- Minimum Value of x 1.0, !- Maximum Value of x 0.0, !- Minimum Curve Output 5.0, !- Maximum Curve Output Dimensionless, !- Input Unit Type for X Dimensionless; !- Output Unit Type + Schedule:Compact, + VRFFanSchedule, !- Name + Any Number, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 7:00,1.0, !- Field 3 + Until: 18:00,1.0, !- Field 5 + Until: 24:00,1.0; !- Field 7 + + OutdoorAir:Mixer, + TU1 OA Mixer, !- Name + TU1 VRF DX CCoil Inlet Node, !- Mixed Air Node Name + Outside Air Inlet Node 1,!- Outdoor Air Stream Node Name + Relief Air Outlet Node 1,!- Relief Air Stream Node Name + TU1 Inlet Node; !- Return Air Stream Node Name + + OutdoorAir:Mixer, + TU2 OA Mixer, !- Name + TU2 VRF DX CCoil Inlet Node, !- Mixed Air Node Name + Outside Air Inlet Node 2,!- Outdoor Air Stream Node Name + Relief Air Outlet Node 2,!- Relief Air Stream Node Name + TU2 Inlet Node; !- Return Air Stream Node Name + + OutdoorAir:Mixer, + TU3 OA Mixer, !- Name + TU3 VRF DX CCoil Inlet Node, !- Mixed Air Node Name + Outside Air Inlet Node 3,!- Outdoor Air Stream Node Name + Relief Air Outlet Node 3,!- Relief Air Stream Node Name + TU3 Inlet Node; !- Return Air Stream Node Name + + OutdoorAir:Mixer, + TU4 OA Mixer, !- Name + TU4 VRF DX CCoil Inlet Node, !- Mixed Air Node Name + Outside Air Inlet Node 4,!- Outdoor Air Stream Node Name + Relief Air Outlet Node 4,!- Relief Air Stream Node Name + TU4 Inlet Node; !- Return Air Stream Node Name + + OutdoorAir:Mixer, + TU5 OA Mixer, !- Name + TU5 VRF DX CCoil Inlet Node, !- Mixed Air Node Name + Outside Air Inlet Node 5,!- Outdoor Air Stream Node Name + Relief Air Outlet Node 5,!- Relief Air Stream Node Name + TU5 Inlet Node; !- Return Air Stream Node Name + !- =========== ALL OBJECTS IN CLASS: COIL:COOLING:DX:VARIABLEREFRIGERANTFLOW:FLUIDTEMPERATURECONTROL =========== Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, @@ -2125,7 +2130,8 @@ HeatBalanceAlgorithm,ConductionTransferFunction; ZoneAirHeatBalanceAlgorithm, - AnalyticalSolution; !- Algorithm + AnalyticalSolution, !- Algorithm + ; !- Do Space Heat Balance for Sizing GlobalGeometryRules, UpperLeftCorner, !- Starting Vertex Position @@ -2827,8 +2833,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.0167, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -2853,7 +2859,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -2867,7 +2873,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -3042,8 +3048,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.00717, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -3068,7 +3074,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -3082,7 +3088,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -3222,8 +3228,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.0167, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -3248,7 +3254,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -3262,7 +3268,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -3417,8 +3423,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.00717, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -3443,7 +3449,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -3457,7 +3463,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -3597,8 +3603,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.031089, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -3623,7 +3629,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -3637,7 +3643,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -3776,7 +3782,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} DesignSpecification:OutdoorAir, SZ DSOA SPACE1-1, !- Name @@ -3812,7 +3825,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} DesignSpecification:OutdoorAir, SZ DSOA SPACE2-1, !- Name @@ -3848,7 +3868,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} DesignSpecification:OutdoorAir, SZ DSOA SPACE3-1, !- Name @@ -3884,7 +3911,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} DesignSpecification:OutdoorAir, SZ DSOA SPACE4-1, !- Name @@ -3920,7 +3954,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} DesignSpecification:OutdoorAir, SZ DSOA SPACE5-1, !- Name diff --git a/testfiles/VariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf b/testfiles/VariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf index 423639c97d9..c40c8642f64 100644 --- a/testfiles/VariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf +++ b/testfiles/VariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf @@ -354,175 +354,8 @@ , !- Design Specification ZoneHVAC Sizing Object Name , !- Supplemental Heating Coil Object Type , !- Supplemental Heating Coil Name - ; !- Maximum Supply Air Temperature from Supplemental Heater {C} - - ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, - TU2, !- Zone Terminal Unit Name - VRFAvailSched, !- Terminal Unit Availability Schedule - TU2 Inlet Node, !- Terminal Unit Air Inlet Node Name - TU2 Outlet Node, !- Terminal Unit Air Outlet Node Name - autosize, !- Cooling Supply Air Flow Rate {m3/s} - autosize, !- No Cooling Supply Air Flow Rate {m3/s} - autosize, !- Heating Supply Air Flow Rate {m3/s} - autosize, !- No Heating Supply Air Flow Rate {m3/s} - autosize, !- Cooling Outdoor Air Flow Rate {m3/s} - autosize, !- Heating Outdoor Air Flow Rate {m3/s} - autosize, !- No Load Outdoor Air Flow Rate {m3/s} - VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name - drawthrough, !- Supply Air Fan Placement - Fan:SystemModel, !- Supply Air Fan Object Type - TU2 VRF Supply Fan, !- Supply Air Fan Object Name - OutdoorAir:Mixer, !- Outside Air Mixer Object Type - TU2 OA Mixer, !- Outside Air Mixer Object Name - Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type - TU2 VRF DX Cooling Coil, !- Cooling Coil Object Name - COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type - TU2 VRF DX Heating Coil, !- Heating Coil Object Name - 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} - 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} - , !- Rated Heating Capacity Sizing Ratio {W/W} - , !- Availability Manager List Name - , !- Design Specification ZoneHVAC Sizing Object Name - , !- Supplemental Heating Coil Object Type - , !- Supplemental Heating Coil Name - ; !- Maximum Supply Air Temperature from Supplemental Heater {C} - - ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, - TU3, !- Zone Terminal Unit Name - VRFAvailSched, !- Terminal Unit Availability Schedule - TU3 Inlet Node, !- Terminal Unit Air Inlet Node Name - TU3 Outlet Node, !- Terminal Unit Air Outlet Node Name - autosize, !- Cooling Supply Air Flow Rate {m3/s} - autosize, !- No Cooling Supply Air Flow Rate {m3/s} - autosize, !- Heating Supply Air Flow Rate {m3/s} - autosize, !- No Heating Supply Air Flow Rate {m3/s} - autosize, !- Cooling Outdoor Air Flow Rate {m3/s} - autosize, !- Heating Outdoor Air Flow Rate {m3/s} - autosize, !- No Load Outdoor Air Flow Rate {m3/s} - VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name - drawthrough, !- Supply Air Fan Placement - Fan:SystemModel, !- Supply Air Fan Object Type - TU3 VRF Supply Fan, !- Supply Air Fan Object Name - OutdoorAir:Mixer, !- Outside Air Mixer Object Type - TU3 OA Mixer, !- Outside Air Mixer Object Name - Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type - TU3 VRF DX Cooling Coil, !- Cooling Coil Object Name - COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type - TU3 VRF DX Heating Coil, !- Heating Coil Object Name - 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} - 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} - , !- Rated Heating Capacity Sizing Ratio {W/W} - , !- Availability Manager List Name - , !- Design Specification ZoneHVAC Sizing Object Name - , !- Supplemental Heating Coil Object Type - , !- Supplemental Heating Coil Name - ; !- Maximum Supply Air Temperature from Supplemental Heater {C} - - ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, - TU4, !- Zone Terminal Unit Name - VRFAvailSched, !- Terminal Unit Availability Schedule - TU4 Inlet Node, !- Terminal Unit Air Inlet Node Name - TU4 Outlet Node, !- Terminal Unit Air Outlet Node Name - autosize, !- Cooling Supply Air Flow Rate {m3/s} - autosize, !- No Cooling Supply Air Flow Rate {m3/s} - autosize, !- Heating Supply Air Flow Rate {m3/s} - autosize, !- No Heating Supply Air Flow Rate {m3/s} - autosize, !- Cooling Outdoor Air Flow Rate {m3/s} - autosize, !- Heating Outdoor Air Flow Rate {m3/s} - autosize, !- No Load Outdoor Air Flow Rate {m3/s} - VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name - drawthrough, !- Supply Air Fan Placement - Fan:SystemModel, !- Supply Air Fan Object Type - TU4 VRF Supply Fan, !- Supply Air Fan Object Name - OutdoorAir:Mixer, !- Outside Air Mixer Object Type - TU4 OA Mixer, !- Outside Air Mixer Object Name - Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type - TU4 VRF DX Cooling Coil, !- Cooling Coil Object Name - COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type - TU4 VRF DX Heating Coil, !- Heating Coil Object Name - 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} - 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} - , !- Rated Heating Capacity Sizing Ratio {W/W} - , !- Availability Manager List Name - , !- Design Specification ZoneHVAC Sizing Object Name - , !- Supplemental Heating Coil Object Type - , !- Supplemental Heating Coil Name - ; !- Maximum Supply Air Temperature from Supplemental Heater {C} - - ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, - TU5, !- Zone Terminal Unit Name - VRFAvailSched, !- Terminal Unit Availability Schedule - TU5 Inlet Node, !- Terminal Unit Air Inlet Node Name - TU5 Outlet Node, !- Terminal Unit Air Outlet Node Name - autosize, !- Cooling Supply Air Flow Rate {m3/s} - autosize, !- No Cooling Supply Air Flow Rate {m3/s} - autosize, !- Heating Supply Air Flow Rate {m3/s} - autosize, !- No Heating Supply Air Flow Rate {m3/s} - autosize, !- Cooling Outdoor Air Flow Rate {m3/s} - autosize, !- Heating Outdoor Air Flow Rate {m3/s} - autosize, !- No Load Outdoor Air Flow Rate {m3/s} - VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name - drawthrough, !- Supply Air Fan Placement - Fan:SystemModel, !- Supply Air Fan Object Type - TU5 VRF Supply Fan, !- Supply Air Fan Object Name - OutdoorAir:Mixer, !- Outside Air Mixer Object Type - TU5 OA Mixer, !- Outside Air Mixer Object Name - Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type - TU5 VRF DX Cooling Coil, !- Cooling Coil Object Name - COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type - TU5 VRF DX Heating Coil, !- Heating Coil Object Name - 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} - 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} - , !- Rated Heating Capacity Sizing Ratio {W/W} - , !- Availability Manager List Name - , !- Design Specification ZoneHVAC Sizing Object Name - , !- Supplemental Heating Coil Object Type - , !- Supplemental Heating Coil Name - ; !- Maximum Supply Air Temperature from Supplemental Heater {C} - - Schedule:Compact, - VRFFanSchedule, !- Name - Any Number, !- Schedule Type Limits Name - Through: 12/31, !- Field 1 - For: AllDays, !- Field 2 - Until: 7:00,1.0, !- Field 3 - Until: 18:00,1.0, !- Field 5 - Until: 24:00,1.0; !- Field 7 - - OutdoorAir:Mixer, - TU1 OA Mixer, !- Name - TU1 VRF DX CCoil Inlet Node, !- Mixed Air Node Name - Outside Air Inlet Node 1,!- Outdoor Air Stream Node Name - Relief Air Outlet Node 1,!- Relief Air Stream Node Name - TU1 Inlet Node; !- Return Air Stream Node Name - - OutdoorAir:Mixer, - TU2 OA Mixer, !- Name - TU2 VRF DX CCoil Inlet Node, !- Mixed Air Node Name - Outside Air Inlet Node 2,!- Outdoor Air Stream Node Name - Relief Air Outlet Node 2,!- Relief Air Stream Node Name - TU2 Inlet Node; !- Return Air Stream Node Name - - OutdoorAir:Mixer, - TU3 OA Mixer, !- Name - TU3 VRF DX CCoil Inlet Node, !- Mixed Air Node Name - Outside Air Inlet Node 3,!- Outdoor Air Stream Node Name - Relief Air Outlet Node 3,!- Relief Air Stream Node Name - TU3 Inlet Node; !- Return Air Stream Node Name - - OutdoorAir:Mixer, - TU4 OA Mixer, !- Name - TU4 VRF DX CCoil Inlet Node, !- Mixed Air Node Name - Outside Air Inlet Node 4,!- Outdoor Air Stream Node Name - Relief Air Outlet Node 4,!- Relief Air Stream Node Name - TU4 Inlet Node; !- Return Air Stream Node Name - - OutdoorAir:Mixer, - TU5 OA Mixer, !- Name - TU5 VRF DX CCoil Inlet Node, !- Mixed Air Node Name - Outside Air Inlet Node 5,!- Outdoor Air Stream Node Name - Relief Air Outlet Node 5,!- Relief Air Stream Node Name - TU5 Inlet Node; !- Return Air Stream Node Name + , !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} Fan:SystemModel, TU1 VRF Supply Fan, !- Name @@ -531,7 +364,7 @@ TU1 Outlet Node, !- Air Outlet Node Name autosize, !- Design Maximum Air Flow Rate {m3/s} Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction + 0, !- Electric Power Minimum Flow Rate Fraction 600, !- Design Pressure Rise {Pa} 0.9, !- Motor Efficiency 1, !- Motor In Air Stream Fraction @@ -561,6 +394,38 @@ Dimensionless, !- Input Unit Type for X Dimensionless; !- Output Unit Type + ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, + TU2, !- Zone Terminal Unit Name + VRFAvailSched, !- Terminal Unit Availability Schedule + TU2 Inlet Node, !- Terminal Unit Air Inlet Node Name + TU2 Outlet Node, !- Terminal Unit Air Outlet Node Name + autosize, !- Cooling Supply Air Flow Rate {m3/s} + autosize, !- No Cooling Supply Air Flow Rate {m3/s} + autosize, !- Heating Supply Air Flow Rate {m3/s} + autosize, !- No Heating Supply Air Flow Rate {m3/s} + autosize, !- Cooling Outdoor Air Flow Rate {m3/s} + autosize, !- Heating Outdoor Air Flow Rate {m3/s} + autosize, !- No Load Outdoor Air Flow Rate {m3/s} + VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name + drawthrough, !- Supply Air Fan Placement + Fan:SystemModel, !- Supply Air Fan Object Type + TU2 VRF Supply Fan, !- Supply Air Fan Object Name + OutdoorAir:Mixer, !- Outside Air Mixer Object Type + TU2 OA Mixer, !- Outside Air Mixer Object Name + Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type + TU2 VRF DX Cooling Coil, !- Cooling Coil Object Name + COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type + TU2 VRF DX Heating Coil, !- Heating Coil Object Name + 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} + 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} + , !- Rated Heating Capacity Sizing Ratio {W/W} + , !- Availability Manager List Name + , !- Design Specification ZoneHVAC Sizing Object Name + , !- Supplemental Heating Coil Object Type + , !- Supplemental Heating Coil Name + , !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + Fan:SystemModel, TU2 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name @@ -568,7 +433,7 @@ TU2 Outlet Node, !- Air Outlet Node Name autosize, !- Design Maximum Air Flow Rate {m3/s} Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction + 0, !- Electric Power Minimum Flow Rate Fraction 600, !- Design Pressure Rise {Pa} 0.9, !- Motor Efficiency 1, !- Motor In Air Stream Fraction @@ -598,6 +463,38 @@ Dimensionless, !- Input Unit Type for X Dimensionless; !- Output Unit Type + ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, + TU3, !- Zone Terminal Unit Name + VRFAvailSched, !- Terminal Unit Availability Schedule + TU3 Inlet Node, !- Terminal Unit Air Inlet Node Name + TU3 Outlet Node, !- Terminal Unit Air Outlet Node Name + autosize, !- Cooling Supply Air Flow Rate {m3/s} + autosize, !- No Cooling Supply Air Flow Rate {m3/s} + autosize, !- Heating Supply Air Flow Rate {m3/s} + autosize, !- No Heating Supply Air Flow Rate {m3/s} + autosize, !- Cooling Outdoor Air Flow Rate {m3/s} + autosize, !- Heating Outdoor Air Flow Rate {m3/s} + autosize, !- No Load Outdoor Air Flow Rate {m3/s} + VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name + drawthrough, !- Supply Air Fan Placement + Fan:SystemModel, !- Supply Air Fan Object Type + TU3 VRF Supply Fan, !- Supply Air Fan Object Name + OutdoorAir:Mixer, !- Outside Air Mixer Object Type + TU3 OA Mixer, !- Outside Air Mixer Object Name + Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type + TU3 VRF DX Cooling Coil, !- Cooling Coil Object Name + COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type + TU3 VRF DX Heating Coil, !- Heating Coil Object Name + 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} + 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} + , !- Rated Heating Capacity Sizing Ratio {W/W} + , !- Availability Manager List Name + , !- Design Specification ZoneHVAC Sizing Object Name + , !- Supplemental Heating Coil Object Type + , !- Supplemental Heating Coil Name + , !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + Fan:SystemModel, TU3 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name @@ -605,7 +502,7 @@ TU3 Outlet Node, !- Air Outlet Node Name autosize, !- Design Maximum Air Flow Rate {m3/s} Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction + 0, !- Electric Power Minimum Flow Rate Fraction 600, !- Design Pressure Rise {Pa} 0.9, !- Motor Efficiency 1, !- Motor In Air Stream Fraction @@ -635,6 +532,38 @@ Dimensionless, !- Input Unit Type for X Dimensionless; !- Output Unit Type + ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, + TU4, !- Zone Terminal Unit Name + VRFAvailSched, !- Terminal Unit Availability Schedule + TU4 Inlet Node, !- Terminal Unit Air Inlet Node Name + TU4 Outlet Node, !- Terminal Unit Air Outlet Node Name + autosize, !- Cooling Supply Air Flow Rate {m3/s} + autosize, !- No Cooling Supply Air Flow Rate {m3/s} + autosize, !- Heating Supply Air Flow Rate {m3/s} + autosize, !- No Heating Supply Air Flow Rate {m3/s} + autosize, !- Cooling Outdoor Air Flow Rate {m3/s} + autosize, !- Heating Outdoor Air Flow Rate {m3/s} + autosize, !- No Load Outdoor Air Flow Rate {m3/s} + VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name + drawthrough, !- Supply Air Fan Placement + Fan:SystemModel, !- Supply Air Fan Object Type + TU4 VRF Supply Fan, !- Supply Air Fan Object Name + OutdoorAir:Mixer, !- Outside Air Mixer Object Type + TU4 OA Mixer, !- Outside Air Mixer Object Name + Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type + TU4 VRF DX Cooling Coil, !- Cooling Coil Object Name + COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type + TU4 VRF DX Heating Coil, !- Heating Coil Object Name + 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} + 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} + , !- Rated Heating Capacity Sizing Ratio {W/W} + , !- Availability Manager List Name + , !- Design Specification ZoneHVAC Sizing Object Name + , !- Supplemental Heating Coil Object Type + , !- Supplemental Heating Coil Name + , !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + Fan:SystemModel, TU4 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name @@ -642,7 +571,7 @@ TU4 Outlet Node, !- Air Outlet Node Name autosize, !- Design Maximum Air Flow Rate {m3/s} Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction + 0, !- Electric Power Minimum Flow Rate Fraction 600, !- Design Pressure Rise {Pa} 0.9, !- Motor Efficiency 1, !- Motor In Air Stream Fraction @@ -672,6 +601,38 @@ Dimensionless, !- Input Unit Type for X Dimensionless; !- Output Unit Type + ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, + TU5, !- Zone Terminal Unit Name + VRFAvailSched, !- Terminal Unit Availability Schedule + TU5 Inlet Node, !- Terminal Unit Air Inlet Node Name + TU5 Outlet Node, !- Terminal Unit Air Outlet Node Name + autosize, !- Cooling Supply Air Flow Rate {m3/s} + autosize, !- No Cooling Supply Air Flow Rate {m3/s} + autosize, !- Heating Supply Air Flow Rate {m3/s} + autosize, !- No Heating Supply Air Flow Rate {m3/s} + autosize, !- Cooling Outdoor Air Flow Rate {m3/s} + autosize, !- Heating Outdoor Air Flow Rate {m3/s} + autosize, !- No Load Outdoor Air Flow Rate {m3/s} + VRFFanSchedule, !- Supply Air Fan Operating Mode Schedule Name + drawthrough, !- Supply Air Fan Placement + Fan:SystemModel, !- Supply Air Fan Object Type + TU5 VRF Supply Fan, !- Supply Air Fan Object Name + OutdoorAir:Mixer, !- Outside Air Mixer Object Type + TU5 OA Mixer, !- Outside Air Mixer Object Name + Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, !- Cooling Coil Object Type + TU5 VRF DX Cooling Coil, !- Cooling Coil Object Name + COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FluidTemperatureControl, !- Heating Coil Object Type + TU5 VRF DX Heating Coil, !- Heating Coil Object Name + 30, !- Zone Terminal Unit On Parasitic Electric Energy Use {W} + 20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W} + , !- Rated Heating Capacity Sizing Ratio {W/W} + , !- Availability Manager List Name + , !- Design Specification ZoneHVAC Sizing Object Name + , !- Supplemental Heating Coil Object Type + , !- Supplemental Heating Coil Name + , !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + Fan:SystemModel, TU5 VRF Supply Fan, !- Name VRFAvailSched, !- Availability Schedule Name @@ -679,7 +640,7 @@ TU5 Outlet Node, !- Air Outlet Node Name autosize, !- Design Maximum Air Flow Rate {m3/s} Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction + 0, !- Electric Power Minimum Flow Rate Fraction 600, !- Design Pressure Rise {Pa} 0.9, !- Motor Efficiency 1, !- Motor In Air Stream Fraction @@ -709,6 +670,50 @@ Dimensionless, !- Input Unit Type for X Dimensionless; !- Output Unit Type + Schedule:Compact, + VRFFanSchedule, !- Name + Any Number, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 7:00,1.0, !- Field 3 + Until: 18:00,1.0, !- Field 5 + Until: 24:00,1.0; !- Field 7 + + OutdoorAir:Mixer, + TU1 OA Mixer, !- Name + TU1 VRF DX CCoil Inlet Node, !- Mixed Air Node Name + Outside Air Inlet Node 1,!- Outdoor Air Stream Node Name + Relief Air Outlet Node 1,!- Relief Air Stream Node Name + TU1 Inlet Node; !- Return Air Stream Node Name + + OutdoorAir:Mixer, + TU2 OA Mixer, !- Name + TU2 VRF DX CCoil Inlet Node, !- Mixed Air Node Name + Outside Air Inlet Node 2,!- Outdoor Air Stream Node Name + Relief Air Outlet Node 2,!- Relief Air Stream Node Name + TU2 Inlet Node; !- Return Air Stream Node Name + + OutdoorAir:Mixer, + TU3 OA Mixer, !- Name + TU3 VRF DX CCoil Inlet Node, !- Mixed Air Node Name + Outside Air Inlet Node 3,!- Outdoor Air Stream Node Name + Relief Air Outlet Node 3,!- Relief Air Stream Node Name + TU3 Inlet Node; !- Return Air Stream Node Name + + OutdoorAir:Mixer, + TU4 OA Mixer, !- Name + TU4 VRF DX CCoil Inlet Node, !- Mixed Air Node Name + Outside Air Inlet Node 4,!- Outdoor Air Stream Node Name + Relief Air Outlet Node 4,!- Relief Air Stream Node Name + TU4 Inlet Node; !- Return Air Stream Node Name + + OutdoorAir:Mixer, + TU5 OA Mixer, !- Name + TU5 VRF DX CCoil Inlet Node, !- Mixed Air Node Name + Outside Air Inlet Node 5,!- Outdoor Air Stream Node Name + Relief Air Outlet Node 5,!- Relief Air Stream Node Name + TU5 Inlet Node; !- Return Air Stream Node Name + !- =========== ALL OBJECTS IN CLASS: COIL:COOLING:DX:VARIABLEREFRIGERANTFLOW:FLUIDTEMPERATURECONTROL =========== Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, @@ -2144,7 +2149,8 @@ HeatBalanceAlgorithm,ConductionTransferFunction; ZoneAirHeatBalanceAlgorithm, - AnalyticalSolution; !- Algorithm + AnalyticalSolution, !- Algorithm + ; !- Do Space Heat Balance for Sizing GlobalGeometryRules, UpperLeftCorner, !- Starting Vertex Position @@ -2846,8 +2852,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.0167, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -2872,7 +2878,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -2886,7 +2892,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -3061,8 +3067,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.00717, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -3087,7 +3093,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -3101,7 +3107,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -3241,8 +3247,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.0167, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -3267,7 +3273,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -3281,7 +3287,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -3436,8 +3442,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.00717, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -3462,7 +3468,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -3476,7 +3482,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -3616,8 +3622,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.031089, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -3642,7 +3648,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -3656,7 +3662,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 107.64, !- Watts per Zone Floor Area {W/m2} + 107.64, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -3795,7 +3801,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} DesignSpecification:OutdoorAir, SZ DSOA SPACE1-1, !- Name @@ -3831,7 +3844,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} DesignSpecification:OutdoorAir, SZ DSOA SPACE2-1, !- Name @@ -3867,7 +3887,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} DesignSpecification:OutdoorAir, SZ DSOA SPACE3-1, !- Name @@ -3903,7 +3930,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} DesignSpecification:OutdoorAir, SZ DSOA SPACE4-1, !- Name @@ -3939,7 +3973,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} DesignSpecification:OutdoorAir, SZ DSOA SPACE5-1, !- Name diff --git a/testfiles/VariableRefrigerantFlow_FluidTCtrl_wSuppHeater_5Zone.idf b/testfiles/VariableRefrigerantFlow_FluidTCtrl_wSuppHeater_5Zone.idf index 611e87422c2..4b4c889d90c 100644 --- a/testfiles/VariableRefrigerantFlow_FluidTCtrl_wSuppHeater_5Zone.idf +++ b/testfiles/VariableRefrigerantFlow_FluidTCtrl_wSuppHeater_5Zone.idf @@ -145,7 +145,8 @@ !- =========== ALL OBJECTS IN CLASS: ZONEAIRHEATBALANCEALGORITHM =========== ZoneAirHeatBalanceAlgorithm, - AnalyticalSolution; !- Algorithm + AnalyticalSolution, !- Algorithm + ; !- Do Space Heat Balance for Sizing !- =========== ALL OBJECTS IN CLASS: TIMESTEP =========== @@ -1721,7 +1722,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -1735,7 +1736,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -1749,7 +1750,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -1763,7 +1764,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -1777,7 +1778,7 @@ LIGHTS-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 16.15, !- Watts per Zone Floor Area {W/m2} + 16.15, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0.0, !- Return Air Fraction 0.59, !- Fraction Radiant @@ -1793,7 +1794,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -1805,7 +1806,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -1817,7 +1818,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -1829,7 +1830,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -1841,7 +1842,7 @@ EQUIP-1, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Design Level {W} - 10.76, !- Watts per Zone Floor Area {W/m2} + 10.76, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.3, !- Fraction Radiant @@ -1855,8 +1856,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.0167, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -1869,8 +1870,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.00717, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -1883,8 +1884,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.0167, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -1897,8 +1898,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.00717, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -1911,8 +1912,8 @@ INFIL-SCH, !- Schedule Name flow/zone, !- Design Flow Rate Calculation Method 0.031089, !- Design Flow Rate {m3/s} - , !- Flow per Zone Floor Area {m3/s-m2} - , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Flow Rate per Floor Area {m3/s-m2} + , !- Flow Rate per Exterior Surface Area {m3/s-m2} , !- Air Changes per Hour {1/hr} 0, !- Constant Term Coefficient 0, !- Temperature Term Coefficient @@ -1991,7 +1992,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} Sizing:Zone, SPACE2-1, !- Zone or ZoneList Name @@ -2020,7 +2028,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} Sizing:Zone, SPACE3-1, !- Zone or ZoneList Name @@ -2049,7 +2064,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} Sizing:Zone, SPACE4-1, !- Zone or ZoneList Name @@ -2078,7 +2100,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} Sizing:Zone, SPACE5-1, !- Zone or ZoneList Name @@ -2107,7 +2136,14 @@ No, !- Account for Dedicated Outdoor Air System NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} - autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + autosize, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + , !- Zone Load Sizing Method + , !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + , !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + , !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} + , !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method + , !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir} + ; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir} !- =========== ALL OBJECTS IN CLASS: SIZING:PLANT =========== ! ************* Hot Water Plant Loop for space heating ****************************** @@ -2222,7 +2258,45 @@ , !- Design Specification ZoneHVAC Sizing Object Name Coil:Heating:Electric, !- Supplemental Heating Coil Object Type TU1 Supp Heating Coil, !- Supplemental Heating Coil Name - autosize; !- Maximum Supply Air Temperature from Supplemental Heater {C} + autosize, !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + + Fan:SystemModel, + TU1 VRF Supply Fan, !- Name + VRFAvailSched, !- Availability Schedule Name + TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name + TU1 VRF Fan Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU1 VRF Supply 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 + General; !- End-Use Subcategory + + Curve:Quartic, + TU1 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, TU2, !- Zone Terminal Unit Name @@ -2253,7 +2327,45 @@ , !- Design Specification ZoneHVAC Sizing Object Name Coil:Heating:Fuel, !- Supplemental Heating Coil Object Type TU2 Supp Heating Coil, !- Supplemental Heating Coil Name - autosize; !- Maximum Supply Air Temperature from Supplemental Heater {C} + autosize, !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + + Fan:SystemModel, + TU2 VRF Supply Fan, !- Name + VRFAvailSched, !- Availability Schedule Name + TU2 VRF DX HCoil Outlet Node, !- Air Inlet Node Name + TU2 VRF Fan Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU2 VRF Supply 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 + General; !- End-Use Subcategory + + Curve:Quartic, + TU2 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, TU3, !- Zone Terminal Unit Name @@ -2284,7 +2396,45 @@ , !- Design Specification ZoneHVAC Sizing Object Name Coil:Heating:Water, !- Supplemental Heating Coil Object Type TU3 Supp Heating Coil, !- Supplemental Heating Coil Name - autosize; !- Maximum Supply Air Temperature from Supplemental Heater {C} + autosize, !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + + Fan:SystemModel, + TU3 VRF Supply Fan, !- Name + VRFAvailSched, !- Availability Schedule Name + TU3 VRF DX HCoil Outlet Node, !- Air Inlet Node Name + TU3 VRF Fan Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU3 VRF Supply 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 + General; !- End-Use Subcategory + + Curve:Quartic, + TU3 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, TU4, !- Zone Terminal Unit Name @@ -2315,7 +2465,45 @@ , !- Design Specification ZoneHVAC Sizing Object Name Coil:Heating:Fuel, !- Supplemental Heating Coil Object Type TU4 Supp Heating Coil, !- Supplemental Heating Coil Name - autosize; !- Maximum Supply Air Temperature from Supplemental Heater {C} + autosize, !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + + Fan:SystemModel, + TU4 VRF Supply Fan, !- Name + VRFAvailSched, !- Availability Schedule Name + TU4 VRF DX HCoil Outlet Node, !- Air Inlet Node Name + TU4 VRF Fan Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU4 VRF Supply 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 + General; !- End-Use Subcategory + + Curve:Quartic, + TU4 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type ZoneHVAC:TerminalUnit:VariableRefrigerantFlow, TU5, !- Zone Terminal Unit Name @@ -2346,7 +2534,45 @@ , !- Design Specification ZoneHVAC Sizing Object Name Coil:Heating:Steam, !- Supplemental Heating Coil Object Type TU5 Supp Heating Coil, !- Supplemental Heating Coil Name - autosize; !- Maximum Supply Air Temperature from Supplemental Heater {C} + autosize, !- Maximum Supply Air Temperature from Supplemental Heater {C} + ; !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + + Fan:SystemModel, + TU5 VRF Supply Fan, !- Name + VRFAvailSched, !- Availability Schedule Name + TU5 VRF DX HCoil Outlet Node, !- Air Inlet Node Name + TU5 VRF Fan Outlet Node, !- Air Outlet Node Name + autosize, !- Design Maximum Air Flow Rate {m3/s} + Continuous, !- Speed Control Method + 0, !- Electric Power Minimum Flow Rate Fraction + 600, !- Design Pressure Rise {Pa} + 0.9, !- Motor Efficiency + 1, !- 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 + TU5 VRF Supply 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 + General; !- End-Use Subcategory + + Curve:Quartic, + TU5 VRF Supply Fan_curve,!- Name + 0.059, !- Coefficient1 Constant + 0, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.928, !- Coefficient4 x**3 + 0, !- Coefficient5 x**4 + 0.0000000, !- Minimum Value of x + 1.0, !- Maximum Value of x + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Dimensionless, !- Input Unit Type for X + Dimensionless; !- Output Unit Type !- =========== ALL OBJECTS IN CLASS: ZONEHVAC:EQUIPMENTLIST =========== @@ -2442,193 +2668,6 @@ SPACE5-1 Node, !- Zone Air Node Name SPACE5-1 Out Node; !- Zone Return Air Node or NodeList Name -!- =========== ALL OBJECTS IN CLASS: FAN:VARIABLEVOLUME =========== - - Fan:SystemModel, - TU1 VRF Supply Fan, !- Name - VRFAvailSched, !- Availability Schedule Name - TU1 VRF DX HCoil Outlet Node, !- Air Inlet Node Name - TU1 VRF Fan Outlet Node, !- Air Outlet Node Name - autosize, !- Design Maximum Air Flow Rate {m3/s} - Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction - 600, !- Design Pressure Rise {Pa} - 0.9, !- Motor Efficiency - 1, !- 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 - TU1 VRF Supply 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 - General; !- End-Use Subcategory - - Curve:Quartic, - TU1 VRF Supply Fan_curve,!- Name - 0.059, !- Coefficient1 Constant - 0, !- Coefficient2 x - 0, !- Coefficient3 x**2 - 0.928, !- Coefficient4 x**3 - 0, !- Coefficient5 x**4 - 0.0000000, !- Minimum Value of x - 1.0, !- Maximum Value of x - 0.0, !- Minimum Curve Output - 5.0, !- Maximum Curve Output - Dimensionless, !- Input Unit Type for X - Dimensionless; !- Output Unit Type - - Fan:SystemModel, - TU2 VRF Supply Fan, !- Name - VRFAvailSched, !- Availability Schedule Name - TU2 VRF DX HCoil Outlet Node, !- Air Inlet Node Name - TU2 VRF Fan Outlet Node, !- Air Outlet Node Name - autosize, !- Design Maximum Air Flow Rate {m3/s} - Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction - 600, !- Design Pressure Rise {Pa} - 0.9, !- Motor Efficiency - 1, !- 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 - TU2 VRF Supply 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 - General; !- End-Use Subcategory - - Curve:Quartic, - TU2 VRF Supply Fan_curve,!- Name - 0.059, !- Coefficient1 Constant - 0, !- Coefficient2 x - 0, !- Coefficient3 x**2 - 0.928, !- Coefficient4 x**3 - 0, !- Coefficient5 x**4 - 0.0000000, !- Minimum Value of x - 1.0, !- Maximum Value of x - 0.0, !- Minimum Curve Output - 5.0, !- Maximum Curve Output - Dimensionless, !- Input Unit Type for X - Dimensionless; !- Output Unit Type - - Fan:SystemModel, - TU3 VRF Supply Fan, !- Name - VRFAvailSched, !- Availability Schedule Name - TU3 VRF DX HCoil Outlet Node, !- Air Inlet Node Name - TU3 VRF Fan Outlet Node, !- Air Outlet Node Name - autosize, !- Design Maximum Air Flow Rate {m3/s} - Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction - 600, !- Design Pressure Rise {Pa} - 0.9, !- Motor Efficiency - 1, !- 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 - TU3 VRF Supply 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 - General; !- End-Use Subcategory - - Curve:Quartic, - TU3 VRF Supply Fan_curve,!- Name - 0.059, !- Coefficient1 Constant - 0, !- Coefficient2 x - 0, !- Coefficient3 x**2 - 0.928, !- Coefficient4 x**3 - 0, !- Coefficient5 x**4 - 0.0000000, !- Minimum Value of x - 1.0, !- Maximum Value of x - 0.0, !- Minimum Curve Output - 5.0, !- Maximum Curve Output - Dimensionless, !- Input Unit Type for X - Dimensionless; !- Output Unit Type - - Fan:SystemModel, - TU4 VRF Supply Fan, !- Name - VRFAvailSched, !- Availability Schedule Name - TU4 VRF DX HCoil Outlet Node, !- Air Inlet Node Name - TU4 VRF Fan Outlet Node, !- Air Outlet Node Name - autosize, !- Design Maximum Air Flow Rate {m3/s} - Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction - 600, !- Design Pressure Rise {Pa} - 0.9, !- Motor Efficiency - 1, !- 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 - TU4 VRF Supply 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 - General; !- End-Use Subcategory - - Curve:Quartic, - TU4 VRF Supply Fan_curve,!- Name - 0.059, !- Coefficient1 Constant - 0, !- Coefficient2 x - 0, !- Coefficient3 x**2 - 0.928, !- Coefficient4 x**3 - 0, !- Coefficient5 x**4 - 0.0000000, !- Minimum Value of x - 1.0, !- Maximum Value of x - 0.0, !- Minimum Curve Output - 5.0, !- Maximum Curve Output - Dimensionless, !- Input Unit Type for X - Dimensionless; !- Output Unit Type - - Fan:SystemModel, - TU5 VRF Supply Fan, !- Name - VRFAvailSched, !- Availability Schedule Name - TU5 VRF DX HCoil Outlet Node, !- Air Inlet Node Name - TU5 VRF Fan Outlet Node, !- Air Outlet Node Name - autosize, !- Design Maximum Air Flow Rate {m3/s} - Continuous, !- Speed Control Method - 0.0, !- Electric Power Minimum Flow Rate Fraction - 600, !- Design Pressure Rise {Pa} - 0.9, !- Motor Efficiency - 1, !- 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 - TU5 VRF Supply 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 - General; !- End-Use Subcategory - - Curve:Quartic, - TU5 VRF Supply Fan_curve,!- Name - 0.059, !- Coefficient1 Constant - 0, !- Coefficient2 x - 0, !- Coefficient3 x**2 - 0.928, !- Coefficient4 x**3 - 0, !- Coefficient5 x**4 - 0.0000000, !- Minimum Value of x - 1.0, !- Maximum Value of x - 0.0, !- Minimum Curve Output - 5.0, !- Maximum Curve Output - Dimensionless, !- Input Unit Type for X - Dimensionless; !- Output Unit Type - !- =========== ALL OBJECTS IN CLASS: COIL:COOLING:DX:VARIABLEREFRIGERANTFLOW:FLUIDTEMPERATURECONTROL =========== Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl, @@ -2905,7 +2944,7 @@ Branch, Heating Purchased Hot Water Branch, !- Name , !- Pressure Drop Curve Name - DistrictHeating:Water, !- Component 1 Object Type + DistrictHeating:Water, !- Component 1 Object Type Purchased Heating, !- Component 1 Name Purchased Heat Inlet Node, !- Component 1 Inlet Node Name Purchased Heat Outlet Node; !- Component 1 Outlet Node Name @@ -3357,7 +3396,7 @@ PlantEquipmentList, heating plant, !- Name - DistrictHeating:Water, !- Equipment 1 Object Type + DistrictHeating:Water, !- Equipment 1 Object Type Purchased Heating; !- Equipment 1 Name PlantEquipmentList, From dc5c34246fd34b83c3790c06cb581e6af9f121a5 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Thu, 1 Aug 2024 17:58:36 -0700 Subject: [PATCH 57/81] change READ to ProcessNumber --- src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 index 67a848f7a97..8015e693f6b 100644 --- a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 +++ b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 @@ -601,11 +601,20 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile OutArgs(6) = 'Continuous' !- Speed Control Method IF (SameString(OldFanVO(Num3)%minFlowInputMethod, "FixedFlowRate")) THEN IF (.NOT. SameString(OldFanVO(Num3)%maxAirFlow_str, "AUTOSIZE")) THEN - READ(OldFanVO(Num3)%fanPowerMinAirFlow_str, '(F15.5)') fanPowerMinAirFlow - READ(OldFanVO(Num3)%maxAirFlow_str, '(F15.5)') maxAirFlow + fanPowerMinAirFlow = ProcessNumber(OldFanVO(Num3)%fanPowerMinAirFlow_str, ErrFlag) + IF (ErrFlag) THEN + CALL ShowSevereError('Invalid Number, FAN:VARIABLEVOLUME field 8, Fan Power Minimum Air Flow Rate, Name=' // TRIM(OutArgs(1)), Auditf) + END IF + maxAirFlow = ProcessNumber(OldFanVO(Num3)%maxAirFlow_str, ErrFlag) + IF (ErrFlag) THEN + CALL ShowSevereError('Invalid Number, FAN:VARIABLEVOLUME field 5, Maximum Flow Rate, Name=' // TRIM(OutArgs(1)), Auditf) + END IF WRITE(OutArgs(7), '(F15.5)') (fanPowerMinAirFlow / maxAirFlow) ELSE ! maxAirFlow_stris autosize - READ(OldFanVO(Num3)%fanPowerMinAirFlow_str, '(F15.5)') fanPowerMinAirFlow + fanPowerMinAirFlow = ProcessNumber(OldFanVO(Num3)%fanPowerMinAirFlow_str, ErrFlag) + IF (ErrFlag) THEN + CALL ShowSevereError('Invalid Number, FAN:VARIABLEVOLUME field 8, Fan Power Minimum Air Flow Rate, Name=' // TRIM(OutArgs(1)), Auditf) + END IF IF (.NOT. fanPowerMinAirFlow == 0) THEN ! don't know how to do division with autosize CALL writePreprocessorObject(DifLfn, PrognameConversion, 'Warning', & 'Cannot calculate Electric Power Minimum Flow Rate Fraction for' // sysFanName // & From d1c3cd7fd1522b564943cd416a53ca6eb15d1a31 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Thu, 1 Aug 2024 17:59:12 -0700 Subject: [PATCH 58/81] update err message and call ShowWarningError --- src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 index 8015e693f6b..78cd7eb1b90 100644 --- a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 +++ b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 @@ -617,8 +617,14 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile END IF IF (.NOT. fanPowerMinAirFlow == 0) THEN ! don't know how to do division with autosize CALL writePreprocessorObject(DifLfn, PrognameConversion, 'Warning', & - 'Cannot calculate Electric Power Minimum Flow Rate Fraction for' // sysFanName // & - 'when Maximum Flow Rate is autosize and Fan Power Minimum Air Flow Rate is non-zero') + 'Cannot calculate Electric Power Minimum Flow Rate Fraction for Fan:SystemModel=' // sysFanName // & + ' when old Fan:VariableVolume Maximum Flow Rate is autosize and Fan Power Minimum Air Flow Rate is non-zero. ' // & + 'Electric Power Minimum Flow Rate Fraction is set to zero. ' // & + 'Manually size the Maximum Flow Rate if Electric Power Minimum Flow Rate Fraction should not be zero.') + CALL ShowWarningError('Cannot calculate Electric Power Minimum Flow Rate Fraction for Fan:SystemModel=' // sysFanName // & + ' when old Fan:VariableVolume Maximum Flow Rate is autosize and Fan Power Minimum Air Flow Rate is non-zero. ' // & + 'Electric Power Minimum Flow Rate Fraction is set to zero. ' // & + 'Manually size the Maximum Flow Rate if Electric Power Minimum Flow Rate Fraction should not be zero.', Auditf) END IF OutArgs(7) = '0.0' ENDIF From 3c6c5813377b6e3a560e3553e57a9b3612b2c352 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Thu, 1 Aug 2024 17:59:32 -0700 Subject: [PATCH 59/81] use 0.0 as min x value of fan performance curve --- src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 index 78cd7eb1b90..d8bf573e276 100644 --- a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 +++ b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 @@ -657,8 +657,7 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile OutArgs(4) = OldFanVO(Num3)%coeff3 !- Coefficient3 x**2 OutArgs(5) = OldFanVO(Num3)%coeff4 !- Coefficient4 x**3 OutArgs(6) = OldFanVO(Num3)%coeff5 !- Coefficient5 x**4 - READ(OldFanVO(Num3)%fanPowerMinAirFlow_str, '(F15.5)') fanPowerMinAirFlow - WRITE(OutArgs(7), '(F10.7)') (fanPowerMinAirFlow / maxAirFlow) !- Minimum Value of x + OutArgs(7) = '0.0' !- Minimum Value of x OutArgs(8) = '1.0' !- Maximum Value of x OutArgs(9) = '0.0' !- Minimum Curve Output OutArgs(10) = '5.0' !- Maximum Curve Output From f1cb19f478affeb3d5d2f24671c3bcb359f25503 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Fri, 2 Aug 2024 11:39:56 -0500 Subject: [PATCH 60/81] Space IV-Final NFP and Design --- .../FY2024/NFP-Space Sizing and HVAC-Part4.md | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/design/FY2024/NFP-Space Sizing and HVAC-Part4.md b/design/FY2024/NFP-Space Sizing and HVAC-Part4.md index 5f6aef92e27..029ba7e734b 100644 --- a/design/FY2024/NFP-Space Sizing and HVAC-Part4.md +++ b/design/FY2024/NFP-Space Sizing and HVAC-Part4.md @@ -4,6 +4,7 @@ Extend Spaces to Sizing and HVAC - Part 4 **Michael J. Witte, GARD Analytics, Inc.** - Original June 17, 2024 + - Revised, August 2, 2024 ## Table of Contents ## @@ -26,6 +27,7 @@ Extend Spaces to Sizing and HVAC - Part 4 [Design](#design) ## E-mail and Conference Call Conclusions ## +June 17-20, Q&A in the pull request with rraustad. Made some minor updates to the NFP to clarify the sizing methods and to mention that an spsz output file will be created, similar to the existing zsz output. ## Background and Overview ## @@ -61,7 +63,16 @@ This NFP proposes additional optional capabilities: ## Approach ## ### Sizing -* Currently zone sizing is independent of space sizing, essentially sizing all zone equipment to the coincident space peak. A new input will be added to Sizing:Zone to allow zone sizing using the non-coincident space peaks. +A new input will be added to Sizing:Zone to allow zone sizing using the non-coincident space peaks or the coincident peak. + +Space sizing is an actual heat balance on each space. Currently zone sizing is an actual heat balance on each zone (as a whole) although some of the components for the zone heat balance are sums across the spaces (even when space heat balance is off). e.g. internal gains. The current zone sizing calculations will be used to calculate the coincident zone sizing using the combined spaces. + +For the non-coincident zone sizing, the individual space peaks will be summed and other values (such as outdoor temperature) will be averaged. + +When space sizing is active, sizing results are reported in the table output for both spaces and zones. There will be no change here. + +When space sizing is active, a new spssz output file will be generated, similar to the existing zsz output. This will require a new field in the OutputControl:Files object. + ### HVAC * Calculate return flows at the Space level. Currently, space return nodes can be specified, but there is no flow assigned to them. All return flow is lumped at the zone level. @@ -79,14 +90,25 @@ Compare Space vs Zone-level results. Some new objects and some changes to existing objects are proposed. ### Sizing:Zone -* *New field:"* +* *New field at the end:"* ``` - A??, \field Type of Space Sum to Use + A15; \field Type of Space Sum to Use \type choice \key Coincident \key NonCoincident \default Coincident ``` + +### OutputControl:Files +* *New field in the middle:"* +``` + A9 , \field Output Space Sizing + \type choice + \key Yes + \key No + \default Yes +``` + ### ZoneRefrigerationDoorMixing (If budget allows, otherwise limit these to single-space zones.) * *Change field "Zone 1 Name" to "Zone or Space Name 1."* @@ -105,6 +127,7 @@ Some new objects and some changes to existing objects are proposed. ## Outputs Description ## +A new Spsz output file will be created when space sizing is active. ## Engineering Reference ## @@ -112,11 +135,11 @@ Some new objects and some changes to existing objects are proposed. ## Example File and Transition Changes ## -* Transition may be required for idf Sizing:Zone if the new field is placed in the middle of the object. +* Transition will be required for idf OutputControl:Files. * Field name changes may be required for epJSON inputs for ZoneRefrigerationDoorMixing, ZoneCoolTower:Shower, and/or ZoneThermalChimney. -* The existing example file 5ZoneAirCooledWithSpaces will be copied to a new example file that uses the new Sizing:Zone Conincident Space sum option. +* The existing example file 5ZoneAirCooledWithSpaces will be copied to a new example file that uses the new Sizing:Zone Coincident Space sum option. ## Design ## From 698ddbf4ce3aa023a9becab9188875d9e373daca Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Mon, 5 Aug 2024 09:18:14 -0700 Subject: [PATCH 61/81] min value of system fan curve in idf change to 0 --- testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf b/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf index 2a21a3cbc47..b766fbdc1a5 100644 --- a/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf +++ b/testfiles/US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf @@ -530,7 +530,7 @@ 0, !- Coefficient3 x**2 0.91, !- Coefficient4 x**3 0, !- Coefficient5 x**4 - 0.6974790, !- Minimum Value of x + 0.0, !- Minimum Value of x 1.0, !- Maximum Value of x 0.0, !- Minimum Curve Output 5.0, !- Maximum Curve Output From 261699abc631efc6eb20e73a8181f49c6442e2db Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 7 Aug 2024 12:07:20 -0700 Subject: [PATCH 62/81] remove OU fan adjustment and put it in a different PR there might be larger issue with the OU fan like negative VRF Heat Pump Outdoor Unit Fan Power value. This will be fixed in another PR --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index cda29a32fe6..497f4a341a1 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -11506,9 +11506,9 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) // Key outputs of this subroutine this->CompActSpeed = max(CompSpdActual, 0.0); - this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter; // 0.95 is the efficiency of the compressor inverter, can come from IDF //@minor - this->OUFanPower = this->RatedOUFanPower * CyclingRatio; //@ * pow_3( CondFlowRatio ) - this->VRFCondCyclingRatio = CyclingRatio; // report variable for cycling rate + this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter; // 0.95 is the efficiency of the compressor inverter, can come from IDF //@minor + this->OUFanPower = this->RatedOUFanPower; //@ * pow_3( CondFlowRatio ) + this->VRFCondCyclingRatio = CyclingRatio; // report variable for cycling rate Tdischarge = this->CondensingTemp; // outdoor unit condensing temperature this->CoolingCapacity = @@ -11736,7 +11736,7 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) // Key outputs of this subroutine this->CompActSpeed = max(CompSpdActual, 0.0); this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter; - this->OUFanPower = this->RatedOUFanPower * CyclingRatio; + this->OUFanPower = this->RatedOUFanPower; this->VRFCondCyclingRatio = CyclingRatio; Tsuction = this->EvaporatingTemp; // Outdoor unit evaporating temperature From 390e393bd1ec528b60f943c5f06ed6d93506172f Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Fri, 9 Aug 2024 08:01:35 -0500 Subject: [PATCH 63/81] Space IV-ZoneRefrigerationDoorMixing --- .../src/overview/group-airflow.tex | 10 ++-- idd/Energy+.idd.in | 10 +++- src/EnergyPlus/HeatBalanceAirManager.cc | 19 +++++- src/EnergyPlus/ZoneEquipmentManager.cc | 59 ++++++++++++++----- 4 files changed, 72 insertions(+), 26 deletions(-) diff --git a/doc/input-output-reference/src/overview/group-airflow.tex b/doc/input-output-reference/src/overview/group-airflow.tex index 4d6aea4e36c..db393414b97 100644 --- a/doc/input-output-reference/src/overview/group-airflow.tex +++ b/doc/input-output-reference/src/overview/group-airflow.tex @@ -1518,7 +1518,7 @@ \subsection{ZoneRefrigerationDoorMixing}\label{zonerefrigerationdoormixing} ZoneRefrigerationDoorMixing is ideally suited for two zones, at least one of which is refrigerated, that exchange an equal amount of dry air. As with \hyperref[zonemixing]{ZoneMixing}, this is a simplified interzone airflow in EnergyPlus. The ZoneRefrigerationDoorMixing approach shares some features of both \hyperref[zonemixing]{ZoneMixing} and \hyperref[zonecrossmixing]{ZoneCrossMixing}. Like \hyperref[zonecrossmixing]{ZoneCrossMixing}, ZoneRefrigerationDoorMixing has an energy effect on both the source and the receiving zone, thus maintaining both the air mass and energy balances in the two zones. Unlike the other two mixing objects, ZoneRefrigerationDoorMixing always calculates the air exchange rate based on the zone temperature and relative humidity. That is, the user does not specify the air flow rate. The user can moderate the flow through a door-opening schedule. -ZoneRefrigerationDoorMixing can only be entered once for any unique pair of zones. It doesn't matter which zone is listed first and the zones will automatically switch back and forth between source and receiving zones depending upon which zone is colder. +ZoneRefrigerationDoorMixing can only be entered once for any unique pair of zones. It doesn't matter which zone is listed first and the zones will automatically switch back and forth between source and receiving zones depending upon which zone is colder. If space heat balance is active and a space name is specified for Space or Zone Name 1 or 2, then the space conditions will be used and the exchange will be with that space only. If space heat balance is active and a zone name is specified, then the aveerage zone conditions will be used, and the exchange will be proportioned to all spaces in the zone by space volume. \subsubsection{Inputs}\label{inputs-7-003} @@ -1526,13 +1526,13 @@ \subsubsection{Inputs}\label{inputs-7-003} The name of the ZoneRefrigerationDoorMixing object. -\paragraph{Field: Zone 1~ Name}\label{field-zone-1-name} +\paragraph{Field: Zone or Space Name 1}\label{field-zone-1-name} -This field is the name of one of the two zones (ref: Zone) exchanging air and attaches a particular refrigeration door~ mixing statement to both thermal zones in the building. +This field is the name of one of the two zones (ref: Zone) or spaces exchanging air and attaches a particular refrigeration door~ mixing statement to both thermal zones or spaces in the building. If a space name is used, it must belong to a different zone than Zone or Space Name 2. -\paragraph{Field: Zone 2~ Name}\label{field-zone-2-name} +\paragraph{Field: Zone or Space Name 2}\label{field-zone-2-name} -This field is the name of the other zone (ref: Zone) exchanging air and attaches a particular refrigeration door~ mixing statement to both thermal zones in the building. +This field is the name of the other zone (ref: Zone) or space exchanging air and attaches a particular refrigeration door~ mixing statement to both thermal zones or spaces in the building. If a space name is used, it must belong to a different zone than Zone or Space Name 1. \paragraph{Field: Schedule Name}\label{field-schedule-name-5} diff --git a/idd/Energy+.idd.in b/idd/Energy+.idd.in index d0901eae735..a3ebbedd817 100644 --- a/idd/Energy+.idd.in +++ b/idd/Energy+.idd.in @@ -24572,7 +24572,7 @@ ZoneCrossMixing, ZoneRefrigerationDoorMixing, \min-fields 4 - \memo Refrigeration Door Mixing is used for an opening between two zones that are at the + \memo Refrigeration Door Mixing is used for an opening between two zones (or spaces) that are at the \memo same elevation but have different air temperatures. In this case, the mixing air flow \memo between the two zones is determined by the density difference between the two zones. \memo This would typically be used between two zones in a refrigerated warehouse that are @@ -24581,14 +24581,18 @@ ZoneRefrigerationDoorMixing, A1 , \field Name \required-field \type alpha - A2 , \field Zone 1 Name + A2 , \field Zone or Space Name 1 + \note If a space name is used, it must belong to a different zone than Zone or Space Name 2. \required-field \type object-list \object-list ZoneNames - A3 , \field Zone 2 Name + \object-list SpaceNames + A3 , \field Zone or Space Name 2 + \note If a space name is used, it must belong to a different zone than Zone or Space Name 1. \required-field \type object-list \object-list ZoneNames + \object-list SpaceNames A4 , \field Schedule Name \note This schedule defines the fraction of the time the refrigeration door is open \note For example, if the warehouse is closed at night and there are no door openings diff --git a/src/EnergyPlus/HeatBalanceAirManager.cc b/src/EnergyPlus/HeatBalanceAirManager.cc index e9745fcad4f..870f2f35162 100644 --- a/src/EnergyPlus/HeatBalanceAirManager.cc +++ b/src/EnergyPlus/HeatBalanceAirManager.cc @@ -3802,7 +3802,8 @@ void GetSimpleAirModelInputs(EnergyPlusData &state, bool &ErrorsFound) // IF err int AlphaNum = 2; int Zone1Num = Util::FindItemInList(cAlphaArgs(AlphaNum), state.dataHeatBal->Zone); - if (Zone1Num == 0) { + int space1Num = Util::FindItemInList(cAlphaArgs(AlphaNum), state.dataHeatBal->space); + if ((Zone1Num == 0) && (space1Num==0)) { ShowSevereError(state, format("{}{}=\"{}\", invalid (not found) {}=\"{}\".", RoutineName, @@ -3811,11 +3812,14 @@ void GetSimpleAirModelInputs(EnergyPlusData &state, bool &ErrorsFound) // IF err cAlphaFieldNames(AlphaNum), cAlphaArgs(AlphaNum))); ErrorsFound = true; + } else if (Zone1Num == 0) { + Zone1Num = state.dataHeatBal->space(space1Num).zoneNum; } ++AlphaNum; // 3 int Zone2Num = Util::FindItemInList(cAlphaArgs(AlphaNum), state.dataHeatBal->Zone); - if (Zone2Num == 0) { + int space2Num = Util::FindItemInList(cAlphaArgs(AlphaNum), state.dataHeatBal->space); + if ((Zone2Num == 0) && (space2Num==0)) { ShowSevereError(state, format("{}{}=\"{}\", invalid (not found) {}=\"{}\".", RoutineName, @@ -3824,7 +3828,12 @@ void GetSimpleAirModelInputs(EnergyPlusData &state, bool &ErrorsFound) // IF err cAlphaFieldNames(AlphaNum), cAlphaArgs(AlphaNum))); ErrorsFound = true; + } else if (Zone2Num == 0) { + Zone2Num = state.dataHeatBal->space(space2Num).zoneNum; } + + int spaceNumA = 0; + int spaceNumB = 0; if (Zone1Num == Zone2Num) { ShowSevereError(state, format("{}{}=\"{}\", The same zone name has been entered for both sides of a refrigerated door {}=\"{}\".", @@ -3837,9 +3846,13 @@ void GetSimpleAirModelInputs(EnergyPlusData &state, bool &ErrorsFound) // IF err } else if (Zone1Num < Zone2Num) { // zone 1 will come first in soln loop, id zone 2 as mate zone ZoneNumA = Zone1Num; ZoneNumB = Zone2Num; + spaceNumA = space1Num; + spaceNumB = space2Num; } else { // zone 2 will come first in soln loop, id zone 1 as mate zone ZoneNumA = Zone2Num; ZoneNumB = Zone1Num; + spaceNumA = space2Num; + spaceNumB = space1Num; } if (!allocated(state.dataHeatBal->RefDoorMixing(ZoneNumA).OpenSchedPtr)) { @@ -3891,6 +3904,8 @@ void GetSimpleAirModelInputs(EnergyPlusData &state, bool &ErrorsFound) // IF err ConnectionNumber = state.dataHeatBal->RefDoorMixing(ZoneNumA).NumRefDoorConnections + 1; state.dataHeatBal->RefDoorMixing(ZoneNumA).NumRefDoorConnections = ConnectionNumber; state.dataHeatBal->RefDoorMixing(ZoneNumA).ZonePtr = ZoneNumA; + state.dataHeatBal->RefDoorMixing(ZoneNumA).spaceIndex = spaceNumA; + state.dataHeatBal->RefDoorMixing(ZoneNumA).fromSpaceIndex = spaceNumB; state.dataHeatBal->RefDoorMixing(ZoneNumA).MateZonePtr(ConnectionNumber) = ZoneNumB; state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorMixingObjectName(ConnectionNumber) = NameThisObject; // need to make sure same pair of zones is only entered once. diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index 6c4089019e1..ae3ecdf4cbd 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -6403,9 +6403,15 @@ void CalcAirFlowSimple(EnergyPlusData &state, // Zone loops structured in getinput so only do each pair of zones bounding door once, even if multiple doors in one zone for (int ZoneA = 1; ZoneA <= (state.dataGlobal->NumOfZones - 1); ++ZoneA) { if (!state.dataHeatBal->RefDoorMixing(ZoneA).RefDoorMixFlag) continue; + auto &thisRefDoorMixing = state.dataHeatBal->RefDoorMixing(ZoneA); auto &zoneAHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneA); Real64 TZoneA = zoneAHB.MixingMAT; Real64 HumRatZoneA = zoneAHB.MixingHumRat; + if ((state.dataHeatBal->doSpaceHeatBalance) && (thisRefDoorMixing.spaceIndex > 0)) { + auto &spaceAHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisRefDoorMixing.spaceIndex); + TZoneA = spaceAHB.MixingMAT; + HumRatZoneA = spaceAHB.MixingHumRat; + } Real64 AirDensityZoneA = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TZoneA, HumRatZoneA, RoutineNameRefrigerationDoorMixing); Real64 CpAirZoneA = PsyCpAirFnW(HumRatZoneA); for (int j = 1; j <= state.dataHeatBal->RefDoorMixing(ZoneA).NumRefDoorConnections; ++j) { @@ -6414,6 +6420,11 @@ void CalcAirFlowSimple(EnergyPlusData &state, Real64 TZoneB = zoneBHB.MixingMAT; Real64 HumRatZoneB = zoneBHB.MixingHumRat; Real64 CpAirZoneB = PsyCpAirFnW(HumRatZoneB); + if ((state.dataHeatBal->doSpaceHeatBalance) && (thisRefDoorMixing.fromSpaceIndex > 0)) { + auto &spaceBHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisRefDoorMixing.fromSpaceIndex); + TZoneB = spaceBHB.MixingMAT; + HumRatZoneB = spaceBHB.MixingHumRat; + } Real64 Tavg = (TZoneA + TZoneB) / 2.0; Real64 Wavg = (HumRatZoneA + HumRatZoneB) / 2.0; Real64 AirDensityAvg = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, Tavg, Wavg, RoutineNameRefrigerationDoorMixing); @@ -6471,23 +6482,39 @@ void CalcAirFlowSimple(EnergyPlusData &state, zoneAHB.MixingMassFlowXHumRat += MassFlowXHumRatToA; zoneBHB.MixingMassFlowXHumRat += MassFlowXHumRatToB; if (state.dataHeatBal->doSpaceHeatBalance) { - // ZoneRefrigerationDoorMixing has no space information, just zones - // Allocate mixing flows by space volume fraction of zone volume - for (int spaceNum : state.dataHeatBal->Zone(ZoneA).spaceIndexes) { - Real64 spaceFrac = state.dataHeatBal->space(spaceNum).fracZoneVolume; - auto &spaceAHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum); - spaceAHB.MCPM += MassFlowXCpToA * spaceFrac; - spaceAHB.MCPTM += MassFlowXCpXTempToA * spaceFrac; - spaceAHB.MixingMassFlowZone += MassFlowToA * spaceFrac; - spaceAHB.MixingMassFlowXHumRat += MassFlowXHumRatToA * spaceFrac; + if (thisRefDoorMixing.spaceIndex > 0) { + auto &spaceAHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisRefDoorMixing.spaceIndex); + spaceAHB.MCPM += MassFlowXCpToA; + spaceAHB.MCPTM += MassFlowXCpXTempToA; + spaceAHB.MixingMassFlowZone += MassFlowToA; + spaceAHB.MixingMassFlowXHumRat += MassFlowXHumRatToA; + } else { + // Allocate mixing flows by space volume fraction of zone volume + for (int spaceNum : state.dataHeatBal->Zone(ZoneA).spaceIndexes) { + Real64 spaceFrac = state.dataHeatBal->space(spaceNum).fracZoneVolume; + auto &spaceAHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum); + spaceAHB.MCPM += MassFlowXCpToA * spaceFrac; + spaceAHB.MCPTM += MassFlowXCpXTempToA * spaceFrac; + spaceAHB.MixingMassFlowZone += MassFlowToA * spaceFrac; + spaceAHB.MixingMassFlowXHumRat += MassFlowXHumRatToA * spaceFrac; + } } - for (int spaceNum : state.dataHeatBal->Zone(ZoneB).spaceIndexes) { - Real64 spaceFrac = state.dataHeatBal->space(spaceNum).fracZoneVolume; - auto &spaceBHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum); - spaceBHB.MCPM += MassFlowXCpToB * spaceFrac; - spaceBHB.MCPTM += MassFlowXCpXTempToB * spaceFrac; - spaceBHB.MixingMassFlowZone += MassFlowToB * spaceFrac; - spaceBHB.MixingMassFlowXHumRat += MassFlowXHumRatToB * spaceFrac; + if (thisRefDoorMixing.spaceIndex > 0) { + auto &spaceBHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisRefDoorMixing.fromSpaceIndex); + spaceBHB.MCPM += MassFlowXCpToB; + spaceBHB.MCPTM += MassFlowXCpXTempToB; + spaceBHB.MixingMassFlowZone += MassFlowToB; + spaceBHB.MixingMassFlowXHumRat += MassFlowXHumRatToB; + } else { + // Allocate mixing flows by space volume fraction of zone volume + for (int spaceNum : state.dataHeatBal->Zone(ZoneB).spaceIndexes) { + Real64 spaceFrac = state.dataHeatBal->space(spaceNum).fracZoneVolume; + auto &spaceBHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum); + spaceBHB.MCPM += MassFlowXCpToB * spaceFrac; + spaceBHB.MCPTM += MassFlowXCpXTempToB * spaceFrac; + spaceBHB.MixingMassFlowZone += MassFlowToB * spaceFrac; + spaceBHB.MixingMassFlowXHumRat += MassFlowXHumRatToB * spaceFrac; + } } } From 8d8fec6187a832ee6e360ceee8c8027434c8d6ee Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Fri, 9 Aug 2024 15:53:06 -0500 Subject: [PATCH 64/81] Space IV-ZoneRefrigerationDoorMixing --- src/EnergyPlus/HeatBalanceAirManager.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EnergyPlus/HeatBalanceAirManager.cc b/src/EnergyPlus/HeatBalanceAirManager.cc index 870f2f35162..8467d62d731 100644 --- a/src/EnergyPlus/HeatBalanceAirManager.cc +++ b/src/EnergyPlus/HeatBalanceAirManager.cc @@ -3803,7 +3803,7 @@ void GetSimpleAirModelInputs(EnergyPlusData &state, bool &ErrorsFound) // IF err int AlphaNum = 2; int Zone1Num = Util::FindItemInList(cAlphaArgs(AlphaNum), state.dataHeatBal->Zone); int space1Num = Util::FindItemInList(cAlphaArgs(AlphaNum), state.dataHeatBal->space); - if ((Zone1Num == 0) && (space1Num==0)) { + if ((Zone1Num == 0) && (space1Num == 0)) { ShowSevereError(state, format("{}{}=\"{}\", invalid (not found) {}=\"{}\".", RoutineName, @@ -3819,7 +3819,7 @@ void GetSimpleAirModelInputs(EnergyPlusData &state, bool &ErrorsFound) // IF err ++AlphaNum; // 3 int Zone2Num = Util::FindItemInList(cAlphaArgs(AlphaNum), state.dataHeatBal->Zone); int space2Num = Util::FindItemInList(cAlphaArgs(AlphaNum), state.dataHeatBal->space); - if ((Zone2Num == 0) && (space2Num==0)) { + if ((Zone2Num == 0) && (space2Num == 0)) { ShowSevereError(state, format("{}{}=\"{}\", invalid (not found) {}=\"{}\".", RoutineName, From 2a966e9e96060b379b51fbcd5e7891b92ec688e3 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Fri, 9 Aug 2024 16:54:43 -0500 Subject: [PATCH 65/81] Space IV-ZoneCoolTowerShower --- .../src/overview/group-airflow.tex | 4 +- idd/Energy+.idd.in | 5 +- src/EnergyPlus/CoolTower.cc | 46 ++++++++++++++----- src/EnergyPlus/CoolTower.hh | 4 +- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/doc/input-output-reference/src/overview/group-airflow.tex b/doc/input-output-reference/src/overview/group-airflow.tex index db393414b97..157e30f5a91 100644 --- a/doc/input-output-reference/src/overview/group-airflow.tex +++ b/doc/input-output-reference/src/overview/group-airflow.tex @@ -1965,9 +1965,9 @@ \subsubsection{Inputs}\label{inputs-8-002} This field is the name of the schedule that denotes whether the cooltower can run during a given time period. A schedule value greater than 0 (usually 1 is used) indicates that the cooltower is available and can be on during the time period. A value less than or equal to 0 (usually 0 is used) denotes that the cooltower is not available and must be off for the time period. If this field is blank, the schedule has values of 1 for all time periods. -\paragraph{Field: Zone Name}\label{field-zone-name-6} +\paragraph{Field: Zone or Space Name}\label{field-zone-name-6} -This field is the name of the zone (ref: Zone) and attaches a particular cooltower statement to a thermal zone in the building. +This field is the name of the zone (ref: Zone) or space the cooltower is attached to. \paragraph{Field: Water Supply Storage Tank Name}\label{field-water-supply-storage-tank-name} diff --git a/idd/Energy+.idd.in b/idd/Energy+.idd.in index a3ebbedd817..1d4e673dd17 100644 --- a/idd/Energy+.idd.in +++ b/idd/Energy+.idd.in @@ -24795,7 +24795,7 @@ ZoneCoolTower:Shower, \memo A cooltower (sometimes referred to as a wind tower or a shower cooling tower) \memo models passive downdraught evaporative cooling (PDEC) that is designed to capture the \memo wind at the top of a tower and cool the outdoor air using water evaporation before - \memo delivering it to a space. + \memo delivering it to a zone (or space). A1, \field Name \required-field A2, \field Availability Schedule Name @@ -24803,10 +24803,11 @@ ZoneCoolTower:Shower, \note If this field is blank, the system is always available. \type object-list \object-list ScheduleNames - A3, \field Zone Name + A3, \field Zone or Space Name \required-field \type object-list \object-list ZoneNames + \object-list SpaceNames A4, \field Water Supply Storage Tank Name \note In case of stand alone tank or underground water, leave this input blank \type object-list diff --git a/src/EnergyPlus/CoolTower.cc b/src/EnergyPlus/CoolTower.cc index 4991348103a..b0d46af320f 100644 --- a/src/EnergyPlus/CoolTower.cc +++ b/src/EnergyPlus/CoolTower.cc @@ -198,9 +198,10 @@ namespace CoolTower { } } - state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZoneName = state.dataIPShortCut->cAlphaArgs(3); // Name of zone where cooltower is serving state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr = Util::FindItemInList(state.dataIPShortCut->cAlphaArgs(3), Zone); - if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr == 0) { + state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr = + Util::FindItemInList(state.dataIPShortCut->cAlphaArgs(3), state.dataHeatBal->space); + if ((state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr == 0) && (state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr == 0)) { if (lAlphaBlanks(3)) { ShowSevereError(state, format("{}=\"{}\" invalid {} is required but input is blank.", @@ -216,6 +217,9 @@ namespace CoolTower { state.dataIPShortCut->cAlphaArgs(3))); } ErrorsFound = true; + } else if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr == 0) { + state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr = + state.dataHeatBal->space(state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr).zoneNum; } state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyName = state.dataIPShortCut->cAlphaArgs(4); // Name of water storage tank @@ -627,7 +631,12 @@ namespace CoolTower { thisZoneHB.MCPTC = 0.0; thisZoneHB.MCPC = 0.0; thisZoneHB.CTMFL = 0.0; - + if ((state.dataHeatBal->doSpaceHeatBalance) && (state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr > 0)) { + auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr); + thisSpaceHB.MCPTC = 0.0; + thisSpaceHB.MCPC = 0.0; + thisSpaceHB.CTMFL = 0.0; + } if (ScheduleManager::GetCurrentScheduleValue(state, state.dataCoolTower->CoolTowerSys(CoolTowerNum).SchedPtr) > 0.0) { // check component operation if (state.dataEnvrn->WindSpeed < MinWindSpeed || state.dataEnvrn->WindSpeed > MaxWindSpeed) continue; @@ -707,22 +716,35 @@ namespace CoolTower { AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, OutletTemp, OutletHumRat); // Outlet air density CVF_ZoneNum = state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualAirVolFlowRate * ScheduleManager::GetCurrentScheduleValue(state, state.dataCoolTower->CoolTowerSys(CoolTowerNum).SchedPtr); - thisZoneHB.MCPC = CVF_ZoneNum * AirDensity * AirSpecHeat; - thisZoneHB.MCPTC = thisZoneHB.MCPC * OutletTemp; - thisZoneHB.CTMFL = thisZoneHB.MCPC / AirSpecHeat; + Real64 thisMCPC = CVF_ZoneNum * AirDensity * AirSpecHeat; + Real64 thisMCPTC = thisMCPC * OutletTemp; + Real64 thisCTMFL = thisMCPC / AirSpecHeat; + Real64 thisZT = thisZoneHB.ZT; + Real64 thisAirHumRat = thisZoneHB.airHumRat; + thisZoneHB.MCPC = thisMCPC; + thisZoneHB.MCPTC = thisMCPTC; + thisZoneHB.CTMFL = thisCTMFL; + if ((state.dataHeatBal->doSpaceHeatBalance) && (state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr > 0)) { + auto &thisSpaceHB = + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr); + thisSpaceHB.MCPC = thisMCPC; + thisSpaceHB.MCPTC = thisMCPTC; + thisSpaceHB.CTMFL = thisCTMFL; + thisZT = thisSpaceHB.ZT; + thisAirHumRat = thisSpaceHB.airHumRat; + } - state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatPower = thisZoneHB.MCPC * std::abs(thisZoneHB.ZT - OutletTemp); - state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatPower = CVF_ZoneNum * std::abs(thisZoneHB.airHumRat - OutletHumRat); + state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatPower = thisMCPC * std::abs(thisZT - OutletTemp); + state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatPower = CVF_ZoneNum * std::abs(thisAirHumRat - OutletHumRat); state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletTemp = OutletTemp; state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletHumRat = OutletHumRat; state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRate = CVF_ZoneNum; - state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirMassFlowRate = thisZoneHB.CTMFL; - state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRateStd = thisZoneHB.CTMFL / state.dataEnvrn->StdRhoAir; + state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirMassFlowRate = thisCTMFL; + state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRateStd = thisCTMFL / state.dataEnvrn->StdRhoAir; state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletDBTemp = Zone(ZoneNum).OutDryBulbTemp; state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletWBTemp = Zone(ZoneNum).OutWetBulbTemp; state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletHumRat = state.dataEnvrn->OutHumRat; - state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate = - (std::abs(InletHumRat - OutletHumRat) * thisZoneHB.CTMFL) / RhoWater; + state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate = (std::abs(InletHumRat - OutletHumRat) * thisCTMFL) / RhoWater; state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeupRate = 0.0; // initialize -- calc in update state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecPower = state.dataCoolTower->CoolTowerSys(CoolTowerNum).RatedPumpPower * PumpPartLoadRat; diff --git a/src/EnergyPlus/CoolTower.hh b/src/EnergyPlus/CoolTower.hh index 47cc18415a6..0353f82aa39 100644 --- a/src/EnergyPlus/CoolTower.hh +++ b/src/EnergyPlus/CoolTower.hh @@ -85,9 +85,9 @@ namespace CoolTower { std::string Name; // The component name std::string CompType; // Type of component std::string Schedule; // Available schedule - std::string ZoneName; // Name of zone the component is serving int SchedPtr = 0; // Index to schedule - int ZonePtr = 0; // Point to this zone + int ZonePtr = 0; // Index to zone + int spacePtr = 0; // Index to space (if applicable) int PumpSchedPtr = 0; // Index to schedule for water pump FlowCtrl FlowCtrlType = FlowCtrl::Invalid; // Type of cooltower operation WaterSupplyMode CoolTWaterSupplyMode = WaterSupplyMode::FromMains; // Type of water source From cebfcb59666acdd3ac07985665962c3edde5380e Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Fri, 9 Aug 2024 19:46:38 -0500 Subject: [PATCH 66/81] Space IV-ZoneThermalChimney --- .../src/overview/group-airflow.tex | 6 +- idd/Energy+.idd.in | 104 +++++++++++------- src/EnergyPlus/ThermalChimney.cc | 104 +++++++++++++----- src/EnergyPlus/ThermalChimney.hh | 1 + 4 files changed, 140 insertions(+), 75 deletions(-) diff --git a/doc/input-output-reference/src/overview/group-airflow.tex b/doc/input-output-reference/src/overview/group-airflow.tex index 157e30f5a91..f70b854e548 100644 --- a/doc/input-output-reference/src/overview/group-airflow.tex +++ b/doc/input-output-reference/src/overview/group-airflow.tex @@ -1518,7 +1518,7 @@ \subsection{ZoneRefrigerationDoorMixing}\label{zonerefrigerationdoormixing} ZoneRefrigerationDoorMixing is ideally suited for two zones, at least one of which is refrigerated, that exchange an equal amount of dry air. As with \hyperref[zonemixing]{ZoneMixing}, this is a simplified interzone airflow in EnergyPlus. The ZoneRefrigerationDoorMixing approach shares some features of both \hyperref[zonemixing]{ZoneMixing} and \hyperref[zonecrossmixing]{ZoneCrossMixing}. Like \hyperref[zonecrossmixing]{ZoneCrossMixing}, ZoneRefrigerationDoorMixing has an energy effect on both the source and the receiving zone, thus maintaining both the air mass and energy balances in the two zones. Unlike the other two mixing objects, ZoneRefrigerationDoorMixing always calculates the air exchange rate based on the zone temperature and relative humidity. That is, the user does not specify the air flow rate. The user can moderate the flow through a door-opening schedule. -ZoneRefrigerationDoorMixing can only be entered once for any unique pair of zones. It doesn't matter which zone is listed first and the zones will automatically switch back and forth between source and receiving zones depending upon which zone is colder. If space heat balance is active and a space name is specified for Space or Zone Name 1 or 2, then the space conditions will be used and the exchange will be with that space only. If space heat balance is active and a zone name is specified, then the aveerage zone conditions will be used, and the exchange will be proportioned to all spaces in the zone by space volume. +ZoneRefrigerationDoorMixing can only be entered once for any unique pair of zones. It doesn't matter which zone is listed first and the zones will automatically switch back and forth between source and receiving zones depending upon which zone is colder. If space heat balance is active and a space name is specified for Zone or Space Name 1 or 2, then the space conditions will be used and the exchange will be with that space only. If space heat balance is active and a zone name is specified, then the aveerage zone conditions will be used, and the exchange will be proportioned to all spaces in the zone by space volume. \subsubsection{Inputs}\label{inputs-7-003} @@ -2185,9 +2185,9 @@ \subsubsection{Inputs} This dimensionless number is the discharge coefficient of the thermal chimney. The ventilation rate enhanced by the thermal chimney is also dependent on the discharge coefficient. -\paragraph{Field: Zone \textless{}\#\textgreater{} Name}\label{field-zone-name-8} +\paragraph{Field: Zone or Space Name \textless{}\#\textgreater{}}\label{field-zone-name-8} -This field is the name of the zone (ref: Zone) to which the thermal chimney is attached. It is used in conjunction with the next three fields. Note that up to 20 sets of zone name, distance from the top of the thermal chimney to each inlet, relative ratios of air flow rates passing through each zone and cross sectional areas of each air channel inlet may be entered for a single thermal chimney if multiple zones share the common thermal chimney. +This field is the name of the zone (ref: Zone) or space to which the thermal chimney is attached. It is used in conjunction with the next three fields. Note that up to 20 sets of zone or space name, distance from the top of the thermal chimney to each inlet, relative ratios of air flow rates passing through each zone and cross sectional areas of each air channel inlet may be entered for a single thermal chimney if multiple zones or spaces share the common thermal chimney. If space heat balance is active and a space name is specified for Zone or Space Name, then the space conditions will be used and the exchange will be with that space only. If space heat balance is active and a zone name is specified, then the aveerage zone conditions will be used, and the exchange will be proportioned to all spaces in the zone by space volume. \paragraph{Field: Distance from Top of Thermal Chimney to Inlet \textless{}\#\textgreater{}}\label{field-distance-from-top-of-thermal-chimney-to-inlet} diff --git a/idd/Energy+.idd.in b/idd/Energy+.idd.in index 1d4e673dd17..ba438f1829c 100644 --- a/idd/Energy+.idd.in +++ b/idd/Energy+.idd.in @@ -24866,11 +24866,11 @@ ZoneThermalChimney, \memo A thermal chimney is a vertical shaft utilizing solar radiation to enhance natural \memo ventilation. It consists of an absorber wall, air gap and glass cover with high solar \memo transmissivity. - \min-fields 10 + \min-fields 10 A1, \field Name \required-field A2, \field Zone Name - \note Name of zone that is the thermal chimney + \note Name of zone that is the thermal chimney. \required-field \type object-list \object-list ZoneNames @@ -24894,16 +24894,17 @@ ZoneThermalChimney, \minimum 0 \maximum 1 \default 0.8 - A4, \field Zone 1 Name + A4, \field Zone or Space Name 1 \required-field \type object-list \object-list ZoneNames + \object-list SpaceNames N4, \field Distance from Top of Thermal Chimney to Inlet 1 \required-field \units m \type real \minimum 0 - N5, \field Relative Ratios of Air Flow Rates Passing through Zone 1 + N5, \field Relative Ratios of Air Flow Rates Passing through Inlet 1 \type real \minimum 0 \maximum 1 @@ -24913,14 +24914,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A5, \field Zone 2 Name + A5, \field Zone or Space Name 2 \type object-list \object-list ZoneNames + \object-list SpaceNames N7, \field Distance from Top of Thermal Chimney to Inlet 2 \units m \type real \minimum 0 - N8, \field Relative Ratios of Air Flow Rates Passing through Zone 2 + N8, \field Relative Ratios of Air Flow Rates Passing through Inlet 2 \type real \minimum 0 \maximum 1 @@ -24928,14 +24930,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A6, \field Zone 3 Name + A6, \field Zone or Space Name 3 \type object-list \object-list ZoneNames + \object-list SpaceNames N10, \field Distance from Top of Thermal Chimney to Inlet 3 \units m \type real \minimum 0 - N11, \field Relative Ratios of Air Flow Rates Passing through Zone 3 + N11, \field Relative Ratios of Air Flow Rates Passing through Inlet 3 \type real \minimum 0 \maximum 1 @@ -24943,14 +24946,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A7, \field Zone 4 Name + A7, \field Zone or Space Name 4 \type object-list \object-list ZoneNames + \object-list SpaceNames N13, \field Distance from Top of Thermal Chimney to Inlet 4 \units m \type real \minimum 0 - N14, \field Relative Ratios of Air Flow Rates Passing through Zone 4 + N14, \field Relative Ratios of Air Flow Rates Passing through Inlet 4 \type real \minimum 0 \maximum 1 @@ -24958,14 +24962,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A8, \field Zone 5 Name + A8, \field Zone or Space Name 5 \type object-list \object-list ZoneNames + \object-list SpaceNames N16, \field Distance from Top of Thermal Chimney to Inlet 5 \units m \type real \minimum 0 - N17, \field Relative Ratios of Air Flow Rates Passing through Zone 5 + N17, \field Relative Ratios of Air Flow Rates Passing through Inlet 5 \type real \minimum 0 \maximum 1 @@ -24973,14 +24978,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A9, \field Zone 6 Name + A9, \field Zone or Space Name 6 \type object-list \object-list ZoneNames + \object-list SpaceNames N19, \field Distance from Top of Thermal Chimney to Inlet 6 \units m \type real \minimum 0 - N20, \field Relative Ratios of Air Flow Rates Passing through Zone 6 + N20, \field Relative Ratios of Air Flow Rates Passing through Inlet 6 \type real \minimum 0 \maximum 1 @@ -24988,14 +24994,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A10, \field Zone 7 Name + A10, \field Zone or Space Name 7 \type object-list \object-list ZoneNames + \object-list SpaceNames N22, \field Distance from Top of Thermal Chimney to Inlet 7 \units m \type real \minimum 0 - N23, \field Relative Ratios of Air Flow Rates Passing through Zone 7 + N23, \field Relative Ratios of Air Flow Rates Passing through Inlet 7 \type real \minimum 0 \maximum 1 @@ -25003,14 +25010,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A11, \field Zone 8 Name + A11, \field Zone or Space Name 8 \type object-list \object-list ZoneNames + \object-list SpaceNames N25, \field Distance from Top of Thermal Chimney to Inlet 8 \units m \type real \minimum 0 - N26, \field Relative Ratios of Air Flow Rates Passing through Zone 8 + N26, \field Relative Ratios of Air Flow Rates Passing through Inlet 8 \type real \minimum 0 \maximum 1 @@ -25018,14 +25026,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A12, \field Zone 9 Name + A12, \field Zone or Space Name 9 \type object-list \object-list ZoneNames + \object-list SpaceNames N28, \field Distance from Top of Thermal Chimney to Inlet 9 \units m \type real \minimum 0 - N29, \field Relative Ratios of Air Flow Rates Passing through Zone 9 + N29, \field Relative Ratios of Air Flow Rates Passing through Inlet 9 \type real \minimum 0 \maximum 1 @@ -25033,14 +25042,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A13, \field Zone 10 Name + A13, \field Zone or Space Name 10 \type object-list \object-list ZoneNames + \object-list SpaceNames N31, \field Distance from Top of Thermal Chimney to Inlet 10 \units m \type real \minimum 0 - N32, \field Relative Ratios of Air Flow Rates Passing through Zone 10 + N32, \field Relative Ratios of Air Flow Rates Passing through Inlet 10 \type real \minimum 0 \maximum 1 @@ -25048,14 +25058,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A14, \field Zone 11 Name + A14, \field Zone or Space Name 11 \type object-list \object-list ZoneNames + \object-list SpaceNames N34, \field Distance from Top of Thermal Chimney to Inlet 11 \units m \type real \minimum 0 - N35, \field Relative Ratios of Air Flow Rates Passing through Zone 11 + N35, \field Relative Ratios of Air Flow Rates Passing through Inlet 11 \type real \minimum 0 \maximum 1 @@ -25063,14 +25074,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A15, \field Zone 12 Name + A15, \field Zone or Space Name 12 \type object-list \object-list ZoneNames + \object-list SpaceNames N37, \field Distance from Top of Thermal Chimney to Inlet 12 \units m \type real \minimum 0 - N38, \field Relative Ratios of Air Flow Rates Passing through Zone 12 + N38, \field Relative Ratios of Air Flow Rates Passing through Inlet 12 \type real \minimum 0 \maximum 1 @@ -25078,14 +25090,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A16, \field Zone 13 Name + A16, \field Zone or Space Name 13 \type object-list \object-list ZoneNames + \object-list SpaceNames N40, \field Distance from Top of Thermal Chimney to Inlet 13 \units m \type real \minimum 0 - N41, \field Relative Ratios of Air Flow Rates Passing through Zone 13 + N41, \field Relative Ratios of Air Flow Rates Passing through Inlet 13 \type real \minimum 0 \maximum 1 @@ -25093,14 +25106,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A17, \field Zone 14 Name + A17, \field Zone or Space Name 14 \type object-list \object-list ZoneNames + \object-list SpaceNames N43, \field Distance from Top of Thermal Chimney to Inlet 14 \units m \type real \minimum 0 - N44, \field Relative Ratios of Air Flow Rates Passing through Zone 14 + N44, \field Relative Ratios of Air Flow Rates Passing through Inlet 14 \type real \minimum 0 \maximum 1 @@ -25108,14 +25122,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A18, \field Zone 15 Name + A18, \field Zone or Space Name 15 \type object-list \object-list ZoneNames + \object-list SpaceNames N46, \field Distance from Top of Thermal Chimney to Inlet 15 \units m \type real \minimum 0 - N47, \field Relative Ratios of Air Flow Rates Passing through Zone 15 + N47, \field Relative Ratios of Air Flow Rates Passing through Inlet 15 \type real \minimum 0 \maximum 1 @@ -25123,14 +25138,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A19, \field Zone 16 Name + A19, \field Zone or Space Name 16 \type object-list \object-list ZoneNames + \object-list SpaceNames N49, \field Distance from Top of Thermal Chimney to Inlet 16 \units m \type real \minimum 0 - N50, \field Relative Ratios of Air Flow Rates Passing through Zone 16 + N50, \field Relative Ratios of Air Flow Rates Passing through Inlet 16 \type real \minimum 0 \maximum 1 @@ -25138,14 +25154,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A20, \field Zone 17 Name + A20, \field Zone or Space Name 17 \type object-list \object-list ZoneNames + \object-list SpaceNames N52, \field Distance from Top of Thermal Chimney to Inlet 17 \units m \type real \minimum 0 - N53, \field Relative Ratios of Air Flow Rates Passing through Zone 17 + N53, \field Relative Ratios of Air Flow Rates Passing through Inlet 17 \type real \minimum 0 \maximum 1 @@ -25153,14 +25170,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A21, \field Zone 18 Name + A21, \field Zone or Space Name 18 \type object-list \object-list ZoneNames + \object-list SpaceNames N55, \field Distance from Top of Thermal Chimney to Inlet 18 \units m \type real \minimum 0 - N56, \field Relative Ratios of Air Flow Rates Passing through Zone 18 + N56, \field Relative Ratios of Air Flow Rates Passing through Inlet 18 \type real \minimum 0 \maximum 1 @@ -25168,14 +25186,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A22, \field Zone 19 Name + A22, \field Zone or Space Name 19 \type object-list \object-list ZoneNames + \object-list SpaceNames N58, \field Distance from Top of Thermal Chimney to Inlet 19 \units m \type real \minimum 0 - N59, \field Relative Ratios of Air Flow Rates Passing through Zone 19 + N59, \field Relative Ratios of Air Flow Rates Passing through Inlet 19 \type real \minimum 0 \maximum 1 @@ -25183,14 +25202,15 @@ ZoneThermalChimney, \units m2 \type real \minimum 0 - A23, \field Zone 20 Name + A23, \field Zone or Space Name 20 \type object-list \object-list ZoneNames + \object-list SpaceNames N61, \field Distance from Top of Thermal Chimney to Inlet 20 \units m \type real \minimum 0 - N62, \field Relative Ratios of Air Flow Rates Passing through Zone 20 + N62, \field Relative Ratios of Air Flow Rates Passing through Inlet 20 \type real \minimum 0 \maximum 1 diff --git a/src/EnergyPlus/ThermalChimney.cc b/src/EnergyPlus/ThermalChimney.cc index ba0329917ed..58b236f75c5 100644 --- a/src/EnergyPlus/ThermalChimney.cc +++ b/src/EnergyPlus/ThermalChimney.cc @@ -264,6 +264,7 @@ namespace ThermalChimney { state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib = NumAlpha - 3; state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr.allocate(state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib); + state.dataThermalChimneys->ThermalChimneySys(Loop).spacePtr.allocate(state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib); state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName.allocate(state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib); state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet.allocate( state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib); @@ -277,6 +278,15 @@ namespace ThermalChimney { state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum) = state.dataIPShortCut->cAlphaArgs(TCZoneNum + 3); state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) = Util::FindItemInList(state.dataIPShortCut->cAlphaArgs(TCZoneNum + 3), state.dataHeatBal->Zone); + if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) == 0) { + int spaceNum = Util::FindItemInList(state.dataIPShortCut->cAlphaArgs(TCZoneNum + 3), state.dataHeatBal->space); + if (spaceNum > 0) { + state.dataThermalChimneys->ThermalChimneySys(Loop).spacePtr(TCZoneNum) = spaceNum; + int zoneNum = state.dataHeatBal->space(spaceNum).zoneNum; + state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) = zoneNum; + } + } + state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet(TCZoneNum) = state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 1); state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) = @@ -676,8 +686,6 @@ namespace ThermalChimney { // SUBROUTINE LOCAL VARIABLE DECLARATIONS: // Real local vaiables - int TCZoneNumCounter; - int TCZoneNum; Real64 minorW; // width of enclosure (narrow dimension) Real64 majorW; // width of major surface Real64 TempmajorW; @@ -771,28 +779,41 @@ namespace ThermalChimney { DischargeCoeffTC = state.dataThermalChimneys->ThermalChimneySys(Loop).DischargeCoeff; AirInletCrossArea = 0.0; - for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { + for (int TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { AirInletCrossArea += state.dataThermalChimneys->ThermalChimneySys(Loop).EachAirInletCrossArea(TCZoneNum); } RoomAirTemp = 0.0; - for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { - TCZoneNumCounter = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum); - RoomAirTemp += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) * - state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter).MAT; + for (int TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { + int tcSpacePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).spacePtr(TCZoneNum); + if ((state.dataHeatBal->doSpaceHeatBalance) && (tcSpacePtr > 0)) { + RoomAirTemp += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) * + state.dataZoneTempPredictorCorrector->spaceHeatBalance(tcSpacePtr).MAT; + } else { + int tcZonePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum); + RoomAirTemp += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) * + state.dataZoneTempPredictorCorrector->zoneHeatBalance(tcZonePtr).MAT; + } } RoomAirTemp += Constant::Kelvin; Process1 = 0.0; Process2 = 0.0; - for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { - TCZoneNumCounter = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum); - auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter); - Process1 += PsyHFnTdbW(thisTCZoneHB.MAT, thisTCZoneHB.airHumRat) * - state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet(TCZoneNum) * + for (int TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { + int tcZonePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum); + auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(tcZonePtr); + Real64 tcZoneMAT = thisTCZoneHB.MAT; + Real64 tcZoneHumRat = thisTCZoneHB.airHumRat; + int tcSpacePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).spacePtr(TCZoneNum); + if ((state.dataHeatBal->doSpaceHeatBalance) && (tcSpacePtr > 0)) { + auto &thisTCspaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(tcSpacePtr); + tcZoneMAT = thisTCspaceHB.MAT; + tcZoneHumRat = thisTCspaceHB.airHumRat; + } + Real64 tcZoneEnth = PsyHFnTdbW(tcZoneMAT, tcZoneHumRat); + Process1 += tcZoneEnth * state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet(TCZoneNum) * state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum); - Process2 += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) * - PsyHFnTdbW(state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter).MAT, thisTCZoneHB.airHumRat); + Process2 += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) * tcZoneEnth; } OverallThermalChimLength = Process1 / Process2; @@ -888,23 +909,39 @@ namespace ThermalChimney { } // Now assignment of the overall mass flow rate into each zone - for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { - TCZoneNumCounter = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum); - auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter); - AirDensity = PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter).MAT, - thisTCZoneHB.airHumRat); - CpAir = PsyCpAirFnW(thisTCZoneHB.airHumRat); - thisTCZoneHB.MCPThermChim = + for (int TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { + int tcZonePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum); + auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(tcZonePtr); + Real64 tcZoneMAT = thisTCZoneHB.MAT; + Real64 tcZoneHumRat = thisTCZoneHB.airHumRat; + int tcSpacePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).spacePtr(TCZoneNum); + if ((state.dataHeatBal->doSpaceHeatBalance) && (tcSpacePtr > 0)) { + auto &thisTCSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(tcSpacePtr); + tcZoneMAT = thisTCSpaceHB.MAT; + tcZoneHumRat = thisTCSpaceHB.airHumRat; + } + // ToDo - Let this persist to avoid diffs, but should be local + AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, tcZoneMAT, tcZoneHumRat); + CpAir = PsyCpAirFnW(tcZoneHumRat); + Real64 thisMCPThermChim = TCVolumeAirFlowRate * AirDensity * CpAir * state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum); - if (thisTCZoneHB.MCPThermChim <= 0.0) { - thisTCZoneHB.MCPThermChim = 0.0; + if (thisMCPThermChim <= 0.0) { + thisMCPThermChim = 0.0; + } + Real64 thisThermChimAMFL = thisMCPThermChim / CpAir; + Real64 thisMCPTThermChim = thisMCPThermChim * state.dataHeatBal->Zone(tcZonePtr).OutDryBulbTemp; // Only zones have an ODB temp value + thisTCZoneHB.MCPThermChim = thisMCPThermChim; + thisTCZoneHB.ThermChimAMFL = thisThermChimAMFL; + thisTCZoneHB.MCPTThermChim = thisMCPTThermChim; + if ((state.dataHeatBal->doSpaceHeatBalance) && (tcSpacePtr > 0)) { + auto &thisTCSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(tcSpacePtr); + thisTCSpaceHB.MCPThermChim = thisMCPThermChim; + thisTCSpaceHB.ThermChimAMFL = thisThermChimAMFL; + thisTCSpaceHB.MCPTThermChim = thisMCPTThermChim; } - thisTCZoneHB.ThermChimAMFL = thisTCZoneHB.MCPThermChim / CpAir; - thisTCZoneHB.MCPTThermChim = thisTCZoneHB.MCPThermChim * state.dataHeatBal->Zone(TCZoneNumCounter).OutDryBulbTemp; } + // ToDo - This should probably be using AirDensityThermalChim here instead of AirDensity which is leftover from the last inlet zone thisZoneHB.MCPThermChim = TCVolumeAirFlowRate * AirDensity * CpAir; if (thisZoneHB.MCPThermChim <= 0.0) { thisZoneHB.MCPThermChim = 0.0; @@ -922,12 +959,19 @@ namespace ThermalChimney { state.dataThermalChimneys->ThermalChimneyReport(Loop).OutletAirTempThermalChim = ThermChimSubTemp(NTC) - Constant::Kelvin; if (GetCurrentScheduleValue(state, state.dataThermalChimneys->ThermalChimneySys(Loop).SchedPtr) <= 0.0) { - for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { - TCZoneNumCounter = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum); - auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter); + for (int TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { + int tcZonePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum); + auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(tcZonePtr); thisTCZoneHB.MCPThermChim = 0.0; thisTCZoneHB.ThermChimAMFL = 0.0; thisTCZoneHB.MCPTThermChim = 0.0; + int tcSpacePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).spacePtr(TCZoneNum); + if ((state.dataHeatBal->doSpaceHeatBalance) && (tcSpacePtr > 0)) { + auto &thisTCSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(tcSpacePtr); + thisTCSpaceHB.MCPThermChim = 0.0; + thisTCSpaceHB.ThermChimAMFL = 0.0; + thisTCSpaceHB.MCPTThermChim = 0.0; + } } thisZoneHB.MCPThermChim = 0.0; thisZoneHB.ThermChimAMFL = 0.0; diff --git a/src/EnergyPlus/ThermalChimney.hh b/src/EnergyPlus/ThermalChimney.hh index 4731ca007e5..797594f6756 100644 --- a/src/EnergyPlus/ThermalChimney.hh +++ b/src/EnergyPlus/ThermalChimney.hh @@ -79,6 +79,7 @@ namespace ThermalChimney { bool EMSOverrideOn; // if true then EMS is requesting to override Real64 EMSAirFlowRateValue; // value EMS is setting for air flow rate Array1D_int ZonePtr; + Array1D_int spacePtr; Array1D_string ZoneName; Array1D DistanceThermChimInlet; Array1D RatioThermChimAirFlow; From 57a62ce0f254af5eff21cb8da05e41d3245ae7a7 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Sun, 11 Aug 2024 23:42:18 -0500 Subject: [PATCH 67/81] Space IV-SpaceHVACZoneReturnMixer --- .../overview/group-simulation-parameters.tex | 2 +- .../src/overview/group-zone-equipment.tex | 44 ++- idd/Energy+.idd.in | 53 +++ idd/schema/modify_schema.py | 1 + src/EnergyPlus/DataLoopNode.hh | 1 + src/EnergyPlus/DataZoneEquipment.cc | 302 +++++++++++++++++- src/EnergyPlus/DataZoneEquipment.hh | 21 ++ src/EnergyPlus/ZoneEquipmentManager.cc | 184 +---------- src/EnergyPlus/ZoneEquipmentManager.hh | 6 - .../unit/ZoneEquipmentManager.unit.cc | 10 +- 10 files changed, 430 insertions(+), 194 deletions(-) diff --git a/doc/input-output-reference/src/overview/group-simulation-parameters.tex b/doc/input-output-reference/src/overview/group-simulation-parameters.tex index f26cd185a3e..133543c557a 100644 --- a/doc/input-output-reference/src/overview/group-simulation-parameters.tex +++ b/doc/input-output-reference/src/overview/group-simulation-parameters.tex @@ -473,7 +473,7 @@ \subsubsection{Inputs}\label{inputs-8-023} If yes, space-level heat balance will be calculated and reported during sizing, and space sizing results will be reported along with zone sizing results. If no, then only zone-level heat balance will be calculated. This field defaults to No. For zones with more than one space, the zone sizing results are calculated for the whole zone and represent the coincident peak for the spaces in the zone. Note that space heat balance is not supported for \hyperref[inputs-hm]{HybridModel:Zone}, \hyperref[roomairmodeltype]{RoomAirModelType} other than Mixing, \hyperref[heatbalancealgorithm]{HeatBalanceAlgorithm} MoisturePenetrationDepthConductionTransferFunction and CombinedHeatAndMoistureFiniteElement. \paragraph{Field: Do Space Heat Balance for Simulation}\label{field-do-space-heat-balance-simulation} -If yes, space-level heat balance will be calculated and reported during the simulation. If no, then only zone-level heat balance will be calculated. This field defaults to No. When this field is Yes, optional SpaceHVAC objects may be used to distribute zone HVAC equipment output to the spaces in the zone. See \hyperref[spacehvacequipmentconnections]{SpaceHVAC:EquipmentConnections}, \hyperref[spacehvaczoneequipmentsplitter]{SpaceHVAC:ZoneEquipmentSplitter} and \hyperref[spacehvaczoneequipmentmixer]{SpaceHVAC:ZoneEquipmentMixer}. +If yes, space-level heat balance will be calculated and reported during the simulation. If no, then only zone-level heat balance will be calculated. This field defaults to No. When this field is Yes, optional SpaceHVAC objects may be used to distribute zone HVAC equipment output to the spaces in the zone. See \hyperref[spacehvacequipmentconnections]{SpaceHVAC:EquipmentConnections}, \hyperref[spacehvaczoneequipmentsplitter]{SpaceHVAC:ZoneEquipmentSplitter}, \hyperref[spacehvaczoneequipmentmixer]{SpaceHVAC:ZoneEquipmentMixer} and \hyperref[spacehvaczonereturnmixer]{SpaceHVAC:ZoneReturnMixer}. And, a default IDF example is shown below: diff --git a/doc/input-output-reference/src/overview/group-zone-equipment.tex b/doc/input-output-reference/src/overview/group-zone-equipment.tex index 32ffff31da9..600d3c236ef 100644 --- a/doc/input-output-reference/src/overview/group-zone-equipment.tex +++ b/doc/input-output-reference/src/overview/group-zone-equipment.tex @@ -388,7 +388,7 @@ \subsubsection{Inputs}\label{inputs-2-048} \subsection{SpaceHVAC:EquipmentConnections}\label{spacehvacequipmentconnections} If HVAC equipment is modeled at the Space level for one or more zones, the SpaceHVAC:EquipmentConnections statement defines the node connections to a space. Any space modeled with SpaceHVAC:EquipmentConnections will have its own air temperature and humidity ratio, and surfaces and internal gains in the zone will interact with the space conditions. -Note that all nodes mentioned in the SpaceHVAC:EquipmentConnections input must be unique. That is, all nodes in all the SpaceHVAC:EquipmentConnections statements referenced by the ``Space Air Inlet Nodes'', ``Space Air Exhaust Nodes'', ``Space Air Node Name'' and ``Space Return Air Node Name'' cannot have any node name appearing more than once. Unlike ZoneHVAC:EquipmentConnections, there is no equipment list. Equipment is connected to spaces using \hyperref[spacehvaczoneequipmentsplitter]{SpaceHVAC:ZoneEquipmentSplitter} and \hyperref[spacehvaczoneequipmentmixer]{SpaceHVAC:ZoneEquipmentMixer} as shown in Figure \ref{fig:space-hvac-equipment-connections}. If any space in a zone has a SpaceHVAC:EquipmentConnections object, then all spaces in that zone must have one, even if they are not served by any HVAC equipment. SpaceHVAC is only used when \hyperref[zoneairheatbalancealgorithm]{ZoneAirHeatBalanceAlgorithm} ``Do Space Heat Balance for Simulation'' is Yes. +Note that all nodes mentioned in the SpaceHVAC:EquipmentConnections input must be unique. That is, all nodes in all the SpaceHVAC:EquipmentConnections statements referenced by the ``Space Air Inlet Nodes'', ``Space Air Exhaust Nodes'', ``Space Air Node Name'' and ``Space Return Air Node Name'' cannot have any node name appearing more than once. Unlike ZoneHVAC:EquipmentConnections, there is no equipment list. Equipment is connected to spaces using \hyperref[spacehvaczoneequipmentsplitter]{SpaceHVAC:ZoneEquipmentSplitter}, \hyperref[spacehvaczoneequipmentmixer]{SpaceHVAC:ZoneEquipmentMixer} and \hyperref[spacehvaczonereturnmixer]{SpaceHVAC:ZoneReturnMixer} as shown in Figure \ref{fig:space-hvac-equipment-connections}. If any space in a zone has a SpaceHVAC:EquipmentConnections object, then all spaces in that zone must have one, even if they are not served by any HVAC equipment. SpaceHVAC is only used when \hyperref[zoneairheatbalancealgorithm]{ZoneAirHeatBalanceAlgorithm} ``Do Space Heat Balance for Simulation'' is Yes. \begin{figure}[hbtp] \centering @@ -581,3 +581,45 @@ \subsubsection{Inputs}\label{inputs-1-052-seqmixer} Zone 5-Remainder In Node; !- Space 3 Node Name \end{lstlisting} +\subsection{SpaceHVAC:ZoneReturnMixer}\label{spacehvaczonereturnmixer} + +The SpaceHVAC:ZoneReturnMixer object mixes the airflow from one or more space return air nodes to a zone return air node. + +\subsubsection{Inputs}\label{inputs-1-052-sretmixer} + +\paragraph{Field: Name}\label{field-sretmixer-name-015} + +Name of the mixer object. + +\paragraph{Field: Zone Name}\label{field-sretmixer-zone-name} + +Name of the zone which contains the return air node. + +\paragraph{Field: Zone Return Air Node Name}\label{field-sretmixer-zone-return-air-node-name} + +Name of the zone return air node that is supplied by the Space Return Air Nodes. + +\paragraph{Field: Space \textless{}x\textgreater{} Name}\label{field-sretmixer-space-name} + +Name of a space to supply air to this zone return air node. + +\paragraph{Field: Space \textless{}x\textgreater{} Return Air Node Name}\label{field-sretmixer-space-node-name} + +The name of a \hyperref[spacehvacequipmentconnections]{SpaceHVAC:EquipmentConnections} Return Air Node Name that sends airflow to the Zone Return Air Node. + +An example of this statement in an IDF is: + +\begin{lstlisting} + + SpaceHVAC:ZoneReturnMixer, + Zone 5 Return Mixer, !- Name + Zone 5, !- Zone Name + Zone 5 Out Node, !- Zone Return Air Node Name + Space 5 Office, !- Space 1 Name + Space 5 Office Return Node, !- Space 1 Return Air Node Name + Space 5 Conference, !- Space 2 Name + Space 5 Conference Return Node, !- Space 2 Return Air Node Name + Zone 5-Remainder, !- Space 3 Name + Zone 5-Remainder Return Node; !- Space 3 Return Air Node Name +\end{lstlisting} + diff --git a/idd/Energy+.idd.in b/idd/Energy+.idd.in index ba438f1829c..47002a4c942 100644 --- a/idd/Energy+.idd.in +++ b/idd/Energy+.idd.in @@ -50820,6 +50820,59 @@ SpaceHVAC:ZoneEquipmentMixer, \note Matches a SpaceHVAC:EquipmentConnections Exhaust Node Name \type node +SpaceHVAC:ZoneReturnMixer, + \extensible:2 + \memo Mixes the return airflow from one or more Spaces into a zone return node. + \memo All spaces in the zone must also have a SpaceHVAC:EquipmentConnections object. + \memo Used only when ZoneAirHeatBalanceAlgorithm "Do Space Heat Balance for Sizing" = Yes. + \min-fields 5 + A1, \field Name + \required-field + \reference SpaceMixerNames + A2, \field Zone Name + \note Must be a controlled zone which has a ZoneHVAC:EquipmentConfiguration object. + \required-field + \type object-list + \object-list ZoneNames + A3, \field Zone Return Air Node Name + \note The zone return air node will be mixed from the spaces. + \note Must match a Zone Return Air Node for this zone. + \required-field + \type node + A4, \field Space 1 Name + \begin-extensible + \required-field + \type object-list + \object-list SpaceNames + A5, \field Space 1 Return Air Node Name + \note Matches a SpaceHVAC:EquipmentConnections Return Air Node Name + \required-field + \type node + A6, \field Space 2 Name + \type object-list + \object-list SpaceNames + A7, \field Space 3 Return Air Node Name + \note Matches a SpaceHVAC:EquipmentConnections Return Air Node Name + \type node + A8, \field Space 3 Name + \type object-list + \object-list SpaceNames + A9, \field Space 3 Return Air Node Name + \note Matches a SpaceHVAC:EquipmentConnections Return Air Node Name + \type node + A10,\field Space 4 Name + \type object-list + \object-list SpaceNames + A11,\field Space 4 Return Air Node Name + \note Matches a SpaceHVAC:EquipmentConnections Return Air Node Name + \type node + A12,\field Space 5 Name + \type object-list + \object-list SpaceNames + A13;\field Space 5 Return Air Node Name + \note Matches a SpaceHVAC:EquipmentConnections Return Air Node Name + \type node + \group Fans !*****************AIR LOOP COMPONENTS********************* Fan:SystemModel, diff --git a/idd/schema/modify_schema.py b/idd/schema/modify_schema.py index 3d9e631facf..04b59c37f6e 100644 --- a/idd/schema/modify_schema.py +++ b/idd/schema/modify_schema.py @@ -139,6 +139,7 @@ def isInt(s): 'ZoneHVAC:EquipmentList': 'equipment', 'SpaceHVAC:ZoneEquipmentSplitter': 'spaces', 'SpaceHVAC:ZoneEquipmentMixer': 'spaces', + 'SpaceHVAC:ZoneReturnMixer': 'spaces', 'AvailabilityManagerAssignmentList': 'managers', 'Table:IndependentVariable': 'values', 'Table:IndependentVariableList': 'independent_variables', diff --git a/src/EnergyPlus/DataLoopNode.hh b/src/EnergyPlus/DataLoopNode.hh index 4b809c59911..6d409b27070 100644 --- a/src/EnergyPlus/DataLoopNode.hh +++ b/src/EnergyPlus/DataLoopNode.hh @@ -427,6 +427,7 @@ namespace DataLoopNode { SpaceHVACEquipmentConnections, SpaceHVACZoneEquipmentSplitter, SpaceHVACZoneEquipmentMixer, + SpaceHVACZoneReturnMixer, Num, }; diff --git a/src/EnergyPlus/DataZoneEquipment.cc b/src/EnergyPlus/DataZoneEquipment.cc index 45fbab68918..d4c6087da87 100644 --- a/src/EnergyPlus/DataZoneEquipment.cc +++ b/src/EnergyPlus/DataZoneEquipment.cc @@ -552,7 +552,44 @@ void GetZoneEquipmentData(EnergyPlusData &state) processZoneEquipMixerInput(state, CurrentModuleObject, zoneNum, objectSchemaProps, objectFields, thisZeqMixer); } - } // end loop over zone equipment splitters + } // end loop over zone equipment mixers + + CurrentModuleObject = "SpaceHVAC:ZoneReturnMixer"; + instances = ip->epJSON.find(CurrentModuleObject); + if (instances != ip->epJSON.end()) { + auto const &objectSchemaProps = ip->getObjectSchemaProps(state, CurrentModuleObject); + auto &instancesValue = instances.value(); + int numZoneRetMixers = instancesValue.size(); + state.dataZoneEquip->zoneReturnMixer.resize(numZoneRetMixers); + int zeqRetNum = -1; + for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) { + ++zeqRetNum; + auto const &objectFields = instance.value(); + auto &thisZretMixer = state.dataZoneEquip->zoneReturnMixer[zeqRetNum]; + thisZretMixer.Name = Util::makeUPPER(instance.key()); + thisZretMixer.spaceEquipType = DataLoopNode::ConnectionObjectType::SpaceHVACZoneReturnMixer; + ip->markObjectAsUsed(CurrentModuleObject, instance.key()); + + std::string zoneName = ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_name"); + int zoneNum = Util::FindItemInList(zoneName, state.dataHeatBal->Zone); + if (zoneNum == 0) { + ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisZretMixer.Name)); + ShowContinueError(state, format("..Zone Name={} not found, remaining items for this object not processed.", zoneName)); + state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; + continue; + } + if (!state.dataHeatBal->Zone(zoneNum).IsControlled) { + ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisZretMixer.Name)); + ShowContinueError( + state, + format("..Zone Name={} is not a controlled zone. A ZoneHVAC:EquipmentConfiguration object is required for this zone.", zoneName)); + state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; + continue; + } + + processZoneReturnMixerInput(state, CurrentModuleObject, zoneNum, objectSchemaProps, objectFields, thisZretMixer); + } + } // end loop over zone return mixers CurrentModuleObject = "AirLoopHVAC:SupplyPath"; for (int PathNum = 1; PathNum <= state.dataZoneEquip->NumSupplyAirPaths; ++PathNum) { @@ -1368,6 +1405,93 @@ void processZoneEquipMixerInput(EnergyPlusData &state, } } +void processZoneReturnMixerInput(EnergyPlusData &state, + std::string_view zeqMixerModuleObject, + int const zoneNum, + InputProcessor::json const objectSchemaProps, + InputProcessor::json const objectFields, + DataZoneEquipment::ZoneReturnMixer &thisZretMixer) + +{ + static constexpr std::string_view RoutineName("processZoneReturnMixerInput: "); // include trailing blank space + auto &ip = state.dataInputProcessing->inputProcessor; + bool objectIsParent = true; + thisZretMixer.zoneReturnNodeNum = GetOnlySingleNode(state, + ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_return_air_node_name"), + state.dataZoneEquip->GetZoneEquipmentDataErrorsFound, + thisZretMixer.spaceEquipType, + thisZretMixer.Name, + DataLoopNode::NodeFluidType::Air, + DataLoopNode::ConnectionType::Outlet, + NodeInputManager::CompFluidStream::Primary, + objectIsParent); + // Check zone return nodes + bool found = false; + auto &thisZoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(zoneNum); + for (int retNodeNum : thisZoneEquipConfig.ReturnNode) { + if (thisZretMixer.zoneReturnNodeNum == retNodeNum) { + found = true; + break; + } + } + if (!found) { + ShowSevereError(state, format("{}{}={}", RoutineName, zeqMixerModuleObject, thisZretMixer.Name)); + ShowContinueError(state, + format("Zone Equipment Return Air Node Name={} is not a return air node for ZoneHVAC:EquipmentConnections={}.", + state.dataLoopNodes->NodeID(thisZretMixer.zoneReturnNodeNum), + thisZoneEquipConfig.ZoneName)); + state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; + } + + auto extensibles = objectFields.find("spaces"); + auto const &extensionSchemaProps = objectSchemaProps["spaces"]["items"]["properties"]; + if (extensibles != objectFields.end()) { + auto &extensiblesArray = extensibles.value(); + int const numSpaces = extensiblesArray.size(); + thisZretMixer.spaces.resize(numSpaces); + int spaceCount = -1; + for (auto &extensibleInstance : extensiblesArray) { + ++spaceCount; + auto &thisZeqSpace = thisZretMixer.spaces[spaceCount]; + std::string const spaceName = ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "space_name"); + thisZeqSpace.spaceIndex = Util::FindItemInList(spaceName, state.dataHeatBal->space); + if (thisZeqSpace.spaceIndex == 0) { + ShowSevereError(state, format("{}{}={}", RoutineName, zeqMixerModuleObject, thisZretMixer.Name)); + ShowContinueError(state, format("Space Name={} not found.", spaceName)); + state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; + } else { + thisZeqSpace.spaceNodeNum = + GetOnlySingleNode(state, + ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "space_return_air_node_name"), + state.dataZoneEquip->GetZoneEquipmentDataErrorsFound, + thisZretMixer.spaceEquipType, + thisZretMixer.Name, + DataLoopNode::NodeFluidType::Air, + DataLoopNode::ConnectionType::Inlet, + NodeInputManager::CompFluidStream::Primary, + objectIsParent); + // Check space return nodes + bool found = false; + auto &thisSpaceEquipConfig = state.dataZoneEquip->spaceEquipConfig(thisZeqSpace.spaceIndex); + for (int retNodeNum : thisSpaceEquipConfig.ReturnNode) { + if (thisZeqSpace.spaceNodeNum == retNodeNum) { + found = true; + break; + } + } + if (!found) { + ShowSevereError(state, format("{}{}={}", RoutineName, zeqMixerModuleObject, thisZretMixer.Name)); + ShowContinueError(state, + format("Space Return Air Node Name={} is not a return air node for SpaceHVAC:EquipmentConnections={}.", + state.dataLoopNodes->NodeID(thisZeqSpace.spaceNodeNum), + thisSpaceEquipConfig.ZoneName)); + state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; + } + } + } + } +} + bool CheckZoneEquipmentList(EnergyPlusData &state, std::string_view const ComponentType, // Type of component std::string_view const ComponentName, // Name of component @@ -1743,6 +1867,8 @@ void ZoneEquipmentSplitterMixer::size(EnergyPlusData &state) this->Name)); break; default: + // If method is not set, then return + return; break; } @@ -2057,4 +2183,178 @@ void EquipConfiguration::hvacTimeStepInit(EnergyPlusData &state, bool FirstHVACI } } +void EquipConfiguration::calcReturnFlows(EnergyPlusData &state, + Real64 &ExpTotalReturnMassFlow, // Expected total return air mass flow rate + Real64 &FinalTotalReturnMassFlow // Final total return air mass flow rate +) +{ + int numRetNodes = this->NumReturnNodes; + Real64 totReturnFlow = 0.0; // Total flow to all return nodes in the zone (kg/s) + Real64 totVarReturnFlow = + 0.0; // Total variable return flow, for return nodes connected to an airloop with an OA system or not with specified flow (kg/s) + Real64 returnSchedFrac = ScheduleManager::GetCurrentScheduleValue(state, this->ReturnFlowSchedPtrNum); + this->FixedReturnFlow = false; + FinalTotalReturnMassFlow = 0.0; + this->TotAvailAirLoopOA = 0.0; + + // Set initial flow rate for each return node + for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) { + int retNode = this->ReturnNode(returnNum); + + if (retNode > 0) { + Real64 returnNodeMassFlow = 0.0; + auto &retNodeData(state.dataLoopNodes->Node(retNode)); + + int inletNum = this->ReturnNodeInletNum(returnNum); // which inlet node matches this return node (same airloop) + int ADUNum = 0; + if (inletNum > 0) ADUNum = this->InletNodeADUNum(inletNum); + int airLoop = this->ReturnNodeAirLoopNum(returnNum); + Real64 airLoopReturnFrac = 1.0; + if (airLoop > 0) { + // Establish corresponding airloop inlet(s) mass flow rate and set return node max/min/maxavail + Real64 inletMassFlow = 0.0; + int maxMinNodeNum = 0; + auto &thisAirLoopFlow(state.dataAirLoop->AirLoopFlow(airLoop)); + if (ADUNum > 0) { + // Zone return node could carry supply flow to zone without leaks plus any induced flow from plenum (but don't include other + // secondary flows from exhaust nodes) + inletMassFlow = state.dataDefineEquipment->AirDistUnit(ADUNum).MassFlowRateZSup + + state.dataDefineEquipment->AirDistUnit(ADUNum).MassFlowRatePlenInd; + maxMinNodeNum = state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum; + } else if (inletNum > 0) { + // If not connected to an ADU, then use the inlet node flow + inletMassFlow = state.dataLoopNodes->Node(this->InletNode(inletNum)).MassFlowRate; + maxMinNodeNum = this->InletNode(inletNum); + } + if (maxMinNodeNum > 0) { + auto const &maxMinNodeData(state.dataLoopNodes->Node(maxMinNodeNum)); + retNodeData.MassFlowRateMax = maxMinNodeData.MassFlowRateMax; + retNodeData.MassFlowRateMin = maxMinNodeData.MassFlowRateMin; + retNodeData.MassFlowRateMaxAvail = maxMinNodeData.MassFlowRateMaxAvail; + } else { + auto const &zoneNodeData(state.dataLoopNodes->Node(this->ZoneNode)); + retNodeData.MassFlowRateMax = zoneNodeData.MassFlowRateMax; + retNodeData.MassFlowRateMin = zoneNodeData.MassFlowRateMin; + retNodeData.MassFlowRateMaxAvail = zoneNodeData.MassFlowRateMaxAvail; + } + + airLoopReturnFrac = thisAirLoopFlow.DesReturnFrac; + if (state.dataAirSystemsData->PrimaryAirSystems(airLoop).OASysExists && (thisAirLoopFlow.MaxOutAir > 0.0)) { + // Set return flow as fraction of matching inlet node flow if there is an OA system and available OA flow > 0.0 + returnNodeMassFlow = airLoopReturnFrac * inletMassFlow; + this->TotAvailAirLoopOA += thisAirLoopFlow.MaxOutAir; + } else { + // Set return flow to matching inlet node flow + returnNodeMassFlow = inletMassFlow; + this->FixedReturnFlow(returnNum) = true; + } + } else { + returnNodeMassFlow = 0.0; + } + + // Return node 1 is special + if (returnNum == 1) { + // Make no return air flow adjustments during sizing + if ((state.dataGlobal->DoingSizing) && numRetNodes == 1) { + returnNodeMassFlow = ExpTotalReturnMassFlow; + if (airLoop > 0) { + if (!state.dataAirSystemsData->PrimaryAirSystems(airLoop).OASysExists || + (state.dataAirLoop->AirLoopFlow(airLoop).MaxOutAir == 0.0)) { + ExpTotalReturnMassFlow = max(0.0, ExpTotalReturnMassFlow - this->ZoneExhBalanced + this->ZoneExh); + returnNodeMassFlow = ExpTotalReturnMassFlow; + } + } + } else if (!state.dataGlobal->DoingSizing) { + if (this->NumReturnFlowBasisNodes > 0) { + // Set base return air flow rate for node 1 using basis node flow rates + Real64 basisNodesMassFlow = 0.0; + for (int nodeNum = 1; nodeNum <= this->NumReturnFlowBasisNodes; ++nodeNum) { + basisNodesMassFlow += state.dataLoopNodes->Node(this->ReturnFlowBasisNode(nodeNum)).MassFlowRate; + } + returnNodeMassFlow = max(0.0, (basisNodesMassFlow * returnSchedFrac)); + this->FixedReturnFlow(returnNum) = true; + } else { + // If only 1 return node, use the standard return mass flow + if ((numRetNodes == 1) && !this->FixedReturnFlow(returnNum)) { + returnNodeMassFlow = max(0.0, (ExpTotalReturnMassFlow * returnSchedFrac * airLoopReturnFrac)); + } + } + } + } + totReturnFlow += returnNodeMassFlow; + retNodeData.MassFlowRate = returnNodeMassFlow; + retNodeData.MassFlowRateMinAvail = 0.0; + if (!this->FixedReturnFlow(returnNum)) totVarReturnFlow += returnNodeMassFlow; + } + } + + // if zone mass balance true, set to expected return flow + if (state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment != DataHeatBalance::AdjustmentType::NoAdjustReturnAndMixing) { + // applies zone return flow schedule multiplier + ExpTotalReturnMassFlow = returnSchedFrac * ExpTotalReturnMassFlow; + // set air flow rate for each return node + Real64 zoneTotReturnFlow = 0.0; + Real64 returnNodeMassFlow = 0.0; + for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) { + int retNode = this->ReturnNode(returnNum); + if (retNode > 0) { + if (numRetNodes == 1) { + returnNodeMassFlow = ExpTotalReturnMassFlow; + } else { // multiple return nodes + if (ExpTotalReturnMassFlow > 0.0) { + Real64 returnAdjFactor = state.dataLoopNodes->Node(retNode).MassFlowRate / ExpTotalReturnMassFlow; + returnNodeMassFlow = returnAdjFactor * ExpTotalReturnMassFlow; + } else { + returnNodeMassFlow = 0.0; + } + } + } + zoneTotReturnFlow += returnNodeMassFlow; + } + // Adjust return node flows if zone total return flow is > 0 + if (zoneTotReturnFlow > 0.0) { + for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) { + int retNode = this->ReturnNode(returnNum); + if (retNode > 0) { + if (numRetNodes == 1) { + // set it to expected return flows + state.dataLoopNodes->Node(retNode).MassFlowRate = ExpTotalReturnMassFlow; + FinalTotalReturnMassFlow = ExpTotalReturnMassFlow; + } else { // multiple return nodes, adjust nodes flow + Real64 newReturnFlow = 0.0; + Real64 returnAdjFactor = ExpTotalReturnMassFlow / zoneTotReturnFlow; + Real64 curReturnFlow = state.dataLoopNodes->Node(retNode).MassFlowRate; + newReturnFlow = curReturnFlow * returnAdjFactor; + state.dataLoopNodes->Node(retNode).MassFlowRate = newReturnFlow; + FinalTotalReturnMassFlow += newReturnFlow; + } + } + } + } else { + FinalTotalReturnMassFlow = ExpTotalReturnMassFlow; + } + } else { + // Adjust return flows if greater than expected (i.e. there is exhaust or mixing flow reducing the total available for return) + if ((totReturnFlow > ExpTotalReturnMassFlow) && (totVarReturnFlow > 0.0)) { + Real64 newReturnFlow = 0.0; + Real64 returnAdjFactor = (1 - ((totReturnFlow - ExpTotalReturnMassFlow) / totVarReturnFlow)); // Return flow adjustment factor + for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) { + int retNode = this->ReturnNode(returnNum); + Real64 curReturnFlow = state.dataLoopNodes->Node(retNode).MassFlowRate; + if (retNode > 0) { + if (!this->FixedReturnFlow(returnNum)) { + newReturnFlow = curReturnFlow * returnAdjFactor; + FinalTotalReturnMassFlow += newReturnFlow; + state.dataLoopNodes->Node(retNode).MassFlowRate = newReturnFlow; + } else { + FinalTotalReturnMassFlow += curReturnFlow; + } + } + } + } else { + FinalTotalReturnMassFlow = totReturnFlow; + } + } +} + } // namespace EnergyPlus::DataZoneEquipment diff --git a/src/EnergyPlus/DataZoneEquipment.hh b/src/EnergyPlus/DataZoneEquipment.hh index 9746958919f..af898323a1b 100644 --- a/src/EnergyPlus/DataZoneEquipment.hh +++ b/src/EnergyPlus/DataZoneEquipment.hh @@ -372,6 +372,11 @@ namespace DataZoneEquipment { void beginEnvirnInit(EnergyPlusData &state); void hvacTimeStepInit(EnergyPlusData &state, bool FirstHVACIteration); + + void calcReturnFlows(EnergyPlusData &state, + Real64 &ExpTotalReturnMassFlow, // Expected total return air mass flow rate + Real64 &FinalTotalReturnMassFlow // Final total return air mass flow rate + ); }; struct EquipmentData // data for an individual component @@ -486,6 +491,14 @@ namespace DataZoneEquipment { void setInletFlows(EnergyPlusData &state); }; + struct ZoneReturnMixer : ZoneEquipmentSplitterMixer + { + int zoneReturnNodeNum = 0; + + // void setOutletConditions(EnergyPlusData &state); + + // void setInletFlows(EnergyPlusData &state); + }; struct ControlList { // Members @@ -567,6 +580,13 @@ namespace DataZoneEquipment { InputProcessor::json const objectFields, DataZoneEquipment::ZoneEquipmentMixer &thisZeqMixer); + void processZoneReturnMixerInput(EnergyPlusData &state, + std::string_view zeqMixerModuleObject, + int const zoneNum, + InputProcessor::json const objectSchemaProps, + InputProcessor::json const objectFields, + DataZoneEquipment::ZoneReturnMixer &thisZretMixer); + bool CheckZoneEquipmentList(EnergyPlusData &state, std::string_view ComponentType, // Type of component std::string_view ComponentName, // Name of component @@ -623,6 +643,7 @@ struct DataZoneEquipmentData : BaseGlobalStruct Array1D ZoneExhaustControlSystem; // 2022-01: maybe a better name? std::vector zoneEquipSplitter; std::vector zoneEquipMixer; + std::vector zoneReturnMixer; void init_state([[maybe_unused]] EnergyPlusData &state) override { diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index ae3ecdf4cbd..3653be24fb4 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -4908,7 +4908,7 @@ void CalcZoneMassBalance(EnergyPlusData &state, bool const FirstHVACIteration) } Real64 FinalTotalReturnMassFlow = 0; - CalcZoneReturnFlows(state, ZoneNum, StdTotalReturnMassFlow, FinalTotalReturnMassFlow); + zoneEquipConfig.calcReturnFlows(state, StdTotalReturnMassFlow, FinalTotalReturnMassFlow); if (state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) { // set mass conservation variables massConservation.InMassFlowRate = TotInletAirMassFlowRate; @@ -4927,7 +4927,7 @@ void CalcZoneMassBalance(EnergyPlusData &state, bool const FirstHVACIteration) AdjustedTotalReturnMassFlow = min(AdjustedTotalReturnMassFlow, zoneEquipConfig.AirLoopDesSupply); } // add adjust zone return node air flow calc - CalcZoneReturnFlows(state, ZoneNum, AdjustedTotalReturnMassFlow, FinalTotalReturnMassFlow); + zoneEquipConfig.calcReturnFlows(state, AdjustedTotalReturnMassFlow, FinalTotalReturnMassFlow); massConservation.RetMassFlowRate = FinalTotalReturnMassFlow; ZoneReturnAirMassFlowRate = FinalTotalReturnMassFlow; } @@ -4944,7 +4944,7 @@ void CalcZoneMassBalance(EnergyPlusData &state, bool const FirstHVACIteration) } // add adjust zone return node air flow calculation - CalcZoneReturnFlows(state, ZoneNum, AdjustedTotalReturnMassFlow, FinalTotalReturnMassFlow); + zoneEquipConfig.calcReturnFlows(state, AdjustedTotalReturnMassFlow, FinalTotalReturnMassFlow); massConservation.RetMassFlowRate = FinalTotalReturnMassFlow; ZoneReturnAirMassFlowRate = FinalTotalReturnMassFlow; @@ -4962,7 +4962,7 @@ void CalcZoneMassBalance(EnergyPlusData &state, bool const FirstHVACIteration) } // add adjust zone return node air flow calc - CalcZoneReturnFlows(state, ZoneNum, AdjustedTotalReturnMassFlow, FinalTotalReturnMassFlow); + zoneEquipConfig.calcReturnFlows(state, AdjustedTotalReturnMassFlow, FinalTotalReturnMassFlow); massConservation.RetMassFlowRate = FinalTotalReturnMassFlow; ZoneReturnAirMassFlowRate = FinalTotalReturnMassFlow; } @@ -5094,182 +5094,6 @@ void CalcZoneMassBalance(EnergyPlusData &state, bool const FirstHVACIteration) } } -void CalcZoneReturnFlows(EnergyPlusData &state, - int const ZoneNum, - Real64 &ExpTotalReturnMassFlow, // Expected total return air mass flow rate - Real64 &FinalTotalReturnMassFlow // Final total return air mass flow rate -) -{ - auto &thisZoneEquip(state.dataZoneEquip->ZoneEquipConfig(ZoneNum)); - int numRetNodes = thisZoneEquip.NumReturnNodes; - Real64 totReturnFlow = 0.0; // Total flow to all return nodes in the zone (kg/s) - Real64 totVarReturnFlow = - 0.0; // Total variable return flow, for return nodes connected to an airloop with an OA system or not with specified flow (kg/s) - Real64 returnSchedFrac = ScheduleManager::GetCurrentScheduleValue(state, thisZoneEquip.ReturnFlowSchedPtrNum); - thisZoneEquip.FixedReturnFlow = false; - FinalTotalReturnMassFlow = 0.0; - thisZoneEquip.TotAvailAirLoopOA = 0.0; - - // Set initial flow rate for each return node - for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) { - int retNode = thisZoneEquip.ReturnNode(returnNum); - - if (retNode > 0) { - Real64 returnNodeMassFlow = 0.0; - auto &retNodeData(state.dataLoopNodes->Node(retNode)); - - int inletNum = thisZoneEquip.ReturnNodeInletNum(returnNum); // which inlet node matches this return node (same airloop) - int ADUNum = 0; - if (inletNum > 0) ADUNum = thisZoneEquip.InletNodeADUNum(inletNum); - int airLoop = thisZoneEquip.ReturnNodeAirLoopNum(returnNum); - Real64 airLoopReturnFrac = 1.0; - if (airLoop > 0) { - // Establish corresponding airloop inlet(s) mass flow rate and set return node max/min/maxavail - Real64 inletMassFlow = 0.0; - int maxMinNodeNum = 0; - auto &thisAirLoopFlow(state.dataAirLoop->AirLoopFlow(airLoop)); - if (ADUNum > 0) { - // Zone return node could carry supply flow to zone without leaks plus any induced flow from plenum (but don't include other - // secondary flows from exhaust nodes) - inletMassFlow = state.dataDefineEquipment->AirDistUnit(ADUNum).MassFlowRateZSup + - state.dataDefineEquipment->AirDistUnit(ADUNum).MassFlowRatePlenInd; - maxMinNodeNum = state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum; - } else if (inletNum > 0) { - // If not connected to an ADU, then use the inlet node flow - inletMassFlow = state.dataLoopNodes->Node(thisZoneEquip.InletNode(inletNum)).MassFlowRate; - maxMinNodeNum = thisZoneEquip.InletNode(inletNum); - } - if (maxMinNodeNum > 0) { - auto const &maxMinNodeData(state.dataLoopNodes->Node(maxMinNodeNum)); - retNodeData.MassFlowRateMax = maxMinNodeData.MassFlowRateMax; - retNodeData.MassFlowRateMin = maxMinNodeData.MassFlowRateMin; - retNodeData.MassFlowRateMaxAvail = maxMinNodeData.MassFlowRateMaxAvail; - } else { - auto const &zoneNodeData(state.dataLoopNodes->Node(thisZoneEquip.ZoneNode)); - retNodeData.MassFlowRateMax = zoneNodeData.MassFlowRateMax; - retNodeData.MassFlowRateMin = zoneNodeData.MassFlowRateMin; - retNodeData.MassFlowRateMaxAvail = zoneNodeData.MassFlowRateMaxAvail; - } - - airLoopReturnFrac = thisAirLoopFlow.DesReturnFrac; - if (state.dataAirSystemsData->PrimaryAirSystems(airLoop).OASysExists && (thisAirLoopFlow.MaxOutAir > 0.0)) { - // Set return flow as fraction of matching inlet node flow if there is an OA system and available OA flow > 0.0 - returnNodeMassFlow = airLoopReturnFrac * inletMassFlow; - thisZoneEquip.TotAvailAirLoopOA += thisAirLoopFlow.MaxOutAir; - } else { - // Set return flow to matching inlet node flow - returnNodeMassFlow = inletMassFlow; - thisZoneEquip.FixedReturnFlow(returnNum) = true; - } - } else { - returnNodeMassFlow = 0.0; - } - - // Return node 1 is special - if (returnNum == 1) { - // Make no return air flow adjustments during sizing - if ((state.dataGlobal->DoingSizing) && numRetNodes == 1) { - returnNodeMassFlow = ExpTotalReturnMassFlow; - if (airLoop > 0) { - if (!state.dataAirSystemsData->PrimaryAirSystems(airLoop).OASysExists || - (state.dataAirLoop->AirLoopFlow(airLoop).MaxOutAir == 0.0)) { - ExpTotalReturnMassFlow = max(0.0, ExpTotalReturnMassFlow - thisZoneEquip.ZoneExhBalanced + thisZoneEquip.ZoneExh); - returnNodeMassFlow = ExpTotalReturnMassFlow; - } - } - } else if (!state.dataGlobal->DoingSizing) { - if (thisZoneEquip.NumReturnFlowBasisNodes > 0) { - // Set base return air flow rate for node 1 using basis node flow rates - Real64 basisNodesMassFlow = 0.0; - for (int nodeNum = 1; nodeNum <= thisZoneEquip.NumReturnFlowBasisNodes; ++nodeNum) { - basisNodesMassFlow += state.dataLoopNodes->Node(thisZoneEquip.ReturnFlowBasisNode(nodeNum)).MassFlowRate; - } - returnNodeMassFlow = max(0.0, (basisNodesMassFlow * returnSchedFrac)); - thisZoneEquip.FixedReturnFlow(returnNum) = true; - } else { - // If only 1 return node, use the standard return mass flow - if ((numRetNodes == 1) && !thisZoneEquip.FixedReturnFlow(returnNum)) { - returnNodeMassFlow = max(0.0, (ExpTotalReturnMassFlow * returnSchedFrac * airLoopReturnFrac)); - } - } - } - } - totReturnFlow += returnNodeMassFlow; - retNodeData.MassFlowRate = returnNodeMassFlow; - retNodeData.MassFlowRateMinAvail = 0.0; - if (!thisZoneEquip.FixedReturnFlow(returnNum)) totVarReturnFlow += returnNodeMassFlow; - } - } - - // if zone mass balance true, set to expected return flow - if (state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment != DataHeatBalance::AdjustmentType::NoAdjustReturnAndMixing) { - // applies zone return flow schedule multiplier - ExpTotalReturnMassFlow = returnSchedFrac * ExpTotalReturnMassFlow; - // set air flow rate for each return node - Real64 zoneTotReturnFlow = 0.0; - Real64 returnNodeMassFlow = 0.0; - for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) { - int retNode = thisZoneEquip.ReturnNode(returnNum); - if (retNode > 0) { - if (numRetNodes == 1) { - returnNodeMassFlow = ExpTotalReturnMassFlow; - } else { // multiple return nodes - if (ExpTotalReturnMassFlow > 0.0) { - Real64 returnAdjFactor = state.dataLoopNodes->Node(retNode).MassFlowRate / ExpTotalReturnMassFlow; - returnNodeMassFlow = returnAdjFactor * ExpTotalReturnMassFlow; - } else { - returnNodeMassFlow = 0.0; - } - } - } - zoneTotReturnFlow += returnNodeMassFlow; - } - // Adjust return node flows if zone total return flow is > 0 - if (zoneTotReturnFlow > 0.0) { - for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) { - int retNode = thisZoneEquip.ReturnNode(returnNum); - if (retNode > 0) { - if (numRetNodes == 1) { - // set it to expected return flows - state.dataLoopNodes->Node(retNode).MassFlowRate = ExpTotalReturnMassFlow; - FinalTotalReturnMassFlow = ExpTotalReturnMassFlow; - } else { // multiple return nodes, adjust nodes flow - Real64 newReturnFlow = 0.0; - Real64 returnAdjFactor = ExpTotalReturnMassFlow / zoneTotReturnFlow; - Real64 curReturnFlow = state.dataLoopNodes->Node(retNode).MassFlowRate; - newReturnFlow = curReturnFlow * returnAdjFactor; - state.dataLoopNodes->Node(retNode).MassFlowRate = newReturnFlow; - FinalTotalReturnMassFlow += newReturnFlow; - } - } - } - } else { - FinalTotalReturnMassFlow = ExpTotalReturnMassFlow; - } - } else { - // Adjust return flows if greater than expected (i.e. there is exhaust or mixing flow reducing the total available for return) - if ((totReturnFlow > ExpTotalReturnMassFlow) && (totVarReturnFlow > 0.0)) { - Real64 newReturnFlow = 0.0; - Real64 returnAdjFactor = (1 - ((totReturnFlow - ExpTotalReturnMassFlow) / totVarReturnFlow)); // Return flow adjustment factor - for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) { - int retNode = thisZoneEquip.ReturnNode(returnNum); - Real64 curReturnFlow = state.dataLoopNodes->Node(retNode).MassFlowRate; - if (retNode > 0) { - if (!thisZoneEquip.FixedReturnFlow(returnNum)) { - newReturnFlow = curReturnFlow * returnAdjFactor; - FinalTotalReturnMassFlow += newReturnFlow; - state.dataLoopNodes->Node(retNode).MassFlowRate = newReturnFlow; - } else { - FinalTotalReturnMassFlow += curReturnFlow; - } - } - } - } else { - FinalTotalReturnMassFlow = totReturnFlow; - } - } -} - void CalcZoneInfiltrationFlows(EnergyPlusData &state, int const ZoneNum, // current zone index Real64 &ZoneReturnAirMassFlowRate // zone total zone return air mass flow rate diff --git a/src/EnergyPlus/ZoneEquipmentManager.hh b/src/EnergyPlus/ZoneEquipmentManager.hh index 25e10c8b2f2..b1114a23688 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.hh +++ b/src/EnergyPlus/ZoneEquipmentManager.hh @@ -212,12 +212,6 @@ namespace ZoneEquipmentManager { void CalcZoneMassBalance(EnergyPlusData &state, bool FirstHVACIteration); - void CalcZoneReturnFlows(EnergyPlusData &state, - int ZoneNum, - Real64 &ExpTotalReturnMassFlow, // Expected total return air mass flow rate - Real64 &FinalTotalReturnMassFlow // Final total return air mass flow rate - ); - void CalcZoneInfiltrationFlows(EnergyPlusData &state, int ZoneNum, // current zone index Real64 &ZoneReturnAirMassFlowRate // zone total zone return air mass flow rate diff --git a/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc b/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc index 7dcaa240cb5..8f27f0bfe7d 100644 --- a/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc +++ b/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc @@ -555,7 +555,7 @@ TEST_F(EnergyPlusFixture, ZoneEquipmentManager_CalcZoneMassBalanceTest2) Real64 StdTotalReturnMassFlow = 0.0; Real64 FinalTotalReturnMassFlow = 0.0; - CalcZoneReturnFlows(*state, ZoneNum, StdTotalReturnMassFlow, FinalTotalReturnMassFlow); + state->dataZoneEquip->ZoneEquipConfig(ZoneNum).calcReturnFlows(*state, StdTotalReturnMassFlow, FinalTotalReturnMassFlow); EXPECT_EQ(FinalTotalReturnMassFlow, 0.0); EXPECT_EQ(state->dataLoopNodes->Node(returnNode1).MassFlowRate, 0.0); EXPECT_EQ(state->dataLoopNodes->Node(returnNode2).MassFlowRate, 0.0); @@ -572,7 +572,7 @@ TEST_F(EnergyPlusFixture, ZoneEquipmentManager_CalcZoneMassBalanceTest2) StdTotalReturnMassFlow = 0.0; FinalTotalReturnMassFlow = 0.0; - CalcZoneReturnFlows(*state, ZoneNum, StdTotalReturnMassFlow, FinalTotalReturnMassFlow); + state->dataZoneEquip->ZoneEquipConfig(ZoneNum).calcReturnFlows(*state, StdTotalReturnMassFlow, FinalTotalReturnMassFlow); EXPECT_EQ(FinalTotalReturnMassFlow, 6.0); EXPECT_EQ(state->dataLoopNodes->Node(returnNode1).MassFlowRate, 2.0); EXPECT_EQ(state->dataLoopNodes->Node(returnNode2).MassFlowRate, 1.0); @@ -792,7 +792,7 @@ TEST_F(EnergyPlusFixture, ZoneEquipmentManager_CalcZoneMassBalanceTest4) Real64 StdTotalReturnMassFlow = 0.0; Real64 FinalTotalReturnMassFlow = 0.0; - CalcZoneReturnFlows(*state, ZoneNum, StdTotalReturnMassFlow, FinalTotalReturnMassFlow); + state->dataZoneEquip->ZoneEquipConfig(ZoneNum).calcReturnFlows(*state, StdTotalReturnMassFlow, FinalTotalReturnMassFlow); EXPECT_EQ(FinalTotalReturnMassFlow, 0.0); EXPECT_EQ(state->dataLoopNodes->Node(returnNode1).MassFlowRate, 0.0); EXPECT_EQ(state->dataLoopNodes->Node(returnNode2).MassFlowRate, 0.0); @@ -809,7 +809,7 @@ TEST_F(EnergyPlusFixture, ZoneEquipmentManager_CalcZoneMassBalanceTest4) StdTotalReturnMassFlow = 6.0; FinalTotalReturnMassFlow = 0.0; - CalcZoneReturnFlows(*state, ZoneNum, StdTotalReturnMassFlow, FinalTotalReturnMassFlow); + state->dataZoneEquip->ZoneEquipConfig(ZoneNum).calcReturnFlows(*state, StdTotalReturnMassFlow, FinalTotalReturnMassFlow); EXPECT_EQ(FinalTotalReturnMassFlow, 5.9); EXPECT_EQ(state->dataLoopNodes->Node(returnNode1).MassFlowRate, 2.0); EXPECT_EQ(state->dataLoopNodes->Node(returnNode2).MassFlowRate, 0.9); @@ -832,7 +832,7 @@ TEST_F(EnergyPlusFixture, ZoneEquipmentManager_CalcZoneMassBalanceTest4) StdTotalReturnMassFlow = 6.0; FinalTotalReturnMassFlow = 0.0; - CalcZoneReturnFlows(*state, ZoneNum, StdTotalReturnMassFlow, FinalTotalReturnMassFlow); + state->dataZoneEquip->ZoneEquipConfig(ZoneNum).calcReturnFlows(*state, StdTotalReturnMassFlow, FinalTotalReturnMassFlow); EXPECT_EQ(FinalTotalReturnMassFlow, 6.0); EXPECT_EQ(state->dataLoopNodes->Node(returnNode1).MassFlowRate, 2.0); EXPECT_EQ(state->dataLoopNodes->Node(returnNode2).MassFlowRate, 1.0); From fd2a28f67a847ab090cd73e2524ba4e8a3ff9d1d Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Mon, 12 Aug 2024 10:28:35 -0500 Subject: [PATCH 68/81] Space IV-SpaceHVACZoneReturnMixer 2 --- src/EnergyPlus/DataZoneEquipment.cc | 141 +++++++++++++----- src/EnergyPlus/DataZoneEquipment.hh | 22 +-- src/EnergyPlus/ZoneEquipmentManager.cc | 9 ++ .../unit/ZoneEquipmentManager.unit.cc | 4 +- 4 files changed, 125 insertions(+), 51 deletions(-) diff --git a/src/EnergyPlus/DataZoneEquipment.cc b/src/EnergyPlus/DataZoneEquipment.cc index d4c6087da87..5228b809e6a 100644 --- a/src/EnergyPlus/DataZoneEquipment.cc +++ b/src/EnergyPlus/DataZoneEquipment.cc @@ -587,7 +587,7 @@ void GetZoneEquipmentData(EnergyPlusData &state) continue; } - processZoneReturnMixerInput(state, CurrentModuleObject, zoneNum, objectSchemaProps, objectFields, thisZretMixer); + processZoneReturnMixerInput(state, CurrentModuleObject, zoneNum, objectSchemaProps, objectFields, zeqRetNum); } } // end loop over zone return mixers @@ -1326,20 +1326,20 @@ void processZoneEquipMixerInput(EnergyPlusData &state, static constexpr std::string_view RoutineName("processZoneEquipMixerInput: "); // include trailing blank space auto &ip = state.dataInputProcessing->inputProcessor; bool objectIsParent = true; - thisZeqMixer.zoneEquipInletNodeNum = GetOnlySingleNode(state, - ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_equipment_inlet_node_name"), - state.dataZoneEquip->GetZoneEquipmentDataErrorsFound, - thisZeqMixer.spaceEquipType, - thisZeqMixer.Name, - DataLoopNode::NodeFluidType::Air, - DataLoopNode::ConnectionType::Outlet, - NodeInputManager::CompFluidStream::Primary, - objectIsParent); + thisZeqMixer.outletNodeNum = GetOnlySingleNode(state, + ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_equipment_inlet_node_name"), + state.dataZoneEquip->GetZoneEquipmentDataErrorsFound, + thisZeqMixer.spaceEquipType, + thisZeqMixer.Name, + DataLoopNode::NodeFluidType::Air, + DataLoopNode::ConnectionType::Outlet, + NodeInputManager::CompFluidStream::Primary, + objectIsParent); // Check zone exhaust nodes bool found = false; auto &thisZoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(zoneNum); for (int exhNodeNum : thisZoneEquipConfig.ExhaustNode) { - if (thisZeqMixer.zoneEquipInletNodeNum == exhNodeNum) { + if (thisZeqMixer.outletNodeNum == exhNodeNum) { found = true; break; } @@ -1348,7 +1348,7 @@ void processZoneEquipMixerInput(EnergyPlusData &state, ShowSevereError(state, format("{}{}={}", RoutineName, zeqMixerModuleObject, thisZeqMixer.Name)); ShowContinueError(state, format("Zone Equipment Inlet Node Name={} is not an exhaust node for ZoneHVAC:EquipmentConnections={}.", - state.dataLoopNodes->NodeID(thisZeqMixer.zoneEquipInletNodeNum), + state.dataLoopNodes->NodeID(thisZeqMixer.outletNodeNum), thisZoneEquipConfig.ZoneName)); state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; } @@ -1410,27 +1410,37 @@ void processZoneReturnMixerInput(EnergyPlusData &state, int const zoneNum, InputProcessor::json const objectSchemaProps, InputProcessor::json const objectFields, - DataZoneEquipment::ZoneReturnMixer &thisZretMixer) + int mixerIndex) { static constexpr std::string_view RoutineName("processZoneReturnMixerInput: "); // include trailing blank space auto &ip = state.dataInputProcessing->inputProcessor; bool objectIsParent = true; - thisZretMixer.zoneReturnNodeNum = GetOnlySingleNode(state, - ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_return_air_node_name"), - state.dataZoneEquip->GetZoneEquipmentDataErrorsFound, - thisZretMixer.spaceEquipType, - thisZretMixer.Name, - DataLoopNode::NodeFluidType::Air, - DataLoopNode::ConnectionType::Outlet, - NodeInputManager::CompFluidStream::Primary, - objectIsParent); + auto &thisZretMixer = state.dataZoneEquip->zoneReturnMixer[mixerIndex]; + thisZretMixer.outletNodeNum = GetOnlySingleNode(state, + ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_return_air_node_name"), + state.dataZoneEquip->GetZoneEquipmentDataErrorsFound, + thisZretMixer.spaceEquipType, + thisZretMixer.Name, + DataLoopNode::NodeFluidType::Air, + DataLoopNode::ConnectionType::Outlet, + NodeInputManager::CompFluidStream::Primary, + objectIsParent); // Check zone return nodes bool found = false; auto &thisZoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(zoneNum); + thisZoneEquipConfig.returnNodeSpaceMixerIndex.allocate(thisZoneEquipConfig.NumReturnNodes); + for (int &mixIndex : thisZoneEquipConfig.returnNodeSpaceMixerIndex) { + mixIndex = -1; + } + + int nodeCounter = 0; for (int retNodeNum : thisZoneEquipConfig.ReturnNode) { - if (thisZretMixer.zoneReturnNodeNum == retNodeNum) { + ++nodeCounter; + if (thisZretMixer.outletNodeNum == retNodeNum) { found = true; + // Zone return node is fed by a space return mixer + thisZoneEquipConfig.returnNodeSpaceMixerIndex(nodeCounter) = mixerIndex; break; } } @@ -1438,7 +1448,7 @@ void processZoneReturnMixerInput(EnergyPlusData &state, ShowSevereError(state, format("{}{}={}", RoutineName, zeqMixerModuleObject, thisZretMixer.Name)); ShowContinueError(state, format("Zone Equipment Return Air Node Name={} is not a return air node for ZoneHVAC:EquipmentConnections={}.", - state.dataLoopNodes->NodeID(thisZretMixer.zoneReturnNodeNum), + state.dataLoopNodes->NodeID(thisZretMixer.outletNodeNum), thisZoneEquipConfig.ZoneName)); state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; } @@ -1923,9 +1933,9 @@ void ZoneEquipmentSplitterMixer::size(EnergyPlusData &state) } } -void ZoneEquipmentMixer::setOutletConditions(EnergyPlusData &state) +void ZoneMixer::setOutletConditions(EnergyPlusData &state) { - if (this->zoneEquipInletNodeNum == 0) return; + if (this->outletNodeNum == 0) return; Real64 sumEnthalpy = 0.0; Real64 sumHumRat = 0.0; @@ -1933,7 +1943,7 @@ void ZoneEquipmentMixer::setOutletConditions(EnergyPlusData &state) Real64 sumGenContam = 0.0; Real64 sumPressure = 0.0; Real64 sumFractions = 0.0; - auto &equipInletNode = state.dataLoopNodes->Node(this->zoneEquipInletNodeNum); + auto &outletNode = state.dataLoopNodes->Node(this->outletNodeNum); for (auto &mixerSpace : this->spaces) { auto &spaceOutletNode = state.dataLoopNodes->Node(mixerSpace.spaceNodeNum); sumEnthalpy += spaceOutletNode.Enthalpy * mixerSpace.fraction; @@ -1947,25 +1957,47 @@ void ZoneEquipmentMixer::setOutletConditions(EnergyPlusData &state) sumPressure += spaceOutletNode.Press * mixerSpace.fraction; sumFractions += mixerSpace.fraction; } - equipInletNode.Enthalpy = sumEnthalpy / sumFractions; - equipInletNode.HumRat = sumHumRat / sumFractions; - if (state.dataContaminantBalance->Contaminant.CO2Simulation) { - equipInletNode.CO2 = sumCO2 / sumFractions; - } - if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) { - equipInletNode.GenContam = sumGenContam / sumFractions; - } - equipInletNode.Press = sumPressure / sumFractions; - // Use Enthalpy and humidity ratio to get outlet temperature from psych chart - equipInletNode.Temp = Psychrometrics::PsyTdbFnHW(equipInletNode.Enthalpy, equipInletNode.HumRat); + // For SpaceHVAC:ZoneReturnMixer, the fractions are dynamic and could be zero if there is no flow + if (sumFractions > 0) { + outletNode.Enthalpy = sumEnthalpy / sumFractions; + outletNode.HumRat = sumHumRat / sumFractions; + if (state.dataContaminantBalance->Contaminant.CO2Simulation) { + outletNode.CO2 = sumCO2 / sumFractions; + } + if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) { + outletNode.GenContam = sumGenContam / sumFractions; + } + outletNode.Press = sumPressure / sumFractions; + + // Use Enthalpy and humidity ratio to get outlet temperature from psych chart + outletNode.Temp = Psychrometrics::PsyTdbFnHW(outletNode.Enthalpy, outletNode.HumRat); + } } +void ZoneReturnMixer::setInletConditions(EnergyPlusData &state) +{ + for (auto &mixerSpace : this->spaces) { + auto &spaceOutletNode = state.dataLoopNodes->Node(mixerSpace.spaceNodeNum); + int spaceZoneNodeNum = state.dataZoneEquip->spaceEquipConfig(mixerSpace.spaceIndex).ZoneNode; + auto &spaceNode = state.dataLoopNodes->Node(spaceZoneNodeNum); + spaceOutletNode.Temp = spaceNode.Temp; + spaceOutletNode.HumRat = spaceNode.HumRat; + spaceOutletNode.Enthalpy = spaceNode.Enthalpy; + spaceOutletNode.Press = spaceNode.Press; + if (state.dataContaminantBalance->Contaminant.CO2Simulation) { + spaceOutletNode.CO2 = spaceNode.CO2; + } + if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) { + spaceOutletNode.GenContam = spaceNode.GenContam; + } + } +} void ZoneEquipmentMixer::setInletFlows(EnergyPlusData &state) { - if (this->zoneEquipInletNodeNum == 0) return; + if (this->outletNodeNum == 0) return; - auto &equipInletNode = state.dataLoopNodes->Node(this->zoneEquipInletNodeNum); + auto &equipInletNode = state.dataLoopNodes->Node(this->outletNodeNum); for (auto &mixerSpace : this->spaces) { auto &spaceOutletNode = state.dataLoopNodes->Node(mixerSpace.spaceNodeNum); spaceOutletNode.MassFlowRate = equipInletNode.MassFlowRate * mixerSpace.fraction; @@ -1974,6 +2006,35 @@ void ZoneEquipmentMixer::setInletFlows(EnergyPlusData &state) } } +void ZoneReturnMixer::setInletFlows(EnergyPlusData &state) +{ + if (this->outletNodeNum == 0) return; + auto &outletNode = state.dataLoopNodes->Node(this->outletNodeNum); + + Real64 sumMixerInletMassFlow = 0; + for (auto const &mixerSpace : this->spaces) { + // calc return flows for spaces feeding this mixer + auto &spaceEquipConfig = state.dataZoneEquip->spaceEquipConfig(mixerSpace.spaceIndex); + Real64 outletMassFlowRate = outletNode.MassFlowRate; // calcReturnFlows might adjust this parameter value, so make a copy here + Real64 spaceReturnFlow = 0.0; + spaceEquipConfig.calcReturnFlows(state, outletMassFlowRate, spaceReturnFlow); + sumMixerInletMassFlow += spaceReturnFlow; + } + + for (auto &mixerSpace : this->spaces) { + auto &spaceOutletNode = state.dataLoopNodes->Node(mixerSpace.spaceNodeNum); + // For return mixer, fraction is calculated every time step, not a user input + if (sumMixerInletMassFlow > 0.0) { + mixerSpace.fraction = spaceOutletNode.MassFlowRate / sumMixerInletMassFlow; + } else { + mixerSpace.fraction = 0.0; + } + spaceOutletNode.MassFlowRate = outletNode.MassFlowRate * mixerSpace.fraction; + spaceOutletNode.MassFlowRateMaxAvail = outletNode.MassFlowRateMaxAvail * mixerSpace.fraction; + spaceOutletNode.MassFlowRateMinAvail = outletNode.MassFlowRateMinAvail * mixerSpace.fraction; + } +} + void ZoneEquipmentSplitter::adjustLoads(EnergyPlusData &state, int zoneNum, int equipTypeNum) { auto &thisZoneEnergyDemand = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum); diff --git a/src/EnergyPlus/DataZoneEquipment.hh b/src/EnergyPlus/DataZoneEquipment.hh index af898323a1b..772ee8001f6 100644 --- a/src/EnergyPlus/DataZoneEquipment.hh +++ b/src/EnergyPlus/DataZoneEquipment.hh @@ -326,10 +326,9 @@ namespace DataZoneEquipment { Array1D_int ReturnNodePlenumNum; // number of the return plenum attached to this return node (zero if none) Array1D_int ReturnFlowBasisNode; // return air flow basis nodes Array1D_int ReturnNodeExhaustNodeNum; // Exhaust node number flow to a corrsponding return node due to light heat gain - // Array1D_int SharedExhaustNode; // Exhaust node number shared by return nodes 0 No exhaust; 1 No share; > 1 shared; -1 use the - // exhaust node value Array1D SharedExhaustNode; // Exhaust node number shared by return nodes 0 No exhaust; 1 No share; > 1 shared; -1 use the exhaust node value + Array1D_int returnNodeSpaceMixerIndex; // index to SpaceHVAC:ZoneReturnMixer that feeds this return node (-1 if there is none) bool ZonalSystemOnly; // TRUE if served by a zonal system (only) bool IsControlled; // True when this is a controlled zone. @@ -482,22 +481,27 @@ namespace DataZoneEquipment { void adjustLoads(EnergyPlusData &state, int zoneNum, int equipTypeNum); }; - struct ZoneEquipmentMixer : ZoneEquipmentSplitterMixer + struct ZoneMixer : ZoneEquipmentSplitterMixer { - int zoneEquipInletNodeNum = 0; + int outletNodeNum = 0; void setOutletConditions(EnergyPlusData &state); + }; + + struct ZoneEquipmentMixer : ZoneMixer + { + // int zoneEquipInletNodeNum = 0; void setInletFlows(EnergyPlusData &state); }; - struct ZoneReturnMixer : ZoneEquipmentSplitterMixer + struct ZoneReturnMixer : ZoneMixer { - int zoneReturnNodeNum = 0; + // int zoneReturnNodeNum = 0; - // void setOutletConditions(EnergyPlusData &state); + void setInletConditions(EnergyPlusData &state); - // void setInletFlows(EnergyPlusData &state); + void setInletFlows(EnergyPlusData &state); }; struct ControlList { @@ -585,7 +589,7 @@ namespace DataZoneEquipment { int const zoneNum, InputProcessor::json const objectSchemaProps, InputProcessor::json const objectFields, - DataZoneEquipment::ZoneReturnMixer &thisZretMixer); + int mixerIndex); bool CheckZoneEquipmentList(EnergyPlusData &state, std::string_view ComponentType, // Type of component diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index 3653be24fb4..df12bda5248 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -5170,6 +5170,15 @@ void CalcZoneLeavingConditions(EnergyPlusData &state, bool const FirstHVACIterat Real64 TempZoneAir; // Zone air temperature [C] Real64 SumRetAirLatentGainRate; + // If SpaceHVAC is active calculate SpaceHVAC:ReturnMixer inlet and outlet conditions before setting zone return conditions + if (state.dataHeatBal->doSpaceHeatBalanceSimulation && !state.dataGlobal->DoingSizing) { + for (auto &thisSpaceHVACMixer : state.dataZoneEquip->zoneReturnMixer) { + thisSpaceHVACMixer.setInletFlows(state); + thisSpaceHVACMixer.setInletConditions(state); + thisSpaceHVACMixer.setOutletConditions(state); + } + } + for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { if (!state.dataZoneEquip->ZoneEquipConfig(ZoneNum).IsControlled) continue; // A return air system may not exist for certain systems; Therefore when no return node exists diff --git a/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc b/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc index 8f27f0bfe7d..4d036e12ce8 100644 --- a/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc +++ b/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc @@ -5217,8 +5217,8 @@ TEST_F(EnergyPlusFixture, SpaceHVACMixerTest) mixSpace2.spaceNodeNum = 12; mixSpace3.spaceNodeNum = 13; state->dataLoopNodes->Node.allocate(13); - thisMixer.zoneEquipInletNodeNum = 1; - auto &equipInletNode = state->dataLoopNodes->Node(thisMixer.zoneEquipInletNodeNum); + thisMixer.outletNodeNum = 1; + auto &equipInletNode = state->dataLoopNodes->Node(thisMixer.outletNodeNum); auto &mixSpace1Node = state->dataLoopNodes->Node(mixSpace1.spaceNodeNum); auto &mixSpace2Node = state->dataLoopNodes->Node(mixSpace2.spaceNodeNum); auto &mixSpace3Node = state->dataLoopNodes->Node(mixSpace3.spaceNodeNum); From 58aa2f9ce372559c5a024c20ad58edabcbb78646 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Mon, 12 Aug 2024 15:55:27 -0500 Subject: [PATCH 69/81] Space IV-Transition etc --- src/EnergyPlus/DataZoneEquipment.hh | 4 ---- .../CreateNewIDFUsingRulesV24_2_0.f90 | 7 +++++++ .../InputRulesFiles/Rules24-1-0-to-24-2-0.md | 21 +++++++++++++++++-- .../OutputChanges24-1-0-to-24-2-0.md | 11 +++++++--- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/EnergyPlus/DataZoneEquipment.hh b/src/EnergyPlus/DataZoneEquipment.hh index 772ee8001f6..008be07c127 100644 --- a/src/EnergyPlus/DataZoneEquipment.hh +++ b/src/EnergyPlus/DataZoneEquipment.hh @@ -490,15 +490,11 @@ namespace DataZoneEquipment { struct ZoneEquipmentMixer : ZoneMixer { - // int zoneEquipInletNodeNum = 0; - void setInletFlows(EnergyPlusData &state); }; struct ZoneReturnMixer : ZoneMixer { - // int zoneReturnNodeNum = 0; - void setInletConditions(EnergyPlusData &state); void setInletFlows(EnergyPlusData &state); diff --git a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 index 78900861161..4ab6cd2ffb3 100644 --- a/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 +++ b/src/Transition/CreateNewIDFUsingRulesV24_2_0.f90 @@ -468,6 +468,13 @@ SUBROUTINE CreateNewIDFUsingRules(EndOfFile,DiffOnly,InLfn,AskForInput,InputFile ! If your original object starts with N, insert the rules here ! If your original object starts with O, insert the rules here + CASE('OUTPUTCONTROL:FILES') + CALL GetNewObjectDefInIDD(ObjectName,NwNumArgs,NwAorN,NwReqFld,NwObjMinFlds,NwFldNames,NwFldDefaults,NwFldUnits) + nodiff=.false. + OutArgs(1:8)=InArgs(1:8) + OutArgs(9) = InArgs(9) ! Set new Output Space Sizing the same as old Output Zone Sizing + OutArgs(10:CurArgs+1)=InArgs(9:CurArgs) + CurArgs = CurArgs + 1 ! If your original object starts with P, insert the rules here diff --git a/src/Transition/InputRulesFiles/Rules24-1-0-to-24-2-0.md b/src/Transition/InputRulesFiles/Rules24-1-0-to-24-2-0.md index dd4cf24cda0..e863dd25f13 100644 --- a/src/Transition/InputRulesFiles/Rules24-1-0-to-24-2-0.md +++ b/src/Transition/InputRulesFiles/Rules24-1-0-to-24-2-0.md @@ -50,7 +50,11 @@ There are three new optional heat recovery fields at the end which transition wi # Object Change: ObjectStartsWithN -# Object Change: ObjectStartsWithO +# Object Change: OutputControl:Files +Insert new field F9 "A9 , \field Output Space Sizing" +Set this to the same value as the old F9 "A9 , \field Output Zone Sizing". +Shift remaining fields down 1. +See pull request [#10566](https://github.com/NREL/EnergyPlus/pull/10566) for more details. # Object Change: ObjectStartsWithP @@ -72,4 +76,17 @@ There are three new optional heat recovery fields at the end which transition wi # Object Change: ObjectStartsWithY -# Object Change: ObjectStartsWithZ +# epJSON Field Name Changes: ZoneRefrigerationDoorMixing +`zone_1_name` --> `zone_or_space_name_1` +`zone_2_name` --> `zone_or_space_name_2` + +# epJSON Field Name Changes: ZoneCoolTower:Shower +`zone_name` --> `zone_or_space_name` + +# epJSON Field Name Changes: ZoneThermalChimney +`zone_1_name` --> `zone_or_space_name_1` +`relative_ratios_of_air_flow_rates_passing_through_zone_1` --> `relative_ratios_of_air_flow_rates_passing_through_inlet_1` +thru +`zone_20_name` --> `zone_or_space_name_20` +`relative_ratios_of_air_flow_rates_passing_through_zone_20` --> `relative_ratios_of_air_flow_rates_passing_through_inlet_20` + diff --git a/src/Transition/OutputRulesFiles/OutputChanges24-1-0-to-24-2-0.md b/src/Transition/OutputRulesFiles/OutputChanges24-1-0-to-24-2-0.md index ee0d911e964..06aa8ae379c 100644 --- a/src/Transition/OutputRulesFiles/OutputChanges24-1-0-to-24-2-0.md +++ b/src/Transition/OutputRulesFiles/OutputChanges24-1-0-to-24-2-0.md @@ -50,11 +50,12 @@ Temperature The EIO and html tabular output files now have a seprate heading and data stream for DX Heating Coils with the AHRI 2023 and prior versions. +``` ! , Component Type, Component Name, High Temperature Heating (net) Rating Capacity {W}, Low Temperature Heating (net) Rating Capacity {W}, HSPF {Btu/W-h}, Region Number ! , Component Type, Component Name, High Temperature Heating (net) Rating Capacity {W}, Low Temperature Heating (net) Rating Capacity {W}, HSPF2 {Btu/W-h}, Region Number +``` - -### Euipment Summary Report +### Equipment Summary Report Renamed a table name in the Equipment Summary report: @@ -115,8 +116,12 @@ In the Demand Controlled Ventilation table added the "type" Added an entirely new table called Thermostat Schedules -## New HVAC Topology report in Tabular Reports +### New HVAC Topology report in Tabular Reports The HVAC Topology report provides information about the arrangement of HVAC components in the supply and demand side of the airloop, zone equipment, and plant loop. Each row shows the additional component, sub-component, or sub-sub-component being added to the arrangement. +### New Space Sizing Output File (spsz) +When space sizing is active (ZoneAirHeatBalanceAlgorithm, "Do Space Heat Balance for Sizing=Yes") a new space sizing (spsz) output file is created, similar to the existing zone sizing (zsz) output. A new field "Output Space Sizing" has been added to OutputControl:Files to control this file. + +See pull request [#10566](https://github.com/NREL/EnergyPlus/pull/10566) for more details. From 3ccf6e5aa74b4f2d591db99dbdfc37f45deba79d Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Mon, 12 Aug 2024 16:00:23 -0500 Subject: [PATCH 70/81] Space IV-Update 5ZoneAirCooledWithSpacesHVAC --- testfiles/5ZoneAirCooledWithSpacesHVAC.idf | 27 +++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/testfiles/5ZoneAirCooledWithSpacesHVAC.idf b/testfiles/5ZoneAirCooledWithSpacesHVAC.idf index aa2a19233fb..799f1f8e735 100644 --- a/testfiles/5ZoneAirCooledWithSpacesHVAC.idf +++ b/testfiles/5ZoneAirCooledWithSpacesHVAC.idf @@ -2536,9 +2536,20 @@ ZoneAirHeatBalanceAlgorithm, Zone 5 Exhaust Fan Inlet,!- Zone Equipment Inlet Node Name DesignCoolingLoad, !- Space Fraction Method Space 5 Conference, !- Space 1 Name - autosize, !- Space 1 Fraction {dimensionless} + autosize, !- Space 1 Fraction {dimensionless} Space 5 Conference Exhaust Fan Inlet; !- Space 1 Node Name + SpaceHVAC:ZoneReturnMixer, + Zone 5 Return Mixer, !- Name + Zone 5, !- Zone Name + Zone 5 Out Node, !- Zone Return Air Node Name + Space 5 Office, !- Space 1 Name + Space 5 Office Return Node, !- Space 1 Return Air Node Name + Space 5 Conference, !- Space 2 Name + Space 5 Conference Return Node, !- Space 2 Return Air Node Name + Zone 5-Remainder, !- Space 3 Name + Zone 5-Remainder Return Node; !- Space 3 Return Air Node Name + SpaceHVAC:EquipmentConnections, Space 5 Office, !- Space Name Space 5 Office In Node, !- Space Air Inlet Node or NodeList Name @@ -3828,6 +3839,20 @@ Output:Variable,*,Space Predicted Sensible Load to Setpoint Heat Transfer Rate,h Output:Variable,Space 5 Conference In Node,System Node Temperature,hourly; !- HVAC Average [kg/s] Output:Variable,Zone 5-Remainder In Node,System Node Temperature,hourly; !- HVAC Average [kg/s] + Output:Variable,Zone 5 Out Node,System Node Mass Flow Rate,hourly; !- HVAC Average [kg/s] + Output:Variable,Zone 5 Exhaust Fan Inlet,System Node Mass Flow Rate,hourly; !- HVAC Average [kg/s] + Output:Variable,Space 5 Office Return Node,System Node Mass Flow Rate,hourly; !- HVAC Average [kg/s] + Output:Variable,Space 5 Conference Return Node,System Node Mass Flow Rate,hourly; !- HVAC Average [kg/s] + Output:Variable,Space 5 Conference Exhaust Fan Inlet,System Node Mass Flow Rate,hourly; !- HVAC Average [kg/s] + Output:Variable,Zone 5-Remainder Return Node,System Node Mass Flow Rate,hourly; !- HVAC Average [kg/s] + + Output:Variable,Zone 5 Out Node,System Node Temperature,hourly; !- HVAC Average [kg/s] + Output:Variable,Zone 5 Exhaust Fan Inlet,System Node Temperature,hourly; !- HVAC Average [kg/s] + Output:Variable,Space 5 Office Return Node,System Node Temperature,hourly; !- HVAC Average [kg/s] + Output:Variable,Space 5 Conference Return Node,System Node Temperature,hourly; !- HVAC Average [kg/s] + Output:Variable,Space 5 Conference Exhaust Fan Inlet,System Node Temperature,hourly; !- HVAC Average [kg/s] + Output:Variable,Zone 5-Remainder Return Node,System Node Temperature,hourly; !- HVAC Average [kg/s] + Output:Variable,*,EMS Zone Wetbulb Globe Temperature,hourly; Output:Variable,*,EMS Space Wetbulb Globe Temperature,hourly; From 5e85740f91fa7a6a3d278de45274add1068def1b Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Mon, 12 Aug 2024 16:44:05 -0500 Subject: [PATCH 71/81] Space IV-SpaceHVACZoneReturnMixer 3 --- src/EnergyPlus/DataZoneEquipment.cc | 9 ++++----- src/EnergyPlus/ZoneEquipmentManager.cc | 9 ++++++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/EnergyPlus/DataZoneEquipment.cc b/src/EnergyPlus/DataZoneEquipment.cc index 5228b809e6a..56e0952aac1 100644 --- a/src/EnergyPlus/DataZoneEquipment.cc +++ b/src/EnergyPlus/DataZoneEquipment.cc @@ -1136,6 +1136,10 @@ void processZoneEquipmentInput(EnergyPlusData &state, thisEquipConfig.NumReturnNodes = NumNodes; thisEquipConfig.ReturnNode.allocate(NumNodes); + thisEquipConfig.returnNodeSpaceMixerIndex.allocate(NumNodes); + for (int &mixIndex : thisEquipConfig.returnNodeSpaceMixerIndex) { + mixIndex = -1; + } thisEquipConfig.ReturnNodeAirLoopNum.allocate(NumNodes); thisEquipConfig.ReturnNodeRetPathNum.allocate(NumNodes); thisEquipConfig.ReturnNodeRetPathCompNum.allocate(NumNodes); @@ -1429,11 +1433,6 @@ void processZoneReturnMixerInput(EnergyPlusData &state, // Check zone return nodes bool found = false; auto &thisZoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(zoneNum); - thisZoneEquipConfig.returnNodeSpaceMixerIndex.allocate(thisZoneEquipConfig.NumReturnNodes); - for (int &mixIndex : thisZoneEquipConfig.returnNodeSpaceMixerIndex) { - mixIndex = -1; - } - int nodeCounter = 0; for (int retNodeNum : thisZoneEquipConfig.ReturnNode) { ++nodeCounter; diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index df12bda5248..d321e8965c4 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -5207,7 +5207,14 @@ void CalcZoneLeavingConditions(EnergyPlusData &state, bool const FirstHVACIterat } // user defined room air model may feed temp that differs from zone node - if (allocated(state.dataRoomAir->AirPatternZoneInfo)) { + + if (state.dataHeatBal->doSpaceHeatBalanceSimulation && !state.dataGlobal->DoingSizing && + (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).returnNodeSpaceMixerIndex(nodeCount) > -1)) { + // If a SpaceHVAC:ZoneReturnMixer feeds this node, use the node conditions which was set above in + // thisSpaceHVACMixer.setOutletConditions + TempZoneAir = state.dataLoopNodes->Node(ReturnNode).Temp; + TempRetAir = TempZoneAir; + } else if (allocated(state.dataRoomAir->AirPatternZoneInfo)) { if ((state.dataRoomAir->AirPatternZoneInfo(ZoneNum).IsUsed) && (!state.dataGlobal->BeginEnvrnFlag)) { TempZoneAir = state.dataRoomAir->AirPatternZoneInfo(ZoneNum).Tleaving; TempRetAir = TempZoneAir; From de9baf302ad24431736e9968f9e9cce2cc0a0d6a Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Mon, 12 Aug 2024 14:46:27 -0700 Subject: [PATCH 72/81] change OnOffFanPartLoadFraction back to use PLF --- src/EnergyPlus/DXCoils.cc | 2 +- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/EnergyPlus/DXCoils.cc b/src/EnergyPlus/DXCoils.cc index 2738bf5f501..c2fcfaef4a0 100644 --- a/src/EnergyPlus/DXCoils.cc +++ b/src/EnergyPlus/DXCoils.cc @@ -16880,7 +16880,7 @@ void CalcVRFCoolingCoil_FluidTCtrl(EnergyPlusData &state, } // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals - if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = thisDXCoil.CoolingCoilRuntimeFraction; + if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF; // Check for saturation error and modify temperature at constant enthalpy if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) { diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 497f4a341a1..dee354b86d5 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -12828,7 +12828,16 @@ void VRFTerminalUnitEquipment::CalcVRF_FluidTCtrl(EnergyPlusData &state, auto *fan = state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex); if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::SystemModel) { if (OnOffAirFlowRatio > 0.0) { - fan->simulate(state, FirstHVACIteration, _, _, _, fan->inletAirMassFlowRate, OnOffFanPartLoadFraction, 0, 0, _); + fan->simulate(state, + FirstHVACIteration, + _, + _, + _, + fan->inletAirMassFlowRate, + state.dataDXCoils->DXCoil(this->CoolCoilIndex).CoolingCoilRuntimeFraction, + 0, + 0, + _); } else { fan->simulate(state, FirstHVACIteration, _, _, PartLoadRatio); } From c01601c1a95d3c5cf0c319b97da58f10cc729419 Mon Sep 17 00:00:00 2001 From: Edwin Lee Date: Tue, 13 Aug 2024 12:07:31 -0500 Subject: [PATCH 73/81] Skip builtin EMS vars and add testing of new endpoints --- scripts/dev/verify_idfs_in_cmake.py | 2 +- src/EnergyPlus/CMakeLists.txt | 2 +- src/EnergyPlus/DataRuntimeLanguage.hh | 5 + src/EnergyPlus/RuntimeLanguageProcessor.cc | 3 + src/EnergyPlus/api/datatransfer.cc | 15 +- src/EnergyPlus/api/datatransfer.h | 6 + src/EnergyPlus/api/datatransfer.py | 15 +- .../_1ZoneUncontrolled_ForAPITesting.idf | 466 ++++++++++++++++++ tst/EnergyPlus/api/TestDataTransfer.c | 28 +- tst/EnergyPlus/api/TestDataTransfer.py | 20 + 10 files changed, 552 insertions(+), 10 deletions(-) create mode 100644 testfiles/_1ZoneUncontrolled_ForAPITesting.idf diff --git a/scripts/dev/verify_idfs_in_cmake.py b/scripts/dev/verify_idfs_in_cmake.py index 2c48a107401..2adaa1b45ce 100755 --- a/scripts/dev/verify_idfs_in_cmake.py +++ b/scripts/dev/verify_idfs_in_cmake.py @@ -94,7 +94,7 @@ # there are a few files we purposely skip files_to_skip = {"_1a-Long0.0.idf", "_ExternalInterface-actuator.idf", "_ExternalInterface-schedule.idf", "_ExternalInterface-variable.idf", "HVAC3Zone-IntGains-Def.imf", "HVAC3ZoneChillerSpec.imf", - "HVAC3ZoneGeometry.imf", "HVAC3ZoneMat-Const.imf"} + "HVAC3ZoneGeometry.imf", "HVAC3ZoneMat-Const.imf", "_1ZoneUncontrolled_ForAPITesting.idf"} found_idf_files_trimmed = found_idf_files - files_to_skip # the CMakeLists file will always have "forward" slashes diff --git a/src/EnergyPlus/CMakeLists.txt b/src/EnergyPlus/CMakeLists.txt index 9f4f3565624..cfb928e00dc 100644 --- a/src/EnergyPlus/CMakeLists.txt +++ b/src/EnergyPlus/CMakeLists.txt @@ -991,7 +991,7 @@ if(BUILD_TESTING) -DEPW_FILE=USA_CO_Golden-NREL.724666_TMY3.epw -P ${PROJECT_SOURCE_DIR}/cmake/RunCallbackTest.cmake) set(EPW_FILE "${PROJECT_SOURCE_DIR}/weather/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw") - set(IDF_FILE "${PROJECT_SOURCE_DIR}/testfiles/1ZoneUncontrolled.idf") + set(IDF_FILE "${PROJECT_SOURCE_DIR}/testfiles/_1ZoneUncontrolled_ForAPITesting.idf") add_executable(TestAPI_Functional_C ${PROJECT_SOURCE_DIR}/tst/EnergyPlus/api/TestFunctional.c) # project_warnings is essentially a C++ interface, and not included here because this is C, not C++ diff --git a/src/EnergyPlus/DataRuntimeLanguage.hh b/src/EnergyPlus/DataRuntimeLanguage.hh index dbfb131cda2..e55cc25e588 100644 --- a/src/EnergyPlus/DataRuntimeLanguage.hh +++ b/src/EnergyPlus/DataRuntimeLanguage.hh @@ -737,6 +737,11 @@ namespace DataRuntimeLanguage { struct RuntimeLanguageData : BaseGlobalStruct { + // In the API, we allow the user to manipulate user-defined EMS globals, but we skip the built-in ones to avoid + // problems. This constexpr should be incremented if we ever add more built-ins so that we skip the right amount + // in the API calls. + static int constexpr NumBuiltInErlVariables = 27; + int NumProgramCallManagers = 0; // count of Erl program managers with calling points int NumSensors = 0; // count of EMS sensors used in model (data from output variables) int numActuatorsUsed = 0; // count of EMS actuators used in model diff --git a/src/EnergyPlus/RuntimeLanguageProcessor.cc b/src/EnergyPlus/RuntimeLanguageProcessor.cc index 71214b90f17..0e08e3b2ba5 100644 --- a/src/EnergyPlus/RuntimeLanguageProcessor.cc +++ b/src/EnergyPlus/RuntimeLanguageProcessor.cc @@ -160,6 +160,9 @@ void InitializeRuntimeLanguage(EnergyPlusData &state) state.dataRuntimeLangProcessor->ActualTimeNum = NewEMSVariable(state, "ACTUALTIME", 0); state.dataRuntimeLangProcessor->WarmUpFlagNum = NewEMSVariable(state, "WARMUPFLAG", 0); + // this ensures we stay in sync with the number of skipped built-ins for API calls + assert(state.dataRuntimeLang->NumErlVariables == state.dataRuntimeLang->NumBuiltInErlVariables); + GetRuntimeLanguageUserInput(state); // Load and parse all runtime language objects date_and_time(datestring, _, _, datevalues); diff --git a/src/EnergyPlus/api/datatransfer.cc b/src/EnergyPlus/api/datatransfer.cc index 066e0ccfb6e..26017f46c0a 100644 --- a/src/EnergyPlus/api/datatransfer.cc +++ b/src/EnergyPlus/api/datatransfer.cc @@ -248,6 +248,14 @@ char *inputFilePath(EnergyPlusState state) return p; } +char *epwFilePath(EnergyPlusState state) +{ + const auto *thisState = static_cast(state); + char *p = new char[std::strlen(thisState->files.inputWeatherFilePath.filePath.c_str()) + 1]; + std::strcpy(p, thisState->files.inputWeatherFilePath.filePath.c_str()); + return p; +} + char **getObjectNames(EnergyPlusState state, const char *objectType, unsigned int *resultingSize) { const auto *thisState = static_cast(state); @@ -588,6 +596,9 @@ int getEMSGlobalVariableHandle(EnergyPlusState state, const char *name) int index = 0; for (auto const &erlVar : thisState->dataRuntimeLang->ErlVariable) { index++; + if (index <= thisState->dataRuntimeLang->NumBuiltInErlVariables) { + continue; // don't return handles to the built-in EMS variables, they can be accessed via API endpoints + } if (EnergyPlus::Util::SameString(name, erlVar.Name)) { return index; } @@ -598,7 +609,7 @@ int getEMSGlobalVariableHandle(EnergyPlusState state, const char *name) Real64 getEMSGlobalVariableValue(EnergyPlusState state, int handle) { auto *thisState = static_cast(state); - if (handle < 0 || handle > thisState->dataRuntimeLang->NumErlVariables) { + if (handle < thisState->dataRuntimeLang->NumBuiltInErlVariables || handle > thisState->dataRuntimeLang->NumErlVariables) { // need to fatal out once the process is done // throw an error, set the fatal flag, and then return 0 EnergyPlus::ShowSevereError( @@ -614,7 +625,7 @@ Real64 getEMSGlobalVariableValue(EnergyPlusState state, int handle) void setEMSGlobalVariableValue(EnergyPlusState state, int handle, Real64 value) { auto *thisState = static_cast(state); - if (handle < 0 || handle > thisState->dataRuntimeLang->NumErlVariables) { + if (handle < thisState->dataRuntimeLang->NumBuiltInErlVariables || handle > thisState->dataRuntimeLang->NumErlVariables) { // need to fatal out once the plugin is done // throw an error, set the fatal flag, and then return EnergyPlus::ShowSevereError( diff --git a/src/EnergyPlus/api/datatransfer.h b/src/EnergyPlus/api/datatransfer.h index 6ab69306286..7b31ba56970 100644 --- a/src/EnergyPlus/api/datatransfer.h +++ b/src/EnergyPlus/api/datatransfer.h @@ -127,6 +127,12 @@ ENERGYPLUSLIB_API void resetErrorFlag(EnergyPlusState state); /// \param[in] state An active EnergyPlusState instance created with `stateNew`. /// \return A char * of the input file path. This allocates a new char *, and calling clients must free this when done with it! ENERGYPLUSLIB_API char *inputFilePath(EnergyPlusState state); +/// \brief Provides the weather file path back to the user +/// \details In most circumstances the client will know the path to the weather file, but there are some cases where code +/// is generalized in unexpected workflows. Users have requested a way to get the weather file path back from the running instance. +/// \param[in] state An active EnergyPlusState instance created with `stateNew`. +/// \return A char * of the weather file path. This allocates a new char *, and calling clients must free this when done with it! +ENERGYPLUSLIB_API char *epwFilePath(EnergyPlusState state); // ----- DATA TRANSFER HELPER FUNCTIONS diff --git a/src/EnergyPlus/api/datatransfer.py b/src/EnergyPlus/api/datatransfer.py index 312da6c0a3b..7f7985b9721 100644 --- a/src/EnergyPlus/api/datatransfer.py +++ b/src/EnergyPlus/api/datatransfer.py @@ -141,6 +141,8 @@ def __init__(self, api: cdll, running_as_python_plugin: bool = False): self.api.resetErrorFlag.restype = c_void_p self.api.inputFilePath.argtypes = [c_void_p] self.api.inputFilePath.restype = c_char_p + self.api.epwFilePath.argtypes = [c_void_p] + self.api.epwFilePath.restype = c_char_p self.api.requestVariable.argtypes = [c_void_p, c_char_p, c_char_p] self.api.getNumNodesInCondFDSurfaceLayer.argtypes = [c_void_p, c_char_p, c_char_p] self.api.requestVariable.restype = c_void_p @@ -370,7 +372,18 @@ def get_input_file_path(self, state: c_void_p) -> bytes: :param state: An active EnergyPlus "state" that is returned from a call to `api.state_manager.new_state()`. :return: Returns a raw bytes representation of the input file path """ - return self.api.inputFilePath(state) + return self.api.inputFilePath(state) # TODO: Need to call free for the underlying char *? + + def get_weather_file_path(self, state: c_void_p) -> bytes: + """ + Provides the weather file path back to the client. In most circumstances the client will know the path to the + weather file, but there are some cases where code is generalized in unexpected workflows. Users have requested + a way to get the weather file path back from the running instance. + + :param state: An active EnergyPlus "state" that is returned from a call to `api.state_manager.new_state()`. + :return: Returns a raw bytes representation of the weather file path + """ + return self.api.epwFilePath(state) def get_object_names(self, state: c_void_p, object_type_name: Union[str, bytes]) -> List[str]: """ diff --git a/testfiles/_1ZoneUncontrolled_ForAPITesting.idf b/testfiles/_1ZoneUncontrolled_ForAPITesting.idf new file mode 100644 index 00000000000..371220f4605 --- /dev/null +++ b/testfiles/_1ZoneUncontrolled_ForAPITesting.idf @@ -0,0 +1,466 @@ +!-Generator IDFEditor 1.34 +!-Option OriginalOrderTop UseSpecialFormat +!-NOTE: All comments with '!-' are ignored by the IDFEditor and are generated automatically. +!- Use '!' comments if they need to be retained when using the IDFEditor. +!1ZoneUncontrolled.idf +! Basic file description: Basic test for EnergyPlus. Resistive Walls. Regular (no ground contact) floor. +! Regular roof. No Windows. +! +! Highlights: Very basic test to see that EnergyPlus "works". +! +! +! Simulation Location/Run: Denver Centennial Golden CO USA WMO=724666, 2 design days, 1 run period, +! Run Control executes two design days (see RUN PERIOD object) +! +! Location: Denver, CO +! +! Design Days: Denver Centennial Golden CO USA Annual Heating 99%, MaxDB=-15.5°C +! Denver Centennial Golden CO USA Annual Cooling (DB=>MWB) 1%, MaxDB=32°C MWB=15.5°C +! +! Run Period (Weather File): Full Annual Simulation, DENVER_STAPLETON_CO_USA_WMO_724690 +! +! Run Control: No zone or system sizing, design day run control (no weather file simulation) +! +! Building: Fictional 1 zone building with resistive walls. +! +! The building is oriented due north. +! +! Floor Area: 232.25 m2 +! Number of Stories: 1 +! +! Zone Description Details: +! +! (0,15.24,0) (15.24,15.24,0) +! _____________________________ +! | | +! | | +! | | +! | | +! | | +! | | +! | | +! | | +! | | +! | | +! | | +! | | +! | | +! | | +! | | +! |_____________________________| +! +! (0,0,0) (15.24,0,0) +! +! Internal gains description: NA +! +! Interzone Surfaces: None +! Internal Mass: None +! People: None +! Lights: None +! Equipment: None +! Windows: 0 +! Detached Shading: None +! Daylight: None +! Natural Ventilation: None +! Compact Schedules: NA (Example of non-Compact Schedules) +! Solar Distribution: MinimalShadowing +! +! HVAC: NA +! +! Zonal Equipment: NA +! Central Air Handling Equipment: No +! System Equipment Autosize: No +! Purchased Cooling: No +! Purchased Heating: No +! Purchased Chilled Water: No +! Purchased Hot Water: No +! Coils: None +! Pumps: None +! Boilers: None +! Chillers: None +! Towers: None +! +! Results: +! Standard Reports: Variable Dictionary, Surfaces (dxf-wireframe), Meter File +! Timestep or Hourly Variables: Hourly and Daily +! Time bins Report: None +! HTML Report: None +! Environmental Emissions: None +! Utility Tariffs: None + + Version,24.2; + + Timestep,4; + + Building, + Simple One Zone (Wireframe DXF), !- Name + 0, !- North Axis {deg} + Suburbs, !- Terrain + 0.04, !- Loads Convergence Tolerance Value {W} + 0.004, !- Temperature Convergence Tolerance Value {deltaC} + MinimalShadowing, !- Solar Distribution + 30, !- Maximum Number of Warmup Days + 6; !- Minimum Number of Warmup Days + + HeatBalanceAlgorithm,ConductionTransferFunction; + + SurfaceConvectionAlgorithm:Inside,TARP; + + SurfaceConvectionAlgorithm:Outside,DOE-2; + + SimulationControl, + No, !- Do Zone Sizing Calculation + No, !- Do System Sizing Calculation + No, !- Do Plant Sizing Calculation + Yes, !- Run Simulation for Sizing Periods + Yes, !- Run Simulation for Weather File Run Periods + No, !- Do HVAC Sizing Simulation for Sizing Periods + 1; !- Maximum Number of HVAC Sizing Simulation Passes + + RunPeriod, + Run Period 1, !- Name + 1, !- Begin Month + 1, !- Begin Day of Month + , !- Begin Year + 12, !- End Month + 31, !- End Day of Month + , !- End Year + Tuesday, !- Day of Week for Start Day + Yes, !- Use Weather File Holidays and Special Days + Yes, !- Use Weather File Daylight Saving Period + No, !- Apply Weekend Holiday Rule + Yes, !- Use Weather File Rain Indicators + Yes; !- Use Weather File Snow Indicators + + Site:Location, + Denver Centennial Golden N_CO_USA Design_Conditions, !- Name + 39.74, !- Latitude {deg} + -105.18, !- Longitude {deg} + -7.00, !- Time Zone {hr} + 1829.00; !- Elevation {m} + + ! WMO=724666 Time Zone=NAM: (GMT-07:00) Mountain Time (US & Canada) + ! Data Source=ASHRAE 2009 Annual Design Conditions + ! Denver Centennial Golden N_CO_USA Annual Heating Design Conditions Wind Speed=3m/s Wind Dir=340 + ! Coldest Month=DEC + ! Denver Centennial Golden N_CO_USA Annual Heating 99%, MaxDB=-15.5°C + + SizingPeriod:DesignDay, + Denver Centennial Golden N Ann Htg 99% Condns DB, !- Name + 12, !- Month + 21, !- Day of Month + WinterDesignDay, !- Day Type + -15.5, !- Maximum Dry-Bulb Temperature {C} + 0.0, !- Daily Dry-Bulb Temperature Range {deltaC} + , !- Dry-Bulb Temperature Range Modifier Type + , !- Dry-Bulb Temperature Range Modifier Day Schedule Name + Wetbulb, !- Humidity Condition Type + -15.5, !- Wetbulb or DewPoint at Maximum Dry-Bulb {C} + , !- Humidity Condition Day Schedule Name + , !- Humidity Ratio at Maximum Dry-Bulb {kgWater/kgDryAir} + , !- Enthalpy at Maximum Dry-Bulb {J/kg} + , !- Daily Wet-Bulb Temperature Range {deltaC} + 81198., !- Barometric Pressure {Pa} + 3, !- Wind Speed {m/s} + 340, !- Wind Direction {deg} + No, !- Rain Indicator + No, !- Snow Indicator + No, !- Daylight Saving Time Indicator + ASHRAEClearSky, !- Solar Model Indicator + , !- Beam Solar Day Schedule Name + , !- Diffuse Solar Day Schedule Name + , !- ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub) {dimensionless} + , !- ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud) {dimensionless} + 0.00; !- Sky Clearness + + ! Denver Centennial Golden N Annual Cooling Design Conditions Wind Speed=4.9m/s Wind Dir=0 + ! Hottest Month=JUL + ! Denver Centennial Golden N_CO_USA Annual Cooling (DB=>MWB) 1%, MaxDB=32°C MWB=15.5°C + + SizingPeriod:DesignDay, + Denver Centennial Golden N Ann Clg 1% Condns DB=>MWB, !- Name + 7, !- Month + 21, !- Day of Month + SummerDesignDay, !- Day Type + 32, !- Maximum Dry-Bulb Temperature {C} + 15.2, !- Daily Dry-Bulb Temperature Range {deltaC} + , !- Dry-Bulb Temperature Range Modifier Type + , !- Dry-Bulb Temperature Range Modifier Day Schedule Name + Wetbulb, !- Humidity Condition Type + 15.5, !- Wetbulb or DewPoint at Maximum Dry-Bulb {C} + , !- Humidity Condition Day Schedule Name + , !- Humidity Ratio at Maximum Dry-Bulb {kgWater/kgDryAir} + , !- Enthalpy at Maximum Dry-Bulb {J/kg} + , !- Daily Wet-Bulb Temperature Range {deltaC} + 81198., !- Barometric Pressure {Pa} + 4.9, !- Wind Speed {m/s} + 0, !- Wind Direction {deg} + No, !- Rain Indicator + No, !- Snow Indicator + No, !- Daylight Saving Time Indicator + ASHRAEClearSky, !- Solar Model Indicator + , !- Beam Solar Day Schedule Name + , !- Diffuse Solar Day Schedule Name + , !- ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub) {dimensionless} + , !- ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud) {dimensionless} + 1.00; !- Sky Clearness + + Material:NoMass, + R13LAYER, !- Name + Rough, !- Roughness + 2.290965, !- Thermal Resistance {m2-K/W} + 0.9000000, !- Thermal Absorptance + 0.7500000, !- Solar Absorptance + 0.7500000; !- Visible Absorptance + + Material:NoMass, + R31LAYER, !- Name + Rough, !- Roughness + 5.456, !- Thermal Resistance {m2-K/W} + 0.9000000, !- Thermal Absorptance + 0.7500000, !- Solar Absorptance + 0.7500000; !- Visible Absorptance + + Material, + C5 - 4 IN HW CONCRETE, !- Name + MediumRough, !- Roughness + 0.1014984, !- Thickness {m} + 1.729577, !- Conductivity {W/m-K} + 2242.585, !- Density {kg/m3} + 836.8000, !- Specific Heat {J/kg-K} + 0.9000000, !- Thermal Absorptance + 0.6500000, !- Solar Absorptance + 0.6500000; !- Visible Absorptance + + Construction, + R13WALL, !- Name + R13LAYER; !- Outside Layer + + Construction, + FLOOR, !- Name + C5 - 4 IN HW CONCRETE; !- Outside Layer + + Construction, + ROOF31, !- Name + R31LAYER; !- Outside Layer + + Zone, + ZONE ONE, !- Name + 0, !- Direction of Relative North {deg} + 0, !- X Origin {m} + 0, !- Y Origin {m} + 0, !- Z Origin {m} + 1, !- Type + 1, !- Multiplier + autocalculate, !- Ceiling Height {m} + autocalculate; !- Volume {m3} + + ScheduleTypeLimits, + Fraction, !- Name + 0.0, !- Lower Limit Value + 1.0, !- Upper Limit Value + CONTINUOUS; !- Numeric Type + + GlobalGeometryRules, + UpperLeftCorner, !- Starting Vertex Position + CounterClockWise, !- Vertex Entry Direction + World; !- Coordinate System + + BuildingSurface:Detailed, + Zn001:Wall001, !- Name + Wall, !- Surface Type + R13WALL, !- Construction Name + ZONE ONE, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 0,0,4.572000, !- X,Y,Z ==> Vertex 1 {m} + 0,0,0, !- X,Y,Z ==> Vertex 2 {m} + 15.24000,0,0, !- X,Y,Z ==> Vertex 3 {m} + 15.24000,0,4.572000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn001:Wall002, !- Name + Wall, !- Surface Type + R13WALL, !- Construction Name + ZONE ONE, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 15.24000,0,4.572000, !- X,Y,Z ==> Vertex 1 {m} + 15.24000,0,0, !- X,Y,Z ==> Vertex 2 {m} + 15.24000,15.24000,0, !- X,Y,Z ==> Vertex 3 {m} + 15.24000,15.24000,4.572000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn001:Wall003, !- Name + Wall, !- Surface Type + R13WALL, !- Construction Name + ZONE ONE, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 15.24000,15.24000,4.572000, !- X,Y,Z ==> Vertex 1 {m} + 15.24000,15.24000,0, !- X,Y,Z ==> Vertex 2 {m} + 0,15.24000,0, !- X,Y,Z ==> Vertex 3 {m} + 0,15.24000,4.572000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn001:Wall004, !- Name + Wall, !- Surface Type + R13WALL, !- Construction Name + ZONE ONE, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 0,15.24000,4.572000, !- X,Y,Z ==> Vertex 1 {m} + 0,15.24000,0, !- X,Y,Z ==> Vertex 2 {m} + 0,0,0, !- X,Y,Z ==> Vertex 3 {m} + 0,0,4.572000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn001:Flr001, !- Name + Floor, !- Surface Type + FLOOR, !- Construction Name + ZONE ONE, !- Zone Name + , !- Space Name + Adiabatic, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 1.000000, !- View Factor to Ground + 4, !- Number of Vertices + 15.24000,0.000000,0.0, !- X,Y,Z ==> Vertex 1 {m} + 0.000000,0.000000,0.0, !- X,Y,Z ==> Vertex 2 {m} + 0.000000,15.24000,0.0, !- X,Y,Z ==> Vertex 3 {m} + 15.24000,15.24000,0.0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn001:Roof001, !- Name + Roof, !- Surface Type + ROOF31, !- Construction Name + ZONE ONE, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0, !- View Factor to Ground + 4, !- Number of Vertices + 0.000000,15.24000,4.572, !- X,Y,Z ==> Vertex 1 {m} + 0.000000,0.000000,4.572, !- X,Y,Z ==> Vertex 2 {m} + 15.24000,0.000000,4.572, !- X,Y,Z ==> Vertex 3 {m} + 15.24000,15.24000,4.572; !- X,Y,Z ==> Vertex 4 {m} + + Output:Variable,*,Site Outdoor Air Drybulb Temperature,hourly; + + Output:Variable,*,Site Total Sky Cover,hourly; + + Output:Variable,*,Site Opaque Sky Cover,hourly; + + Output:Variable,*,Site Daylight Saving Time Status,daily; + + Output:Variable,*,Site Day Type Index,daily; + + Output:Variable,*,Zone Mean Air Temperature,hourly; + + Output:Variable,*,Zone Operative Temperature,hourly; !- Zone Average [C] + + Output:Variable,ZONE ONE,Zone Wetbulb Globe Temperature,hourly; + + Output:Variable,*,Zone Total Internal Latent Gain Energy,hourly; + + Output:Variable,*,Zone Mean Radiant Temperature,hourly; + + Output:Variable,*,Zone Air Heat Balance Surface Convection Rate,hourly; + + Output:Variable,*,Zone Air Heat Balance Air Energy Storage Rate,hourly; + + Output:Variable,*,Surface Inside Face Temperature,daily; + + Output:Variable,*,Surface Outside Face Temperature,daily; + + Output:Variable,*,Surface Inside Face Convection Heat Transfer Coefficient,daily; + + Output:Variable,*,Surface Outside Face Convection Heat Transfer Coefficient,daily; + + Output:Variable,*,Other Equipment Total Heating Energy,monthly; + + Output:Variable,*,Zone Other Equipment Total Heating Energy,monthly; + + Output:VariableDictionary,IDF; + + Output:Surfaces:Drawing,dxf:wireframe; + + Output:Constructions,Constructions; + + Output:Meter:MeterFileOnly,ExteriorLights:Electricity,hourly; + + Output:Meter:MeterFileOnly,EnergyTransfer:Building,hourly; + + Output:Meter:MeterFileOnly,EnergyTransfer:Facility,hourly; + + OutputControl:Table:Style, + ALL; !- Column Separator + + Output:Table:SummaryReports, + AllSummary; !- Report 1 Name + + Exterior:Lights, + ExtLights, !- Name + AlwaysOn, !- Schedule Name + 5250, !- Design Level {W} + AstronomicalClock, !- Control Option + Grounds Lights; !- End-Use Subcategory + + ScheduleTypeLimits, + On/Off, !- Name + 0, !- Lower Limit Value + 1, !- Upper Limit Value + DISCRETE; !- Numeric Type + + OtherEquipment, + Test 352a, !- Name + None, !- Fuel Type + ZONE ONE, !- Zone or ZoneList or Space or SpaceList Name + AlwaysOn, !- Schedule Name + EquipmentLevel, !- Design Level Calculation Method + 352, !- Design Level {W} + , !- Power per Zone Floor Area {W/m2} + , !- Power per Person {W/person} + 0, !- Fraction Latent + 0, !- Fraction Radiant + 0; !- Fraction Lost + + OtherEquipment, + Test 352 minus, !- Name + None, !- Fuel Type + ZONE ONE, !- Zone or ZoneList or Space or SpaceList Name + AlwaysOn, !- Schedule Name + EquipmentLevel, !- Design Level Calculation Method + -352, !- Design Level {W} + , !- Power per Zone Floor Area {W/m2} + , !- Power per Person {W/person} + 0, !- Fraction Latent + 0, !- Fraction Radiant + 0; !- Fraction Lost + + Schedule:Constant,AlwaysOn,On/Off,1.0; + + EnergyManagementSystem:GlobalVariable,MaximumEffort; diff --git a/tst/EnergyPlus/api/TestDataTransfer.c b/tst/EnergyPlus/api/TestDataTransfer.c index 5544756772d..978d1bbde5f 100644 --- a/tst/EnergyPlus/api/TestDataTransfer.c +++ b/tst/EnergyPlus/api/TestDataTransfer.c @@ -79,7 +79,7 @@ void afterZoneTimeStepHandler(EnergyPlusState state) char **surfaceNames = getObjectNames(state, "BuildingSurface:Detailed", &arraySize); if (arraySize == 0) { - printf("Encountered a file with no BuildingSurface:Detailed, can't run this script on that file! Aborting!"); + printf("Encountered a file with no BuildingSurface:Detailed, can't run this script on that file! Aborting!\n"); exit(1); } @@ -91,7 +91,23 @@ void afterZoneTimeStepHandler(EnergyPlusState state) wallConstruction = getConstructionHandle(state, "R13WALL"); floorConstruction = getConstructionHandle(state, "FLOOR"); - // don't forget to free memory from the API! + // checking for EMS globals + int const emsGlobalValid = getEMSGlobalVariableHandle(state, "MaximumEffort"); + int const emsGlobalInvalid = getEMSGlobalVariableHandle(state, "4or5moments"); + int const emsGlobalBuiltIn = getEMSGlobalVariableHandle(state, "WARMUPFLAG"); + if (emsGlobalValid > 0 && emsGlobalInvalid == 0 && emsGlobalBuiltIn == 0) { + printf("EMS Global handle lookups worked just fine!\n"); + } else { + printf("EMS Global handle lookup failed. Make sure to call this with _1ZoneUncontrolled_ForAPITesting.idf\n"); + exit(1); + } + setEMSGlobalVariableValue(state, emsGlobalValid, 2.0); + Real64 const val = getEMSGlobalVariableValue(state, emsGlobalValid); + if (val < 1.9999 || val > 2.0001) { + printf("EMS Global assignment/lookup didn't seem to work, odd\n"); + exit(1); + } + freeAPIData(data, arraySize); freeObjectNames(surfaceNames, arraySize); @@ -107,9 +123,11 @@ void afterZoneTimeStepHandler(EnergyPlusState state) exit(1); } - char *filePath = inputFilePath(state); - printf("Input file path accessed via API: %s\n", filePath); - free(filePath); + char *idfPath = inputFilePath(state); + char *epwPath = epwFilePath(state); + printf("Got an input file path of: %s, and weather file path of: %s\n", idfPath, epwPath); + free(idfPath); + free(epwPath); handlesRetrieved = 1; } diff --git a/tst/EnergyPlus/api/TestDataTransfer.py b/tst/EnergyPlus/api/TestDataTransfer.py index a73a91b1107..422670190d7 100644 --- a/tst/EnergyPlus/api/TestDataTransfer.py +++ b/tst/EnergyPlus/api/TestDataTransfer.py @@ -101,6 +101,26 @@ def time_step_handler(state): wall_construction_handle = api.exchange.get_construction_handle(state, "R13WALL") floor_construction_handle = api.exchange.get_construction_handle(state, "FLOOR") + + idf_path = api.exchange.get_input_file_path(state) + epw_path = api.exchange.get_weather_file_path(state) + print(f"Got an input file path of: {idf_path}, and weather file path of: {epw_path}") + + # checking for EMS globals + ems_global_valid = api.exchange.get_ems_global_handle(state, "MaximumEffort") + ems_global_invalid = api.exchange.get_ems_global_handle(state, "4or5moments") + ems_global_builtin = api.exchange.get_ems_global_handle(state, "WARMUPFLAG") + if ems_global_valid > 0 and ems_global_invalid == 0 and ems_global_builtin == 0: + print("EMS Global handle lookups worked just fine!") + else: + raise Exception( + "EMS Global handle lookup failed. Make sure to call this with _1ZoneUncontrolled_ForAPITesting.idf" + ) + api.exchange.set_ems_global_value(state, ems_global_valid, 2.0) + val = api.exchange.get_ems_global_value(state, ems_global_valid) + if val < 1.9999 or val > 2.0001: + raise Exception("EMS Global assignment/lookup didn't seem to work, odd") + except Exception as e: # Capture ok and exception message exception = e From e03dea0d12f9a3912dab751bb025977548ae1796 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Tue, 13 Aug 2024 10:38:04 -0700 Subject: [PATCH 74/81] fix unit test related to OU fan, as it's not fixed here --- tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index 1658ce38122..c7f26710338 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -13278,9 +13278,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_ReportOutputVerificationTest) EXPECT_NEAR(125.2573 * thisDXCoolingCoil.CoolingCoilRuntimeFraction, thisFan->totalPower, 0.0001); EXPECT_NEAR(thisDXCoolingCoil.TotalCoolingEnergyRate, (thisVRFTU.TotalCoolingRate + thisFan->totalPower), 0.0001); EXPECT_NEAR(0.8930, state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio, 0.0001); - EXPECT_NEAR(state->dataHVACVarRefFlow->VRF(1).OUFanPower, - state->dataHVACVarRefFlow->VRF(1).RatedOUFanPower * state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio, - 0.0001); + EXPECT_NEAR(state->dataHVACVarRefFlow->VRF(1).OUFanPower, state->dataHVACVarRefFlow->VRF(1).RatedOUFanPower, 0.0001); } // Test for #7648: HREIRFTHeat wrongly used HRCAPFTHeatConst. Occurs only if you have Heat Recovery From 37471e12a01982b1585ce6bbb4374b542714af75 Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Tue, 13 Aug 2024 10:38:52 -0700 Subject: [PATCH 75/81] pass in OnOffFanPartLoadFraction of constant 1 --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index dee354b86d5..fc8ff1253fc 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -12834,7 +12834,7 @@ void VRFTerminalUnitEquipment::CalcVRF_FluidTCtrl(EnergyPlusData &state, _, _, fan->inletAirMassFlowRate, - state.dataDXCoils->DXCoil(this->CoolCoilIndex).CoolingCoilRuntimeFraction, + OnOffFanPartLoadFraction, 0, 0, _); From 2c31f9fc35b78f28875f5545f59adc17bc5bd43b Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Wed, 14 Aug 2024 14:41:12 +0200 Subject: [PATCH 76/81] Use toGenericString and return a Pathlib.Path instead of a string --- src/EnergyPlus/api/datatransfer.cc | 10 ++++++---- src/EnergyPlus/api/datatransfer.py | 19 ++++++++++++------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/EnergyPlus/api/datatransfer.cc b/src/EnergyPlus/api/datatransfer.cc index 26017f46c0a..258b60c791e 100644 --- a/src/EnergyPlus/api/datatransfer.cc +++ b/src/EnergyPlus/api/datatransfer.cc @@ -243,16 +243,18 @@ void resetErrorFlag(EnergyPlusState state) char *inputFilePath(EnergyPlusState state) { const auto *thisState = static_cast(state); - char *p = new char[std::strlen(thisState->dataStrGlobals->inputFilePath.string().c_str()) + 1]; - std::strcpy(p, thisState->dataStrGlobals->inputFilePath.string().c_str()); + std::string const path_utf8 = EnergyPlus::FileSystem::toGenericString(thisState->dataStrGlobals->inputFilePath); + char *p = new char[std::strlen(path_utf8.c_str()) + 1]; + std::strcpy(p, path_utf8.c_str()); return p; } char *epwFilePath(EnergyPlusState state) { const auto *thisState = static_cast(state); - char *p = new char[std::strlen(thisState->files.inputWeatherFilePath.filePath.c_str()) + 1]; - std::strcpy(p, thisState->files.inputWeatherFilePath.filePath.c_str()); + std::string const path_utf8 = EnergyPlus::FileSystem::toGenericString(thisState->files.inputWeatherFilePath.filePath); + char *p = new char[std::strlen(path_utf8.c_str()) + 1]; + std::strcpy(p, path_utf8.c_str()); return p; } diff --git a/src/EnergyPlus/api/datatransfer.py b/src/EnergyPlus/api/datatransfer.py index 7f7985b9721..0a1c9112d28 100644 --- a/src/EnergyPlus/api/datatransfer.py +++ b/src/EnergyPlus/api/datatransfer.py @@ -56,7 +56,7 @@ from ctypes import cdll, c_int, c_char_p, c_void_p, POINTER, Structure, byref from pyenergyplus.common import RealEP, EnergyPlusException, is_number from typing import List, Union - +from pathlib import Path class DataExchange: """ @@ -363,27 +363,32 @@ def reset_api_error_flag(self, state: c_void_p) -> None: """ self.api.resetErrorFlag(state) - def get_input_file_path(self, state: c_void_p) -> bytes: + def get_input_file_path(self, state: c_void_p) -> Path: """ Provides the input file path back to the client. In most circumstances the client will know the path to the input file, but there are some cases where code is generalized in unexpected workflows. Users have requested a way to get the input file path back from the running instance. :param state: An active EnergyPlus "state" that is returned from a call to `api.state_manager.new_state()`. - :return: Returns a raw bytes representation of the input file path + :return: A pathlib.Path of the input file path """ - return self.api.inputFilePath(state) # TODO: Need to call free for the underlying char *? + c_string = self.api.inputFilePath(state) + res = Path(c_string.decode('utf-8')) + return res - def get_weather_file_path(self, state: c_void_p) -> bytes: + def get_weather_file_path(self, state: c_void_p) -> Path: """ Provides the weather file path back to the client. In most circumstances the client will know the path to the weather file, but there are some cases where code is generalized in unexpected workflows. Users have requested a way to get the weather file path back from the running instance. :param state: An active EnergyPlus "state" that is returned from a call to `api.state_manager.new_state()`. - :return: Returns a raw bytes representation of the weather file path + :return: A pathlib.Path of the weather file """ - return self.api.epwFilePath(state) + c_string = self.api.epwFilePath(state) + res = Path(c_string.decode('utf-8')) + return res + def get_object_names(self, state: c_void_p, object_type_name: Union[str, bytes]) -> List[str]: """ From 0ba4621c6b63427dacdbecad2a2c82d92f77ff0b Mon Sep 17 00:00:00 2001 From: Edwin Lee Date: Wed, 14 Aug 2024 08:39:42 -0500 Subject: [PATCH 77/81] Add better range checking on erl var index --- src/EnergyPlus/DataRuntimeLanguage.hh | 6 +++--- src/EnergyPlus/RuntimeLanguageProcessor.cc | 6 ++++-- src/EnergyPlus/api/datatransfer.cc | 22 +++++++++++++--------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/EnergyPlus/DataRuntimeLanguage.hh b/src/EnergyPlus/DataRuntimeLanguage.hh index e55cc25e588..85a0424dad6 100644 --- a/src/EnergyPlus/DataRuntimeLanguage.hh +++ b/src/EnergyPlus/DataRuntimeLanguage.hh @@ -738,9 +738,9 @@ struct RuntimeLanguageData : BaseGlobalStruct { // In the API, we allow the user to manipulate user-defined EMS globals, but we skip the built-in ones to avoid - // problems. This constexpr should be incremented if we ever add more built-ins so that we skip the right amount - // in the API calls. - static int constexpr NumBuiltInErlVariables = 27; + // problems. The built-in ones will not always start at zero, so we keep a start/end to ignore that specific range. + int emsVarBuiltInStart = 0; + int emsVarBuiltInEnd = 0; int NumProgramCallManagers = 0; // count of Erl program managers with calling points int NumSensors = 0; // count of EMS sensors used in model (data from output variables) diff --git a/src/EnergyPlus/RuntimeLanguageProcessor.cc b/src/EnergyPlus/RuntimeLanguageProcessor.cc index 0e08e3b2ba5..55dc9cd6380 100644 --- a/src/EnergyPlus/RuntimeLanguageProcessor.cc +++ b/src/EnergyPlus/RuntimeLanguageProcessor.cc @@ -122,6 +122,8 @@ void InitializeRuntimeLanguage(EnergyPlusData &state) if (state.dataRuntimeLangProcessor->InitializeOnce) { + state.dataRuntimeLang->emsVarBuiltInStart = state.dataRuntimeLang->NumErlVariables + 1; + state.dataRuntimeLang->False = SetErlValueNumber(0.0); state.dataRuntimeLang->True = SetErlValueNumber(1.0); @@ -160,8 +162,8 @@ void InitializeRuntimeLanguage(EnergyPlusData &state) state.dataRuntimeLangProcessor->ActualTimeNum = NewEMSVariable(state, "ACTUALTIME", 0); state.dataRuntimeLangProcessor->WarmUpFlagNum = NewEMSVariable(state, "WARMUPFLAG", 0); - // this ensures we stay in sync with the number of skipped built-ins for API calls - assert(state.dataRuntimeLang->NumErlVariables == state.dataRuntimeLang->NumBuiltInErlVariables); + // update the end of the built-in range so we can ignore those on API calls + state.dataRuntimeLang->emsVarBuiltInEnd = state.dataRuntimeLang->NumErlVariables; GetRuntimeLanguageUserInput(state); // Load and parse all runtime language objects diff --git a/src/EnergyPlus/api/datatransfer.cc b/src/EnergyPlus/api/datatransfer.cc index 26017f46c0a..41c57c1d03e 100644 --- a/src/EnergyPlus/api/datatransfer.cc +++ b/src/EnergyPlus/api/datatransfer.cc @@ -596,11 +596,11 @@ int getEMSGlobalVariableHandle(EnergyPlusState state, const char *name) int index = 0; for (auto const &erlVar : thisState->dataRuntimeLang->ErlVariable) { index++; - if (index <= thisState->dataRuntimeLang->NumBuiltInErlVariables) { - continue; // don't return handles to the built-in EMS variables, they can be accessed via API endpoints - } - if (EnergyPlus::Util::SameString(name, erlVar.Name)) { - return index; + // only respond if we are outside of the built-in EMS var range + if (index < thisState->dataRuntimeLang->emsVarBuiltInStart || index > thisState->dataRuntimeLang->emsVarBuiltInEnd) { + if (EnergyPlus::Util::SameString(name, erlVar.Name)) { + return index; + } } } return 0; @@ -609,7 +609,9 @@ int getEMSGlobalVariableHandle(EnergyPlusState state, const char *name) Real64 getEMSGlobalVariableValue(EnergyPlusState state, int handle) { auto *thisState = static_cast(state); - if (handle < thisState->dataRuntimeLang->NumBuiltInErlVariables || handle > thisState->dataRuntimeLang->NumErlVariables) { + auto const &erl = thisState->dataRuntimeLang; + bool const insideBuiltInRange = index >= erl->emsVarBuiltInStart && index <= erl->emsVarBuiltInEnd; + if (insideBuiltInRange || handle > thisState->dataRuntimeLang->NumErlVariables) { // need to fatal out once the process is done // throw an error, set the fatal flag, and then return 0 EnergyPlus::ShowSevereError( @@ -619,13 +621,15 @@ Real64 getEMSGlobalVariableValue(EnergyPlusState state, int handle) thisState->dataPluginManager->apiErrorFlag = true; return 0; } - return thisState->dataRuntimeLang->ErlVariable(handle).Value.Number; + return erl->ErlVariable(handle).Value.Number; } void setEMSGlobalVariableValue(EnergyPlusState state, int handle, Real64 value) { auto *thisState = static_cast(state); - if (handle < thisState->dataRuntimeLang->NumBuiltInErlVariables || handle > thisState->dataRuntimeLang->NumErlVariables) { + auto const &erl = thisState->dataRuntimeLang; + bool const insideBuiltInRange = index >= erl->emsVarBuiltInStart && index <= erl->emsVarBuiltInEnd; + if (insideBuiltInRange || handle > erl->NumErlVariables) { // need to fatal out once the plugin is done // throw an error, set the fatal flag, and then return EnergyPlus::ShowSevereError( @@ -634,7 +638,7 @@ void setEMSGlobalVariableValue(EnergyPlusState state, int handle, Real64 value) "The setEMSGlobalVariableValue function will return to allow the plugin to finish, then EnergyPlus will abort"); thisState->dataPluginManager->apiErrorFlag = true; } - thisState->dataRuntimeLang->ErlVariable(handle).Value.Number = value; + erl->ErlVariable(handle).Value.Number = value; } int getPluginGlobalVariableHandle(EnergyPlusState state, const char *name) From bcf41183f5cf727f462266b06274d51d79e6073d Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Wed, 14 Aug 2024 10:32:48 -0700 Subject: [PATCH 78/81] fix err message blow->draw through --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index fc8ff1253fc..19ac6450f64 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -5494,7 +5494,7 @@ void CheckVRFTUNodeConnections(EnergyPlusData &state, int const VRFTUNum, bool & if (fanOutletNode != VRFTUOutletNodeNum) { ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName)); ShowContinueError(state, - "... For blow through fan and no supplemental heating coil the fan outlet node name must " + "... For draw through fan and no supplemental heating coil the fan outlet node name must " "match the terminal unit outlet node name."); if (fanOutletNode > 0 && VRFTUOutletNodeNum > 0) { ShowContinueError(state, format("... Fan outlet node name = {}.", nodeID(fanOutletNode))); From 49f4d36b6033919a32cc427601b2b20e827ec3bd Mon Sep 17 00:00:00 2001 From: Edwin Lee Date: Wed, 14 Aug 2024 12:44:41 -0500 Subject: [PATCH 79/81] Use handle not index --- src/EnergyPlus/api/datatransfer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EnergyPlus/api/datatransfer.cc b/src/EnergyPlus/api/datatransfer.cc index 9ed4f2458f4..25b274b469e 100644 --- a/src/EnergyPlus/api/datatransfer.cc +++ b/src/EnergyPlus/api/datatransfer.cc @@ -612,7 +612,7 @@ Real64 getEMSGlobalVariableValue(EnergyPlusState state, int handle) { auto *thisState = static_cast(state); auto const &erl = thisState->dataRuntimeLang; - bool const insideBuiltInRange = index >= erl->emsVarBuiltInStart && index <= erl->emsVarBuiltInEnd; + bool const insideBuiltInRange = handle >= erl->emsVarBuiltInStart && handle <= erl->emsVarBuiltInEnd; if (insideBuiltInRange || handle > thisState->dataRuntimeLang->NumErlVariables) { // need to fatal out once the process is done // throw an error, set the fatal flag, and then return 0 @@ -630,7 +630,7 @@ void setEMSGlobalVariableValue(EnergyPlusState state, int handle, Real64 value) { auto *thisState = static_cast(state); auto const &erl = thisState->dataRuntimeLang; - bool const insideBuiltInRange = index >= erl->emsVarBuiltInStart && index <= erl->emsVarBuiltInEnd; + bool const insideBuiltInRange = handle >= erl->emsVarBuiltInStart && handle <= erl->emsVarBuiltInEnd; if (insideBuiltInRange || handle > erl->NumErlVariables) { // need to fatal out once the plugin is done // throw an error, set the fatal flag, and then return From 49fd825b3d68d4d99114afe5e047d720cb41d96c Mon Sep 17 00:00:00 2001 From: Yujie Xu Date: Fri, 16 Aug 2024 12:36:46 -0700 Subject: [PATCH 80/81] clang-format --- src/EnergyPlus/HVACVariableRefrigerantFlow.cc | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 1422378f6cd..070dd4939fe 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -12850,16 +12850,7 @@ void VRFTerminalUnitEquipment::CalcVRF_FluidTCtrl(EnergyPlusData &state, auto *fan = state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex); if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::SystemModel) { if (OnOffAirFlowRatio > 0.0) { - fan->simulate(state, - FirstHVACIteration, - _, - _, - _, - fan->inletAirMassFlowRate, - OnOffFanPartLoadFraction, - 0, - 0, - _); + fan->simulate(state, FirstHVACIteration, _, _, _, fan->inletAirMassFlowRate, OnOffFanPartLoadFraction, 0, 0, _); } else { fan->simulate(state, FirstHVACIteration, _, _, PartLoadRatio); } From be14c932c58a1d260457344704c88e298e14fca0 Mon Sep 17 00:00:00 2001 From: "Michael J. Witte" Date: Sun, 18 Aug 2024 20:02:49 -0500 Subject: [PATCH 81/81] SpaceReturnMixerTest --- .../unit/ZoneEquipmentManager.unit.cc | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) diff --git a/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc b/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc index 4d036e12ce8..86ba25331bb 100644 --- a/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc +++ b/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc @@ -5357,3 +5357,181 @@ TEST_F(EnergyPlusFixture, ZoneEquipmentManager_GetZoneEquipmentTest) EXPECT_FALSE(state->dataZoneEquipmentManager->GetZoneEquipmentInputFlag); EXPECT_EQ(state->dataZoneEquipmentManager->NumOfTimeStepInDay, 24); } +TEST_F(EnergyPlusFixture, SpaceReturnMixerTest) +{ + state->dataZoneEquip->zoneReturnMixer.resize(1); + auto &thisMixer = state->dataZoneEquip->zoneReturnMixer[0]; + // Assume 3 spaces are served by this mixter + int numSpaces = 3; + thisMixer.spaces.resize(numSpaces); + auto &mixSpace1 = thisMixer.spaces[0]; + auto &mixSpace2 = thisMixer.spaces[1]; + auto &mixSpace3 = thisMixer.spaces[2]; + mixSpace1.spaceIndex = 1; + mixSpace2.spaceIndex = 3; + mixSpace3.spaceIndex = 2; + mixSpace1.spaceNodeNum = 11; + mixSpace2.spaceNodeNum = 13; + mixSpace3.spaceNodeNum = 12; + state->dataLoopNodes->Node.allocate(13); + thisMixer.outletNodeNum = 10; + auto &outletNode = state->dataLoopNodes->Node(thisMixer.outletNodeNum); + auto &mixSpace1Node = state->dataLoopNodes->Node(mixSpace1.spaceNodeNum); + auto &mixSpace2Node = state->dataLoopNodes->Node(mixSpace2.spaceNodeNum); + auto &mixSpace3Node = state->dataLoopNodes->Node(mixSpace3.spaceNodeNum); + state->dataContaminantBalance->Contaminant.CO2Simulation = true; + state->dataContaminantBalance->Contaminant.GenericContamSimulation = true; + state->dataZoneEquip->spaceEquipConfig.allocate(numSpaces); + auto &spaceEquipConfig1 = state->dataZoneEquip->spaceEquipConfig(1); + auto &spaceEquipConfig2 = state->dataZoneEquip->spaceEquipConfig(2); + auto &spaceEquipConfig3 = state->dataZoneEquip->spaceEquipConfig(3); + spaceEquipConfig1.NumReturnNodes = 1; + spaceEquipConfig2.NumReturnNodes = 1; + spaceEquipConfig3.NumReturnNodes = 1; + spaceEquipConfig1.ReturnNode.allocate(1); + spaceEquipConfig2.ReturnNode.allocate(1); + spaceEquipConfig3.ReturnNode.allocate(1); + spaceEquipConfig1.ReturnNode(1) = 11; + spaceEquipConfig2.ReturnNode(1) = 12; + spaceEquipConfig3.ReturnNode(1) = 13; + spaceEquipConfig1.ReturnNodeInletNum.allocate(1); + spaceEquipConfig2.ReturnNodeInletNum.allocate(1); + spaceEquipConfig3.ReturnNodeInletNum.allocate(1); + spaceEquipConfig1.ReturnNodeInletNum(1) = 1; + spaceEquipConfig2.ReturnNodeInletNum(1) = 1; + spaceEquipConfig3.ReturnNodeInletNum(1) = 1; + spaceEquipConfig1.InletNodeADUNum.allocate(1); + spaceEquipConfig2.InletNodeADUNum.allocate(1); + spaceEquipConfig3.InletNodeADUNum.allocate(1); + spaceEquipConfig1.InletNodeADUNum(1) = 0; + spaceEquipConfig2.InletNodeADUNum(1) = 0; + spaceEquipConfig3.InletNodeADUNum(1) = 0; + spaceEquipConfig1.ReturnNodeAirLoopNum.allocate(1); + spaceEquipConfig2.ReturnNodeAirLoopNum.allocate(1); + spaceEquipConfig3.ReturnNodeAirLoopNum.allocate(1); + spaceEquipConfig1.ReturnNodeAirLoopNum(1) = 1; + spaceEquipConfig2.ReturnNodeAirLoopNum(1) = 1; + spaceEquipConfig3.ReturnNodeAirLoopNum(1) = 1; + spaceEquipConfig1.InletNode.allocate(1); + spaceEquipConfig2.InletNode.allocate(1); + spaceEquipConfig3.InletNode.allocate(1); + spaceEquipConfig1.InletNode(1) = 1; + spaceEquipConfig2.InletNode(1) = 2; + spaceEquipConfig3.InletNode(1) = 3; + auto &space1InletNode = state->dataLoopNodes->Node(spaceEquipConfig1.InletNode(1)); + auto &space2InletNode = state->dataLoopNodes->Node(spaceEquipConfig2.InletNode(1)); + auto &space3InletNode = state->dataLoopNodes->Node(spaceEquipConfig3.InletNode(1)); + spaceEquipConfig1.FixedReturnFlow.allocate(1); + spaceEquipConfig2.FixedReturnFlow.allocate(1); + spaceEquipConfig3.FixedReturnFlow.allocate(1); + + spaceEquipConfig1.ZoneNode = 5; + spaceEquipConfig2.ZoneNode = 6; + spaceEquipConfig3.ZoneNode = 7; + auto &space1Node = state->dataLoopNodes->Node(spaceEquipConfig1.ZoneNode); + auto &space2Node = state->dataLoopNodes->Node(spaceEquipConfig2.ZoneNode); + auto &space3Node = state->dataLoopNodes->Node(spaceEquipConfig3.ZoneNode); + + // Note that spaces are not in numerical order + // mixSpace1.spaceIndex = 1; + // mixSpace2.spaceIndex = 3; + // mixSpace3.spaceIndex = 2; + space1InletNode.MassFlowRate = 0.2; + space3InletNode.MassFlowRate = 0.5; + space2InletNode.MassFlowRate = 0.3; + + state->dataAirLoop->AirLoopFlow.allocate(1); + auto &thisAirLoopFlow = state->dataAirLoop->AirLoopFlow(1); + thisAirLoopFlow.SysRetFlow = 1.0; + state->dataAirSystemsData->PrimaryAirSystems.allocate(1); + + // Set flow rates/fractions + outletNode.MassFlowRate = 1.0; + thisMixer.setInletFlows(*state); + EXPECT_NEAR(mixSpace1.fraction, 0.2, 0.001); + EXPECT_NEAR(mixSpace2.fraction, 0.5, 0.001); + EXPECT_NEAR(mixSpace3.fraction, 0.3, 0.001); + + // Case 1 + space1Node.Temp = 15.0; + space3Node.Temp = 15.0; + space2Node.Temp = 15.0; + + space1Node.HumRat = 0.004; + space3Node.HumRat = 0.001; + space2Node.HumRat = 0.080; + + space1Node.Press = 100000.0; + space3Node.Press = 100020.0; + space2Node.Press = 99400.0; + + space1Node.GenContam = 10.0; + space3Node.GenContam = 20.0; + space2Node.GenContam = 30.0; + + space1Node.Enthalpy = Psychrometrics::PsyHFnTdbW(space1Node.Temp, space1Node.HumRat); + space2Node.Enthalpy = Psychrometrics::PsyHFnTdbW(space2Node.Temp, space2Node.HumRat); + space3Node.Enthalpy = Psychrometrics::PsyHFnTdbW(space3Node.Temp, space3Node.HumRat); + + thisMixer.setInletConditions(*state); + + EXPECT_NEAR(mixSpace1Node.Temp, space1Node.Temp, 0.01); + EXPECT_NEAR(mixSpace2Node.Temp, space3Node.Temp, 0.01); + EXPECT_NEAR(mixSpace3Node.Temp, space2Node.Temp, 0.01); + + EXPECT_NEAR(mixSpace1Node.HumRat, space1Node.HumRat, 0.01); + EXPECT_NEAR(mixSpace2Node.HumRat, space3Node.HumRat, 0.01); + EXPECT_NEAR(mixSpace3Node.HumRat, space2Node.HumRat, 0.01); + + EXPECT_NEAR(mixSpace1Node.Enthalpy, space1Node.Enthalpy, 0.001); + EXPECT_NEAR(mixSpace2Node.Enthalpy, space3Node.Enthalpy, 0.001); + EXPECT_NEAR(mixSpace3Node.Enthalpy, space2Node.Enthalpy, 0.001); + + EXPECT_NEAR(mixSpace1Node.Press, space1Node.Press, 0.001); + EXPECT_NEAR(mixSpace2Node.Press, space3Node.Press, 0.001); + EXPECT_NEAR(mixSpace3Node.Press, space2Node.Press, 0.001); + + EXPECT_NEAR(mixSpace1Node.GenContam, space1Node.GenContam, 0.001); + EXPECT_NEAR(mixSpace2Node.GenContam, space3Node.GenContam, 0.001); + EXPECT_NEAR(mixSpace3Node.GenContam, space2Node.GenContam, 0.001); + + outletNode.Temp = 19.2; + outletNode.HumRat = 0.005; + outletNode.CO2 = 100.0; + + thisMixer.setOutletConditions(*state); + Real64 expectedInletEnthalpy = + mixSpace1Node.Enthalpy * mixSpace1.fraction + mixSpace2Node.Enthalpy * mixSpace2.fraction + mixSpace3Node.Enthalpy * mixSpace3.fraction; + Real64 expectedInletHumRat = + mixSpace1Node.HumRat * mixSpace1.fraction + mixSpace2Node.HumRat * mixSpace2.fraction + mixSpace3Node.HumRat * mixSpace3.fraction; + Real64 expectedInletCO2 = + mixSpace1Node.CO2 * mixSpace1.fraction + mixSpace2Node.CO2 * mixSpace2.fraction + mixSpace3Node.CO2 * mixSpace3.fraction; + Real64 expectedInletGenContam = + mixSpace1Node.GenContam * mixSpace1.fraction + mixSpace2Node.GenContam * mixSpace2.fraction + mixSpace3Node.GenContam * mixSpace3.fraction; + Real64 expectedInletPress = + mixSpace1Node.Press * mixSpace1.fraction + mixSpace2Node.Press * mixSpace2.fraction + mixSpace3Node.Press * mixSpace3.fraction; + Real64 expectedInletTemp = Psychrometrics::PsyTdbFnHW(expectedInletEnthalpy, expectedInletHumRat); + + EXPECT_NEAR(expectedInletEnthalpy, outletNode.Enthalpy, 0.0001); + EXPECT_NEAR(expectedInletTemp, outletNode.Temp, 0.0001); + EXPECT_NEAR(expectedInletHumRat, outletNode.HumRat, 0.0001); + EXPECT_NEAR(expectedInletCO2, outletNode.CO2, 0.0001); + EXPECT_NEAR(expectedInletGenContam, outletNode.GenContam, 0.0001); + EXPECT_NEAR(expectedInletPress, outletNode.Press, 0.0001); + + outletNode.MassFlowRate = 0.1; + outletNode.MassFlowRateMinAvail = 0.0; + outletNode.MassFlowRateMaxAvail = 0.15; + + thisMixer.setInletFlows(*state); + + EXPECT_NEAR(mixSpace1Node.MassFlowRate, outletNode.MassFlowRate * mixSpace1.fraction, 0.0001); + EXPECT_NEAR(mixSpace2Node.MassFlowRate, outletNode.MassFlowRate * mixSpace2.fraction, 0.0001); + EXPECT_NEAR(mixSpace3Node.MassFlowRate, outletNode.MassFlowRate * mixSpace3.fraction, 0.0001); + EXPECT_NEAR(mixSpace1Node.MassFlowRateMinAvail, outletNode.MassFlowRateMinAvail * mixSpace1.fraction, 0.0001); + EXPECT_NEAR(mixSpace2Node.MassFlowRateMinAvail, outletNode.MassFlowRateMinAvail * mixSpace2.fraction, 0.0001); + EXPECT_NEAR(mixSpace3Node.MassFlowRateMinAvail, outletNode.MassFlowRateMinAvail * mixSpace3.fraction, 0.0001); + EXPECT_NEAR(mixSpace1Node.MassFlowRateMaxAvail, outletNode.MassFlowRateMaxAvail * mixSpace1.fraction, 0.0001); + EXPECT_NEAR(mixSpace2Node.MassFlowRateMaxAvail, outletNode.MassFlowRateMaxAvail * mixSpace2.fraction, 0.0001); + EXPECT_NEAR(mixSpace3Node.MassFlowRateMaxAvail, outletNode.MassFlowRateMaxAvail * mixSpace3.fraction, 0.0001); +}