diff --git a/doc/engineering-reference/src/simulation-models-encyclopedic-reference-002/variable-refrigerant-flow-heat-pumps.tex b/doc/engineering-reference/src/simulation-models-encyclopedic-reference-002/variable-refrigerant-flow-heat-pumps.tex index 904c20ef133..7407449a29c 100644 --- a/doc/engineering-reference/src/simulation-models-encyclopedic-reference-002/variable-refrigerant-flow-heat-pumps.tex +++ b/doc/engineering-reference/src/simulation-models-encyclopedic-reference-002/variable-refrigerant-flow-heat-pumps.tex @@ -895,7 +895,7 @@ \subsubsection{Overview}\label{VRF-FluidTCtrl-HP-overview} Note that a number of calculation steps are coupled together in the VRF-FluidTCtrl model, for instance, the piping loss calculation and the system performance calculation. More specifically, the piping loss changes the operating conditions of the system, which may lead to a different control strategy and thus in reverse affect the amount of piping loss. This makes it difficult to obtain an analytical solution for a number of operational parameters (e.g., enthalpy of refrigerant entering the indoor unit), and therefore numerical iterations are employed to address this problem (refer to Figure VRF-FluidTCtrl-3 for more details). Therefore, the VRF-FluidTCtrl model can have a longer execution time to perform the simulation than the VRF-SysCurve model. -The object connections for VRF-FluidTCtrl model is similar to those for VRF-SysCurve model. The difference lies in the object used to describe a specific components. For example, VRF-SysCurve model uses \emph{AirConditioner:VariableRefrigerantFlow} object to describe the VRF outdoor unit performance, while in VRF-FluidTCtrl model the \emph{AirConditioner:VariableRefrigerantFlow} object is used. +The object connections for VRF-FluidTCtrl model is similar to those for VRF-SysCurve model. The difference lies in the object used to describe a specific components. For example, VRF-SysCurve model uses \emph{AirConditioner:VariableRefrigerantFlow} object to describe the VRF outdoor unit performance, while in VRF-FluidTCtrl model the \emph{AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl} object is used. \begin{figure}[hbtp] % figure VRF-FluidTCtrl-1b \centering diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index f97c8e9317d..3320d7aff00 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -3287,6 +3287,8 @@ namespace HVACVariableRefrigerantFlow { if (errFlag) { ShowContinueError("...occurs in " + cCurrentModuleObject + " = " + VRFTU(VRFTUNum).Name); ErrorsFound = true; + } else { + VRFTU(VRFTUNum).fanOutletNode = Fans::Fan(VRFTU(VRFTUNum).FanIndex).OutletNodeNum; } // Set the Design Fan Volume Flow Rate @@ -3350,6 +3352,7 @@ namespace HVACVariableRefrigerantFlow { FanInletNodeNum = HVACFan::fanObjs[VRFTU(VRFTUNum).FanIndex]->inletNodeNum; FanOutletNodeNum = HVACFan::fanObjs[VRFTU(VRFTUNum).FanIndex]->outletNodeNum; VRFTU(VRFTUNum).FanAvailSchedPtr = HVACFan::fanObjs[VRFTU(VRFTUNum).FanIndex]->availSchedIndex; + VRFTU(VRFTUNum).fanOutletNode = HVACFan::fanObjs[VRFTU(VRFTUNum).FanIndex]->outletNodeNum; } } else { // IF (FanType_Num == FanType_SimpleOnOff .OR. FanType_Num == FanType_SimpleConstVolume)THEN ShowSevereError(cCurrentModuleObject + " = " + VRFTU(VRFTUNum).Name); @@ -7017,6 +7020,15 @@ namespace HVACVariableRefrigerantFlow { // Algorithm Type: VRF model based on physics, appliable for Fluid Temperature Control VRFTU(VRFTUNum).ControlVRF_FluidTCtrl(VRFTUNum, QZnReq, FirstHVACIteration, PartLoadRatio, OnOffAirFlowRatio); VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(VRFTUNum, FirstHVACIteration, PartLoadRatio, SysOutputProvided, OnOffAirFlowRatio, LatOutputProvided); + if (PartLoadRatio == 0.0) { // set coil inlet conditions when coil does not operate. Inlet conditions are set in ControlVRF_FluidTCtrl when PLR=1 + if (VRFTU(VRFTUNum).CoolingCoilPresent) { + VRFTU(VRFTUNum).coilInNodeT = DataLoopNode::Node(DXCoils::DXCoil(VRFTU(VRFTUNum).CoolCoilIndex).AirInNode).Temp; + VRFTU(VRFTUNum).coilInNodeW = DataLoopNode::Node(DXCoils::DXCoil(VRFTU(VRFTUNum).CoolCoilIndex).AirInNode).HumRat; + } else { + VRFTU(VRFTUNum).coilInNodeT = DataLoopNode::Node(DXCoils::DXCoil(VRFTU(VRFTUNum).HeatCoilIndex).AirInNode).Temp; + VRFTU(VRFTUNum).coilInNodeW = DataLoopNode::Node(DXCoils::DXCoil(VRFTU(VRFTUNum).HeatCoilIndex).AirInNode).HumRat; + } + } // CalcVRF( VRFTUNum, FirstHVACIteration, PartLoadRatio, SysOutputProvided, OnOffAirFlowRatio, LatOutputProvided ); } else { // Algorithm Type: VRF model based on system curve @@ -7094,7 +7106,6 @@ namespace HVACVariableRefrigerantFlow { // The RETURNS here will jump back to SimVRF where the CalcVRF routine will simulate with latest PLR // do nothing else if TU is scheduled off - //!!LKL Discrepancy < 0 if (GetCurrentScheduleValue(VRFTU(VRFTUNum).SchedPtr) == 0.0) return; // do nothing if TU has no load (TU will be modeled using PLR=0) @@ -8526,7 +8537,7 @@ namespace HVACVariableRefrigerantFlow { for (int i = 1; i <= TerminalUnitList(TUListNum).NumTUInList; i++) { int VRFTUNum = TerminalUnitList(TUListNum).ZoneTUPtr(i); // analyze the conditions of each IU - VRFTU(VRFTUNum).CalcVRFIUVariableTeTc(VRFTUNum, EvapTemp(i), CondTemp(i)); + VRFTU(VRFTUNum).CalcVRFIUVariableTeTc(EvapTemp(i), CondTemp(i)); // select the Te/Tc that can satisfy all the zones IUMinEvapTemp = min(IUMinEvapTemp, EvapTemp(i), this->IUEvapTempHigh); @@ -8543,8 +8554,7 @@ namespace HVACVariableRefrigerantFlow { } } - void VRFTerminalUnitEquipment::CalcVRFIUVariableTeTc(int const VRFTUNum, // Index to VRF terminal unit - Real64 &EvapTemp, // evaporating temperature + void VRFTerminalUnitEquipment::CalcVRFIUVariableTeTc(Real64 &EvapTemp, // evaporating temperature Real64 &CondTemp // condensing temperature ) { @@ -8570,7 +8580,6 @@ namespace HVACVariableRefrigerantFlow { using DXCoils::DXCoil; using HVACVariableRefrigerantFlow::VRF; using HVACVariableRefrigerantFlow::VRFTU; - using MixedAir::OAMixer; using MixedAir::SimOAMixer; using Psychrometrics::PsyHFnTdbW; using SingleDuct::SimATMixer; @@ -8588,12 +8597,8 @@ namespace HVACVariableRefrigerantFlow { // na // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int const Mode(1); // Performance mode for MultiMode DX coil. Always 1 for other coil types int CoolCoilNum; // index to the VRF Cooling DX coil to be simulated - int FanOutletNode; // index to the outlet node of the fan int HeatCoilNum; // index to the VRF Heating DX coil to be simulated - int OAMixerNum; // OA mixer index - int OAMixNode; // index to the mix node of OA mixer int IndexToTUInTUList; // index to TU in specific list for the VRF system int TUListIndex; // index to TU list for this VRF system int VRFNum; // index to VRF that the VRF Terminal Unit serves @@ -8619,7 +8624,6 @@ namespace HVACVariableRefrigerantFlow { Real64 RHsat; // Relative humidity of the air at saturated condition(-) Real64 SH; // Super heating degrees (C) Real64 SC; // Subcooling degrees (C) - Real64 temp; // for temporary use Real64 T_coil_in; // Temperature of the air at the coil inlet, after absorbing the heat released by fan (C) Real64 T_TU_in; // Air temperature at the indoor unit inlet (C) Real64 Tout; // Air temperature at the indoor unit outlet (C) @@ -8651,46 +8655,11 @@ namespace HVACVariableRefrigerantFlow { C2Tcond = DXCoil(HeatCoilNum).C2Tc; C3Tcond = DXCoil(HeatCoilNum).C3Tc; - // Rated air flow rate for the coil - if ((!VRF(VRFNum).HeatRecoveryUsed && CoolingLoad(VRFNum)) || - (VRF(VRFNum).HeatRecoveryUsed && TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList))) { - // VRF terminal unit is on cooling mode - CompOnMassFlow = DXCoil(CoolCoilNum).RatedAirMassFlowRate(Mode); - } else if ((!VRF(VRFNum).HeatRecoveryUsed && HeatingLoad(VRFNum)) || - (VRF(VRFNum).HeatRecoveryUsed && TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList))) { - // VRF terminal unit is on heating mode - CompOnMassFlow = DXCoil(HeatCoilNum).RatedAirMassFlowRate(Mode); - } - - // Set inlet air mass flow rate based on PLR and compressor on/off air flow rates - SetAverageAirFlow(VRFTUNum, 1.0, temp); VRFInletNode = this->VRFTUInletNodeNum; T_TU_in = Node(VRFInletNode).Temp; W_TU_in = Node(VRFInletNode).HumRat; - T_coil_in = T_TU_in; - W_coil_in = W_TU_in; - - // Simulation the OAMixer if there is any - if (this->OAMixerUsed) { - SimOAMixer(this->OAMixerName, false, this->OAMixerIndex); - - OAMixerNum = UtilityRoutines::FindItemInList(this->OAMixerName, OAMixer); - OAMixNode = OAMixer(OAMixerNum).MixNode; - T_coil_in = Node(OAMixNode).Temp; - W_coil_in = Node(OAMixNode).HumRat; - } - // Simulate the blow-through fan if there is any - if (this->FanPlace == BlowThru) { - if (this->fanType_Num == DataHVACGlobals::FanType_SystemModelObject) { - HVACFan::fanObjs[this->FanIndex]->simulate(1.0 / temp, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _); - FanOutletNode = HVACFan::fanObjs[this->FanIndex]->outletNodeNum; - } else { - Fans::SimulateFanComponents("", false, this->FanIndex, FanSpeedRatio, ZoneCompTurnFansOn, ZoneCompTurnFansOff); - FanOutletNode = Fans::Fan(this->FanIndex).OutletNodeNum; - } - T_coil_in = Node(FanOutletNode).Temp; - W_coil_in = Node(FanOutletNode).HumRat; - } + T_coil_in = this->coilInNodeT; + W_coil_in = this->coilInNodeW; Garate = CompOnMassFlow; H_coil_in = PsyHFnTdbW(T_coil_in, W_coil_in); @@ -10076,8 +10045,7 @@ namespace HVACVariableRefrigerantFlow { bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step Real64 &PartLoadRatio, // unit part load ratio Real64 &OnOffAirFlowRatio // ratio of compressor ON airflow to AVERAGE airflow over timestep - ) - { + ) { // SUBROUTINE INFORMATION: // AUTHOR Rongpeng Zhang @@ -10150,7 +10118,6 @@ namespace HVACVariableRefrigerantFlow { // The RETURNS here will jump back to SimVRF where the CalcVRF routine will simulate with latest PLR // do nothing else if TU is scheduled off - //!!LKL Discrepancy < 0 if (GetCurrentScheduleValue(this->SchedPtr) == 0.0) return; // Block the following statement: QZnReq==0 doesn't mean QCoilReq==0 due to possible OA mixer operation. zrp_201511 @@ -10186,6 +10153,13 @@ namespace HVACVariableRefrigerantFlow { // Otherwise the coil needs to turn on. Get full load result PartLoadRatio = 1.0; this->CalcVRF_FluidTCtrl(VRFTUNum, FirstHVACIteration, PartLoadRatio, FullOutput, OnOffAirFlowRatio); + if (this->CoolingCoilPresent) { + this->coilInNodeT = DataLoopNode::Node(DXCoils::DXCoil(this->CoolCoilIndex).AirInNode).Temp; + this->coilInNodeW = DataLoopNode::Node(DXCoils::DXCoil(this->CoolCoilIndex).AirInNode).HumRat; + } else { + this->coilInNodeT = DataLoopNode::Node(DXCoils::DXCoil(this->HeatCoilIndex).AirInNode).Temp; + this->coilInNodeW = DataLoopNode::Node(DXCoils::DXCoil(this->HeatCoilIndex).AirInNode).HumRat; + } PartLoadRatio = 0.0; @@ -10400,7 +10374,6 @@ namespace HVACVariableRefrigerantFlow { Fans::SimulateFanComponents("", FirstHVACIteration, this->FanIndex, FanSpeedRatio, ZoneCompTurnFansOn, ZoneCompTurnFansOff); } } - if (this->CoolingCoilPresent) { // above condition for heat pump mode, below condition for heat recovery mode if ((!VRF(VRFCond).HeatRecoveryUsed && CoolingLoad(VRFCond)) || @@ -10673,8 +10646,6 @@ namespace HVACVariableRefrigerantFlow { // FUNCTION LOCAL VARIABLE DECLARATIONS: int const Mode(1); // Performance mode for MultiMode DX coil. Always 1 for other coil types int CoilIndex; // index to coil - int FanOutletNode; // index to the outlet node of the fan - int OAMixerNum; // OA mixer index int OAMixNode; // index to the mix node of OA mixer int VRFCond; // index to VRF condenser int VRFTUNum; // Unit index in VRF terminal unit array @@ -10724,10 +10695,7 @@ namespace HVACVariableRefrigerantFlow { // Simulation the OAMixer if there is any if (VRFTU(VRFTUNum).OAMixerUsed) { SimOAMixer(VRFTU(VRFTUNum).OAMixerName, FirstHVACIteration, VRFTU(VRFTUNum).OAMixerIndex); - - OAMixerNum = UtilityRoutines::FindItemInList(VRFTU(VRFTUNum).OAMixerName, - OAMixer); // this not needed, why not use VRFTU( VRFTUNum ).OAMixerIndex var - OAMixNode = OAMixer(OAMixerNum).MixNode; + OAMixNode = OAMixer(VRFTU(VRFTUNum).OAMixerIndex).MixNode; Tin = Node(OAMixNode).Temp; Win = Node(OAMixNode).HumRat; } @@ -10735,13 +10703,11 @@ namespace HVACVariableRefrigerantFlow { if (VRFTU(VRFTUNum).FanPlace == BlowThru) { if (VRFTU(VRFTUNum).fanType_Num == DataHVACGlobals::FanType_SystemModelObject) { HVACFan::fanObjs[VRFTU(VRFTUNum).FanIndex]->simulate(1.0 / temp, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _); - FanOutletNode = HVACFan::fanObjs[VRFTU(VRFTUNum).FanIndex]->outletNodeNum; } else { Fans::SimulateFanComponents("", false, VRFTU(VRFTUNum).FanIndex, FanSpeedRatio, ZoneCompTurnFansOn, ZoneCompTurnFansOff); - FanOutletNode = Fans::Fan(VRFTU(VRFTUNum).FanIndex).OutletNodeNum; } - Tin = Node(FanOutletNode).Temp; - Win = Node(FanOutletNode).HumRat; + Tin = Node(VRFTU(VRFTUNum).fanOutletNode).Temp; + Win = Node(VRFTU(VRFTUNum).fanOutletNode).HumRat; } // Call the coil control logic to determine the air flow rate to match the given coil load diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.hh b/src/EnergyPlus/HVACVariableRefrigerantFlow.hh index 6431c005d4e..11f787decc2 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.hh +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.hh @@ -700,6 +700,9 @@ namespace HVACVariableRefrigerantFlow { int ATMixerSecNode; // secondary air inlet node number for the air terminal mixer int ATMixerOutNode; // outlet air node number for the air terminal mixer bool firstPass; // used to reset global sizing data + Real64 coilInNodeT; // coil inlet node temp at full flow (C) + Real64 coilInNodeW; // coil inlet node humidity ratio at full flow (kg/kg) + int fanOutletNode; // fan outlet node index // Default Constructor VRFTerminalUnitEquipment() : VRFTUType_Num(0), SchedPtr(-1), VRFSysNum(0), TUListIndex(0), IndexToTUInTUList(0), ZoneNum(0), VRFTUInletNodeNum(0), @@ -715,7 +718,8 @@ namespace HVACVariableRefrigerantFlow { SensibleCoolingRate(0.0), SensibleHeatingRate(0.0), LatentCoolingRate(0.0), LatentHeatingRate(0.0), TotalCoolingEnergy(0.0), TotalHeatingEnergy(0.0), SensibleCoolingEnergy(0.0), SensibleHeatingEnergy(0.0), LatentCoolingEnergy(0.0), LatentHeatingEnergy(0.0), EMSOverridePartLoadFrac(false), EMSValueForPartLoadFrac(0.0), IterLimitExceeded(0), FirstIterfailed(0), ZonePtr(0), HVACSizingIndex(0), - ATMixerExists(false), ATMixerIndex(0), ATMixerType(0), ATMixerPriNode(0), ATMixerSecNode(0), ATMixerOutNode(0), firstPass(true) + ATMixerExists(false), ATMixerIndex(0), ATMixerType(0), ATMixerPriNode(0), ATMixerSecNode(0), ATMixerOutNode(0), firstPass(true), + coilInNodeT(0.0), coilInNodeW(0.0), fanOutletNode(0) { } @@ -725,8 +729,7 @@ namespace HVACVariableRefrigerantFlow { // Note: the argument VRFTUNum should be removed later in the deeper OO re-factor. Now this argument may be used by other functions that are // not member functions of this class. - void CalcVRFIUVariableTeTc(int const VRFTUNum, // Index to VRF terminal unit - Real64 &EvapTemp, // evaporating temperature + void CalcVRFIUVariableTeTc(Real64 &EvapTemp, // evaporating temperature Real64 &CondTemp // condensing temperature ); diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index 3139b18546c..0dc91b5e807 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -2440,16 +2440,143 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_CalcVRFIUTeTc) TerminalUnitList(IndexTUList).NumTUInList = 2; VRF(IndexVRFCondenser).ZoneTUListPtr = 1; - VRF(IndexVRFCondenser).AlgorithmIUCtrl = 0; VRF(IndexVRFCondenser).EvapTempFixed = 3; VRF(IndexVRFCondenser).CondTempFixed = 5; + // test fixed evap/cond temp method + VRF(IndexVRFCondenser).AlgorithmIUCtrl = 0; // Run and Check VRF(IndexVRFCondenser).CalcVRFIUTeTc_FluidTCtrl(); EXPECT_EQ(VRF(IndexVRFCondenser).IUEvaporatingTemp, 3); EXPECT_EQ(VRF(IndexVRFCondenser).IUCondensingTemp, 5); + // test variable evap/cond temp method + VRF(IndexVRFCondenser).AlgorithmIUCtrl = 1; + VRF(IndexVRFCondenser).HeatRecoveryUsed = false; + VRFTU.allocate(TerminalUnitList(IndexTUList).NumTUInList); + VRFTU(1).CoolCoilIndex = 1; + VRFTU(1).HeatCoilIndex = 2; + VRFTU(2).CoolCoilIndex = 3; + VRFTU(2).HeatCoilIndex = 4; + VRFTU(1).ZoneNum = 1; + VRFTU(1).VRFSysNum = 1; + VRFTU(2).ZoneNum = 2; + VRFTU(2).VRFSysNum = 1; + VRFTU(1).IndexToTUInTUList = 1; + VRFTU(2).IndexToTUInTUList = 2; + VRFTU(1).VRFTUInletNodeNum = 1; + VRFTU(2).VRFTUInletNodeNum = 2; + TerminalUnitList(1).ZoneTUPtr.allocate(2); + TerminalUnitList(1).ZoneTUPtr(1) = 1; + TerminalUnitList(1).ZoneTUPtr(2) = 2; + TerminalUnitList(1).HRCoolRequest.allocate(2); + TerminalUnitList(1).HRCoolRequest = false; + TerminalUnitList(1).HRHeatRequest.allocate(2); + TerminalUnitList(1).HRHeatRequest = false; + DXCoil.allocate(4); // 2 TUs each with a cooling and heating coil + for (int i = 1; i <= 2; ++i) { + DXCoil((i - 1) * 2 + 1).SH = 8.0 + double(i); + DXCoil((i - 1) * 2 + 1).C1Te = 1.0; + DXCoil((i - 1) * 2 + 1).C2Te = 0.0; + DXCoil((i - 1) * 2 + 1).C3Te = 0.0; + DXCoil((i - 1) * 2 + 2).SC = 6.0 + double(i); + DXCoil((i - 1) * 2 + 2).C1Tc = 1.0; + DXCoil((i - 1) * 2 + 2).C2Tc = 0.0; + DXCoil((i - 1) * 2 + 2).C3Tc = 0.0; + } + Node.allocate(5); + Node(1).Temp = 21.0; // TU 1 inlet node + Node(1).HumRat = 0.011; + Node(2).Temp = 21.0; // TU 2 inlet node + Node(2).HumRat = 0.011; + VRFTU(1).fanOutletNode = 3; + Node(3).Temp = 23.0; // TU 1 fan outlet node + Node(3).HumRat = 0.011; // TU 1 fan outlet node + VRFTU(2).fanOutletNode = 4; + Node(4).Temp = 23.0; // TU 2 fan outlet node + Node(4).HumRat = 0.011; // TU 2 fan outlet node + VRFTU(1).coilInNodeT = Node(1).Temp; + VRFTU(1).coilInNodeW = Node(1).HumRat; + VRFTU(2).coilInNodeT = Node(2).Temp; + VRFTU(2).coilInNodeW = Node(2).HumRat; + + CoolingLoad.allocate(1); + HeatingLoad.allocate(1); + CoolingLoad(1) = true; + HeatingLoad(1) = false; + DataZoneEnergyDemands::ZoneSysEnergyDemand.allocate(2); + DataZoneEnergyDemands::ZoneSysEnergyDemand(1).OutputRequiredToCoolingSP = -100.0; + DataZoneEnergyDemands::ZoneSysEnergyDemand(1).OutputRequiredToHeatingSP = -200.0; + DataZoneEnergyDemands::ZoneSysEnergyDemand(2).OutputRequiredToCoolingSP = -1100.0; + DataZoneEnergyDemands::ZoneSysEnergyDemand(2).OutputRequiredToHeatingSP = -1200.0; + + CompOnMassFlow = 0.0; // system is off + // Run and Check + VRF(IndexVRFCondenser).CalcVRFIUTeTc_FluidTCtrl(); + EXPECT_EQ(VRF(IndexVRFCondenser).IUEvaporatingTemp, 15); // default value, coil inlet temps higher than default + EXPECT_EQ(VRF(IndexVRFCondenser).IUCondensingTemp, 42); // default value, coil inlet temps lower than default + + CompOnMassFlow = 0.1; + // system is on in cooling mode + VRF(IndexVRFCondenser).CalcVRFIUTeTc_FluidTCtrl(); + // minimum coil surface temp of both cooling coils below default + EXPECT_LT(VRF(IndexVRFCondenser).IUEvaporatingTemp, 15); + // default value, coil inlet temps lower than default + EXPECT_EQ(VRF(IndexVRFCondenser).IUCondensingTemp, 42); + Real64 saveCoolingEvapTemp = VRF(IndexVRFCondenser).IUEvaporatingTemp; + + // test blow thru fan + // adjust coil inlet temps for fan heat + VRFTU(1).coilInNodeT = Node(3).Temp; + VRFTU(1).coilInNodeW = Node(3).HumRat; + VRFTU(2).coilInNodeT = Node(3).Temp; + VRFTU(2).coilInNodeW = Node(3).HumRat; + VRFTU(1).FanPlace = DataHVACGlobals::BlowThru; + VRFTU(2).FanPlace = DataHVACGlobals::BlowThru; + // system is on in cooling mode + VRF(IndexVRFCondenser).CalcVRFIUTeTc_FluidTCtrl(); + // fan heat added to coil inlet temp, coil surface temp should also be lower to overcome additional heat tranfer + EXPECT_LT(VRF(IndexVRFCondenser).IUEvaporatingTemp, saveCoolingEvapTemp); + // default value, coil inlet temps lower than default + EXPECT_EQ(VRF(IndexVRFCondenser).IUCondensingTemp, 42); + + VRFTU(1).FanPlace = DataHVACGlobals::DrawThru; + VRFTU(2).FanPlace = DataHVACGlobals::DrawThru; + // rest coil inlet temps + VRFTU(1).coilInNodeT = Node(1).Temp; + VRFTU(1).coilInNodeW = Node(1).HumRat; + VRFTU(2).coilInNodeT = Node(2).Temp; + VRFTU(2).coilInNodeW = Node(2).HumRat; + CoolingLoad(1) = false; + HeatingLoad(1) = true; + DataZoneEnergyDemands::ZoneSysEnergyDemand(1).OutputRequiredToCoolingSP = 300.0; + DataZoneEnergyDemands::ZoneSysEnergyDemand(1).OutputRequiredToHeatingSP = 200.0; + DataZoneEnergyDemands::ZoneSysEnergyDemand(2).OutputRequiredToCoolingSP = 2000.0; + DataZoneEnergyDemands::ZoneSysEnergyDemand(2).OutputRequiredToHeatingSP = 1900.0; + // system is on in heating mode + VRF(IndexVRFCondenser).CalcVRFIUTeTc_FluidTCtrl(); + // default value, coil inlet temps higher than default + EXPECT_EQ(VRF(IndexVRFCondenser).IUEvaporatingTemp, 15); + // maximum coil surface temp of both heating coils above default + EXPECT_GT(VRF(IndexVRFCondenser).IUCondensingTemp, 42); + Real64 saveHeatingCondTemp = VRF(IndexVRFCondenser).IUCondensingTemp; + + // test blow thru fan + VRFTU(1).FanPlace = DataHVACGlobals::BlowThru; + VRFTU(2).FanPlace = DataHVACGlobals::BlowThru; + // adjust coil inlet temps for fan heat + VRFTU(1).coilInNodeT = Node(3).Temp; + VRFTU(1).coilInNodeW = Node(3).HumRat; + VRFTU(2).coilInNodeT = Node(3).Temp; + VRFTU(2).coilInNodeW = Node(3).HumRat; + // system is on in heating mode + VRF(IndexVRFCondenser).CalcVRFIUTeTc_FluidTCtrl(); + // default value, coil inlet temps higher than default + EXPECT_EQ(VRF(IndexVRFCondenser).IUEvaporatingTemp, 15); + // fan heat added to coil inlet temp, coil surface temp should also be lower to account for less heat tranfer + EXPECT_LT(VRF(IndexVRFCondenser).IUCondensingTemp, saveHeatingCondTemp); + // Clean up VRF.deallocate(); TerminalUnitList.deallocate();