Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <array>
50 : #include <cassert>
51 : #include <cmath>
52 : #include <string>
53 :
54 : // ObjexxFCL Headers
55 : #include <ObjexxFCL/Array.functions.hh>
56 : #include <ObjexxFCL/Fmath.hh>
57 :
58 : // EnergyPlus Headers
59 : #include <EnergyPlus/Autosizing/All_Simple_Sizing.hh>
60 : #include <EnergyPlus/Autosizing/CoolingAirFlowSizing.hh>
61 : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
62 : #include <EnergyPlus/Autosizing/HeatingAirFlowSizing.hh>
63 : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
64 : #include <EnergyPlus/Autosizing/SystemAirFlowSizing.hh>
65 : #include <EnergyPlus/Autosizing/WaterHeatingCapacitySizing.hh>
66 : #include <EnergyPlus/BranchNodeConnections.hh>
67 : #include <EnergyPlus/CurveManager.hh>
68 : #include <EnergyPlus/DXCoils.hh>
69 : #include <EnergyPlus/Data/EnergyPlusData.hh>
70 : #include <EnergyPlus/DataAirSystems.hh>
71 : #include <EnergyPlus/DataDefineEquip.hh>
72 : #include <EnergyPlus/DataGlobalConstants.hh>
73 : #include <EnergyPlus/DataHVACGlobals.hh>
74 : #include <EnergyPlus/DataHeatBalFanSys.hh>
75 : #include <EnergyPlus/DataHeatBalance.hh>
76 : #include <EnergyPlus/DataIPShortCuts.hh>
77 : #include <EnergyPlus/DataLoopNode.hh>
78 : #include <EnergyPlus/DataSizing.hh>
79 : #include <EnergyPlus/DataZoneControls.hh>
80 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
81 : #include <EnergyPlus/DataZoneEquipment.hh>
82 : #include <EnergyPlus/EMSManager.hh>
83 : #include <EnergyPlus/Fans.hh>
84 : #include <EnergyPlus/FluidProperties.hh>
85 : #include <EnergyPlus/General.hh>
86 : #include <EnergyPlus/GeneralRoutines.hh>
87 : #include <EnergyPlus/GlobalNames.hh>
88 : #include <EnergyPlus/HVACVariableRefrigerantFlow.hh>
89 : #include <EnergyPlus/HeatingCoils.hh>
90 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
91 : #include <EnergyPlus/MixedAir.hh>
92 : #include <EnergyPlus/NodeInputManager.hh>
93 : #include <EnergyPlus/OutAirNodeManager.hh>
94 : #include <EnergyPlus/OutputProcessor.hh>
95 : #include <EnergyPlus/Plant/DataPlant.hh>
96 : #include <EnergyPlus/Plant/PlantLocation.hh>
97 : #include <EnergyPlus/PlantUtilities.hh>
98 : #include <EnergyPlus/Psychrometrics.hh>
99 : #include <EnergyPlus/ScheduleManager.hh>
100 : #include <EnergyPlus/SteamCoils.hh>
101 : #include <EnergyPlus/UnitarySystem.hh>
102 : #include <EnergyPlus/UtilityRoutines.hh>
103 : #include <EnergyPlus/WaterCoils.hh>
104 : #include <EnergyPlus/WaterManager.hh>
105 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
106 :
107 : namespace EnergyPlus::HVACVariableRefrigerantFlow {
108 : // Module containing the Variable Refrigerant Flow (VRF or VRV) simulation routines
109 :
110 : // MODULE INFORMATION:
111 : // AUTHOR Richard Raustad, FSEC
112 : // DATE WRITTEN August 2010
113 : // MODIFIED Apr 2012, R. Raustad, FSEC, Added Heat Recovery Operating Mode
114 : // Jul 2015, RP Zhang, XF Pang, LBNL, Added a new physics based VRF model applicable for Fluid Temperature Control
115 : // RE-ENGINEERED na
116 :
117 : // PURPOSE OF THIS MODULE:
118 : // To encapsulate the data and algorithms required to
119 : // manage the VRF System Component
120 :
121 : using namespace DataZoneEnergyDemands;
122 : using namespace Psychrometrics;
123 : using namespace DataPlant;
124 :
125 : constexpr std::array<std::string_view, (int)TUType::Num> tuTypeNames = {"ZoneHVAC:TerminalUnit:VariableRefrigerantFlow"};
126 :
127 7087 : void SimulateVRF(EnergyPlusData &state,
128 : std::string_view CompName,
129 : bool const FirstHVACIteration,
130 : int const ZoneNum,
131 : int &CompIndex,
132 : bool &HeatingActive,
133 : bool &CoolingActive,
134 : [[maybe_unused]] int const OAUnitNum, // If the system is an equipment of OutdoorAirUnit
135 : [[maybe_unused]] Real64 const OAUCoilOutTemp, // the coil inlet temperature of OutdoorAirUnit
136 : [[maybe_unused]] bool const ZoneEquipment, // TRUE if called as zone equipment
137 : Real64 &SysOutputProvided,
138 : Real64 &LatOutputProvided)
139 : {
140 :
141 : // SUBROUTINE INFORMATION:
142 : // AUTHOR Richard Raustad, FSEC
143 : // DATE WRITTEN August 2010
144 : // MODIFIED Jul 2015, RP Zhang (LBNL), XF Pang (LBNL), Y Yura (Daikin Inc). Add a physics-based VRF model applicable for Fluid
145 : // Temperature Control RE-ENGINEERED na
146 :
147 : // PURPOSE OF THIS SUBROUTINE:
148 : // This subroutine manages VRF terminal unit simulation.
149 :
150 : // METHODOLOGY EMPLOYED:
151 : // Simulate all terminal units
152 : // Once all terminal units have been simulated, simulate VRF condenser
153 :
154 : int VRFTUNum; // current VRF system terminal unit index
155 : int VRFCondenser; // index to VRF AC system object - AirConditioner:VariableRefrigerantFlow
156 : int TUListNum; // index to VRF AC system terminal unit list
157 : int IndexToTUInTUList; // index to pointer in VRF AC system terminal unit list
158 : Real64 OnOffAirFlowRatio; // ratio of compressor ON airflow to average airflow over timestep
159 : int DXCoolingCoilIndex; // index to this terminal units DX cooling coil
160 : int DXHeatingCoilIndex; // index to this terminal units DX heating coil
161 : Real64 QZnReq;
162 :
163 : // Obtains and Allocates VRF system related parameters from input file
164 7087 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) { // First time subroutine has been entered
165 3 : GetVRFInput(state);
166 3 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
167 : }
168 :
169 : // CompIndex accounting
170 7087 : if (CompIndex == 0) {
171 8 : VRFTUNum = Util::FindItemInList(CompName, state.dataHVACVarRefFlow->VRFTU);
172 8 : if (VRFTUNum == 0) {
173 0 : ShowFatalError(state, format("SimulateVRF: VRF Terminal Unit not found={}", CompName));
174 : }
175 8 : CompIndex = VRFTUNum;
176 :
177 : } else {
178 7079 : VRFTUNum = CompIndex;
179 7079 : if (VRFTUNum > state.dataHVACVarRefFlow->NumVRFTU || VRFTUNum < 1) {
180 0 : ShowFatalError(state,
181 0 : format("SimulateVRF: Invalid CompIndex passed={}, Number of VRF Terminal Units = {}, VRF Terminal Unit name = {}",
182 : VRFTUNum,
183 0 : state.dataHVACVarRefFlow->NumVRFTU,
184 : CompName));
185 : }
186 7079 : if (state.dataHVACVarRefFlow->CheckEquipName(VRFTUNum)) {
187 5 : if (!CompName.empty() && CompName != state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name) {
188 0 : ShowFatalError(state,
189 0 : format("SimulateVRF: Invalid CompIndex passed={}, VRF Terminal Unit name={}, stored VRF TU Name for that index={}",
190 : VRFTUNum,
191 : CompName,
192 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
193 : }
194 5 : state.dataHVACVarRefFlow->CheckEquipName(VRFTUNum) = false;
195 : }
196 : }
197 :
198 : // the VRF condenser index
199 7087 : VRFCondenser = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum;
200 :
201 7092 : if ((state.dataHVACVarRefFlow->VRF(VRFCondenser).CondenserType == DataHeatBalance::RefrigCondenserType::Water) &&
202 5 : (state.dataHVACVarRefFlow->VRF(VRFCondenser).checkPlantCondTypeOneTime)) {
203 : // scan for loop connection data
204 1 : bool errFlag = false;
205 3 : PlantUtilities::ScanPlantLoopsForObject(state,
206 1 : state.dataHVACVarRefFlow->VRF(VRFCondenser).Name,
207 1 : state.dataHVACVarRefFlow->VRF(VRFCondenser).VRFType,
208 1 : state.dataHVACVarRefFlow->VRF(VRFCondenser).SourcePlantLoc,
209 : errFlag,
210 : _,
211 : _,
212 : _,
213 1 : state.dataHVACVarRefFlow->VRF(VRFCondenser).CondenserNodeNum,
214 : _);
215 :
216 1 : if (errFlag) {
217 0 : ShowSevereError(state, "GetVRFInput: Error scanning for plant loop data");
218 : }
219 :
220 1 : state.dataHVACVarRefFlow->VRF(VRFCondenser).checkPlantCondTypeOneTime = false;
221 : }
222 :
223 : // the terminal unit list object index
224 7087 : TUListNum = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex;
225 : // the entry number in the terminal unit list (which item in the terminal unit list, e.g. second in list)
226 7087 : IndexToTUInTUList = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).IndexToTUInTUList;
227 : // index to cooling coil (coil is optional but at least one must be present)
228 7087 : DXCoolingCoilIndex = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolCoilIndex;
229 : // index to heating coil (coil is optional but at least one must be present)
230 7087 : DXHeatingCoilIndex = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatCoilIndex;
231 7087 : QZnReq = 0.0;
232 :
233 : // Initialize terminal unit
234 7087 : InitVRF(state, VRFTUNum, ZoneNum, FirstHVACIteration, OnOffAirFlowRatio, QZnReq); // Initialize all VRFTU related parameters
235 :
236 : // Simulate terminal unit
237 7087 : SimVRF(state, VRFTUNum, FirstHVACIteration, OnOffAirFlowRatio, SysOutputProvided, LatOutputProvided, QZnReq);
238 :
239 : // mark this terminal unit as simulated
240 7087 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).IsSimulated(IndexToTUInTUList) = true;
241 :
242 : // keep track of individual coil loads
243 7087 : if (DXCoolingCoilIndex > 0) {
244 7087 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(IndexToTUInTUList) =
245 7087 : state.dataDXCoils->DXCoilTotalCooling(DXCoolingCoilIndex);
246 : } else {
247 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(IndexToTUInTUList) = 0.0;
248 : }
249 7087 : if (DXHeatingCoilIndex > 0) {
250 7087 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(IndexToTUInTUList) =
251 7087 : state.dataDXCoils->DXCoilTotalHeating(DXHeatingCoilIndex);
252 : } else {
253 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(IndexToTUInTUList) = 0.0;
254 : }
255 :
256 : // Report the current VRF terminal unit
257 7087 : ReportVRFTerminalUnit(state, VRFTUNum);
258 :
259 7087 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalCoolingRate > 0.0) CoolingActive = true;
260 7087 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalHeatingRate > 0.0) HeatingActive = true;
261 :
262 : // make sure all TU in a list are able to get simulated, otherwise condenser is never simulated **
263 : // either fatal on GetInput, or keep track of unused TU's and set their respective flag to TRUE **
264 : // after all VRF terminal units have been simulated, call the VRF condenser model
265 7087 : if (all(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).IsSimulated)) {
266 :
267 7087 : if (state.dataHVACVarRefFlow->VRF(VRFCondenser).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
268 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
269 2368 : state.dataHVACVarRefFlow->VRF(VRFCondenser).CalcVRFCondenser_FluidTCtrl(state, FirstHVACIteration);
270 : } else {
271 : // Algorithm Type: VRF model based on system curve
272 4719 : CalcVRFCondenser(state, VRFCondenser);
273 : }
274 :
275 7087 : ReportVRFCondenser(state, VRFCondenser);
276 :
277 7087 : if (state.dataHVACVarRefFlow->VRF(VRFCondenser).CondenserType == DataHeatBalance::RefrigCondenserType::Water)
278 5 : UpdateVRFCondenser(state, VRFCondenser);
279 : }
280 7087 : }
281 :
282 2 : PlantComponent *VRFCondenserEquipment::factory(EnergyPlusData &state, std::string const &objectName)
283 : {
284 : // Process the input data if it hasn't been done already
285 2 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
286 1 : GetVRFInput(state);
287 1 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
288 : }
289 : // Now look for this object in the list
290 2 : for (auto &obj : state.dataHVACVarRefFlow->VRF) {
291 2 : if (obj.Name == objectName) {
292 2 : return &obj;
293 : }
294 : }
295 : // If we didn't find it, fatal
296 : ShowFatalError(state, format("LocalVRFCondenserFactory: Error getting inputs for object named: {}", objectName)); // LCOV_EXCL_LINE
297 : // Shut up the compiler
298 : return nullptr; // LCOV_EXCL_LINE
299 : }
300 :
301 1 : void VRFCondenserEquipment::onInitLoopEquip(EnergyPlusData &state, [[maybe_unused]] const PlantLocation &calledFromLocation)
302 : {
303 1 : this->SizeVRFCondenser(state);
304 1 : }
305 :
306 0 : void VRFCondenserEquipment::getDesignCapacities([[maybe_unused]] EnergyPlusData &state,
307 : [[maybe_unused]] const PlantLocation &calledFromLocation,
308 : Real64 &MaxLoad,
309 : Real64 &MinLoad,
310 : Real64 &OptLoad)
311 : {
312 0 : MinLoad = 0.0;
313 0 : MaxLoad = max(this->CoolingCapacity, this->HeatingCapacity); // greater of cooling and heating capacity
314 0 : OptLoad = max(this->CoolingCapacity,
315 : this->HeatingCapacity); // connects to single loop, need to switch between cooling/heating capacity?
316 0 : }
317 :
318 0 : void VRFCondenserEquipment::simulate(EnergyPlusData &state,
319 : const PlantLocation &calledFromLocation,
320 : bool FirstHVACIteration,
321 : [[maybe_unused]] Real64 &CurLoad,
322 : [[maybe_unused]] bool RunFlag)
323 : {
324 0 : if (calledFromLocation.loopNum == this->SourcePlantLoc.loopNum) { // condenser loop
325 0 : PlantUtilities::UpdateChillerComponentCondenserSide(state,
326 : this->SourcePlantLoc.loopNum,
327 : this->SourcePlantLoc.loopSideNum,
328 : PlantEquipmentType::HeatPumpVRF,
329 : this->CondenserNodeNum,
330 : this->CondenserOutletNodeNum,
331 : this->QCondenser,
332 : this->CondenserInletTemp,
333 : this->CondenserSideOutletTemp,
334 : this->WaterCondenserMassFlow,
335 : FirstHVACIteration);
336 : } else {
337 0 : ShowFatalError(state, format("SimVRFCondenserPlant:: Invalid loop connection {}", cVRFTypes(VRF_HeatPump)));
338 : }
339 0 : }
340 :
341 4735 : void CalcVRFCondenser(EnergyPlusData &state, int const VRFCond)
342 : {
343 :
344 : // SUBROUTINE INFORMATION:
345 : // AUTHOR R. Raustad, FSEC
346 : // DATE WRITTEN September 2010
347 :
348 : // PURPOSE OF THIS SUBROUTINE:
349 : // Model the interactions of VRF terminal units with a single variable-speed condenser.
350 : // The terminal units are simulated first, and then the condenser is simulated.
351 : // If terminal units require more capacity than can be delivered by condenser, a limit is set.
352 :
353 : using Curve::CurveValue;
354 : using PlantUtilities::SetComponentFlowRate;
355 : using Psychrometrics::RhoH2O;
356 :
357 : static constexpr std::string_view RoutineName("VRFCondenser");
358 :
359 : int NumTU; // loop counter
360 :
361 : Real64 TotCoolCapTempModFac; // cooling CAPFT curve output
362 : Real64 TotHeatCapTempModFac; // heating CAPFT curve output
363 : Real64 TotCoolEIRTempModFac; // cooling EIRFT curve output
364 : Real64 TotHeatEIRTempModFac; // heating EIRFT curve output
365 : Real64 InletAirWetBulbC; // coil inlet air wet-bulb temperature (C)
366 : Real64 InletAirDryBulbC; // coil inlet air dry-bulb temperature (C)
367 4735 : Real64 CondInletTemp(0.0); // condenser inlet air temperature (C)
368 : Real64 CondInletHumRat; // condenser inlet air humidity ratio (kg/kg)
369 : Real64 OutdoorDryBulb; // outdoor dry-bulb temperature (C)
370 : Real64 OutdoorHumRat; // outdoor humidity ratio (kg/kg)
371 : Real64 OutdoorPressure; // outdoor pressure (Pa)
372 : Real64 OutdoorWetBulb; // outdoor wet-bulb temperature (C)
373 : Real64 CoolOABoundary; // output of cooling boundary curve (outdoor temperature, C)
374 : Real64 HeatOABoundary; // output of heating boundary curve (outdoor temperature, C)
375 : Real64 EIRFPLRModFac; // EIRFPLR curve output
376 : Real64 UpperStageCompressorRatio; // used for crankcase heater power calculation
377 : Real64 RhoAir; // Density of air [kg/m3]
378 : Real64 RhoWater; // Density of water [kg/m3]
379 : Real64 CpCond; // Specific Heat of water [J/kg-k]
380 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
381 : Real64 CondWaterMassFlow; // Condenser water mass flow rate [kg/s]
382 : Real64 PartLoadFraction; // Part load fraction from PLFFPLR curve
383 : Real64 VRFRTF; // VRF runtime fraction when cycling below MINPLR
384 : Real64 OutdoorCoilT; // Outdoor coil temperature (C)
385 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
386 : Real64 FractionalDefrostTime; // Fraction of time step system is in defrost
387 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
388 : Real64 InputPowerMultiplier; // Multiplier for power when system is in defrost
389 : Real64 LoadDueToDefrost; // Additional load due to defrost
390 : Real64 DefrostEIRTempModFac; // EIR modifier for defrost (function of entering drybulb, outside wetbulb)
391 : Real64 HRCAPFTConst; // stead-state capacity fraction
392 : Real64 HRInitialCapFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
393 : Real64 HRCapTC; // Time constant used to recover from initial degradation in cooling heat recovery
394 : Real64 HREIRFTConst; // stead-state EIR fraction
395 : Real64 HRInitialEIRFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
396 : Real64 HREIRTC; // Time constant used to recover from initial degradation in cooling heat recovery
397 : Real64 CurrentEndTime; // end time of current time step
398 : Real64 SUMultiplier; // multiplier for simulating mode changes
399 : Real64 CondPower; // condenser power [W]
400 : Real64 CondCapacity; // condenser heat rejection [W]
401 : Real64 CondOutletTemp; // Outlet temperature from VRF condenser [C]
402 : Real64 TotPower; // total condenser power use [W]
403 : bool HRHeatRequestFlag; // flag indicating VRF TU could operate in heating mode
404 : bool HRCoolRequestFlag; // flag indicating VRF TU could operate in cooling mode
405 :
406 4735 : auto &vrf = state.dataHVACVarRefFlow->VRF(VRFCond);
407 :
408 : // variable initializations
409 4735 : int TUListNum = vrf.ZoneTUListPtr;
410 4735 : int NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
411 4735 : int NumTUInCoolingMode = 0; // number of terminal units actually cooling
412 4735 : int NumTUInHeatingMode = 0; // number of terminal units actually heating
413 4735 : Real64 TUCoolingLoad = 0.0; // sum of TU's cooling coil load (W)
414 4735 : Real64 TUHeatingLoad = 0.0; // sum of TU's heating coil load (W)
415 4735 : Real64 TUParasiticPower = 0.0; // total terminal unit parasitic power (W)
416 4735 : Real64 TUFanPower = 0.0; // total terminal unit fan power (W)
417 4735 : Real64 CoolingPLR = 0.0; // condenser cooling PLR
418 4735 : Real64 HeatingPLR = 0.0; // condenser heating PLR
419 4735 : Real64 CyclingRatio = 1.0; // cycling ratio of condenser's compressors
420 4735 : Real64 SumCoolInletWB = 0.0; // sum of active TU's DX cooling coil inlet air wet-bulb temperature
421 4735 : Real64 SumHeatInletDB = 0.0; // sum of active TU's DX heating coil inlet air dry-bulb temperature
422 4735 : Real64 SumHeatInletWB = 0.0; // sum of active TU's DX heating coil inlet air wet-bulb temperature
423 4735 : Real64 TotalCondCoolingCapacity = 0.0; // total available condenser cooling capacity (W)
424 4735 : Real64 TotalCondHeatingCapacity = 0.0; // total available condenser heating capacity (W)
425 4735 : Real64 TotalTUCoolingCapacity = 0.0; // sum of TU's cooling capacity including piping losses (W)
426 4735 : Real64 TotalTUHeatingCapacity = 0.0; // sum of TU's heating capacity including piping losses (W)
427 :
428 4735 : vrf.ElecCoolingPower = 0.0;
429 4735 : vrf.ElecHeatingPower = 0.0;
430 4735 : vrf.CrankCaseHeaterPower = 0.0;
431 4735 : vrf.EvapCondPumpElecPower = 0.0;
432 4735 : vrf.EvapWaterConsumpRate = 0.0;
433 4735 : vrf.DefrostPower = 0.0;
434 4735 : vrf.OperatingCoolingCOP = 0.0;
435 4735 : vrf.OperatingHeatingCOP = 0.0;
436 4735 : vrf.OperatingCOP = 0.0;
437 4735 : vrf.SCHE = 0.0;
438 4735 : vrf.BasinHeaterPower = 0.0;
439 4735 : vrf.VRFHeatRec = 0.0;
440 :
441 : // set condenser entering air conditions
442 4735 : if (vrf.CondenserNodeNum != 0) {
443 4719 : OutdoorDryBulb = state.dataLoopNodes->Node(vrf.CondenserNodeNum).Temp;
444 4719 : if (vrf.CondenserType != DataHeatBalance::RefrigCondenserType::Water) {
445 4714 : OutdoorHumRat = state.dataLoopNodes->Node(vrf.CondenserNodeNum).HumRat;
446 4714 : OutdoorPressure = state.dataLoopNodes->Node(vrf.CondenserNodeNum).Press;
447 4714 : OutdoorWetBulb = state.dataLoopNodes->Node(vrf.CondenserNodeNum).OutAirWetBulb;
448 : } else {
449 5 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
450 5 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
451 5 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
452 : }
453 : } else {
454 16 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
455 16 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
456 16 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
457 16 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
458 : }
459 :
460 4735 : if (vrf.CondenserType == DataHeatBalance::RefrigCondenserType::Air) {
461 4730 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
462 5 : } else if (vrf.CondenserType == DataHeatBalance::RefrigCondenserType::Evap) {
463 0 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
464 0 : CondAirMassFlow = RhoAir * vrf.EvapCondAirVolFlowRate;
465 : // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
466 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - vrf.EvapCondEffectiveness);
467 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
468 5 : } else if (vrf.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
469 5 : CondInletTemp = OutdoorDryBulb; // node inlet temp from above
470 5 : OutdoorWetBulb = CondInletTemp; // for watercooled
471 5 : CondWaterMassFlow = vrf.WaterCondenserDesignMassFlow;
472 : } else {
473 0 : assert(false);
474 : }
475 4735 : vrf.CondenserInletTemp = CondInletTemp;
476 :
477 : // sum loads on TU coils
478 9534 : for (NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
479 4799 : TUCoolingLoad += state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU);
480 4799 : TUHeatingLoad += state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU);
481 : }
482 :
483 4735 : vrf.TUCoolingLoad = TUCoolingLoad;
484 4735 : vrf.TUHeatingLoad = TUHeatingLoad;
485 :
486 : // no need to do anything else if the terminal units are off
487 4735 : if (TUCoolingLoad == 0.0 && TUHeatingLoad == 0.0) {
488 90 : vrf.SUMultiplier = 0.0;
489 90 : vrf.VRFCondPLR = 0.0;
490 90 : vrf.VRFCondRTF = 0.0;
491 90 : vrf.VRFCondCyclingRatio = 0.0;
492 90 : vrf.QCondenser = 0.0;
493 90 : vrf.TotalCoolingCapacity = 0.0;
494 90 : vrf.TotalHeatingCapacity = 0.0;
495 90 : vrf.OperatingMode = 0.0;
496 90 : vrf.HRHeatingActive = false;
497 90 : vrf.HRCoolingActive = false;
498 90 : state.dataHVACVarRefFlow->CurrentEndTimeLast = double((state.dataGlobal->DayOfSim - 1) * 24) + state.dataGlobal->CurrentTime -
499 90 : state.dataGlobal->TimeStepZone + state.dataHVACGlobal->SysTimeElapsed;
500 90 : if (vrf.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
501 3 : state.dataHVACVarRefFlow->CondenserWaterMassFlowRate = 0.0;
502 6 : SetComponentFlowRate(
503 3 : state, state.dataHVACVarRefFlow->CondenserWaterMassFlowRate, vrf.CondenserNodeNum, vrf.CondenserOutletNodeNum, vrf.SourcePlantLoc);
504 3 : vrf.WaterCondenserMassFlow = state.dataHVACVarRefFlow->CondenserWaterMassFlowRate;
505 3 : vrf.CondenserSideOutletTemp = CondInletTemp;
506 : }
507 90 : return;
508 : }
509 :
510 : // switch modes if summed coil capacity shows opposite operating mode
511 : // if total TU heating exceeds total TU cooling * ( 1 + 1/COP) then system is in heating mode
512 4645 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && TUHeatingLoad > (TUCoolingLoad * (1.0 + 1.0 / vrf.CoolingCOP))) {
513 1 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
514 1 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
515 1 : vrf.ModeChange = true;
516 1 : if (!state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
517 1 : state.dataHVACVarRefFlow->LastModeHeating(VRFCond) = true;
518 : // reset heat recovery startup timer
519 1 : vrf.HRTimer = 0.0;
520 1 : vrf.HRHeatingActive = false;
521 1 : vrf.HRCoolingActive = false;
522 : }
523 4644 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && (TUCoolingLoad * (1.0 + 1.0 / vrf.CoolingCOP)) > TUHeatingLoad) {
524 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
525 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
526 0 : vrf.ModeChange = true;
527 0 : if (!state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
528 0 : state.dataHVACVarRefFlow->LastModeCooling(VRFCond) = true;
529 : // reset heat recovery startup timer
530 0 : vrf.HRTimer = 0.0;
531 0 : vrf.HRHeatingActive = false;
532 0 : vrf.HRCoolingActive = false;
533 : }
534 4650 : } else if (TUCoolingLoad > 0.0 && TUHeatingLoad > 0.0 &&
535 6 : ((state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) ||
536 6 : (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && state.dataHVACVarRefFlow->LastModeCooling(VRFCond)))) {
537 0 : vrf.ModeChange = true;
538 : // reset heat recovery startup timer
539 0 : vrf.HRTimer = 0.0;
540 0 : vrf.HRHeatingActive = false;
541 0 : vrf.HRCoolingActive = false;
542 : }
543 :
544 : // loop through TU's and calculate average inlet conditions for active coils
545 9342 : for (NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
546 4697 : int TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
547 4697 : int CoolCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
548 4697 : int HeatCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex;
549 4697 : TUParasiticPower +=
550 4697 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ParasiticCoolElecPower + state.dataHVACVarRefFlow->VRFTU(TUIndex).ParasiticHeatElecPower;
551 4697 : TUFanPower += state.dataHVACVarRefFlow->VRFTU(TUIndex).FanPower;
552 :
553 4697 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) > 0.0) {
554 2335 : SumCoolInletWB += state.dataDXCoils->DXCoilCoolInletAirWBTemp(CoolCoilIndex) *
555 2335 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) / TUCoolingLoad;
556 2335 : ++NumTUInCoolingMode;
557 : }
558 4697 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) > 0.0) {
559 2362 : SumHeatInletDB += state.dataDXCoils->DXCoilHeatInletAirDBTemp(HeatCoilIndex) *
560 2362 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) / TUHeatingLoad;
561 2362 : SumHeatInletWB += state.dataDXCoils->DXCoilHeatInletAirWBTemp(HeatCoilIndex) *
562 2362 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) / TUHeatingLoad;
563 2362 : ++NumTUInHeatingMode;
564 : }
565 : }
566 :
567 4645 : bool CoolingCoilAvailableFlag = any(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).CoolingCoilAvailable);
568 4645 : bool HeatingCoilAvailableFlag = any(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HeatingCoilAvailable);
569 :
570 : // calculate capacities and energy use
571 4645 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && CoolingCoilAvailableFlag) {
572 2309 : InletAirWetBulbC = SumCoolInletWB;
573 2309 : TotCoolCapTempModFac = CurveValue(state, vrf.CoolCapFT, InletAirWetBulbC, CondInletTemp);
574 2309 : TotCoolEIRTempModFac = CurveValue(state, vrf.CoolEIRFT, InletAirWetBulbC, CondInletTemp);
575 :
576 : // recalculate cooling Cap and EIR curve output if using boundary curve along with dual Cap and EIR curves.
577 2309 : if (vrf.CoolBoundaryCurvePtr > 0) {
578 2306 : CoolOABoundary = CurveValue(state, vrf.CoolBoundaryCurvePtr, InletAirWetBulbC);
579 2306 : if (OutdoorDryBulb > CoolOABoundary) {
580 2303 : if (vrf.CoolCapFTHi > 0) TotCoolCapTempModFac = CurveValue(state, vrf.CoolCapFTHi, InletAirWetBulbC, CondInletTemp);
581 : }
582 : }
583 2309 : if (vrf.EIRCoolBoundaryCurvePtr > 0) {
584 2306 : CoolOABoundary = CurveValue(state, vrf.EIRCoolBoundaryCurvePtr, InletAirWetBulbC);
585 2306 : if (OutdoorDryBulb > CoolOABoundary) {
586 2303 : if (vrf.CoolEIRFTHi > 0) TotCoolEIRTempModFac = CurveValue(state, vrf.CoolEIRFTHi, InletAirWetBulbC, CondInletTemp);
587 : }
588 : }
589 :
590 : // Warn user if curve output goes negative
591 2309 : if (TotCoolCapTempModFac < 0.0) {
592 0 : if (!state.dataGlobal->WarmupFlag && NumTUInCoolingMode > 0) {
593 0 : if (vrf.CoolCapFTErrorIndex == 0) {
594 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
595 0 : ShowContinueError(
596 : state,
597 0 : format(" Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCoolCapTempModFac));
598 0 : ShowContinueError(state,
599 0 : format(" Negative value occurs using an outdoor air temperature of {:.1T} C and an average indoor air "
600 : "wet-bulb temperature of {:.1T} C.",
601 : CondInletTemp,
602 : InletAirWetBulbC));
603 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
604 : }
605 0 : ShowRecurringWarningErrorAtEnd(
606 : state,
607 0 : format("{} \"{}\": Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
608 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
609 0 : vrf.Name),
610 0 : vrf.CoolCapFTErrorIndex,
611 : TotCoolCapTempModFac,
612 : TotCoolCapTempModFac);
613 0 : TotCoolCapTempModFac = 0.0;
614 : }
615 : }
616 :
617 : // Warn user if curve output goes negative
618 2309 : if (TotCoolEIRTempModFac < 0.0) {
619 0 : if (!state.dataGlobal->WarmupFlag && NumTUInCoolingMode > 0) {
620 0 : if (vrf.EIRFTempCoolErrorIndex == 0) {
621 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
622 0 : ShowContinueError(state,
623 0 : format(" Cooling Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).",
624 : TotCoolEIRTempModFac));
625 0 : ShowContinueError(state,
626 0 : format(" Negative value occurs using an outdoor air temperature of {:.1T} C and an average indoor air "
627 : "wet-bulb temperature of {:.1T} C.",
628 : CondInletTemp,
629 : InletAirWetBulbC));
630 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
631 : }
632 0 : ShowRecurringWarningErrorAtEnd(
633 : state,
634 0 : format("{} \"{}\": Cooling Energy Input Ratio Modifier curve (function of temperature) output is negative warning continues...",
635 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
636 0 : vrf.Name),
637 0 : vrf.EIRFTempCoolErrorIndex,
638 : TotCoolEIRTempModFac,
639 : TotCoolEIRTempModFac);
640 0 : TotCoolEIRTempModFac = 0.0;
641 : }
642 : }
643 :
644 2309 : TotalCondCoolingCapacity = vrf.CoolingCapacity * state.dataHVACVarRefFlow->CoolCombinationRatio(VRFCond) * TotCoolCapTempModFac;
645 2309 : TotalTUCoolingCapacity = TotalCondCoolingCapacity * vrf.PipingCorrectionCooling;
646 :
647 2309 : if (TotalCondCoolingCapacity > 0.0) {
648 2309 : CoolingPLR = (TUCoolingLoad / vrf.PipingCorrectionCooling) / TotalCondCoolingCapacity;
649 : } else {
650 0 : CoolingPLR = 0.0;
651 : }
652 :
653 : // Warn user if curve output goes negative
654 2309 : if (TotCoolCapTempModFac < 0.0) {
655 0 : if (!state.dataGlobal->WarmupFlag && NumTUInCoolingMode > 0) {
656 0 : if (vrf.CoolCapFTErrorIndex == 0) {
657 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
658 0 : ShowContinueError(
659 : state,
660 0 : format(" Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCoolCapTempModFac));
661 0 : ShowContinueError(state,
662 0 : format(" Negative value occurs using an outdoor air temperature of {:.1T} C and an average indoor air "
663 : "wet-bulb temperature of {:.1T} C.",
664 : CondInletTemp,
665 : InletAirWetBulbC));
666 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
667 : }
668 0 : ShowRecurringWarningErrorAtEnd(
669 : state,
670 0 : format("{} \"{}\": Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
671 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
672 0 : vrf.Name),
673 0 : vrf.CoolCapFTErrorIndex,
674 : TotCoolCapTempModFac,
675 : TotCoolCapTempModFac);
676 0 : TotCoolCapTempModFac = 0.0;
677 : }
678 : }
679 : // Warn user if curve output goes negative
680 2309 : if (TotCoolEIRTempModFac < 0.0) {
681 0 : if (!state.dataGlobal->WarmupFlag && NumTUInCoolingMode > 0) {
682 0 : if (vrf.EIRFTempCoolErrorIndex == 0) {
683 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
684 0 : ShowContinueError(state,
685 0 : format(" Cooling Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).",
686 : TotCoolEIRTempModFac));
687 0 : ShowContinueError(state,
688 0 : format(" Negative value occurs using an outdoor air temperature of {:.1T} C and an average indoor air "
689 : "wet-bulb temperature of {:.1T} C.",
690 : CondInletTemp,
691 : InletAirWetBulbC));
692 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
693 : }
694 0 : ShowRecurringWarningErrorAtEnd(
695 : state,
696 0 : format("{} \"{}\": Cooling Energy Input Ratio Modifier curve (function of temperature) output is negative warning continues...",
697 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
698 0 : vrf.Name),
699 0 : vrf.EIRFTempCoolErrorIndex,
700 : TotCoolEIRTempModFac,
701 : TotCoolEIRTempModFac);
702 0 : TotCoolEIRTempModFac = 0.0;
703 : }
704 : }
705 :
706 2336 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && HeatingCoilAvailableFlag) {
707 2336 : InletAirDryBulbC = SumHeatInletDB;
708 2336 : InletAirWetBulbC = SumHeatInletWB;
709 2336 : switch (vrf.HeatingPerformanceOATType) {
710 0 : case HVAC::OATType::DryBulb: {
711 0 : TotHeatCapTempModFac = CurveValue(state, vrf.HeatCapFT, InletAirDryBulbC, CondInletTemp);
712 0 : TotHeatEIRTempModFac = CurveValue(state, vrf.HeatEIRFT, InletAirDryBulbC, CondInletTemp);
713 0 : } break;
714 2326 : case HVAC::OATType::WetBulb: {
715 2326 : TotHeatCapTempModFac = CurveValue(state, vrf.HeatCapFT, InletAirDryBulbC, OutdoorWetBulb);
716 2326 : TotHeatEIRTempModFac = CurveValue(state, vrf.HeatEIRFT, InletAirDryBulbC, OutdoorWetBulb);
717 2326 : } break;
718 10 : default: {
719 10 : TotHeatCapTempModFac = 1.0;
720 10 : TotHeatEIRTempModFac = 1.0;
721 10 : } break;
722 : }
723 : // recalculate heating Cap and EIR curve output if using boundary curve along with dual Cap and EIR curves.
724 2336 : if (vrf.HeatBoundaryCurvePtr > 0) {
725 2326 : HeatOABoundary = CurveValue(state, vrf.HeatBoundaryCurvePtr, InletAirDryBulbC);
726 2326 : switch (vrf.HeatingPerformanceOATType) {
727 0 : case HVAC::OATType::DryBulb: {
728 0 : if (OutdoorDryBulb > HeatOABoundary) {
729 0 : if (vrf.HeatCapFTHi > 0) TotHeatCapTempModFac = CurveValue(state, vrf.HeatCapFTHi, InletAirDryBulbC, CondInletTemp);
730 : }
731 0 : } break;
732 2326 : case HVAC::OATType::WetBulb: {
733 2326 : if (OutdoorWetBulb > HeatOABoundary) {
734 2323 : if (vrf.HeatCapFTHi > 0) TotHeatCapTempModFac = CurveValue(state, vrf.HeatCapFTHi, InletAirDryBulbC, OutdoorWetBulb);
735 : }
736 2326 : } break;
737 0 : default: {
738 0 : TotHeatCapTempModFac = 1.0;
739 0 : } break;
740 : }
741 : }
742 2336 : if (vrf.EIRHeatBoundaryCurvePtr > 0) {
743 2326 : HeatOABoundary = CurveValue(state, vrf.EIRHeatBoundaryCurvePtr, InletAirDryBulbC);
744 2326 : switch (vrf.HeatingPerformanceOATType) {
745 0 : case HVAC::OATType::DryBulb: {
746 0 : if (OutdoorDryBulb > HeatOABoundary) {
747 0 : if (vrf.HeatEIRFTHi > 0) TotHeatEIRTempModFac = CurveValue(state, vrf.HeatEIRFTHi, InletAirDryBulbC, CondInletTemp);
748 : }
749 0 : } break;
750 2326 : case HVAC::OATType::WetBulb: {
751 2326 : if (OutdoorWetBulb > HeatOABoundary) {
752 2323 : if (vrf.HeatEIRFTHi > 0) TotHeatEIRTempModFac = CurveValue(state, vrf.HeatEIRFTHi, InletAirDryBulbC, OutdoorWetBulb);
753 : }
754 2326 : } break;
755 0 : default: {
756 0 : TotHeatEIRTempModFac = 1.0;
757 0 : } break;
758 : }
759 : }
760 :
761 : // Warn user if curve output goes negative
762 2336 : if (TotHeatCapTempModFac < 0.0) {
763 0 : if (!state.dataGlobal->WarmupFlag && NumTUInHeatingMode > 0) {
764 0 : if (vrf.HeatCapFTErrorIndex == 0) {
765 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
766 0 : ShowContinueError(
767 : state,
768 0 : format(" Heating Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotHeatCapTempModFac));
769 :
770 0 : switch (vrf.HeatingPerformanceOATType) {
771 0 : case HVAC::OATType::DryBulb: {
772 0 : ShowContinueError(state,
773 0 : format(" Negative value occurs using an outdoor air temperature of {:.1T} C and an average indoor air "
774 : "dry-bulb temperature of {:.1T} C.",
775 : CondInletTemp,
776 : InletAirDryBulbC));
777 0 : } break;
778 0 : case HVAC::OATType::WetBulb: {
779 0 : ShowContinueError(state,
780 0 : format(" Negative value occurs using an outdoor air wet-bulb temperature of {:.1T} C and an average "
781 : "indoor air wet-bulb temperature of {:.1T} C.",
782 : OutdoorWetBulb,
783 : InletAirWetBulbC));
784 0 : } break;
785 0 : default:
786 : // should never get here
787 0 : break;
788 : }
789 :
790 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
791 : }
792 0 : ShowRecurringWarningErrorAtEnd(
793 : state,
794 0 : format("{} \"{}\": Heating Capacity Ratio Modifier curve (function of temperature) output is negative warning continues...",
795 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
796 0 : vrf.Name),
797 0 : vrf.HeatCapFTErrorIndex,
798 : TotHeatCapTempModFac,
799 : TotHeatCapTempModFac);
800 0 : TotHeatCapTempModFac = 0.0;
801 : }
802 : }
803 : // Warn user if curve output goes negative
804 2336 : if (TotHeatEIRTempModFac < 0.0) {
805 0 : if (!state.dataGlobal->WarmupFlag && NumTUInHeatingMode > 0) {
806 0 : if (vrf.EIRFTempHeatErrorIndex == 0) {
807 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
808 0 : ShowContinueError(state,
809 0 : format(" Heating Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).",
810 : TotHeatEIRTempModFac));
811 0 : switch (vrf.HeatingPerformanceOATType) {
812 0 : case HVAC::OATType::DryBulb: {
813 0 : ShowContinueError(state,
814 0 : format(" Negative value occurs using an outdoor air dry-bulb temperature of {:.1T} C and an "
815 : "average indoor air dry-bulb temperature of {:.1T} C.",
816 : CondInletTemp,
817 : InletAirDryBulbC));
818 0 : } break;
819 0 : case HVAC::OATType::WetBulb: {
820 0 : ShowContinueError(state,
821 0 : format(" Negative value occurs using an outdoor air wet-bulb temperature of {:.1T} C and an "
822 : "average indoor air wet-bulb temperature of {:.1T} C.",
823 : OutdoorWetBulb,
824 : InletAirWetBulbC));
825 0 : } break;
826 0 : default:
827 0 : break;
828 : }
829 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
830 : }
831 0 : ShowRecurringWarningErrorAtEnd(
832 : state,
833 0 : format("{} \"{}\": Heating Energy Input Ratio Modifier curve (function of temperature) output is negative warning continues...",
834 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
835 0 : vrf.Name),
836 0 : vrf.EIRFTempHeatErrorIndex,
837 : TotHeatEIRTempModFac,
838 : TotHeatEIRTempModFac);
839 0 : TotHeatEIRTempModFac = 0.0;
840 : }
841 : }
842 :
843 : // Initializing defrost adjustment factors
844 2336 : LoadDueToDefrost = 0.0;
845 2336 : HeatingCapacityMultiplier = 1.0;
846 2336 : FractionalDefrostTime = 0.0;
847 2336 : InputPowerMultiplier = 1.0;
848 :
849 : // Check outdoor temperature to determine of defrost is active
850 2336 : if (OutdoorDryBulb <= vrf.MaxOATDefrost && vrf.CondenserType != DataHeatBalance::RefrigCondenserType::Water) {
851 :
852 : // Calculating adjustment factors for defrost
853 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
854 3 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
855 3 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
856 :
857 : // Calculate defrost adjustment factors depending on defrost control type
858 3 : if (vrf.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
859 3 : FractionalDefrostTime = vrf.DefrostFraction;
860 3 : if (FractionalDefrostTime > 0.0) {
861 2 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
862 2 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
863 : }
864 : } else { // else defrost control is on-demand
865 0 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
866 0 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
867 0 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
868 : }
869 :
870 3 : if (FractionalDefrostTime > 0.0) {
871 : // Calculate defrost adjustment factors depending on defrost control strategy
872 2 : if (vrf.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
873 1 : LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (vrf.HeatingCapacity / 1.01667);
874 1 : DefrostEIRTempModFac = CurveValue(state, vrf.DefrostEIRPtr, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
875 :
876 : // Warn user if curve output goes negative
877 1 : if (DefrostEIRTempModFac < 0.0) {
878 0 : if (!state.dataGlobal->WarmupFlag) {
879 0 : if (vrf.DefrostHeatErrorIndex == 0) {
880 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
881 0 : ShowContinueError(
882 : state,
883 0 : format(" Defrost Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).",
884 : DefrostEIRTempModFac));
885 0 : ShowContinueError(state,
886 0 : format(" Negative value occurs using an outdoor air dry-bulb temperature of {:.1T} C and an "
887 : "average indoor air wet-bulb temperature of {:.1T} C.",
888 : OutdoorDryBulb,
889 : InletAirWetBulbC));
890 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
891 : }
892 0 : ShowRecurringWarningErrorAtEnd(state,
893 0 : format("{} \"{}\": Defrost Energy Input Ratio Modifier curve (function of temperature) "
894 : "output is negative warning continues...",
895 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
896 0 : vrf.Name),
897 0 : vrf.DefrostHeatErrorIndex,
898 : DefrostEIRTempModFac,
899 : DefrostEIRTempModFac);
900 0 : DefrostEIRTempModFac = 0.0;
901 : }
902 : }
903 :
904 1 : vrf.DefrostPower = DefrostEIRTempModFac * (vrf.HeatingCapacity / 1.01667) * FractionalDefrostTime;
905 :
906 : } else { // Defrost strategy is resistive
907 1 : vrf.DefrostPower = vrf.DefrostCapacity * FractionalDefrostTime;
908 : }
909 : }
910 : }
911 :
912 2336 : TotalCondHeatingCapacity =
913 2336 : vrf.HeatingCapacity * state.dataHVACVarRefFlow->HeatCombinationRatio(VRFCond) * TotHeatCapTempModFac * HeatingCapacityMultiplier;
914 2336 : TotalTUHeatingCapacity = TotalCondHeatingCapacity * vrf.PipingCorrectionHeating;
915 2336 : if (TotalCondHeatingCapacity > 0.0) {
916 2336 : HeatingPLR = (TUHeatingLoad / vrf.PipingCorrectionHeating) / TotalCondHeatingCapacity;
917 2336 : HeatingPLR += (LoadDueToDefrost * HeatingPLR) / TotalCondHeatingCapacity;
918 : } else {
919 0 : HeatingPLR = 0.0;
920 : }
921 : }
922 :
923 4645 : vrf.VRFCondPLR = max(CoolingPLR, HeatingPLR);
924 4645 : Real64 tmpVRFCondPLR = 0.0;
925 4645 : if (CoolingPLR > 0.0 || HeatingPLR > 0.0) tmpVRFCondPLR = max(vrf.MinPLR, vrf.VRFCondPLR);
926 :
927 4645 : HRHeatRequestFlag = any(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HRHeatRequest);
928 4645 : HRCoolRequestFlag = any(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HRCoolRequest);
929 4645 : HREIRFTConst = 1.0;
930 4645 : Real64 HREIRAdjustment = 1.0;
931 :
932 4645 : if (!state.dataGlobal->DoingSizing && !state.dataGlobal->WarmupFlag) {
933 1175 : if (HRHeatRequestFlag && HRCoolRequestFlag) {
934 : // determine operating mode change
935 7 : if (!vrf.HRCoolingActive && !vrf.HRHeatingActive) {
936 3 : vrf.ModeChange = true;
937 3 : vrf.HRTimer = 0.0;
938 : }
939 7 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
940 0 : if (vrf.HRHeatingActive && !vrf.HRCoolingActive) {
941 0 : vrf.HRModeChange = true;
942 : }
943 0 : vrf.HRCoolingActive = true;
944 0 : vrf.HRHeatingActive = false;
945 0 : int HRCAPFT = vrf.HRCAPFTCool; // Index to cool capacity as a function of temperature\PLR curve for heat recovery
946 0 : if (HRCAPFT > 0) {
947 : // VRF(VRFCond)%HRCAPFTCoolConst = 0.9d0 ! initialized to 0.9
948 0 : if (state.dataCurveManager->curves(vrf.HRCAPFTCool)->numDims == 2) { // Curve type for HRCAPFTCool
949 0 : vrf.HRCAPFTCoolConst = CurveValue(state, HRCAPFT, InletAirWetBulbC, CondInletTemp);
950 : } else {
951 0 : vrf.HRCAPFTCoolConst = CurveValue(state, HRCAPFT, tmpVRFCondPLR);
952 : }
953 : }
954 0 : HRCAPFTConst = vrf.HRCAPFTCoolConst;
955 0 : HRInitialCapFrac = vrf.HRInitialCoolCapFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
956 0 : HRCapTC = vrf.HRCoolCapTC; // Time constant used to recover from initial degradation in cooling heat recovery
957 :
958 0 : int HREIRFT = vrf.HREIRFTCool; // Index to cool EIR as a function of temperature curve for heat recovery
959 0 : if (HREIRFT > 0) {
960 : // VRF(VRFCond)%HREIRFTCoolConst = 1.1d0 ! initialized to 1.1
961 0 : if (state.dataCurveManager->curves(vrf.HREIRFTCool)->numDims == 2) { // Curve type for HREIRFTCool
962 0 : vrf.HREIRFTCoolConst = CurveValue(state, HREIRFT, InletAirWetBulbC, CondInletTemp);
963 : } else {
964 0 : vrf.HREIRFTCoolConst = CurveValue(state, HREIRFT, tmpVRFCondPLR);
965 : }
966 : }
967 0 : HREIRFTConst = vrf.HREIRFTCoolConst;
968 0 : HRInitialEIRFrac = vrf.HRInitialCoolEIRFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
969 0 : HREIRTC = vrf.HRCoolEIRTC; // Time constant used to recover from initial degradation in cooling heat recovery
970 7 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
971 7 : if (!vrf.HRHeatingActive && vrf.HRCoolingActive) {
972 0 : vrf.HRModeChange = true;
973 : }
974 7 : vrf.HRCoolingActive = false;
975 7 : vrf.HRHeatingActive = true;
976 7 : int HRCAPFT = vrf.HRCAPFTHeat; // Index to heat capacity as a function of temperature\PLR curve for heat recovery
977 7 : if (HRCAPFT > 0) {
978 : // VRF(VRFCond)%HRCAPFTHeatConst = 1.1d0 ! initialized to 1.1
979 1 : if (state.dataCurveManager->curves(vrf.HRCAPFTHeat)->numDims == 2) { // Curve type for HRCAPFTCool
980 0 : switch (vrf.HeatingPerformanceOATType) {
981 0 : case HVAC::OATType::DryBulb: {
982 0 : vrf.HRCAPFTHeatConst = CurveValue(state, HRCAPFT, InletAirDryBulbC, CondInletTemp);
983 0 : } break;
984 0 : case HVAC::OATType::WetBulb: {
985 0 : vrf.HRCAPFTHeatConst = CurveValue(state, HRCAPFT, InletAirDryBulbC, OutdoorWetBulb);
986 0 : } break;
987 0 : default: {
988 0 : vrf.HRCAPFTHeatConst = 1.0;
989 0 : } break;
990 : }
991 : } else {
992 1 : vrf.HRCAPFTHeatConst = CurveValue(state, HRCAPFT, tmpVRFCondPLR);
993 : }
994 : }
995 7 : HRCAPFTConst = vrf.HRCAPFTHeatConst;
996 7 : HRInitialCapFrac = vrf.HRInitialHeatCapFrac; // Fractional heating degradation at the start of heat recovery from cooling mode
997 7 : HRCapTC = vrf.HRHeatCapTC; // Time constant used to recover from initial degradation in heating heat recovery
998 :
999 7 : int HREIRFT = vrf.HREIRFTHeat; // Index to cool EIR as a function of temperature curve for heat recovery
1000 7 : if (HREIRFT > 0) {
1001 : // VRF(VRFCond)%HREIRFTCoolConst = 1.1d0 ! initialized to 1.1
1002 1 : if (state.dataCurveManager->curves(vrf.HREIRFTHeat)->numDims == 2) { // Curve type for HREIRFTHeat
1003 0 : switch (vrf.HeatingPerformanceOATType) {
1004 0 : case HVAC::OATType::DryBulb: {
1005 0 : vrf.HREIRFTHeatConst = CurveValue(state, HREIRFT, InletAirDryBulbC, CondInletTemp);
1006 0 : } break;
1007 0 : case HVAC::OATType::WetBulb: {
1008 0 : vrf.HREIRFTHeatConst = CurveValue(state, HREIRFT, InletAirDryBulbC, OutdoorWetBulb);
1009 0 : } break;
1010 0 : default: {
1011 0 : vrf.HREIRFTHeatConst = 1.0;
1012 0 : } break;
1013 : }
1014 : } else {
1015 1 : vrf.HREIRFTHeatConst = CurveValue(state, HREIRFT, tmpVRFCondPLR);
1016 : }
1017 : }
1018 7 : HREIRFTConst = vrf.HREIRFTHeatConst;
1019 7 : HRInitialEIRFrac = vrf.HRInitialHeatEIRFrac; // Fractional heating degradation at the start of heat recovery from heating mode
1020 7 : HREIRTC = vrf.HRHeatEIRTC; // Time constant used to recover from initial degradation in heating heat recovery
1021 : } else {
1022 : // zone thermostats satisfied, condenser is off. Set values anyway
1023 0 : HRCAPFTConst = 1.0;
1024 0 : HRInitialCapFrac = 1.0;
1025 0 : HRCapTC = 1.0;
1026 0 : HREIRFTConst = 1.0;
1027 0 : HRInitialEIRFrac = 1.0;
1028 0 : HREIRTC = 1.0;
1029 0 : if (vrf.HRHeatingActive || vrf.HRCoolingActive) {
1030 0 : vrf.HRModeChange = true;
1031 : }
1032 0 : vrf.HRCoolingActive = false;
1033 0 : vrf.HRHeatingActive = false;
1034 : }
1035 :
1036 7 : } else { // IF(HRHeatRequestFlag .AND. HRCoolRequestFlag)THEN -- Heat recovery turned off
1037 1168 : HRCAPFTConst = 1.0;
1038 1168 : HRInitialCapFrac = 1.0;
1039 1168 : HRCapTC = 0.0;
1040 1168 : HREIRFTConst = 1.0;
1041 1168 : HRInitialEIRFrac = 1.0;
1042 1168 : HREIRTC = 0.0;
1043 1168 : vrf.HRModeChange = false;
1044 1168 : vrf.HRCoolingActive = false;
1045 1168 : vrf.HRHeatingActive = false;
1046 1168 : vrf.HRTimer = 0.0;
1047 : }
1048 :
1049 : // Calculate the capacity modification factor (SUMultiplier) for the HR mode transition period
1050 1175 : CurrentEndTime = double((state.dataGlobal->DayOfSim - 1) * 24) + state.dataGlobal->CurrentTime - state.dataGlobal->TimeStepZone +
1051 1175 : state.dataHVACGlobal->SysTimeElapsed;
1052 :
1053 1175 : if (vrf.ModeChange || vrf.HRModeChange) {
1054 7 : if (vrf.HRCoolingActive && vrf.HRTimer == 0.0) {
1055 0 : vrf.HRTimer = state.dataHVACVarRefFlow->CurrentEndTimeLast;
1056 7 : } else if (vrf.HRHeatingActive && vrf.HRTimer == 0.0) {
1057 3 : vrf.HRTimer = state.dataHVACVarRefFlow->CurrentEndTimeLast;
1058 4 : } else if (!vrf.HRCoolingActive && !vrf.HRHeatingActive) {
1059 0 : vrf.HRTimer = 0.0;
1060 : }
1061 : }
1062 :
1063 1175 : vrf.HRTime = max(0.0, CurrentEndTime - vrf.HRTimer);
1064 1175 : if (vrf.HRTime < (HRCapTC * 5.0)) {
1065 6 : if (HRCapTC > 0.0) {
1066 6 : SUMultiplier = min(1.0, 1.0 - std::exp(-vrf.HRTime / HRCapTC));
1067 : } else {
1068 0 : SUMultiplier = 1.0;
1069 : }
1070 : } else {
1071 1169 : SUMultiplier = 1.0;
1072 1169 : vrf.ModeChange = false;
1073 1169 : vrf.HRModeChange = false;
1074 : }
1075 1175 : vrf.SUMultiplier = SUMultiplier;
1076 :
1077 1175 : state.dataHVACVarRefFlow->CurrentEndTimeLast = CurrentEndTime;
1078 :
1079 1175 : if (vrf.HeatRecoveryUsed && vrf.HRCoolingActive) {
1080 0 : TotalCondCoolingCapacity *= HRCAPFTConst;
1081 0 : TotalCondCoolingCapacity =
1082 0 : HRInitialCapFrac * TotalCondCoolingCapacity + (1.0 - HRInitialCapFrac) * TotalCondCoolingCapacity * SUMultiplier;
1083 0 : TotalTUCoolingCapacity = TotalCondCoolingCapacity * vrf.PipingCorrectionCooling;
1084 0 : if (TotalCondCoolingCapacity > 0.0) {
1085 0 : CoolingPLR = min(1.0, (TUCoolingLoad / vrf.PipingCorrectionCooling) / TotalCondCoolingCapacity);
1086 : } else {
1087 0 : CoolingPLR = 0.0;
1088 : }
1089 0 : HREIRAdjustment = HRInitialEIRFrac + (HREIRFTConst - HRInitialEIRFrac) * SUMultiplier;
1090 0 : vrf.VRFHeatRec = TUHeatingLoad;
1091 1175 : } else if (vrf.HeatRecoveryUsed && vrf.HRHeatingActive) {
1092 7 : TotalCondHeatingCapacity *= HRCAPFTConst;
1093 7 : TotalCondHeatingCapacity =
1094 7 : HRInitialCapFrac * TotalCondHeatingCapacity + (1.0 - HRInitialCapFrac) * TotalCondHeatingCapacity * SUMultiplier;
1095 7 : TotalTUHeatingCapacity = TotalCondHeatingCapacity * vrf.PipingCorrectionHeating;
1096 7 : if (TotalCondHeatingCapacity > 0.0) {
1097 7 : HeatingPLR = min(1.0, (TUHeatingLoad / vrf.PipingCorrectionHeating) / TotalCondHeatingCapacity);
1098 : } else {
1099 0 : HeatingPLR = 0.0;
1100 : }
1101 7 : HREIRAdjustment = HRInitialEIRFrac + (HREIRFTConst - HRInitialEIRFrac) * SUMultiplier;
1102 7 : vrf.VRFHeatRec = TUCoolingLoad;
1103 : }
1104 1175 : vrf.VRFCondPLR = max(CoolingPLR, HeatingPLR);
1105 : }
1106 :
1107 4645 : if (vrf.MinPLR > 0.0) {
1108 4632 : CyclingRatio = min(1.0, vrf.VRFCondPLR / vrf.MinPLR);
1109 4632 : if (vrf.VRFCondPLR < vrf.MinPLR && vrf.VRFCondPLR > 0.0) {
1110 304 : vrf.VRFCondPLR = vrf.MinPLR;
1111 304 : if (CoolingPLR > 0.0) CoolingPLR = vrf.MinPLR; // also adjust local PLR variables
1112 304 : if (HeatingPLR > 0.0) HeatingPLR = vrf.MinPLR; // also adjust local PLR variables
1113 : }
1114 : }
1115 4645 : vrf.VRFCondCyclingRatio = CyclingRatio; // report variable for cycling rate
1116 4645 : vrf.TotalCoolingCapacity = TotalCondCoolingCapacity * CoolingPLR * CyclingRatio;
1117 4645 : vrf.TotalHeatingCapacity = TotalCondHeatingCapacity * HeatingPLR * CyclingRatio;
1118 :
1119 4645 : vrf.OperatingMode = 0; // report variable for heating or cooling mode
1120 4645 : EIRFPLRModFac = 1.0;
1121 4645 : VRFRTF = 0.0;
1122 : // cooling and heating is optional (only one may exist), if so then performance curve for missing coil are not required
1123 4645 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && CoolingPLR > 0.0) {
1124 2309 : vrf.OperatingMode = ModeCoolingOnly;
1125 2309 : if (CoolingPLR > 1.0) {
1126 1 : if (vrf.CoolEIRFPLR2 > 0) EIRFPLRModFac = CurveValue(state, vrf.CoolEIRFPLR2, max(vrf.MinPLR, CoolingPLR));
1127 : } else {
1128 2308 : if (vrf.CoolEIRFPLR1 > 0) EIRFPLRModFac = CurveValue(state, vrf.CoolEIRFPLR1, max(vrf.MinPLR, CoolingPLR));
1129 : }
1130 :
1131 2309 : if (EIRFPLRModFac < 0.0) {
1132 1 : if (vrf.CoolEIRFPLRErrorIndex == 0) {
1133 3 : ShowSevereMessage(state, fmt::format("{} \"{}\":", std::string(cVRFTypes(VRF_HeatPump)), vrf.Name));
1134 1 : ShowContinueError(state, format(" Cooling EIR Modifier curve (function of PLR) output is negative ({:.3T}).", EIRFPLRModFac));
1135 1 : ShowContinueError(state, format(" Negative value occurs using a cooling Part Load Ratio (PLR) of {:.2T}.", CoolingPLR));
1136 3 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
1137 : }
1138 6 : ShowRecurringWarningErrorAtEnd(
1139 : state,
1140 1 : fmt::format("{} \"{}\": Cooling EIR Modifier curve (function of PLR) output is negative warning continues...",
1141 1 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
1142 1 : vrf.Name),
1143 1 : vrf.CoolEIRFPLRErrorIndex,
1144 : EIRFPLRModFac,
1145 : EIRFPLRModFac);
1146 1 : EIRFPLRModFac = 0.0;
1147 : }
1148 :
1149 : // find part load fraction to calculate RTF
1150 2309 : if (vrf.CoolPLFFPLR > 0) {
1151 2306 : PartLoadFraction = max(0.7, CurveValue(state, vrf.CoolPLFFPLR, CyclingRatio));
1152 : } else {
1153 3 : PartLoadFraction = 1.0;
1154 : }
1155 2309 : VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));
1156 :
1157 2309 : vrf.ElecCoolingPower = (vrf.RatedCoolingPower * TotCoolCapTempModFac) * TotCoolEIRTempModFac * EIRFPLRModFac * HREIRAdjustment * VRFRTF;
1158 : }
1159 4645 : if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && HeatingPLR > 0.0) {
1160 2336 : vrf.OperatingMode = ModeHeatingOnly;
1161 2336 : if (HeatingPLR > 1.0) {
1162 0 : if (vrf.HeatEIRFPLR2 > 0) EIRFPLRModFac = CurveValue(state, vrf.HeatEIRFPLR2, max(vrf.MinPLR, HeatingPLR));
1163 : } else {
1164 2336 : if (vrf.HeatEIRFPLR1 > 0) EIRFPLRModFac = CurveValue(state, vrf.HeatEIRFPLR1, max(vrf.MinPLR, HeatingPLR));
1165 : }
1166 :
1167 2336 : if (EIRFPLRModFac < 0.0) {
1168 1 : if (vrf.HeatEIRFPLRErrorIndex == 0) {
1169 3 : ShowSevereMessage(state, fmt::format("{} \"{}\":", std::string(cVRFTypes(VRF_HeatPump)), vrf.Name));
1170 1 : ShowContinueError(state, format(" Heating EIR Modifier curve (function of PLR) output is negative ({:.3T}).", EIRFPLRModFac));
1171 1 : ShowContinueError(state, format(" Negative value occurs using a heating Part Load Ratio (PLR) of {:.2T}.", HeatingPLR));
1172 3 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
1173 : }
1174 6 : ShowRecurringWarningErrorAtEnd(
1175 : state,
1176 1 : fmt::format("{} \"{}\": Heating EIR Modifier curve (function of PLR) output is negative warning continues...",
1177 1 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
1178 1 : vrf.Name),
1179 1 : vrf.HeatEIRFPLRErrorIndex,
1180 : EIRFPLRModFac,
1181 : EIRFPLRModFac);
1182 1 : EIRFPLRModFac = 0.0;
1183 : }
1184 :
1185 : // find part load fraction to calculate RTF
1186 2336 : if (vrf.HeatPLFFPLR > 0) {
1187 2326 : PartLoadFraction = max(0.7, CurveValue(state, vrf.HeatPLFFPLR, CyclingRatio));
1188 : } else {
1189 10 : PartLoadFraction = 1.0;
1190 : }
1191 2336 : VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));
1192 :
1193 2336 : vrf.ElecHeatingPower =
1194 2336 : (vrf.RatedHeatingPower * TotHeatCapTempModFac) * TotHeatEIRTempModFac * EIRFPLRModFac * HREIRAdjustment * VRFRTF * InputPowerMultiplier;
1195 : }
1196 : // adjust defrost power based on RTF
1197 4645 : vrf.DefrostPower *= VRFRTF;
1198 4645 : vrf.VRFCondRTF = VRFRTF;
1199 :
1200 : // calculate crankcase heater power
1201 4645 : if (vrf.MaxOATCCHeater > OutdoorDryBulb) {
1202 : // calculate crankcase heater power
1203 3 : vrf.CrankCaseHeaterPower = vrf.CCHeaterPower * (1.0 - VRFRTF);
1204 3 : if (vrf.NumCompressors > 1) {
1205 3 : UpperStageCompressorRatio = (1.0 - vrf.CompressorSizeRatio) / (vrf.NumCompressors - 1);
1206 6 : for (int Stage = 1; Stage <= vrf.NumCompressors - 2; ++Stage) {
1207 3 : if (vrf.VRFCondPLR < (vrf.CompressorSizeRatio + Stage * UpperStageCompressorRatio)) {
1208 3 : vrf.CrankCaseHeaterPower += vrf.CCHeaterPower;
1209 : }
1210 : }
1211 : }
1212 : } else {
1213 4642 : vrf.CrankCaseHeaterPower = 0.0;
1214 : }
1215 :
1216 4645 : CondCapacity = max(vrf.TotalCoolingCapacity, vrf.TotalHeatingCapacity);
1217 4645 : CondPower = max(vrf.ElecCoolingPower, vrf.ElecHeatingPower);
1218 4645 : if (vrf.ElecCoolingPower > 0.0) {
1219 2308 : vrf.QCondenser = CondCapacity + CondPower - vrf.TUHeatingLoad / vrf.PipingCorrectionHeating;
1220 2337 : } else if (vrf.ElecHeatingPower > 0.0) {
1221 2335 : vrf.QCondenser = -CondCapacity + CondPower + vrf.TUCoolingLoad / vrf.PipingCorrectionCooling;
1222 : } else {
1223 2 : vrf.QCondenser = 0.0;
1224 : }
1225 :
1226 4645 : if (vrf.CondenserType == DataHeatBalance::RefrigCondenserType::Evap) {
1227 : // Calculate basin heater power
1228 0 : CalcBasinHeaterPower(state, vrf.BasinHeaterPowerFTempDiff, vrf.basinHeaterSched, vrf.BasinHeaterSetPointTemp, vrf.BasinHeaterPower);
1229 0 : vrf.BasinHeaterPower *= (1.0 - VRFRTF);
1230 :
1231 : // calculate evaporative condenser pump power and water consumption
1232 0 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && CoolingPLR > 0.0) {
1233 : //******************
1234 : // WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
1235 : // H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
1236 : // /RhoWater [kgWater/m3]
1237 : //******************
1238 0 : RhoWater = RhoH2O(OutdoorDryBulb);
1239 0 : vrf.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater * vrf.VRFCondPLR;
1240 0 : vrf.EvapCondPumpElecPower = vrf.EvapCondPumpPower * VRFRTF;
1241 : }
1242 4645 : } else if (vrf.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
1243 :
1244 2 : if (CondCapacity > 0.0) {
1245 2 : state.dataHVACVarRefFlow->CondenserWaterMassFlowRate = CondWaterMassFlow;
1246 : } else {
1247 0 : state.dataHVACVarRefFlow->CondenserWaterMassFlowRate = 0.0;
1248 : }
1249 4 : SetComponentFlowRate(
1250 2 : state, state.dataHVACVarRefFlow->CondenserWaterMassFlowRate, vrf.CondenserNodeNum, vrf.CondenserOutletNodeNum, vrf.SourcePlantLoc);
1251 :
1252 : // should be the same as above just entering this function
1253 : // VRF( VRFCond ).CondenserInletTemp = state.dataLoopNodes->Node(VRF(VRFCond).CondenserNodeNum).Temp;
1254 2 : vrf.WaterCondenserMassFlow = state.dataLoopNodes->Node(vrf.CondenserNodeNum).MassFlowRate;
1255 :
1256 2 : CpCond = state.dataPlnt->PlantLoop(vrf.SourcePlantLoc.loopNum).glycol->getSpecificHeat(state, vrf.CondenserInletTemp, RoutineName);
1257 2 : if (CondWaterMassFlow > 0.0) {
1258 2 : CondOutletTemp = vrf.QCondenser / (CondWaterMassFlow * CpCond) + CondInletTemp;
1259 : } else {
1260 0 : CondOutletTemp = CondInletTemp;
1261 : }
1262 2 : vrf.CondenserSideOutletTemp = CondOutletTemp;
1263 : }
1264 :
1265 : // calculate operating COP
1266 4645 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && CoolingPLR > 0.0) {
1267 2309 : if (vrf.ElecCoolingPower != 0.0) {
1268 : // this calc should use delivered capacity, not condenser capacity, use VRF(VRFCond)%TUCoolingLoad
1269 2308 : vrf.OperatingCoolingCOP =
1270 2308 : (vrf.TotalCoolingCapacity) / (vrf.ElecCoolingPower + vrf.CrankCaseHeaterPower + vrf.EvapCondPumpElecPower + vrf.DefrostPower);
1271 : } else {
1272 1 : vrf.OperatingCoolingCOP = 0.0;
1273 : }
1274 : }
1275 4645 : if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && HeatingPLR > 0.0) {
1276 2336 : if (vrf.ElecHeatingPower != 0.0) {
1277 : // this calc should use delivered capacity, not condenser capacity, use VRF(VRFCond)%TUHeatingLoad
1278 2335 : vrf.OperatingHeatingCOP =
1279 2335 : (vrf.TotalHeatingCapacity) / (vrf.ElecHeatingPower + vrf.CrankCaseHeaterPower + vrf.EvapCondPumpElecPower + vrf.DefrostPower);
1280 : } else {
1281 1 : vrf.OperatingHeatingCOP = 0.0;
1282 : }
1283 : }
1284 :
1285 4645 : TotPower = TUParasiticPower + TUFanPower + vrf.ElecHeatingPower + vrf.ElecCoolingPower + vrf.CrankCaseHeaterPower + vrf.EvapCondPumpElecPower +
1286 4645 : vrf.DefrostPower;
1287 4645 : if (TotPower > 0.0) {
1288 4643 : vrf.OperatingCOP = (vrf.TUCoolingLoad + vrf.TUHeatingLoad) / TotPower;
1289 4643 : vrf.SCHE = vrf.OperatingCOP * 3.412141633; // see StandardRatings::ConvFromSIToIP
1290 : }
1291 :
1292 : // limit the TU capacity when the condenser is maxed out on capacity
1293 : // I think this next line will make the max cap report variable match the coil objects, will probably change the answer though
1294 : // IF(CoolingLoad(VRFCond) .AND. NumTUInCoolingMode .GT. 0 .AND. MaxCoolingCapacity(VRFCond) == MaxCap)THEN
1295 4645 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && NumTUInCoolingMode > 0) {
1296 :
1297 : // IF TU capacity is greater than condenser capacity find maximum allowed TU capacity (i.e., conserve energy)
1298 2309 : if (TUCoolingLoad > TotalTUCoolingCapacity) {
1299 1 : LimitTUCapacity(state,
1300 : VRFCond,
1301 : NumTUInList,
1302 : TotalTUCoolingCapacity,
1303 1 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad,
1304 1 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond),
1305 : TotalTUHeatingCapacity,
1306 1 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad,
1307 1 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
1308 : }
1309 2336 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && NumTUInHeatingMode > 0) {
1310 : // IF TU capacity is greater than condenser capacity
1311 2336 : if (TUHeatingLoad > TotalTUHeatingCapacity) {
1312 0 : LimitTUCapacity(state,
1313 : VRFCond,
1314 : NumTUInList,
1315 : TotalTUHeatingCapacity,
1316 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad,
1317 0 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond),
1318 : TotalTUCoolingCapacity,
1319 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad,
1320 0 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond));
1321 : }
1322 : } else {
1323 : }
1324 : }
1325 :
1326 19 : void GetVRFInput(EnergyPlusData &state)
1327 : {
1328 :
1329 : // SUBROUTINE INFORMATION:
1330 : // AUTHOR Richard Raustad, FSEC
1331 : // DATE WRITTEN August 2015
1332 : // MODIFIED na
1333 : // RE-ENGINEERED na
1334 :
1335 : // PURPOSE OF THIS SUBROUTINE:
1336 : // Manages GetInput processing and program termination
1337 :
1338 : // METHODOLOGY EMPLOYED:
1339 : // Calls "Get" routines to read in data.
1340 :
1341 : // SUBROUTINE PARAMETER DEFINITIONS:
1342 : static constexpr std::string_view RoutineName("GetVRFInput: "); // include trailing blank space
1343 :
1344 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1345 19 : bool ErrorsFound(false); // If errors detected in input
1346 :
1347 19 : GetVRFInputData(state, ErrorsFound);
1348 :
1349 19 : if (ErrorsFound) {
1350 0 : ShowFatalError(
1351 : state,
1352 0 : format("{}Errors found in getting AirConditioner:VariableRefrigerantFlow system input. Preceding condition(s) causes termination.",
1353 : RoutineName));
1354 : }
1355 19 : }
1356 :
1357 23 : void GetVRFInputData(EnergyPlusData &state, bool &ErrorsFound)
1358 : {
1359 :
1360 : // SUBROUTINE INFORMATION:
1361 : // AUTHOR Richard Raustad, FSEC
1362 : // DATE WRITTEN August 2010
1363 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
1364 : // RE-ENGINEERED na
1365 :
1366 : // PURPOSE OF THIS SUBROUTINE:
1367 : // Obtains input data for VRF systems and stores it in data structures
1368 :
1369 : using namespace DataLoopNode;
1370 : using BranchNodeConnections::SetUpCompSets;
1371 : using BranchNodeConnections::TestCompSet;
1372 : using Curve::checkCurveIsNormalizedToOne;
1373 : using Curve::CurveValue;
1374 : using Curve::GetCurveIndex;
1375 : using DXCoils::GetDXCoilIndex;
1376 :
1377 : using DataSizing::AutoSize;
1378 : using DXCoils::GetCoilCondenserInletNode;
1379 : using DXCoils::GetCoilTypeNum;
1380 : using DXCoils::GetDXCoilCapFTCurveIndex;
1381 : using DXCoils::GetDXCoilName;
1382 : using DXCoils::RatedInletAirTempHeat;
1383 : using DXCoils::RatedInletWetBulbTemp;
1384 : using DXCoils::RatedOutdoorAirTemp;
1385 : using DXCoils::RatedOutdoorAirTempHeat;
1386 : using DXCoils::RatedOutdoorWetBulbTempHeat;
1387 : using DXCoils::SetDXCoolingCoilData;
1388 : using MixedAir::GetOAMixerNodeNumbers;
1389 : using NodeInputManager::GetOnlySingleNode;
1390 : using OutAirNodeManager::CheckOutAirNodeNumber;
1391 : using SingleDuct::GetATMixer;
1392 : using WaterManager::SetupTankDemandComponent;
1393 : using WaterManager::SetupTankSupplyComponent;
1394 :
1395 : static constexpr std::string_view RoutineName("GetVRFInput: "); // include trailing blank space
1396 : static constexpr std::string_view routineName = "GetVRFInput";
1397 :
1398 23 : std::string cCurrentModuleObject;
1399 :
1400 23 : Array1D_int OANodeNums(4); // Node numbers of OA mixer (OA, EA, RA, MA)
1401 :
1402 : // InputProcessor routines
1403 23 : int NumParams = 0; // Number of arguments
1404 23 : int NumAlphas = 0; // Number of alpha arguments
1405 23 : int NumNums = 0; // Number of real arguments
1406 : int IOStat; // Status
1407 : bool errFlag; // error flag for mining functions
1408 : bool IsNotOK; // Flag to verify name
1409 :
1410 : // Compute for allocation
1411 23 : int MaxAlphas = 0;
1412 23 : int MaxNumbers = 0;
1413 :
1414 : {
1415 : // Terminal Units
1416 :
1417 : // The number of VRF constant volume TUs (anticipating different types of TU's)
1418 23 : int NumVRFCTU = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:TerminalUnit:VariableRefrigerantFlow");
1419 23 : if (NumVRFCTU > 0) {
1420 23 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1421 : state, "ZoneHVAC:TerminalUnit:VariableRefrigerantFlow", NumParams, NumAlphas, NumNums);
1422 23 : MaxAlphas = max(MaxAlphas, NumAlphas);
1423 23 : MaxNumbers = max(MaxNumbers, NumNums);
1424 : }
1425 :
1426 23 : state.dataHVACVarRefFlow->NumVRFTU = NumVRFCTU;
1427 23 : if (state.dataHVACVarRefFlow->NumVRFTU > 0) {
1428 23 : state.dataHVACVarRefFlow->VRFTU.allocate(state.dataHVACVarRefFlow->NumVRFTU);
1429 23 : state.dataHVACVarRefFlow->CheckEquipName.dimension(state.dataHVACVarRefFlow->NumVRFTU, true);
1430 23 : state.dataHVACVarRefFlow->VRFTUNumericFields.allocate(state.dataHVACVarRefFlow->NumVRFTU);
1431 : }
1432 : }
1433 :
1434 : {
1435 : // VRF AirConditioners
1436 :
1437 46 : state.dataHVACVarRefFlow->NumVRFCond_SysCurve =
1438 23 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirConditioner:VariableRefrigerantFlow");
1439 23 : if (state.dataHVACVarRefFlow->NumVRFCond_SysCurve > 0) {
1440 16 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1441 : state, "AirConditioner:VariableRefrigerantFlow", NumParams, NumAlphas, NumNums);
1442 16 : MaxAlphas = max(MaxAlphas, NumAlphas);
1443 16 : MaxNumbers = max(MaxNumbers, NumNums);
1444 : }
1445 :
1446 46 : state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HP =
1447 23 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl");
1448 23 : if (state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HP > 0) {
1449 6 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1450 : state, "AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl", NumParams, NumAlphas, NumNums);
1451 6 : MaxAlphas = max(MaxAlphas, NumAlphas);
1452 6 : MaxNumbers = max(MaxNumbers, NumNums);
1453 : }
1454 :
1455 46 : state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HR =
1456 23 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl:HR");
1457 23 : if (state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HR > 0) {
1458 3 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1459 : state, "AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl:HR", NumParams, NumAlphas, NumNums);
1460 3 : MaxAlphas = max(MaxAlphas, NumAlphas);
1461 3 : MaxNumbers = max(MaxNumbers, NumNums);
1462 : }
1463 :
1464 23 : state.dataHVACVarRefFlow->NumVRFCond = state.dataHVACVarRefFlow->NumVRFCond_SysCurve + state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HP +
1465 23 : state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HR;
1466 :
1467 23 : if (state.dataHVACVarRefFlow->NumVRFCond > 0) {
1468 23 : state.dataHVACVarRefFlow->VRF.allocate(state.dataHVACVarRefFlow->NumVRFCond);
1469 23 : state.dataHVACVarRefFlow->VrfUniqueNames.reserve(static_cast<unsigned>(state.dataHVACVarRefFlow->NumVRFCond));
1470 23 : state.dataHVACVarRefFlow->MaxCoolingCapacity.allocate(state.dataHVACVarRefFlow->NumVRFCond);
1471 23 : state.dataHVACVarRefFlow->MaxHeatingCapacity.allocate(state.dataHVACVarRefFlow->NumVRFCond);
1472 23 : state.dataHVACVarRefFlow->CoolCombinationRatio.allocate(state.dataHVACVarRefFlow->NumVRFCond);
1473 23 : state.dataHVACVarRefFlow->HeatCombinationRatio.allocate(state.dataHVACVarRefFlow->NumVRFCond);
1474 23 : state.dataHVACVarRefFlow->MaxCoolingCapacity = Constant::MaxCap;
1475 23 : state.dataHVACVarRefFlow->MaxHeatingCapacity = Constant::MaxCap;
1476 23 : state.dataHVACVarRefFlow->CoolCombinationRatio = 1.0;
1477 23 : state.dataHVACVarRefFlow->HeatCombinationRatio = 1.0;
1478 : }
1479 : }
1480 :
1481 : {
1482 : // ZoneTerminalUnitList
1483 :
1484 23 : state.dataHVACVarRefFlow->NumVRFTULists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneTerminalUnitList");
1485 23 : if (state.dataHVACVarRefFlow->NumVRFTULists > 0) {
1486 23 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "ZoneTerminalUnitList", NumParams, NumAlphas, NumNums);
1487 23 : MaxAlphas = max(MaxAlphas, NumAlphas);
1488 23 : MaxNumbers = max(MaxNumbers, NumNums);
1489 :
1490 23 : state.dataHVACVarRefFlow->TerminalUnitList.allocate(state.dataHVACVarRefFlow->NumVRFTULists);
1491 : }
1492 : }
1493 :
1494 23 : Array1D_string cAlphaFieldNames;
1495 23 : cAlphaFieldNames.allocate(MaxAlphas);
1496 23 : Array1D_string cAlphaArgs;
1497 23 : cAlphaArgs.allocate(MaxAlphas);
1498 23 : Array1D_bool lAlphaFieldBlanks;
1499 23 : lAlphaFieldBlanks.dimension(MaxAlphas, false);
1500 :
1501 23 : Array1D_string cNumericFieldNames;
1502 23 : cNumericFieldNames.allocate(MaxNumbers);
1503 23 : Array1D<Real64> rNumericArgs;
1504 23 : rNumericArgs.dimension(MaxNumbers, 0.0);
1505 23 : Array1D_bool lNumericFieldBlanks;
1506 23 : lNumericFieldBlanks.dimension(MaxNumbers, false);
1507 :
1508 : // read all terminal unit list objects
1509 23 : cCurrentModuleObject = "ZoneTerminalUnitList";
1510 50 : for (int TUListNum = 1; TUListNum <= state.dataHVACVarRefFlow->NumVRFTULists; ++TUListNum) {
1511 27 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1512 : cCurrentModuleObject,
1513 : TUListNum,
1514 : cAlphaArgs,
1515 : NumAlphas,
1516 : rNumericArgs,
1517 : NumNums,
1518 : IOStat,
1519 : lNumericFieldBlanks,
1520 : lAlphaFieldBlanks,
1521 : cAlphaFieldNames,
1522 : cNumericFieldNames);
1523 27 : Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
1524 :
1525 27 : auto &thisTUList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum);
1526 27 : thisTUList.Name = cAlphaArgs(1);
1527 27 : thisTUList.NumTUInList = NumAlphas - 1;
1528 27 : thisTUList.ZoneTUPtr.allocate(thisTUList.NumTUInList);
1529 27 : thisTUList.ZoneTUName.allocate(thisTUList.NumTUInList);
1530 27 : thisTUList.IsSimulated.allocate(thisTUList.NumTUInList);
1531 27 : thisTUList.TotalCoolLoad.allocate(thisTUList.NumTUInList);
1532 27 : thisTUList.TotalHeatLoad.allocate(thisTUList.NumTUInList);
1533 27 : thisTUList.CoolingCoilPresent.allocate(thisTUList.NumTUInList);
1534 27 : thisTUList.HeatingCoilPresent.allocate(thisTUList.NumTUInList);
1535 27 : thisTUList.TerminalUnitNotSizedYet.allocate(thisTUList.NumTUInList);
1536 27 : thisTUList.HRHeatRequest.allocate(thisTUList.NumTUInList);
1537 27 : thisTUList.HRCoolRequest.allocate(thisTUList.NumTUInList);
1538 27 : thisTUList.CoolingCoilAvailable.allocate(thisTUList.NumTUInList);
1539 27 : thisTUList.HeatingCoilAvailable.allocate(thisTUList.NumTUInList);
1540 27 : thisTUList.coolingCoilAvailScheds.allocate(thisTUList.NumTUInList);
1541 27 : thisTUList.heatingCoilAvailScheds.allocate(thisTUList.NumTUInList);
1542 27 : thisTUList.ZoneTUPtr = 0;
1543 27 : thisTUList.IsSimulated = false;
1544 27 : thisTUList.TotalCoolLoad = 0.0;
1545 27 : thisTUList.TotalHeatLoad = 0.0;
1546 27 : thisTUList.CoolingCoilPresent = true;
1547 27 : thisTUList.HeatingCoilPresent = true;
1548 27 : thisTUList.TerminalUnitNotSizedYet = true;
1549 27 : thisTUList.HRHeatRequest = false;
1550 27 : thisTUList.HRCoolRequest = false;
1551 27 : thisTUList.CoolingCoilAvailable = false;
1552 27 : thisTUList.HeatingCoilAvailable = false;
1553 27 : thisTUList.coolingCoilAvailScheds = nullptr;
1554 27 : thisTUList.heatingCoilAvailScheds = nullptr;
1555 :
1556 61 : for (int TUNum = 1; TUNum <= thisTUList.NumTUInList; ++TUNum) {
1557 34 : thisTUList.ZoneTUName(TUNum) = cAlphaArgs(TUNum + 1);
1558 : }
1559 : }
1560 :
1561 34 : auto checkCurveMinMaxOutput = [&state](int CurveIndex) -> std::array<Real64, 4> {
1562 34 : Real64 MinCurveVal = 999.0;
1563 34 : Real64 MaxCurveVal = -999.0;
1564 34 : Real64 MinCurvePLR = 0.0;
1565 34 : Real64 MaxCurvePLR = 1.0;
1566 :
1567 3468 : for (int i = 0; i <= 100; ++i) { // 0 to 1.0 with 0.01 increment
1568 3434 : const Real64 CurveInput = i / 100.0;
1569 3434 : Real64 CurveVal = CurveValue(state, CurveIndex, CurveInput);
1570 3434 : if (CurveVal < MinCurveVal) {
1571 34 : MinCurveVal = CurveVal;
1572 34 : MinCurvePLR = CurveInput;
1573 : }
1574 3434 : if (CurveVal > MaxCurveVal) {
1575 3434 : MaxCurveVal = CurveVal;
1576 3434 : MaxCurvePLR = CurveInput;
1577 : }
1578 : }
1579 34 : return {MinCurvePLR, MinCurveVal, MaxCurvePLR, MaxCurveVal};
1580 23 : };
1581 :
1582 : // read all VRF condenser objects: Algorithm Type 1_system curve based model
1583 23 : cCurrentModuleObject = "AirConditioner:VariableRefrigerantFlow";
1584 41 : for (int VRFNum = 1; VRFNum <= state.dataHVACVarRefFlow->NumVRFCond_SysCurve; ++VRFNum) {
1585 18 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1586 : cCurrentModuleObject,
1587 : VRFNum,
1588 : cAlphaArgs,
1589 : NumAlphas,
1590 : rNumericArgs,
1591 : NumNums,
1592 : IOStat,
1593 : lNumericFieldBlanks,
1594 : lAlphaFieldBlanks,
1595 : cAlphaFieldNames,
1596 : cNumericFieldNames);
1597 :
1598 18 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
1599 18 : GlobalNames::VerifyUniqueInterObjectName(
1600 36 : state, state.dataHVACVarRefFlow->VrfUniqueNames, cAlphaArgs(1), cCurrentModuleObject, cAlphaFieldNames(1), ErrorsFound);
1601 :
1602 18 : auto &thisVrfSys = state.dataHVACVarRefFlow->VRF(VRFNum);
1603 18 : thisVrfSys.Name = cAlphaArgs(1);
1604 18 : thisVrfSys.VRFSystemTypeNum = VRF_HeatPump;
1605 18 : thisVrfSys.VRFAlgorithmType = AlgorithmType::SysCurve;
1606 :
1607 18 : if (lAlphaFieldBlanks(2)) {
1608 5 : thisVrfSys.availSched = Sched::GetScheduleAlwaysOn(state);
1609 13 : } else if ((thisVrfSys.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
1610 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
1611 0 : ErrorsFound = true;
1612 : }
1613 :
1614 18 : thisVrfSys.CoolingCapacity = rNumericArgs(1);
1615 18 : thisVrfSys.CoolingCOP = rNumericArgs(2);
1616 18 : thisVrfSys.MinOATCooling = rNumericArgs(3);
1617 18 : thisVrfSys.MaxOATCooling = rNumericArgs(4);
1618 :
1619 18 : thisVrfSys.CoolCapFT = GetCurveIndex(state, cAlphaArgs(3));
1620 18 : if (thisVrfSys.CoolCapFT > 0) {
1621 : // Verify Curve Object, only legal type is biquadratic
1622 36 : ErrorsFound |= Curve::CheckCurveDims(state,
1623 : thisVrfSys.CoolCapFT, // Curve index
1624 : {2}, // Valid dimensions
1625 : RoutineName, // Routine name
1626 : cCurrentModuleObject, // Object Type
1627 : thisVrfSys.Name, // Object Name
1628 18 : cAlphaFieldNames(3)); // Field Name
1629 :
1630 18 : if (!ErrorsFound) {
1631 18 : checkCurveIsNormalizedToOne(state,
1632 54 : std::string{RoutineName} + cCurrentModuleObject,
1633 18 : thisVrfSys.Name,
1634 : thisVrfSys.CoolCapFT,
1635 18 : cAlphaFieldNames(3),
1636 18 : cAlphaArgs(3),
1637 : RatedInletWetBulbTemp,
1638 : RatedOutdoorAirTemp);
1639 : }
1640 : }
1641 :
1642 18 : thisVrfSys.CoolBoundaryCurvePtr = GetCurveIndex(state, cAlphaArgs(4));
1643 18 : if (thisVrfSys.CoolBoundaryCurvePtr > 0) {
1644 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1645 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1646 : thisVrfSys.CoolBoundaryCurvePtr, // Curve index
1647 : {1}, // Valid dimensions
1648 : RoutineName, // Routine name
1649 : cCurrentModuleObject, // Object Type
1650 : thisVrfSys.Name, // Object Name
1651 17 : cAlphaFieldNames(4)); // Field Name
1652 : }
1653 :
1654 18 : thisVrfSys.CoolCapFTHi = GetCurveIndex(state, cAlphaArgs(5));
1655 18 : if (thisVrfSys.CoolCapFTHi > 0) {
1656 : // Verify Curve Object, only legal type is biquadratic
1657 54 : ErrorsFound |= Curve::CheckCurveDims(state,
1658 : thisVrfSys.CoolCapFTHi, // Curve index
1659 : {2}, // Valid dimensions
1660 : RoutineName, // Routine name
1661 : cCurrentModuleObject, // Object Type
1662 : thisVrfSys.Name, // Object Name
1663 18 : cAlphaFieldNames(5)); // Field Name
1664 : }
1665 :
1666 18 : thisVrfSys.CoolEIRFT = GetCurveIndex(state, cAlphaArgs(6));
1667 18 : if (thisVrfSys.CoolEIRFT > 0) {
1668 : // Verify Curve Object, only legal type is biquadratic
1669 54 : ErrorsFound |= Curve::CheckCurveDims(state,
1670 : thisVrfSys.CoolEIRFT, // Curve index
1671 : {2}, // Valid dimensions
1672 : RoutineName, // Routine name
1673 : cCurrentModuleObject, // Object Type
1674 : thisVrfSys.Name, // Object Name
1675 18 : cAlphaFieldNames(6)); // Field Name
1676 : }
1677 :
1678 18 : thisVrfSys.EIRCoolBoundaryCurvePtr = GetCurveIndex(state, cAlphaArgs(7));
1679 18 : if (thisVrfSys.EIRCoolBoundaryCurvePtr > 0) {
1680 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1681 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1682 : thisVrfSys.EIRCoolBoundaryCurvePtr, // Curve index
1683 : {1}, // Valid dimensions
1684 : RoutineName, // Routine name
1685 : cCurrentModuleObject, // Object Type
1686 : thisVrfSys.Name, // Object Name
1687 17 : cAlphaFieldNames(7)); // Field Name
1688 : }
1689 :
1690 18 : thisVrfSys.CoolEIRFTHi = GetCurveIndex(state, cAlphaArgs(8));
1691 18 : if (thisVrfSys.CoolEIRFTHi > 0) {
1692 : // Verify Curve Object, only legal type is biquadratic
1693 54 : ErrorsFound |= Curve::CheckCurveDims(state,
1694 : thisVrfSys.CoolEIRFTHi, // Curve index
1695 : {2}, // Valid dimensions
1696 : RoutineName, // Routine name
1697 : cCurrentModuleObject, // Object Type
1698 : thisVrfSys.Name, // Object Name
1699 18 : cAlphaFieldNames(8)); // Field Name
1700 : }
1701 :
1702 18 : thisVrfSys.CoolEIRFPLR1 = GetCurveIndex(state, cAlphaArgs(9));
1703 18 : if (thisVrfSys.CoolEIRFPLR1 > 0) {
1704 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1705 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1706 : thisVrfSys.CoolEIRFPLR1, // Curve index
1707 : {1}, // Valid dimensions
1708 : RoutineName, // Routine name
1709 : cCurrentModuleObject, // Object Type
1710 : thisVrfSys.Name, // Object Name
1711 17 : cAlphaFieldNames(9)); // Field Name
1712 : }
1713 :
1714 18 : thisVrfSys.CoolEIRFPLR2 = GetCurveIndex(state, cAlphaArgs(10));
1715 18 : if (thisVrfSys.CoolEIRFPLR2 > 0) {
1716 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1717 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1718 : thisVrfSys.CoolEIRFPLR2, // Curve index
1719 : {1}, // Valid dimensions
1720 : RoutineName, // Routine name
1721 : cCurrentModuleObject, // Object Type
1722 : thisVrfSys.Name, // Object Name
1723 17 : cAlphaFieldNames(10)); // Field Name
1724 : }
1725 :
1726 18 : thisVrfSys.CoolCombRatioPTR = GetCurveIndex(state, cAlphaArgs(11));
1727 18 : if (thisVrfSys.CoolCombRatioPTR > 0) {
1728 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1729 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1730 : thisVrfSys.CoolCombRatioPTR, // Curve index
1731 : {1}, // Valid dimensions
1732 : RoutineName, // Routine name
1733 : cCurrentModuleObject, // Object Type
1734 : thisVrfSys.Name, // Object Name
1735 17 : cAlphaFieldNames(11)); // Field Name
1736 : }
1737 :
1738 18 : thisVrfSys.CoolPLFFPLR = GetCurveIndex(state, cAlphaArgs(12));
1739 18 : if (thisVrfSys.CoolPLFFPLR > 0) {
1740 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1741 34 : ErrorsFound |= Curve::CheckCurveDims(state,
1742 : thisVrfSys.CoolPLFFPLR, // Curve index
1743 : {1}, // Valid dimensions
1744 : RoutineName, // Routine name
1745 : cCurrentModuleObject, // Object Type
1746 : thisVrfSys.Name, // Object Name
1747 17 : cAlphaFieldNames(12)); // Field Name
1748 17 : if (!ErrorsFound) {
1749 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
1750 17 : auto [MinCurvePLR, MinCurveVal, MaxCurvePLR, MaxCurveVal] = checkCurveMinMaxOutput(thisVrfSys.CoolPLFFPLR);
1751 :
1752 17 : if (MinCurveVal < 0.7) {
1753 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
1754 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFieldNames(12), cAlphaArgs(12)));
1755 0 : ShowContinueError(state,
1756 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
1757 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
1758 0 : Curve::SetCurveOutputMinValue(state, thisVrfSys.CoolPLFFPLR, ErrorsFound, 0.7);
1759 : }
1760 :
1761 17 : if (MaxCurveVal > 1.0) {
1762 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
1763 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFieldNames(12), cAlphaArgs(12)));
1764 0 : ShowContinueError(state,
1765 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
1766 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
1767 0 : Curve::SetCurveOutputMaxValue(state, thisVrfSys.CoolPLFFPLR, ErrorsFound, 1.0);
1768 : }
1769 : }
1770 : }
1771 :
1772 18 : thisVrfSys.HeatingCapacity = rNumericArgs(5);
1773 18 : thisVrfSys.HeatingCapacitySizeRatio = rNumericArgs(6);
1774 18 : if (!lNumericFieldBlanks(6) && thisVrfSys.HeatingCapacity == AutoSize) {
1775 5 : thisVrfSys.LockHeatingCapacity = true;
1776 : }
1777 18 : thisVrfSys.HeatingCOP = rNumericArgs(7);
1778 18 : thisVrfSys.MinOATHeating = rNumericArgs(8);
1779 18 : thisVrfSys.MaxOATHeating = rNumericArgs(9);
1780 18 : if (thisVrfSys.MinOATHeating >= thisVrfSys.MaxOATHeating) {
1781 0 : ShowSevereError(state, format("{}, \"{}\"", cCurrentModuleObject, thisVrfSys.Name));
1782 0 : ShowContinueError(state,
1783 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
1784 : cNumericFieldNames(8),
1785 0 : thisVrfSys.MinOATHeating,
1786 0 : thisVrfSys.MaxOATHeating));
1787 0 : ErrorsFound = true;
1788 : }
1789 :
1790 18 : thisVrfSys.HeatCapFT = GetCurveIndex(state, cAlphaArgs(13));
1791 18 : if (thisVrfSys.HeatCapFT > 0) {
1792 : // Verify Curve Object, only legal type is biquadratic
1793 36 : ErrorsFound |= Curve::CheckCurveDims(state,
1794 : thisVrfSys.HeatCapFT, // Curve index
1795 : {2}, // Valid dimensions
1796 : RoutineName, // Routine name
1797 : cCurrentModuleObject, // Object Type
1798 : thisVrfSys.Name, // Object Name
1799 18 : cAlphaFieldNames(13)); // Field Name
1800 :
1801 18 : if (!ErrorsFound) {
1802 18 : if (Util::SameString(cAlphaArgs(19), "WETBULBTEMPERATURE")) {
1803 18 : checkCurveIsNormalizedToOne(state,
1804 54 : std::string{RoutineName} + cCurrentModuleObject,
1805 18 : thisVrfSys.Name,
1806 : thisVrfSys.HeatCapFT,
1807 18 : cAlphaFieldNames(13),
1808 18 : cAlphaArgs(13),
1809 : RatedInletAirTempHeat,
1810 : RatedOutdoorWetBulbTempHeat);
1811 0 : } else if (Util::SameString(cAlphaArgs(19), "DRYBULBTEMPERATURE")) {
1812 0 : checkCurveIsNormalizedToOne(state,
1813 0 : std::string{RoutineName} + cCurrentModuleObject,
1814 0 : thisVrfSys.Name,
1815 : thisVrfSys.HeatCapFT,
1816 0 : cAlphaFieldNames(13),
1817 0 : cAlphaArgs(13),
1818 : RatedInletAirTempHeat,
1819 : RatedOutdoorAirTempHeat);
1820 : }
1821 : }
1822 : }
1823 :
1824 18 : thisVrfSys.HeatBoundaryCurvePtr = GetCurveIndex(state, cAlphaArgs(14));
1825 18 : if (thisVrfSys.HeatBoundaryCurvePtr > 0) {
1826 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1827 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1828 : thisVrfSys.HeatBoundaryCurvePtr, // Curve index
1829 : {1}, // Valid dimensions
1830 : RoutineName, // Routine name
1831 : cCurrentModuleObject, // Object Type
1832 : thisVrfSys.Name, // Object Name
1833 17 : cAlphaFieldNames(14)); // Field Name
1834 : }
1835 :
1836 18 : thisVrfSys.HeatCapFTHi = GetCurveIndex(state, cAlphaArgs(15));
1837 18 : if (thisVrfSys.HeatCapFTHi > 0) {
1838 : // Verify Curve Object, only legal type is biquadratic
1839 54 : ErrorsFound |= Curve::CheckCurveDims(state,
1840 : thisVrfSys.HeatCapFTHi, // Curve index
1841 : {2}, // Valid dimensions
1842 : RoutineName, // Routine name
1843 : cCurrentModuleObject, // Object Type
1844 : thisVrfSys.Name, // Object Name
1845 18 : cAlphaFieldNames(15)); // Field Name
1846 : }
1847 :
1848 18 : thisVrfSys.HeatEIRFT = GetCurveIndex(state, cAlphaArgs(16));
1849 18 : if (thisVrfSys.HeatEIRFT > 0) {
1850 : // Verify Curve Object, only legal type is biquadratic
1851 54 : ErrorsFound |= Curve::CheckCurveDims(state,
1852 : thisVrfSys.HeatEIRFT, // Curve index
1853 : {2}, // Valid dimensions
1854 : RoutineName, // Routine name
1855 : cCurrentModuleObject, // Object Type
1856 : thisVrfSys.Name, // Object Name
1857 18 : cAlphaFieldNames(16)); // Field Name
1858 : }
1859 :
1860 18 : thisVrfSys.EIRHeatBoundaryCurvePtr = GetCurveIndex(state, cAlphaArgs(17));
1861 18 : if (thisVrfSys.EIRHeatBoundaryCurvePtr > 0) {
1862 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1863 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1864 : thisVrfSys.EIRHeatBoundaryCurvePtr, // Curve index
1865 : {1}, // Valid dimensions
1866 : RoutineName, // Routine name
1867 : cCurrentModuleObject, // Object Type
1868 : thisVrfSys.Name, // Object Name
1869 17 : cAlphaFieldNames(17)); // Field Name
1870 : }
1871 :
1872 18 : thisVrfSys.HeatEIRFTHi = GetCurveIndex(state, cAlphaArgs(18));
1873 18 : if (thisVrfSys.HeatEIRFTHi > 0) {
1874 : // Verify Curve Object, only legal type is biquadratic
1875 54 : ErrorsFound |= Curve::CheckCurveDims(state,
1876 : thisVrfSys.HeatEIRFTHi, // Curve index
1877 : {2}, // Valid dimensions
1878 : RoutineName, // Routine name
1879 : cCurrentModuleObject, // Object Type
1880 : thisVrfSys.Name, // Object Name
1881 18 : cAlphaFieldNames(18)); // Field Name
1882 : }
1883 :
1884 18 : if (Util::SameString(cAlphaArgs(19), "WETBULBTEMPERATURE")) {
1885 18 : thisVrfSys.HeatingPerformanceOATType = HVAC::OATType::WetBulb;
1886 0 : } else if (Util::SameString(cAlphaArgs(19), "DRYBULBTEMPERATURE")) {
1887 0 : thisVrfSys.HeatingPerformanceOATType = HVAC::OATType::DryBulb;
1888 : } else {
1889 0 : ShowSevereError(
1890 : state,
1891 0 : format(
1892 0 : "{}, \"{}\" illegal {} input for this object = {}", cCurrentModuleObject, thisVrfSys.Name, cAlphaFieldNames(19), cAlphaArgs(19)));
1893 0 : ShowContinueError(state, "... input must be WETBULBTEMPERATURE or DRYBULBTEMPERATURE.");
1894 0 : ErrorsFound = true;
1895 : }
1896 :
1897 18 : thisVrfSys.HeatEIRFPLR1 = GetCurveIndex(state, cAlphaArgs(20));
1898 18 : if (thisVrfSys.HeatEIRFPLR1 > 0) {
1899 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1900 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1901 : thisVrfSys.HeatEIRFPLR1, // Curve index
1902 : {1}, // Valid dimensions
1903 : RoutineName, // Routine name
1904 : cCurrentModuleObject, // Object Type
1905 : thisVrfSys.Name, // Object Name
1906 17 : cAlphaFieldNames(20)); // Field Name
1907 : }
1908 :
1909 18 : thisVrfSys.HeatEIRFPLR2 = GetCurveIndex(state, cAlphaArgs(21));
1910 18 : if (thisVrfSys.HeatEIRFPLR2 > 0) {
1911 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1912 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1913 : thisVrfSys.HeatEIRFPLR2, // Curve index
1914 : {1}, // Valid dimensions
1915 : RoutineName, // Routine name
1916 : cCurrentModuleObject, // Object Type
1917 : thisVrfSys.Name, // Object Name
1918 17 : cAlphaFieldNames(21)); // Field Name
1919 : }
1920 :
1921 18 : thisVrfSys.HeatCombRatioPTR = GetCurveIndex(state, cAlphaArgs(22));
1922 18 : if (thisVrfSys.HeatCombRatioPTR > 0) {
1923 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1924 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1925 : thisVrfSys.HeatCombRatioPTR, // Curve index
1926 : {1}, // Valid dimensions
1927 : RoutineName, // Routine name
1928 : cCurrentModuleObject, // Object Type
1929 : thisVrfSys.Name, // Object Name
1930 17 : cAlphaFieldNames(22)); // Field Name
1931 : }
1932 18 : thisVrfSys.HeatPLFFPLR = GetCurveIndex(state, cAlphaArgs(23));
1933 18 : if (thisVrfSys.HeatPLFFPLR > 0) {
1934 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1935 34 : ErrorsFound |= Curve::CheckCurveDims(state,
1936 : thisVrfSys.HeatPLFFPLR, // Curve index
1937 : {1}, // Valid dimensions
1938 : RoutineName, // Routine name
1939 : cCurrentModuleObject, // Object Type
1940 : thisVrfSys.Name, // Object Name
1941 17 : cAlphaFieldNames(23)); // Field Name
1942 :
1943 17 : if (!ErrorsFound) {
1944 17 : auto [MinCurvePLR, MinCurveVal, MaxCurvePLR, MaxCurveVal] = checkCurveMinMaxOutput(thisVrfSys.HeatPLFFPLR);
1945 :
1946 17 : if (MinCurveVal < 0.7) {
1947 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
1948 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFieldNames(23), cAlphaArgs(23)));
1949 0 : ShowContinueError(state,
1950 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
1951 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
1952 0 : Curve::SetCurveOutputMinValue(state, thisVrfSys.HeatPLFFPLR, ErrorsFound, 0.7);
1953 : }
1954 :
1955 17 : if (MaxCurveVal > 1.0) {
1956 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
1957 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFieldNames(23), cAlphaArgs(23)));
1958 0 : ShowContinueError(state,
1959 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
1960 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
1961 0 : Curve::SetCurveOutputMaxValue(state, thisVrfSys.HeatPLFFPLR, ErrorsFound, 1.0);
1962 : }
1963 : }
1964 : }
1965 :
1966 18 : thisVrfSys.MinPLR = rNumericArgs(10);
1967 18 : Real64 minEIRfLowPLRXInput = 0.0;
1968 18 : Real64 maxEIRfLowPLRXInput = 0.0;
1969 :
1970 18 : if (thisVrfSys.CoolEIRFPLR1 > 0) {
1971 17 : Curve::GetCurveMinMaxValues(state, thisVrfSys.CoolEIRFPLR1, minEIRfLowPLRXInput, maxEIRfLowPLRXInput);
1972 17 : if (minEIRfLowPLRXInput > thisVrfSys.MinPLR) {
1973 1 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
1974 1 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFieldNames(9), cAlphaArgs(9)));
1975 2 : ShowContinueError(state,
1976 2 : format("...Curve minimum value of X = {:.3T} must be <= Minimum Heat Pump Part-Load Ratio = {:.3T}.",
1977 : minEIRfLowPLRXInput,
1978 1 : thisVrfSys.MinPLR));
1979 1 : ErrorsFound = true;
1980 : }
1981 17 : if (maxEIRfLowPLRXInput < 1.0) {
1982 0 : ShowWarningError(state, format("{}{}=\"{}\", suspicious", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
1983 0 : ShowContinueError(state, format("...{} = {} has unexpected value.", cAlphaFieldNames(9), cAlphaArgs(9)));
1984 0 : ShowContinueError(state,
1985 0 : format("...Curve maximum value of X = {:.3T} should be 1 and will result in lower energy use than expected.",
1986 : maxEIRfLowPLRXInput));
1987 : }
1988 17 : minEIRfLowPLRXInput = 0.0;
1989 17 : maxEIRfLowPLRXInput = 0.0;
1990 : }
1991 18 : if (thisVrfSys.HeatEIRFPLR1 > 0) {
1992 17 : Curve::GetCurveMinMaxValues(state, thisVrfSys.HeatEIRFPLR1, minEIRfLowPLRXInput, maxEIRfLowPLRXInput);
1993 17 : if (minEIRfLowPLRXInput > thisVrfSys.MinPLR) {
1994 1 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
1995 1 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFieldNames(20), cAlphaArgs(20)));
1996 2 : ShowContinueError(state,
1997 2 : format("...Curve minimum value of X = {:.3T} must be <= Minimum Heat Pump Part-Load Ratio = {:.3T}.",
1998 : minEIRfLowPLRXInput,
1999 1 : thisVrfSys.MinPLR));
2000 1 : ErrorsFound = true;
2001 : }
2002 17 : if (maxEIRfLowPLRXInput < 1.0) {
2003 0 : ShowWarningError(state, format("{}{}=\"{}\", suspicious", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
2004 0 : ShowContinueError(state, format("...{} = {} has unexpected value.", cAlphaFieldNames(20), cAlphaArgs(20)));
2005 0 : ShowContinueError(state,
2006 0 : format("...Curve maximum value of X = {:.3T} should be 1 and will result in lower energy use than expected.",
2007 : maxEIRfLowPLRXInput));
2008 : }
2009 : }
2010 :
2011 18 : thisVrfSys.MasterZonePtr = Util::FindItemInList(cAlphaArgs(24), state.dataHeatBal->Zone);
2012 :
2013 18 : thisVrfSys.ThermostatPriority = static_cast<ThermostatCtrlType>(getEnumValue(ThermostatCtrlTypeUC, cAlphaArgs(25)));
2014 :
2015 18 : if (thisVrfSys.ThermostatPriority == ThermostatCtrlType::MasterThermostatPriority) {
2016 0 : if (thisVrfSys.MasterZonePtr == 0) {
2017 0 : ShowSevereError(state, format("{} = \"{}\"", cCurrentModuleObject, thisVrfSys.Name));
2018 0 : ShowContinueError(state, format("{} must be entered when {} = {}", cAlphaFieldNames(24), cAlphaFieldNames(25), cAlphaArgs(25)));
2019 0 : ErrorsFound = true;
2020 : }
2021 18 : } else if (thisVrfSys.ThermostatPriority == ThermostatCtrlType::Invalid) {
2022 0 : ShowSevereError(state, format("{} = \"{}\"", cCurrentModuleObject, thisVrfSys.Name));
2023 0 : ShowContinueError(state, format("Illegal {} = {}", cAlphaFieldNames(25), cAlphaArgs(25)));
2024 0 : ErrorsFound = true;
2025 : }
2026 :
2027 18 : if (thisVrfSys.ThermostatPriority == ThermostatCtrlType::ScheduledPriority) {
2028 0 : if (lAlphaFieldBlanks(26)) {
2029 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(26), cAlphaFieldNames(25), cAlphaArgs(25));
2030 0 : } else if ((thisVrfSys.prioritySched = Sched::GetSchedule(state, cAlphaArgs(26))) == nullptr) {
2031 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(26), cAlphaArgs(26));
2032 0 : ErrorsFound = true;
2033 : }
2034 : }
2035 :
2036 18 : thisVrfSys.ZoneTUListPtr = Util::FindItemInList(cAlphaArgs(27), state.dataHVACVarRefFlow->TerminalUnitList);
2037 18 : if (thisVrfSys.ZoneTUListPtr == 0) {
2038 0 : ShowSevereError(state, format("{} = \"{}\"", cCurrentModuleObject, thisVrfSys.Name));
2039 0 : ShowContinueError(state, format("{} = {} not found.", cAlphaFieldNames(27), cAlphaArgs(27)));
2040 0 : ErrorsFound = true;
2041 : }
2042 :
2043 18 : thisVrfSys.HeatRecoveryUsed = false;
2044 18 : if (!lAlphaFieldBlanks(28)) {
2045 18 : if (Util::SameString(cAlphaArgs(28), "No")) {
2046 16 : thisVrfSys.HeatRecoveryUsed = false;
2047 2 : } else if (Util::SameString(cAlphaArgs(28), "Yes")) {
2048 2 : thisVrfSys.HeatRecoveryUsed = true;
2049 : } else {
2050 0 : ShowSevereError(state, format("{} = \"{}\"", cCurrentModuleObject, thisVrfSys.Name));
2051 0 : ShowContinueError(state, format("Illegal {} = {}", cAlphaFieldNames(28), cAlphaArgs(28)));
2052 0 : ErrorsFound = true;
2053 : }
2054 : }
2055 :
2056 18 : thisVrfSys.EquivPipeLngthCool = rNumericArgs(11);
2057 18 : thisVrfSys.VertPipeLngth = rNumericArgs(12);
2058 18 : thisVrfSys.PCFLengthCoolPtr = GetCurveIndex(state, cAlphaArgs(29));
2059 18 : if (thisVrfSys.PCFLengthCoolPtr > 0) {
2060 : // Verify Curve Object, only legal type is linear, quadratic, cubic, or biquadratic
2061 54 : ErrorsFound |= Curve::CheckCurveDims(state,
2062 : thisVrfSys.PCFLengthCoolPtr, // Curve index
2063 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2064 : RoutineName, // Routine name
2065 : cCurrentModuleObject, // Object Type
2066 : thisVrfSys.Name, // Object Name
2067 18 : cAlphaFieldNames(29)); // Field Name
2068 : }
2069 18 : thisVrfSys.PCFHeightCool = rNumericArgs(13);
2070 :
2071 18 : thisVrfSys.EquivPipeLngthHeat = rNumericArgs(14);
2072 18 : thisVrfSys.PCFLengthHeatPtr = GetCurveIndex(state, cAlphaArgs(30));
2073 18 : if (thisVrfSys.PCFLengthHeatPtr > 0) {
2074 : // Verify Curve Object, only legal type is linear, quadratic, cubic, or biquadratic
2075 15 : ErrorsFound |= Curve::CheckCurveDims(state,
2076 : thisVrfSys.PCFLengthHeatPtr, // Curve index
2077 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2078 : RoutineName, // Routine name
2079 : cCurrentModuleObject, // Object Type
2080 : thisVrfSys.Name, // Object Name
2081 5 : cAlphaFieldNames(30)); // Field Name
2082 : }
2083 :
2084 18 : thisVrfSys.PCFHeightHeat = rNumericArgs(15);
2085 :
2086 18 : thisVrfSys.CCHeaterPower = rNumericArgs(16);
2087 18 : thisVrfSys.NumCompressors = rNumericArgs(17);
2088 18 : thisVrfSys.CompressorSizeRatio = rNumericArgs(18);
2089 18 : thisVrfSys.MaxOATCCHeater = rNumericArgs(19);
2090 :
2091 18 : if (!lAlphaFieldBlanks(31)) {
2092 18 : thisVrfSys.DefrostStrategy = static_cast<StandardRatings::DefrostStrat>(getEnumValue(StandardRatings::DefrostStratUC, cAlphaArgs(31)));
2093 18 : if (thisVrfSys.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
2094 0 : ShowSevereError(state,
2095 0 : format("{}, \"{}\" {} not found: {}", cCurrentModuleObject, thisVrfSys.Name, cAlphaFieldNames(31), cAlphaArgs(31)));
2096 0 : ErrorsFound = true;
2097 : }
2098 : } else {
2099 0 : thisVrfSys.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
2100 : }
2101 :
2102 18 : if (!lAlphaFieldBlanks(32)) {
2103 18 : thisVrfSys.DefrostControl =
2104 18 : static_cast<StandardRatings::HPdefrostControl>(getEnumValue(StandardRatings::HPdefrostControlUC, cAlphaArgs(32)));
2105 :
2106 18 : if (thisVrfSys.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
2107 0 : ShowSevereError(state,
2108 0 : format("{}, \"{}\" {} not found: {}", cCurrentModuleObject, thisVrfSys.Name, cAlphaFieldNames(32), cAlphaArgs(32)));
2109 :
2110 0 : ErrorsFound = true;
2111 : }
2112 : } else {
2113 0 : thisVrfSys.DefrostControl = StandardRatings::HPdefrostControl::Timed;
2114 : }
2115 :
2116 18 : if (!lAlphaFieldBlanks(33)) {
2117 11 : thisVrfSys.DefrostEIRPtr = GetCurveIndex(state, cAlphaArgs(33));
2118 11 : if (thisVrfSys.DefrostEIRPtr > 0) {
2119 : // Verify Curve Object, expected type is BiQuadratic
2120 33 : ErrorsFound |= Curve::CheckCurveDims(state,
2121 : thisVrfSys.DefrostEIRPtr, // Curve index
2122 : {2}, // Valid dimensions
2123 : RoutineName, // Routine name
2124 : cCurrentModuleObject, // Object Type
2125 : thisVrfSys.Name, // Object Name
2126 11 : cAlphaFieldNames(33)); // Field Name
2127 : } else {
2128 0 : if (thisVrfSys.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
2129 0 : ShowSevereError(
2130 0 : state, format("{}, \"{}\" {} not found: {}", cCurrentModuleObject, thisVrfSys.Name, cAlphaFieldNames(33), cAlphaArgs(33)));
2131 0 : ErrorsFound = true;
2132 : }
2133 : }
2134 : } else {
2135 7 : if (thisVrfSys.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
2136 0 : ShowSevereError(state,
2137 0 : format("{}, \"{}\" {} not found: {}", cCurrentModuleObject, thisVrfSys.Name, cAlphaFieldNames(33), cAlphaArgs(33)));
2138 0 : ErrorsFound = true;
2139 : }
2140 : }
2141 :
2142 18 : thisVrfSys.DefrostFraction = rNumericArgs(20);
2143 18 : thisVrfSys.DefrostCapacity = rNumericArgs(21);
2144 18 : if (thisVrfSys.DefrostCapacity == 0.0 && thisVrfSys.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
2145 0 : ShowWarningError(
2146 : state,
2147 0 : format("{}, \"{}\" {} = 0.0 for defrost strategy = RESISTIVE.", cCurrentModuleObject, thisVrfSys.Name, cNumericFieldNames(21)));
2148 : }
2149 :
2150 18 : thisVrfSys.MaxOATDefrost = rNumericArgs(22);
2151 :
2152 18 : if (!lAlphaFieldBlanks(35)) {
2153 18 : if (Util::SameString(cAlphaArgs(34), "AirCooled")) thisVrfSys.CondenserType = DataHeatBalance::RefrigCondenserType::Air;
2154 18 : if (Util::SameString(cAlphaArgs(34), "EvaporativelyCooled")) thisVrfSys.CondenserType = DataHeatBalance::RefrigCondenserType::Evap;
2155 18 : if (Util::SameString(cAlphaArgs(34), "WaterCooled")) {
2156 1 : thisVrfSys.CondenserType = DataHeatBalance::RefrigCondenserType::Water;
2157 1 : thisVrfSys.VRFType = PlantEquipmentType::HeatPumpVRF;
2158 1 : if (thisVrfSys.HeatingPerformanceOATType == HVAC::OATType::WetBulb) {
2159 1 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisVrfSys.Name));
2160 1 : ShowContinueError(state, format("{} = {}", cAlphaFieldNames(34), cAlphaArgs(34)));
2161 1 : ShowContinueError(state, format("Illegal {} input for this object = {}", cAlphaFieldNames(19), cAlphaArgs(19)));
2162 2 : ShowContinueError(state, "... input must be DRYBULBTEMPERATURE when Condenser Type is WaterCooled.");
2163 1 : ShowContinueError(state, format("... {} will be reset to DRYBULBTEMPERATURE and simulation continues.", cAlphaFieldNames(19)));
2164 : }
2165 : }
2166 18 : if (thisVrfSys.CondenserType == DataHeatBalance::RefrigCondenserType::Invalid) {
2167 0 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfSys.Name);
2168 0 : ShowContinueError(state, "Illegal " + cAlphaFieldNames(34) + " = " + cAlphaArgs(34));
2169 0 : ErrorsFound = true;
2170 : }
2171 : } else {
2172 0 : thisVrfSys.CondenserType = DataHeatBalance::RefrigCondenserType::Air;
2173 : }
2174 :
2175 : // outdoor condenser node
2176 18 : if (lAlphaFieldBlanks(35)) {
2177 0 : thisVrfSys.CondenserNodeNum = 0;
2178 : } else {
2179 18 : switch (thisVrfSys.CondenserType) {
2180 17 : case DataHeatBalance::RefrigCondenserType::Air:
2181 : case DataHeatBalance::RefrigCondenserType::Evap: {
2182 17 : thisVrfSys.CondenserNodeNum = GetOnlySingleNode(state,
2183 17 : cAlphaArgs(35),
2184 : ErrorsFound,
2185 : DataLoopNode::ConnectionObjectType::AirConditionerVariableRefrigerantFlow,
2186 17 : thisVrfSys.Name,
2187 : DataLoopNode::NodeFluidType::Air,
2188 : DataLoopNode::ConnectionType::OutsideAirReference,
2189 : NodeInputManager::CompFluidStream::Primary,
2190 : ObjectIsNotParent);
2191 17 : if (!CheckOutAirNodeNumber(state, thisVrfSys.CondenserNodeNum)) {
2192 0 : ShowSevereError(state,
2193 0 : format("{}, \"{}\" {} not a valid Outdoor Air Node = {}",
2194 : cCurrentModuleObject,
2195 0 : thisVrfSys.Name,
2196 : cAlphaFieldNames(35),
2197 : cAlphaArgs(35)));
2198 0 : ShowContinueError(state, "...node name does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
2199 0 : ErrorsFound = true;
2200 : }
2201 17 : } break;
2202 1 : case DataHeatBalance::RefrigCondenserType::Water: {
2203 1 : thisVrfSys.CondenserNodeNum = GetOnlySingleNode(state,
2204 1 : cAlphaArgs(35),
2205 : ErrorsFound,
2206 : DataLoopNode::ConnectionObjectType::AirConditionerVariableRefrigerantFlow,
2207 1 : thisVrfSys.Name,
2208 : DataLoopNode::NodeFluidType::Water,
2209 : DataLoopNode::ConnectionType::Inlet,
2210 : NodeInputManager::CompFluidStream::Secondary,
2211 : ObjectIsNotParent);
2212 1 : } break;
2213 0 : default:
2214 0 : break;
2215 : }
2216 : }
2217 :
2218 18 : if (!lAlphaFieldBlanks(36) && thisVrfSys.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
2219 2 : thisVrfSys.CondenserOutletNodeNum = GetOnlySingleNode(state,
2220 1 : cAlphaArgs(36),
2221 : ErrorsFound,
2222 : DataLoopNode::ConnectionObjectType::AirConditionerVariableRefrigerantFlow,
2223 1 : thisVrfSys.Name,
2224 : DataLoopNode::NodeFluidType::Water,
2225 : DataLoopNode::ConnectionType::Outlet,
2226 : NodeInputManager::CompFluidStream::Secondary,
2227 : ObjectIsNotParent);
2228 2 : TestCompSet(state, cCurrentModuleObject, thisVrfSys.Name, cAlphaArgs(35), cAlphaArgs(36), "Condenser Water Nodes");
2229 17 : } else if (lAlphaFieldBlanks(36) && thisVrfSys.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
2230 0 : ShowSevereError(state, format("{}, \"{}\" {} is blank.", cCurrentModuleObject, thisVrfSys.Name, cAlphaFieldNames(36)));
2231 0 : ShowContinueError(state, "...node name must be entered when Condenser Type = WaterCooled.");
2232 0 : ErrorsFound = true;
2233 : }
2234 :
2235 18 : if (lAlphaFieldBlanks(23)) {
2236 0 : if (thisVrfSys.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
2237 0 : ShowSevereError(state, format("{}, \"{}\" {} is blank.", cCurrentModuleObject, thisVrfSys.Name, cNumericFieldNames(23)));
2238 0 : ShowContinueError(state, format("...input is required when {} = {}", cAlphaFieldNames(34), cAlphaArgs(34)));
2239 0 : ErrorsFound = true;
2240 : }
2241 : } else {
2242 18 : thisVrfSys.WaterCondVolFlowRate = rNumericArgs(23);
2243 : }
2244 18 : thisVrfSys.EvapCondEffectiveness = rNumericArgs(24);
2245 18 : thisVrfSys.EvapCondAirVolFlowRate = rNumericArgs(25);
2246 18 : thisVrfSys.EvapCondPumpPower = rNumericArgs(26);
2247 :
2248 : // Get Water System tank connections
2249 : // A37, \field Supply Water Storage Tank Name
2250 18 : thisVrfSys.EvapWaterSupplyName = cAlphaArgs(37);
2251 18 : if (lAlphaFieldBlanks(37)) {
2252 18 : thisVrfSys.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
2253 : } else {
2254 0 : thisVrfSys.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
2255 0 : SetupTankDemandComponent(state,
2256 : thisVrfSys.Name,
2257 : cCurrentModuleObject,
2258 : thisVrfSys.EvapWaterSupplyName,
2259 : ErrorsFound,
2260 0 : thisVrfSys.EvapWaterSupTankID,
2261 0 : thisVrfSys.EvapWaterTankDemandARRID);
2262 : }
2263 :
2264 : // Basin heater power as a function of temperature must be greater than or equal to 0
2265 18 : thisVrfSys.BasinHeaterPowerFTempDiff = rNumericArgs(27);
2266 18 : if (rNumericArgs(27) < 0.0) {
2267 0 : ShowSevereError(state, format("{}, \"{}\" {} must be >= 0", cCurrentModuleObject, thisVrfSys.Name, cNumericFieldNames(27)));
2268 0 : ErrorsFound = true;
2269 : }
2270 :
2271 18 : thisVrfSys.BasinHeaterSetPointTemp = rNumericArgs(28);
2272 18 : if (thisVrfSys.BasinHeaterPowerFTempDiff > 0.0) {
2273 0 : if (NumNums < 27) {
2274 0 : thisVrfSys.BasinHeaterSetPointTemp = 2.0;
2275 : }
2276 0 : if (thisVrfSys.BasinHeaterSetPointTemp < 2.0) {
2277 0 : ShowWarningError(
2278 : state,
2279 0 : format(
2280 0 : "{}, \"{}\" {} is less than 2 deg C. Freezing could occur.", cCurrentModuleObject, thisVrfSys.Name, cNumericFieldNames(28)));
2281 : }
2282 : }
2283 :
2284 18 : if (!lAlphaFieldBlanks(38)) {
2285 5 : if ((thisVrfSys.basinHeaterSched = Sched::GetSchedule(state, cAlphaArgs(38))) == nullptr) {
2286 0 : ShowWarningItemNotFound(
2287 0 : state, eoh, cAlphaFieldNames(38), cAlphaArgs(38), "Basin heater will be available to operate throughout the simulation.");
2288 : }
2289 : }
2290 :
2291 18 : if (!lAlphaFieldBlanks(39)) {
2292 : // A39; \field Fuel type, Validate fuel type input
2293 18 : if ((thisVrfSys.fuel = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, cAlphaArgs(39)))) == Constant::eFuel::Invalid) {
2294 0 : ShowSevereInvalidKey(state, eoh, cAlphaFieldNames(39), cAlphaArgs(39));
2295 0 : ErrorsFound = true;
2296 : }
2297 : }
2298 :
2299 18 : if (thisVrfSys.HeatRecoveryUsed) {
2300 2 : if (lAlphaFieldBlanks(29)) {
2301 0 : thisVrfSys.MinOATHeatRecovery = max(thisVrfSys.MinOATCooling, thisVrfSys.MinOATHeating);
2302 : } else {
2303 2 : thisVrfSys.MinOATHeatRecovery = rNumericArgs(29);
2304 2 : if (thisVrfSys.MinOATHeatRecovery < thisVrfSys.MinOATCooling || thisVrfSys.MinOATHeatRecovery < thisVrfSys.MinOATHeating) {
2305 4 : ShowWarningError(state,
2306 6 : format("{} = \"{}\", {} is less than the minimum temperature in heat pump mode.",
2307 : cCurrentModuleObject,
2308 2 : thisVrfSys.Name,
2309 : cNumericFieldNames(29)));
2310 2 : ShowContinueError(state, format("...{} = {:.2T} C", cNumericFieldNames(29), thisVrfSys.MinOATHeatRecovery));
2311 2 : ShowContinueError(state, format("...Minimum Outdoor Temperature in Cooling Mode = {:.2T} C", thisVrfSys.MinOATCooling));
2312 2 : ShowContinueError(state, format("...Minimum Outdoor Temperature in Heating Mode = {:.2T} C", thisVrfSys.MinOATHeating));
2313 4 : ShowContinueError(state,
2314 : "...Minimum Outdoor Temperature in Heat Recovery Mode reset to greater of cooling or heating minimum "
2315 : "temperature and simulation continues.");
2316 2 : thisVrfSys.MinOATHeatRecovery = max(thisVrfSys.MinOATCooling, thisVrfSys.MinOATHeating);
2317 2 : ShowContinueError(state, format("... adjusted {} = {:.2T} C", cNumericFieldNames(29), thisVrfSys.MinOATHeatRecovery));
2318 : }
2319 : }
2320 2 : if (lAlphaFieldBlanks(30)) {
2321 0 : thisVrfSys.MaxOATHeatRecovery = min(thisVrfSys.MaxOATCooling, thisVrfSys.MaxOATHeating);
2322 : } else {
2323 2 : thisVrfSys.MaxOATHeatRecovery = rNumericArgs(30);
2324 2 : if (thisVrfSys.MaxOATHeatRecovery > thisVrfSys.MaxOATCooling || thisVrfSys.MaxOATHeatRecovery > thisVrfSys.MaxOATHeating) {
2325 0 : ShowWarningError(state,
2326 0 : format("{} = \"{}\", {} is greater than the maximum temperature in heat pump mode.",
2327 : cCurrentModuleObject,
2328 0 : thisVrfSys.Name,
2329 : cNumericFieldNames(30)));
2330 0 : ShowContinueError(state, format("...{} = {:.2T} C", cNumericFieldNames(30), thisVrfSys.MaxOATHeatRecovery));
2331 0 : ShowContinueError(state, format("...Maximum Outdoor Temperature in Cooling Mode = {:.2T} C", thisVrfSys.MaxOATCooling));
2332 0 : ShowContinueError(state, format("...Maximum Outdoor Temperature in Heating Mode = {:.2T} C", thisVrfSys.MaxOATHeating));
2333 0 : ShowContinueError(state,
2334 : "...Maximum Outdoor Temperature in Heat Recovery Mode reset to lesser of cooling or heating minimum "
2335 : "temperature and simulation continues.");
2336 0 : thisVrfSys.MaxOATHeatRecovery = min(thisVrfSys.MaxOATCooling, thisVrfSys.MaxOATHeating);
2337 0 : ShowContinueError(state, format("... adjusted {} = {:.2T} C", cNumericFieldNames(30), thisVrfSys.MaxOATHeatRecovery));
2338 : }
2339 : }
2340 :
2341 2 : thisVrfSys.HRCAPFTCool = GetCurveIndex(state, cAlphaArgs(40));
2342 2 : if (thisVrfSys.HRCAPFTCool > 0) {
2343 : // Verify Curve Object, only legal type is bi-quadratic or linear, quadratic, or cubic
2344 6 : ErrorsFound |= Curve::CheckCurveDims(state,
2345 : thisVrfSys.HRCAPFTCool, // Curve index
2346 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2347 : RoutineName, // Routine name
2348 : cCurrentModuleObject, // Object Type
2349 : thisVrfSys.Name, // Object Name
2350 2 : cAlphaFieldNames(40)); // Field Name
2351 : }
2352 2 : if (!lNumericFieldBlanks(31)) {
2353 2 : thisVrfSys.HRInitialCoolCapFrac = rNumericArgs(31);
2354 : }
2355 2 : thisVrfSys.HRCoolCapTC = rNumericArgs(32);
2356 2 : thisVrfSys.HREIRFTCool = GetCurveIndex(state, cAlphaArgs(41));
2357 2 : if (thisVrfSys.HREIRFTCool > 0) {
2358 : // Verify Curve Object, only legal type is bi-quadratic or linear, quadratic, or cubic
2359 6 : ErrorsFound |= Curve::CheckCurveDims(state,
2360 : thisVrfSys.HREIRFTCool, // Curve index
2361 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2362 : RoutineName, // Routine name
2363 : cCurrentModuleObject, // Object Type
2364 : thisVrfSys.Name, // Object Name
2365 2 : cAlphaFieldNames(41)); // Field Name
2366 : }
2367 2 : thisVrfSys.HRInitialCoolEIRFrac = rNumericArgs(33);
2368 2 : thisVrfSys.HRCoolEIRTC = rNumericArgs(34);
2369 :
2370 : // INTEGER :: HRCAPFTHeat =0 ! Index to heat capacity as a function of temperature curve for heat recovery
2371 : // REAL(r64) :: HRInitialHeatCapFrac =0.0d0 ! Fractional heating degradation at the start of heat recovery from heating mode
2372 : // REAL(r64) :: HRHeatCapTC =0.0d0 ! Time constant used to recover from initial degradation in heating heat
2373 : // recovery
2374 2 : thisVrfSys.HRCAPFTHeat = GetCurveIndex(state, cAlphaArgs(42));
2375 2 : if (thisVrfSys.HRCAPFTHeat > 0) {
2376 : // Verify Curve Object, only legal type is bi-quadratic or linear, quadratic, or cubic
2377 6 : ErrorsFound |= Curve::CheckCurveDims(state,
2378 : thisVrfSys.HRCAPFTHeat, // Curve index
2379 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2380 : RoutineName, // Routine name
2381 : cCurrentModuleObject, // Object Type
2382 : thisVrfSys.Name, // Object Name
2383 2 : cAlphaFieldNames(42)); // Field Name
2384 : }
2385 2 : thisVrfSys.HRInitialHeatCapFrac = rNumericArgs(35);
2386 2 : thisVrfSys.HRHeatCapTC = rNumericArgs(36);
2387 :
2388 : // INTEGER :: HREIRFTHeat =0 ! Index to heat EIR as a function of temperature curve for heat recovery
2389 : // REAL(r64) :: HRInitialHeatEIRFrac =0.0d0 ! Fractional EIR degradation at the start of heat recovery from heating mode
2390 : // REAL(r64) :: HRHeatEIRTC =0.0d0 ! Time constant used to recover from initial degradation in heating heat
2391 : // recovery
2392 2 : thisVrfSys.HREIRFTHeat = GetCurveIndex(state, cAlphaArgs(43));
2393 2 : if (thisVrfSys.HREIRFTHeat > 0) {
2394 : // Verify Curve Object, only legal type is bi-quadratic or linear, quadratic, or cubic
2395 6 : ErrorsFound |= Curve::CheckCurveDims(state,
2396 : thisVrfSys.HREIRFTHeat, // Curve index
2397 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2398 : RoutineName, // Routine name
2399 : cCurrentModuleObject, // Object Type
2400 : thisVrfSys.Name, // Object Name
2401 2 : cAlphaFieldNames(43)); // Field Name
2402 : }
2403 2 : thisVrfSys.HRInitialHeatEIRFrac = rNumericArgs(37);
2404 2 : thisVrfSys.HRHeatEIRTC = rNumericArgs(38);
2405 : }
2406 : }
2407 :
2408 : // Read all VRF condenser objects: Algorithm Type 2_physics based model (VRF-FluidTCtrl-HP)
2409 23 : cCurrentModuleObject = "AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl";
2410 29 : for (int thisNum = 1; thisNum <= state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HP; ++thisNum) {
2411 :
2412 6 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2413 : cCurrentModuleObject,
2414 : thisNum,
2415 : cAlphaArgs,
2416 : NumAlphas,
2417 : rNumericArgs,
2418 : NumNums,
2419 : IOStat,
2420 : lNumericFieldBlanks,
2421 : lAlphaFieldBlanks,
2422 : cAlphaFieldNames,
2423 : cNumericFieldNames);
2424 :
2425 6 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
2426 :
2427 6 : GlobalNames::VerifyUniqueInterObjectName(
2428 12 : state, state.dataHVACVarRefFlow->VrfUniqueNames, cAlphaArgs(1), cCurrentModuleObject, cAlphaFieldNames(1), ErrorsFound);
2429 :
2430 6 : int VRFNum = state.dataHVACVarRefFlow->NumVRFCond_SysCurve + thisNum;
2431 6 : auto &thisVrfFluidCtrl = state.dataHVACVarRefFlow->VRF(VRFNum);
2432 6 : thisVrfFluidCtrl.Name = cAlphaArgs(1);
2433 6 : thisVrfFluidCtrl.VRFSystemTypeNum = VRF_HeatPump;
2434 6 : thisVrfFluidCtrl.VRFAlgorithmType = AlgorithmType::FluidTCtrl;
2435 6 : thisVrfFluidCtrl.fuel = Constant::eFuel::Electricity;
2436 :
2437 6 : if (lAlphaFieldBlanks(2)) {
2438 2 : thisVrfFluidCtrl.availSched = Sched::GetScheduleAlwaysOn(state);
2439 4 : } else if ((thisVrfFluidCtrl.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
2440 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
2441 0 : ErrorsFound = true;
2442 : }
2443 :
2444 6 : thisVrfFluidCtrl.ZoneTUListPtr =
2445 6 : Util::FindItemInList(cAlphaArgs(3), state.dataHVACVarRefFlow->TerminalUnitList, state.dataHVACVarRefFlow->NumVRFTULists);
2446 6 : if (thisVrfFluidCtrl.ZoneTUListPtr == 0) {
2447 0 : ShowSevereError(state, cCurrentModuleObject + " = \"" + thisVrfFluidCtrl.Name + "\"");
2448 0 : ShowContinueError(state, cAlphaFieldNames(3) + " = " + cAlphaArgs(3) + " not found.");
2449 0 : ErrorsFound = true;
2450 : }
2451 :
2452 : // Refrigerant type
2453 6 : thisVrfFluidCtrl.refrigName = cAlphaArgs(4);
2454 6 : thisVrfFluidCtrl.refrig = Fluid::GetRefrig(state, thisVrfFluidCtrl.refrigName);
2455 6 : if (thisVrfFluidCtrl.refrig == nullptr) {
2456 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(4), cAlphaArgs(4));
2457 0 : ErrorsFound = true;
2458 : }
2459 :
2460 6 : thisVrfFluidCtrl.RatedEvapCapacity = rNumericArgs(1);
2461 6 : thisVrfFluidCtrl.RatedCompPowerPerCapcity = rNumericArgs(2);
2462 6 : thisVrfFluidCtrl.RatedCompPower = thisVrfFluidCtrl.RatedCompPowerPerCapcity * thisVrfFluidCtrl.RatedEvapCapacity;
2463 6 : thisVrfFluidCtrl.CoolingCapacity = thisVrfFluidCtrl.RatedEvapCapacity;
2464 6 : thisVrfFluidCtrl.RatedHeatCapacity = thisVrfFluidCtrl.RatedEvapCapacity * (1 + thisVrfFluidCtrl.RatedCompPowerPerCapcity);
2465 6 : thisVrfFluidCtrl.HeatingCapacity = thisVrfFluidCtrl.RatedHeatCapacity;
2466 :
2467 : // Reference system COP
2468 6 : thisVrfFluidCtrl.CoolingCOP = 1 / thisVrfFluidCtrl.RatedCompPowerPerCapcity;
2469 6 : thisVrfFluidCtrl.HeatingCOP = 1 / thisVrfFluidCtrl.RatedCompPowerPerCapcity + 1;
2470 :
2471 : // OA temperature range for VRF-HP operations
2472 6 : thisVrfFluidCtrl.MinOATCooling = rNumericArgs(3);
2473 6 : thisVrfFluidCtrl.MaxOATCooling = rNumericArgs(4);
2474 6 : thisVrfFluidCtrl.MinOATHeating = rNumericArgs(5);
2475 6 : thisVrfFluidCtrl.MaxOATHeating = rNumericArgs(6);
2476 6 : if (thisVrfFluidCtrl.MinOATCooling >= thisVrfFluidCtrl.MaxOATCooling) {
2477 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\"");
2478 0 : ShowContinueError(state,
2479 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2480 : cNumericFieldNames(3),
2481 0 : thisVrfFluidCtrl.MinOATCooling,
2482 0 : thisVrfFluidCtrl.MaxOATCooling));
2483 0 : ErrorsFound = true;
2484 : }
2485 6 : if (thisVrfFluidCtrl.MinOATHeating >= thisVrfFluidCtrl.MaxOATHeating) {
2486 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\"");
2487 0 : ShowContinueError(state,
2488 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2489 : cNumericFieldNames(5),
2490 0 : thisVrfFluidCtrl.MinOATHeating,
2491 0 : thisVrfFluidCtrl.MaxOATHeating));
2492 0 : ErrorsFound = true;
2493 : }
2494 :
2495 : // Reference OU SH/SC
2496 6 : thisVrfFluidCtrl.SH = rNumericArgs(7);
2497 6 : thisVrfFluidCtrl.SC = rNumericArgs(8);
2498 :
2499 6 : if (Util::SameString(cAlphaArgs(5), "VariableTemp")) {
2500 0 : thisVrfFluidCtrl.AlgorithmIUCtrl = 1;
2501 6 : } else if (Util::SameString(cAlphaArgs(5), "ConstantTemp")) {
2502 6 : thisVrfFluidCtrl.AlgorithmIUCtrl = 2;
2503 : } else {
2504 0 : thisVrfFluidCtrl.AlgorithmIUCtrl = 1;
2505 : }
2506 :
2507 : // Reference IU Te/Tc for IU Control Algorithm: ConstantTemp
2508 6 : thisVrfFluidCtrl.EvapTempFixed = rNumericArgs(9);
2509 6 : thisVrfFluidCtrl.CondTempFixed = rNumericArgs(10);
2510 :
2511 : // Bounds of Te/Tc for IU Control Algorithm: VariableTemp
2512 6 : thisVrfFluidCtrl.IUEvapTempLow = rNumericArgs(11);
2513 6 : thisVrfFluidCtrl.IUEvapTempHigh = rNumericArgs(12);
2514 6 : thisVrfFluidCtrl.IUCondTempLow = rNumericArgs(13);
2515 6 : thisVrfFluidCtrl.IUCondTempHigh = rNumericArgs(14);
2516 6 : if (thisVrfFluidCtrl.IUEvapTempLow >= thisVrfFluidCtrl.IUEvapTempHigh) {
2517 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\"");
2518 0 : ShowContinueError(state,
2519 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2520 : cNumericFieldNames(11),
2521 0 : thisVrfFluidCtrl.IUEvapTempLow,
2522 0 : thisVrfFluidCtrl.IUEvapTempHigh));
2523 0 : ErrorsFound = true;
2524 : }
2525 6 : if (thisVrfFluidCtrl.IUCondTempLow >= thisVrfFluidCtrl.IUCondTempHigh) {
2526 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\"");
2527 0 : ShowContinueError(state,
2528 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2529 : cNumericFieldNames(13),
2530 0 : thisVrfFluidCtrl.IUCondTempLow,
2531 0 : thisVrfFluidCtrl.IUCondTempHigh));
2532 0 : ErrorsFound = true;
2533 : }
2534 :
2535 : // Get OU fan data
2536 6 : thisVrfFluidCtrl.RatedOUFanPowerPerCapcity = rNumericArgs(15);
2537 6 : thisVrfFluidCtrl.OUAirFlowRatePerCapcity = rNumericArgs(16);
2538 6 : thisVrfFluidCtrl.RatedOUFanPower = thisVrfFluidCtrl.RatedOUFanPowerPerCapcity * thisVrfFluidCtrl.RatedEvapCapacity;
2539 6 : thisVrfFluidCtrl.OUAirFlowRate = thisVrfFluidCtrl.OUAirFlowRatePerCapcity * thisVrfFluidCtrl.RatedEvapCapacity;
2540 :
2541 : // OUEvapTempCurve
2542 6 : int indexOUEvapTempCurve = GetCurveIndex(state, cAlphaArgs(6)); // convert curve name to index number
2543 : // Verify curve name and type
2544 6 : if (indexOUEvapTempCurve == 0) {
2545 0 : if (lAlphaFieldBlanks(6)) {
2546 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", missing");
2547 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(6) + " is blank.");
2548 : } else {
2549 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", invalid");
2550 0 : ShowContinueError(state, "...not found " + cAlphaFieldNames(6) + "=\"" + cAlphaArgs(6) + "\".");
2551 : }
2552 0 : ErrorsFound = true;
2553 : } else {
2554 : {
2555 6 : if (state.dataCurveManager->curves(indexOUEvapTempCurve)->curveType == Curve::CurveType::Quadratic) {
2556 6 : thisVrfFluidCtrl.C1Te = state.dataCurveManager->curves(indexOUEvapTempCurve)->coeff[0];
2557 6 : thisVrfFluidCtrl.C2Te = state.dataCurveManager->curves(indexOUEvapTempCurve)->coeff[1];
2558 6 : thisVrfFluidCtrl.C3Te = state.dataCurveManager->curves(indexOUEvapTempCurve)->coeff[2];
2559 :
2560 : } else {
2561 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", invalid");
2562 0 : ShowContinueError(state,
2563 0 : format("...illegal {} type for this object = {}",
2564 : cAlphaFieldNames(6),
2565 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexOUEvapTempCurve)->curveType)]));
2566 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
2567 0 : ErrorsFound = true;
2568 : }
2569 : }
2570 : }
2571 :
2572 : // OUCondTempCurve
2573 6 : int indexOUCondTempCurve = GetCurveIndex(state, cAlphaArgs(7)); // convert curve name to index number
2574 : // Verify curve name and type
2575 6 : if (indexOUCondTempCurve == 0) {
2576 0 : if (lAlphaFieldBlanks(7)) {
2577 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", missing");
2578 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(7) + " is blank.");
2579 : } else {
2580 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", invalid");
2581 0 : ShowContinueError(state, "...not found " + cAlphaFieldNames(7) + "=\"" + cAlphaArgs(7) + "\".");
2582 : }
2583 0 : ErrorsFound = true;
2584 : } else {
2585 : {
2586 6 : if (state.dataCurveManager->curves(indexOUCondTempCurve)->curveType == Curve::CurveType::Quadratic) {
2587 6 : thisVrfFluidCtrl.C1Tc = state.dataCurveManager->curves(indexOUCondTempCurve)->coeff[0];
2588 6 : thisVrfFluidCtrl.C2Tc = state.dataCurveManager->curves(indexOUCondTempCurve)->coeff[1];
2589 6 : thisVrfFluidCtrl.C3Tc = state.dataCurveManager->curves(indexOUCondTempCurve)->coeff[2];
2590 :
2591 : } else {
2592 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", invalid");
2593 0 : ShowContinueError(state,
2594 0 : format("...illegal {} type for this object = {}",
2595 : cAlphaFieldNames(7),
2596 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexOUCondTempCurve)->curveType)]));
2597 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
2598 0 : ErrorsFound = true;
2599 : }
2600 : }
2601 : }
2602 :
2603 : // Pipe parameters
2604 6 : thisVrfFluidCtrl.RefPipDiaSuc = rNumericArgs(17);
2605 6 : thisVrfFluidCtrl.RefPipDiaDis = rNumericArgs(17);
2606 6 : thisVrfFluidCtrl.RefPipLen = rNumericArgs(18);
2607 6 : thisVrfFluidCtrl.RefPipEquLen = rNumericArgs(19);
2608 6 : thisVrfFluidCtrl.RefPipHei = rNumericArgs(20);
2609 6 : thisVrfFluidCtrl.RefPipInsThi = rNumericArgs(21);
2610 6 : thisVrfFluidCtrl.RefPipInsCon = rNumericArgs(22);
2611 :
2612 : // Check the RefPipEquLen
2613 6 : if (lNumericFieldBlanks(19) && !lNumericFieldBlanks(18)) {
2614 0 : thisVrfFluidCtrl.RefPipEquLen = 1.2 * thisVrfFluidCtrl.RefPipLen;
2615 0 : ShowWarningError(
2616 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\", \" " + cNumericFieldNames(19) + "\" is calculated based on");
2617 0 : ShowContinueError(state, "...the provided \"" + cNumericFieldNames(18) + "\" value.");
2618 : }
2619 6 : if (thisVrfFluidCtrl.RefPipEquLen < thisVrfFluidCtrl.RefPipLen) {
2620 0 : thisVrfFluidCtrl.RefPipEquLen = 1.2 * thisVrfFluidCtrl.RefPipLen;
2621 0 : ShowWarningError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\", invalid \" " + cNumericFieldNames(19) + "\" value.");
2622 0 : ShowContinueError(state, "...Equivalent length of main pipe should be greater than or equal to the actual length.");
2623 0 : ShowContinueError(state, format("...The value is recalculated based on the provided \"{}\" value.", cNumericFieldNames(18)));
2624 : }
2625 :
2626 : // Crank case
2627 6 : thisVrfFluidCtrl.CCHeaterPower = rNumericArgs(23);
2628 6 : thisVrfFluidCtrl.NumCompressors = rNumericArgs(24);
2629 6 : thisVrfFluidCtrl.CompressorSizeRatio = rNumericArgs(25);
2630 6 : thisVrfFluidCtrl.MaxOATCCHeater = rNumericArgs(26);
2631 :
2632 : // Defrost
2633 6 : if (!lAlphaFieldBlanks(8)) {
2634 0 : if (Util::SameString(cAlphaArgs(8), "ReverseCycle")) thisVrfFluidCtrl.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
2635 0 : if (Util::SameString(cAlphaArgs(8), "Resistive")) thisVrfFluidCtrl.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
2636 0 : if (thisVrfFluidCtrl.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
2637 0 : ShowSevereError(state,
2638 0 : cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\" " + cAlphaFieldNames(8) + " not found: " + cAlphaArgs(8));
2639 0 : ErrorsFound = true;
2640 : }
2641 : } else {
2642 6 : thisVrfFluidCtrl.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
2643 : }
2644 :
2645 6 : if (!lAlphaFieldBlanks(9)) {
2646 0 : if (Util::SameString(cAlphaArgs(9), "Timed")) thisVrfFluidCtrl.DefrostControl = StandardRatings::HPdefrostControl::Timed;
2647 0 : if (Util::SameString(cAlphaArgs(9), "OnDemand")) thisVrfFluidCtrl.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
2648 0 : if (thisVrfFluidCtrl.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
2649 0 : ShowSevereError(state,
2650 0 : cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\" " + cAlphaFieldNames(9) + " not found: " + cAlphaArgs(9));
2651 0 : ErrorsFound = true;
2652 : }
2653 : } else {
2654 6 : thisVrfFluidCtrl.DefrostControl = StandardRatings::HPdefrostControl::Timed;
2655 : }
2656 :
2657 6 : if (!lAlphaFieldBlanks(10)) {
2658 0 : thisVrfFluidCtrl.DefrostEIRPtr = GetCurveIndex(state, cAlphaArgs(10));
2659 0 : if (thisVrfFluidCtrl.DefrostEIRPtr > 0) {
2660 : // Verify Curve Object, expected type is BiQuadratic
2661 0 : ErrorsFound |= Curve::CheckCurveDims(state,
2662 : thisVrfFluidCtrl.DefrostEIRPtr, // Curve index
2663 : {2}, // Valid dimensions
2664 : RoutineName, // Routine name
2665 : cCurrentModuleObject, // Object Type
2666 : thisVrfFluidCtrl.Name, // Object Name
2667 0 : cAlphaFieldNames(10)); // Field Name
2668 : } else {
2669 0 : if (thisVrfFluidCtrl.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle &&
2670 0 : thisVrfFluidCtrl.DefrostControl == StandardRatings::HPdefrostControl::OnDemand) {
2671 0 : ShowSevereError(
2672 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\" " + cAlphaFieldNames(10) + " not found:" + cAlphaArgs(10));
2673 0 : ErrorsFound = true;
2674 : }
2675 : }
2676 : } else {
2677 6 : if (thisVrfFluidCtrl.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle &&
2678 6 : thisVrfFluidCtrl.DefrostControl == StandardRatings::HPdefrostControl::OnDemand) {
2679 0 : ShowSevereError(
2680 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\" " + cAlphaFieldNames(10) + " not found:" + cAlphaArgs(10));
2681 0 : ErrorsFound = true;
2682 : }
2683 : }
2684 :
2685 6 : thisVrfFluidCtrl.DefrostFraction = rNumericArgs(27);
2686 6 : thisVrfFluidCtrl.DefrostCapacity = rNumericArgs(28);
2687 6 : thisVrfFluidCtrl.MaxOATDefrost = rNumericArgs(29);
2688 6 : if (thisVrfFluidCtrl.DefrostCapacity == 0.0 && thisVrfFluidCtrl.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
2689 0 : ShowWarningError(state,
2690 0 : cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\" " + cNumericFieldNames(28) +
2691 : " = 0.0 for defrost strategy = RESISTIVE.");
2692 : }
2693 :
2694 6 : thisVrfFluidCtrl.CompMaxDeltaP = rNumericArgs(30);
2695 :
2696 : //@@ The control type
2697 6 : std::string ThermostatPriorityType = "LoadPriority"; // cAlphaArgs( 25 )
2698 6 : if (Util::SameString(ThermostatPriorityType, "LoadPriority")) {
2699 6 : thisVrfFluidCtrl.ThermostatPriority = ThermostatCtrlType::LoadPriority;
2700 0 : } else if (Util::SameString(ThermostatPriorityType, "ZonePriority")) {
2701 0 : thisVrfFluidCtrl.ThermostatPriority = ThermostatCtrlType::ZonePriority;
2702 0 : } else if (Util::SameString(ThermostatPriorityType, "ThermostatOffsetPriority")) {
2703 0 : thisVrfFluidCtrl.ThermostatPriority = ThermostatCtrlType::ThermostatOffsetPriority;
2704 0 : } else if (Util::SameString(ThermostatPriorityType, "Scheduled")) {
2705 0 : thisVrfFluidCtrl.ThermostatPriority = ThermostatCtrlType::ScheduledPriority;
2706 0 : } else if (Util::SameString(ThermostatPriorityType, "MasterThermostatPriority")) {
2707 0 : thisVrfFluidCtrl.ThermostatPriority = ThermostatCtrlType::MasterThermostatPriority;
2708 0 : if (thisVrfFluidCtrl.MasterZonePtr == 0) {
2709 0 : ShowSevereError(state, cCurrentModuleObject + " = \"" + thisVrfFluidCtrl.Name + "\"");
2710 : //** ShowContinueError(state, cAlphaFieldNames( 24 ) + " must be entered when " + cAlphaFieldNames( 25 ) + " = " + cAlphaArgs( 25 )
2711 : //);
2712 0 : ErrorsFound = true;
2713 : }
2714 : } else {
2715 0 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfFluidCtrl.Name);
2716 : // ShowContinueError(state, "Illegal " + cAlphaFieldNames( 25 ) + " = " + cAlphaArgs( 25 ) );
2717 0 : ErrorsFound = true;
2718 : }
2719 :
2720 : // The new VRF model is Air cooled
2721 6 : thisVrfFluidCtrl.CondenserType = DataHeatBalance::RefrigCondenserType::Air;
2722 6 : thisVrfFluidCtrl.CondenserNodeNum = 0;
2723 :
2724 : // Evaporative Capacity & Compressor Power Curves corresponding to each Loading Index / compressor speed
2725 6 : int NumOfCompSpd = rNumericArgs(31);
2726 6 : thisVrfFluidCtrl.CompressorSpeed.dimension(NumOfCompSpd);
2727 6 : thisVrfFluidCtrl.OUCoolingCAPFT.dimension(NumOfCompSpd);
2728 6 : thisVrfFluidCtrl.OUCoolingPWRFT.dimension(NumOfCompSpd);
2729 6 : int Count1Index = 31; // the index of the last numeric field before compressor speed entries
2730 6 : int Count2Index = 9; // the index of the last alpha field before capacity/power curves
2731 24 : for (int NumCompSpd = 1; NumCompSpd <= NumOfCompSpd; NumCompSpd++) {
2732 18 : thisVrfFluidCtrl.CompressorSpeed(NumCompSpd) = rNumericArgs(Count1Index + NumCompSpd);
2733 :
2734 : // Evaporating Capacity Curve
2735 18 : if (!lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd)) {
2736 18 : int indexOUEvapCapCurve = GetCurveIndex(state, cAlphaArgs(Count2Index + 2 * NumCompSpd)); // convert curve name to index number
2737 18 : if (indexOUEvapCapCurve == 0) { // Verify curve name and type
2738 0 : if (lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd)) {
2739 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", missing");
2740 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(Count2Index + 2 * NumCompSpd) + " is blank.");
2741 : } else {
2742 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", invalid");
2743 0 : ShowContinueError(state,
2744 0 : format("...not found {}=\"{}\".",
2745 0 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd),
2746 0 : cAlphaArgs(Count2Index + 2 * NumCompSpd)));
2747 : }
2748 0 : ErrorsFound = true;
2749 : } else {
2750 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2751 : indexOUEvapCapCurve, // Curve index
2752 : {2}, // Valid dimensions
2753 : RoutineName, // Routine name
2754 : cCurrentModuleObject, // Object Type
2755 : thisVrfFluidCtrl.Name, // Object Name
2756 18 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd)); // Field Name
2757 :
2758 18 : if (!ErrorsFound) {
2759 18 : thisVrfFluidCtrl.OUCoolingCAPFT(NumCompSpd) = indexOUEvapCapCurve;
2760 : }
2761 : }
2762 : }
2763 :
2764 : // Compressor Power Curve
2765 18 : if (!lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd + 1)) {
2766 18 : int indexOUCompPwrCurve = GetCurveIndex(state, cAlphaArgs(Count2Index + 2 * NumCompSpd + 1)); // convert curve name to index number
2767 18 : if (indexOUCompPwrCurve == 0) { // Verify curve name and type
2768 0 : if (lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd + 1)) {
2769 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", missing");
2770 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(Count2Index + 2 * NumCompSpd + 1) + " is blank.");
2771 : } else {
2772 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", invalid");
2773 0 : ShowContinueError(state,
2774 0 : format("...not found {}=\"{}\".",
2775 0 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd + 1),
2776 0 : cAlphaArgs(Count2Index + 2 * NumCompSpd + 1)));
2777 : }
2778 0 : ErrorsFound = true;
2779 : } else {
2780 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2781 : indexOUCompPwrCurve, // Curve index
2782 : {2}, // Valid dimensions
2783 : RoutineName, // Routine name
2784 : cCurrentModuleObject, // Object Type
2785 : thisVrfFluidCtrl.Name, // Object Name
2786 18 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd + 1)); // Field Name
2787 :
2788 18 : if (!ErrorsFound) {
2789 18 : thisVrfFluidCtrl.OUCoolingPWRFT(NumCompSpd) = indexOUCompPwrCurve;
2790 : }
2791 : }
2792 : }
2793 : }
2794 6 : }
2795 :
2796 : // Read all VRF condenser objects: Algorithm Type 2_physics based model (VRF-FluidTCtrl-HR)
2797 23 : cCurrentModuleObject = "AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl:HR";
2798 26 : for (int thisNum = 1; thisNum <= state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HR; ++thisNum) {
2799 :
2800 3 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2801 : cCurrentModuleObject,
2802 : thisNum,
2803 : cAlphaArgs,
2804 : NumAlphas,
2805 : rNumericArgs,
2806 : NumNums,
2807 : IOStat,
2808 : lNumericFieldBlanks,
2809 : lAlphaFieldBlanks,
2810 : cAlphaFieldNames,
2811 : cNumericFieldNames);
2812 :
2813 3 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
2814 :
2815 3 : GlobalNames::VerifyUniqueInterObjectName(
2816 6 : state, state.dataHVACVarRefFlow->VrfUniqueNames, cAlphaArgs(1), cCurrentModuleObject, cAlphaFieldNames(1), ErrorsFound);
2817 :
2818 3 : int VRFNum = state.dataHVACVarRefFlow->NumVRFCond_SysCurve + state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HP + thisNum;
2819 3 : auto &thisVrfFluidCtrlHR = state.dataHVACVarRefFlow->VRF(VRFNum);
2820 :
2821 3 : thisVrfFluidCtrlHR.Name = cAlphaArgs(1);
2822 :
2823 3 : thisVrfFluidCtrlHR.ThermostatPriority = ThermostatCtrlType::LoadPriority;
2824 3 : thisVrfFluidCtrlHR.HeatRecoveryUsed = true;
2825 3 : thisVrfFluidCtrlHR.VRFSystemTypeNum = VRF_HeatPump;
2826 3 : thisVrfFluidCtrlHR.VRFAlgorithmType = AlgorithmType::FluidTCtrl;
2827 3 : thisVrfFluidCtrlHR.fuel = Constant::eFuel::Electricity;
2828 :
2829 3 : if (lAlphaFieldBlanks(2)) {
2830 1 : thisVrfFluidCtrlHR.availSched = Sched::GetScheduleAlwaysOn(state);
2831 2 : } else if ((thisVrfFluidCtrlHR.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
2832 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
2833 0 : ErrorsFound = true;
2834 : }
2835 :
2836 3 : thisVrfFluidCtrlHR.ZoneTUListPtr =
2837 3 : Util::FindItemInList(cAlphaArgs(3), state.dataHVACVarRefFlow->TerminalUnitList, state.dataHVACVarRefFlow->NumVRFTULists);
2838 3 : if (thisVrfFluidCtrlHR.ZoneTUListPtr == 0) {
2839 0 : ShowSevereError(state, cCurrentModuleObject + " = \"" + thisVrfFluidCtrlHR.Name + "\"");
2840 0 : ShowContinueError(state, cAlphaFieldNames(3) + " = " + cAlphaArgs(3) + " not found.");
2841 0 : ErrorsFound = true;
2842 : }
2843 :
2844 : // Refrigerant type
2845 3 : thisVrfFluidCtrlHR.refrigName = cAlphaArgs(4);
2846 3 : if ((thisVrfFluidCtrlHR.refrig = Fluid::GetRefrig(state, thisVrfFluidCtrlHR.refrigName)) == nullptr) {
2847 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(4), cAlphaArgs(4));
2848 0 : ErrorsFound = true;
2849 : }
2850 :
2851 3 : thisVrfFluidCtrlHR.RatedEvapCapacity = rNumericArgs(1);
2852 3 : thisVrfFluidCtrlHR.RatedCompPowerPerCapcity = rNumericArgs(2);
2853 3 : thisVrfFluidCtrlHR.RatedCompPower = thisVrfFluidCtrlHR.RatedCompPowerPerCapcity * thisVrfFluidCtrlHR.RatedEvapCapacity;
2854 3 : thisVrfFluidCtrlHR.CoolingCapacity = thisVrfFluidCtrlHR.RatedEvapCapacity;
2855 3 : thisVrfFluidCtrlHR.HeatingCapacity = thisVrfFluidCtrlHR.RatedEvapCapacity * (1 + thisVrfFluidCtrlHR.RatedCompPowerPerCapcity);
2856 3 : thisVrfFluidCtrlHR.RatedHeatCapacity = thisVrfFluidCtrlHR.HeatingCapacity;
2857 :
2858 : // Reference system COP
2859 3 : thisVrfFluidCtrlHR.CoolingCOP = 1 / thisVrfFluidCtrlHR.RatedCompPowerPerCapcity;
2860 3 : thisVrfFluidCtrlHR.HeatingCOP = 1 / thisVrfFluidCtrlHR.RatedCompPowerPerCapcity + 1;
2861 :
2862 : // OA temperature range for VRF-HP operations
2863 3 : thisVrfFluidCtrlHR.MinOATCooling = rNumericArgs(3);
2864 3 : thisVrfFluidCtrlHR.MaxOATCooling = rNumericArgs(4);
2865 3 : thisVrfFluidCtrlHR.MinOATHeating = rNumericArgs(5);
2866 3 : thisVrfFluidCtrlHR.MaxOATHeating = rNumericArgs(6);
2867 3 : thisVrfFluidCtrlHR.MinOATHeatRecovery = rNumericArgs(7);
2868 3 : thisVrfFluidCtrlHR.MaxOATHeatRecovery = rNumericArgs(8);
2869 3 : if (thisVrfFluidCtrlHR.MinOATCooling >= thisVrfFluidCtrlHR.MaxOATCooling) {
2870 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\"");
2871 0 : ShowContinueError(state,
2872 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2873 : cNumericFieldNames(3),
2874 0 : thisVrfFluidCtrlHR.MinOATCooling,
2875 0 : thisVrfFluidCtrlHR.MaxOATCooling));
2876 0 : ErrorsFound = true;
2877 : }
2878 3 : if (thisVrfFluidCtrlHR.MinOATHeating >= thisVrfFluidCtrlHR.MaxOATHeating) {
2879 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\"");
2880 0 : ShowContinueError(state,
2881 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2882 : cNumericFieldNames(5),
2883 0 : thisVrfFluidCtrlHR.MinOATHeating,
2884 0 : thisVrfFluidCtrlHR.MaxOATHeating));
2885 0 : ErrorsFound = true;
2886 : }
2887 3 : if (thisVrfFluidCtrlHR.MinOATHeatRecovery >= thisVrfFluidCtrlHR.MaxOATHeatRecovery) {
2888 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\"");
2889 0 : ShowContinueError(state,
2890 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2891 : cNumericFieldNames(7),
2892 0 : thisVrfFluidCtrlHR.MinOATHeating,
2893 0 : thisVrfFluidCtrlHR.MaxOATHeating));
2894 0 : ErrorsFound = true;
2895 : }
2896 3 : if (thisVrfFluidCtrlHR.MinOATHeatRecovery < thisVrfFluidCtrlHR.MinOATCooling &&
2897 3 : thisVrfFluidCtrlHR.MinOATHeatRecovery < thisVrfFluidCtrlHR.MinOATHeating) {
2898 0 : ShowWarningError(state,
2899 0 : cCurrentModuleObject + " = \"" + thisVrfFluidCtrlHR.Name + "\", " + cNumericFieldNames(7) +
2900 : " is less than the minimum temperature in heat pump mode.");
2901 0 : ShowContinueError(state, format("...{} = {:.2T} C", cNumericFieldNames(7), thisVrfFluidCtrlHR.MinOATHeatRecovery));
2902 0 : ShowContinueError(state, format("...Minimum Outdoor Temperature in Cooling Mode = {:.2T} C", thisVrfFluidCtrlHR.MinOATCooling));
2903 0 : ShowContinueError(state, format("...Minimum Outdoor Temperature in Heating Mode = {:.2T} C", thisVrfFluidCtrlHR.MinOATHeating));
2904 0 : ShowContinueError(state,
2905 : "...Minimum Outdoor Temperature in Heat Recovery Mode reset to lesser of cooling or heating minimum temperature "
2906 : "and simulation continues.");
2907 0 : thisVrfFluidCtrlHR.MinOATHeatRecovery = min(thisVrfFluidCtrlHR.MinOATCooling, thisVrfFluidCtrlHR.MinOATHeating);
2908 0 : ShowContinueError(state, format("... adjusted {} = {:.2T} C", cNumericFieldNames(7), thisVrfFluidCtrlHR.MinOATHeatRecovery));
2909 : }
2910 3 : if (thisVrfFluidCtrlHR.MaxOATHeatRecovery > thisVrfFluidCtrlHR.MaxOATCooling &&
2911 0 : thisVrfFluidCtrlHR.MaxOATHeatRecovery > thisVrfFluidCtrlHR.MaxOATHeating) {
2912 0 : ShowWarningError(state,
2913 0 : cCurrentModuleObject + " = \"" + thisVrfFluidCtrlHR.Name + "\", " + cNumericFieldNames(8) +
2914 : " is greater than the maximum temperature in heat pump mode.");
2915 0 : ShowContinueError(state, format("...{} = {:.2T} C", cNumericFieldNames(8), thisVrfFluidCtrlHR.MaxOATHeatRecovery));
2916 0 : ShowContinueError(state, format("...Maximum Outdoor Temperature in Cooling Mode = {:.2T} C", thisVrfFluidCtrlHR.MaxOATCooling));
2917 0 : ShowContinueError(state, format("...Maximum Outdoor Temperature in Heating Mode = {:.2T} C", thisVrfFluidCtrlHR.MaxOATHeating));
2918 0 : ShowContinueError(state,
2919 : "...Maximum Outdoor Temperature in Heat Recovery Mode reset to greater of cooling or heating maximum temperature "
2920 : "and simulation continues.");
2921 0 : thisVrfFluidCtrlHR.MaxOATHeatRecovery = max(thisVrfFluidCtrlHR.MaxOATCooling, thisVrfFluidCtrlHR.MaxOATHeating);
2922 0 : ShowContinueError(state, format("... adjusted {} = {:.2T} C", cNumericFieldNames(8), thisVrfFluidCtrlHR.MaxOATHeatRecovery));
2923 : }
2924 :
2925 : // IU Control Type
2926 3 : if (Util::SameString(cAlphaArgs(5), "VariableTemp")) {
2927 0 : thisVrfFluidCtrlHR.AlgorithmIUCtrl = 1;
2928 3 : } else if (Util::SameString(cAlphaArgs(5), "ConstantTemp")) {
2929 3 : thisVrfFluidCtrlHR.AlgorithmIUCtrl = 2;
2930 : } else {
2931 0 : thisVrfFluidCtrlHR.AlgorithmIUCtrl = 1;
2932 : }
2933 :
2934 : // Reference IU Te/Tc for IU Control Algorithm: ConstantTemp
2935 3 : thisVrfFluidCtrlHR.EvapTempFixed = rNumericArgs(9);
2936 3 : thisVrfFluidCtrlHR.CondTempFixed = rNumericArgs(10);
2937 :
2938 : // Bounds of Te/Tc for IU Control Algorithm: VariableTemp
2939 3 : thisVrfFluidCtrlHR.IUEvapTempLow = rNumericArgs(11);
2940 3 : thisVrfFluidCtrlHR.IUEvapTempHigh = rNumericArgs(12);
2941 3 : thisVrfFluidCtrlHR.IUCondTempLow = rNumericArgs(13);
2942 3 : thisVrfFluidCtrlHR.IUCondTempHigh = rNumericArgs(14);
2943 3 : if (thisVrfFluidCtrlHR.IUEvapTempLow >= thisVrfFluidCtrlHR.IUEvapTempHigh) {
2944 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\"");
2945 0 : ShowContinueError(state,
2946 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2947 : cNumericFieldNames(11),
2948 0 : thisVrfFluidCtrlHR.IUEvapTempLow,
2949 0 : thisVrfFluidCtrlHR.IUEvapTempHigh));
2950 0 : ErrorsFound = true;
2951 : }
2952 3 : if (thisVrfFluidCtrlHR.IUCondTempLow >= thisVrfFluidCtrlHR.IUCondTempHigh) {
2953 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\"");
2954 0 : ShowContinueError(state,
2955 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2956 : cNumericFieldNames(13),
2957 0 : thisVrfFluidCtrlHR.IUCondTempLow,
2958 0 : thisVrfFluidCtrlHR.IUCondTempHigh));
2959 0 : ErrorsFound = true;
2960 : }
2961 :
2962 : // Reference OU SH/SC
2963 3 : thisVrfFluidCtrlHR.SH = rNumericArgs(15);
2964 3 : thisVrfFluidCtrlHR.SC = rNumericArgs(16);
2965 3 : if (thisVrfFluidCtrlHR.SH > 20) {
2966 0 : ShowWarningError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\", \" " + cNumericFieldNames(15));
2967 0 : ShowContinueError(state, "...is higher than 20C, which is usually the maximum of normal range.");
2968 : }
2969 3 : if (thisVrfFluidCtrlHR.SC > 20) {
2970 0 : ShowWarningError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\", \" " + cNumericFieldNames(15));
2971 0 : ShowContinueError(state, "...is higher than 20C, which is usually the maximum of normal range.");
2972 : }
2973 :
2974 : // OU Heat Exchanger Rated Bypass Factor
2975 3 : thisVrfFluidCtrlHR.RateBFOUEvap = rNumericArgs(17);
2976 3 : thisVrfFluidCtrlHR.RateBFOUCond = rNumericArgs(18);
2977 :
2978 : // Difference between Outdoor Unit Te and OAT during Simultaneous Heating and Cooling operations
2979 3 : thisVrfFluidCtrlHR.DiffOUTeTo = rNumericArgs(19);
2980 :
2981 : // HR OU Heat Exchanger Capacity Ratio
2982 3 : thisVrfFluidCtrlHR.HROUHexRatio = rNumericArgs(20);
2983 :
2984 : // Get OU fan data
2985 3 : thisVrfFluidCtrlHR.RatedOUFanPowerPerCapcity = rNumericArgs(21);
2986 3 : thisVrfFluidCtrlHR.OUAirFlowRatePerCapcity = rNumericArgs(22);
2987 3 : thisVrfFluidCtrlHR.RatedOUFanPower = thisVrfFluidCtrlHR.RatedOUFanPowerPerCapcity * thisVrfFluidCtrlHR.RatedEvapCapacity;
2988 3 : thisVrfFluidCtrlHR.OUAirFlowRate = thisVrfFluidCtrlHR.OUAirFlowRatePerCapcity * thisVrfFluidCtrlHR.RatedEvapCapacity;
2989 :
2990 : // OUEvapTempCurve
2991 3 : int indexOUEvapTempCurve = GetCurveIndex(state, cAlphaArgs(6)); // convert curve name to index number
2992 : // Verify curve name and type
2993 3 : if (indexOUEvapTempCurve == 0) {
2994 0 : if (lAlphaFieldBlanks(6)) {
2995 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", missing");
2996 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(6) + " is blank.");
2997 : } else {
2998 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", invalid");
2999 0 : ShowContinueError(state, "...not found " + cAlphaFieldNames(6) + "=\"" + cAlphaArgs(6) + "\".");
3000 : }
3001 0 : ErrorsFound = true;
3002 : } else {
3003 3 : if (state.dataCurveManager->curves(indexOUEvapTempCurve)->curveType == Curve::CurveType::Quadratic) {
3004 3 : thisVrfFluidCtrlHR.C1Te = state.dataCurveManager->curves(indexOUEvapTempCurve)->coeff[0];
3005 3 : thisVrfFluidCtrlHR.C2Te = state.dataCurveManager->curves(indexOUEvapTempCurve)->coeff[1];
3006 3 : thisVrfFluidCtrlHR.C3Te = state.dataCurveManager->curves(indexOUEvapTempCurve)->coeff[2];
3007 : } else {
3008 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", invalid");
3009 0 : ShowContinueError(state,
3010 0 : format("...illegal {} type for this object = {}",
3011 : cAlphaFieldNames(6),
3012 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexOUEvapTempCurve)->curveType)]));
3013 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
3014 0 : ErrorsFound = true;
3015 : }
3016 : }
3017 :
3018 : // OUCondTempCurve
3019 3 : int indexOUCondTempCurve = GetCurveIndex(state, cAlphaArgs(7)); // convert curve name to index number
3020 : // Verify curve name and type
3021 3 : if (indexOUCondTempCurve == 0) {
3022 0 : if (lAlphaFieldBlanks(7)) {
3023 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", missing");
3024 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(7) + " is blank.");
3025 : } else {
3026 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", invalid");
3027 0 : ShowContinueError(state, "...not found " + cAlphaFieldNames(7) + "=\"" + cAlphaArgs(7) + "\".");
3028 : }
3029 0 : ErrorsFound = true;
3030 : } else {
3031 3 : if (state.dataCurveManager->curves(indexOUCondTempCurve)->curveType == Curve::CurveType::Quadratic) {
3032 3 : thisVrfFluidCtrlHR.C1Tc = state.dataCurveManager->curves(indexOUCondTempCurve)->coeff[0];
3033 3 : thisVrfFluidCtrlHR.C2Tc = state.dataCurveManager->curves(indexOUCondTempCurve)->coeff[1];
3034 3 : thisVrfFluidCtrlHR.C3Tc = state.dataCurveManager->curves(indexOUCondTempCurve)->coeff[2];
3035 : } else {
3036 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", invalid");
3037 0 : ShowContinueError(state,
3038 0 : format("...illegal {} type for this object = {}",
3039 : cAlphaFieldNames(7),
3040 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexOUCondTempCurve)->curveType)]));
3041 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
3042 0 : ErrorsFound = true;
3043 : }
3044 : }
3045 :
3046 : // Pipe parameters
3047 3 : thisVrfFluidCtrlHR.RefPipDiaSuc = rNumericArgs(23);
3048 3 : thisVrfFluidCtrlHR.RefPipDiaDis = rNumericArgs(24);
3049 3 : thisVrfFluidCtrlHR.RefPipLen = rNumericArgs(25);
3050 3 : thisVrfFluidCtrlHR.RefPipEquLen = rNumericArgs(26);
3051 3 : thisVrfFluidCtrlHR.RefPipHei = rNumericArgs(27);
3052 3 : thisVrfFluidCtrlHR.RefPipInsThi = rNumericArgs(28);
3053 3 : thisVrfFluidCtrlHR.RefPipInsCon = rNumericArgs(29);
3054 :
3055 : // Check the RefPipEquLen
3056 3 : if (lNumericFieldBlanks(26) && !lNumericFieldBlanks(25)) {
3057 0 : thisVrfFluidCtrlHR.RefPipEquLen = 1.2 * thisVrfFluidCtrlHR.RefPipLen;
3058 0 : ShowWarningError(
3059 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\", \" " + cNumericFieldNames(26) + "\" is calculated based on");
3060 0 : ShowContinueError(state, "...the provided \"" + cNumericFieldNames(25) + "\" value.");
3061 : }
3062 3 : if (thisVrfFluidCtrlHR.RefPipEquLen < thisVrfFluidCtrlHR.RefPipLen) {
3063 0 : thisVrfFluidCtrlHR.RefPipEquLen = 1.2 * thisVrfFluidCtrlHR.RefPipLen;
3064 0 : ShowWarningError(state,
3065 0 : cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\", invalid \" " + cNumericFieldNames(26) + "\" value.");
3066 0 : ShowContinueError(state, "...Equivalent length of main pipe should be greater than or equal to the actual length.");
3067 0 : ShowContinueError(state, format("...The value is recalculated based on the provided \"{}\" value.", cNumericFieldNames(25)));
3068 : }
3069 :
3070 : // Crank case
3071 3 : thisVrfFluidCtrlHR.CCHeaterPower = rNumericArgs(30);
3072 3 : thisVrfFluidCtrlHR.NumCompressors = rNumericArgs(31);
3073 3 : thisVrfFluidCtrlHR.CompressorSizeRatio = rNumericArgs(32);
3074 3 : thisVrfFluidCtrlHR.MaxOATCCHeater = rNumericArgs(33);
3075 :
3076 : // Defrost
3077 3 : if (!lAlphaFieldBlanks(8)) {
3078 0 : if (Util::SameString(cAlphaArgs(8), "ReverseCycle")) thisVrfFluidCtrlHR.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
3079 0 : if (Util::SameString(cAlphaArgs(8), "Resistive")) thisVrfFluidCtrlHR.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
3080 0 : if (thisVrfFluidCtrlHR.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
3081 0 : ShowSevereError(
3082 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\" " + cAlphaFieldNames(8) + " not found: " + cAlphaArgs(8));
3083 0 : ErrorsFound = true;
3084 : }
3085 : } else {
3086 3 : thisVrfFluidCtrlHR.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
3087 : }
3088 :
3089 3 : if (!lAlphaFieldBlanks(9)) {
3090 0 : if (Util::SameString(cAlphaArgs(9), "Timed")) thisVrfFluidCtrlHR.DefrostControl = StandardRatings::HPdefrostControl::Timed;
3091 0 : if (Util::SameString(cAlphaArgs(9), "OnDemand")) thisVrfFluidCtrlHR.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
3092 0 : if (thisVrfFluidCtrlHR.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
3093 0 : ShowSevereError(
3094 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\" " + cAlphaFieldNames(9) + " not found: " + cAlphaArgs(9));
3095 0 : ErrorsFound = true;
3096 : }
3097 : } else {
3098 3 : thisVrfFluidCtrlHR.DefrostControl = StandardRatings::HPdefrostControl::Timed;
3099 : }
3100 :
3101 3 : if (!lAlphaFieldBlanks(10)) {
3102 0 : thisVrfFluidCtrlHR.DefrostEIRPtr = GetCurveIndex(state, cAlphaArgs(10));
3103 0 : if (thisVrfFluidCtrlHR.DefrostEIRPtr > 0) {
3104 : // Verify Curve Object, expected type is BiQuadratic
3105 0 : ErrorsFound |= Curve::CheckCurveDims(state,
3106 : thisVrfFluidCtrlHR.DefrostEIRPtr, // Curve index
3107 : {2}, // Valid dimensions
3108 : RoutineName, // Routine name
3109 : cCurrentModuleObject, // Object Type
3110 : thisVrfFluidCtrlHR.Name, // Object Name
3111 0 : cAlphaFieldNames(10)); // Field Name
3112 : } else {
3113 0 : if (thisVrfFluidCtrlHR.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle &&
3114 0 : thisVrfFluidCtrlHR.DefrostControl == StandardRatings::HPdefrostControl::OnDemand) {
3115 0 : ShowSevereError(state,
3116 0 : cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\" " + cAlphaFieldNames(10) +
3117 0 : " not found:" + cAlphaArgs(10));
3118 0 : ErrorsFound = true;
3119 : }
3120 : }
3121 : } else {
3122 3 : if (thisVrfFluidCtrlHR.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle &&
3123 3 : thisVrfFluidCtrlHR.DefrostControl == StandardRatings::HPdefrostControl::OnDemand) {
3124 0 : ShowSevereError(
3125 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\" " + cAlphaFieldNames(10) + " not found:" + cAlphaArgs(10));
3126 0 : ErrorsFound = true;
3127 : }
3128 : }
3129 :
3130 3 : thisVrfFluidCtrlHR.DefrostFraction = rNumericArgs(34);
3131 3 : thisVrfFluidCtrlHR.DefrostCapacity = rNumericArgs(35);
3132 3 : thisVrfFluidCtrlHR.MaxOATDefrost = rNumericArgs(36);
3133 3 : if (thisVrfFluidCtrlHR.DefrostCapacity == 0.0 && thisVrfFluidCtrlHR.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
3134 0 : ShowWarningError(state,
3135 0 : cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\" " + cNumericFieldNames(35) +
3136 : " = 0.0 for defrost strategy = RESISTIVE.");
3137 : }
3138 :
3139 : // HR mode transition
3140 3 : thisVrfFluidCtrlHR.HRInitialCoolCapFrac = rNumericArgs(37);
3141 3 : thisVrfFluidCtrlHR.HRCoolCapTC = rNumericArgs(38);
3142 3 : thisVrfFluidCtrlHR.HRInitialCoolEIRFrac = rNumericArgs(39);
3143 3 : thisVrfFluidCtrlHR.HRCoolEIRTC = rNumericArgs(40);
3144 3 : thisVrfFluidCtrlHR.HRInitialHeatCapFrac = rNumericArgs(41);
3145 3 : thisVrfFluidCtrlHR.HRHeatCapTC = rNumericArgs(42);
3146 3 : thisVrfFluidCtrlHR.HRInitialHeatEIRFrac = rNumericArgs(43);
3147 3 : thisVrfFluidCtrlHR.HRHeatEIRTC = rNumericArgs(44);
3148 :
3149 : // Compressor configuration
3150 3 : thisVrfFluidCtrlHR.CompMaxDeltaP = rNumericArgs(45);
3151 3 : thisVrfFluidCtrlHR.EffCompInverter = rNumericArgs(46);
3152 3 : thisVrfFluidCtrlHR.CoffEvapCap = rNumericArgs(47);
3153 :
3154 : // The new VRF model is Air cooled
3155 3 : thisVrfFluidCtrlHR.CondenserType = DataHeatBalance::RefrigCondenserType::Air;
3156 3 : thisVrfFluidCtrlHR.CondenserNodeNum = 0;
3157 :
3158 : // Evaporative Capacity & Compressor Power Curves corresponding to each Loading Index / compressor speed
3159 3 : int NumOfCompSpd = rNumericArgs(48);
3160 3 : thisVrfFluidCtrlHR.CompressorSpeed.dimension(NumOfCompSpd);
3161 3 : thisVrfFluidCtrlHR.OUCoolingCAPFT.dimension(NumOfCompSpd);
3162 3 : thisVrfFluidCtrlHR.OUCoolingPWRFT.dimension(NumOfCompSpd);
3163 3 : int Count1Index = 48; // the index of the last numeric field before compressor speed entries
3164 3 : int Count2Index = 9; // the index of the last alpha field before capacity/power curves
3165 12 : for (int NumCompSpd = 1; NumCompSpd <= NumOfCompSpd; NumCompSpd++) {
3166 9 : thisVrfFluidCtrlHR.CompressorSpeed(NumCompSpd) = rNumericArgs(Count1Index + NumCompSpd);
3167 :
3168 : // Evaporating Capacity Curve
3169 9 : if (!lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd)) {
3170 9 : int indexOUEvapCapCurve = GetCurveIndex(state, cAlphaArgs(Count2Index + 2 * NumCompSpd)); // convert curve name to index number
3171 9 : if (indexOUEvapCapCurve == 0) { // Verify curve name and type
3172 0 : if (lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd)) {
3173 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", missing");
3174 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(Count2Index + 2 * NumCompSpd) + " is blank.");
3175 : } else {
3176 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", invalid");
3177 0 : ShowContinueError(state,
3178 0 : format("...not found {}=\"{}\".",
3179 0 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd),
3180 0 : cAlphaArgs(Count2Index + 2 * NumCompSpd)));
3181 : }
3182 0 : ErrorsFound = true;
3183 : } else {
3184 18 : ErrorsFound |= Curve::CheckCurveDims(state,
3185 : indexOUEvapCapCurve, // Curve index
3186 : {2}, // Valid dimensions
3187 : RoutineName, // Routine name
3188 : cCurrentModuleObject, // Object Type
3189 : thisVrfFluidCtrlHR.Name, // Object Name
3190 9 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd)); // Field Name
3191 :
3192 9 : if (!ErrorsFound) {
3193 9 : thisVrfFluidCtrlHR.OUCoolingCAPFT(NumCompSpd) = indexOUEvapCapCurve;
3194 : }
3195 : }
3196 : }
3197 :
3198 : // Compressor Power Curve
3199 9 : if (!lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd + 1)) {
3200 9 : int indexOUCompPwrCurve = GetCurveIndex(state, cAlphaArgs(Count2Index + 2 * NumCompSpd + 1)); // convert curve name to index number
3201 9 : if (indexOUCompPwrCurve == 0) { // Verify curve name and type
3202 0 : if (lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd + 1)) {
3203 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", missing");
3204 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(Count2Index + 2 * NumCompSpd + 1) + " is blank.");
3205 : } else {
3206 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", invalid");
3207 0 : ShowContinueError(state,
3208 0 : format("...not found {}=\"{}\".",
3209 0 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd + 1),
3210 0 : cAlphaArgs(Count2Index + 2 * NumCompSpd + 1)));
3211 : }
3212 0 : ErrorsFound = true;
3213 : } else {
3214 18 : ErrorsFound |= Curve::CheckCurveDims(state,
3215 : indexOUCompPwrCurve, // Curve index
3216 : {2}, // Valid dimensions
3217 : RoutineName, // Routine name
3218 : cCurrentModuleObject, // Object Type
3219 : thisVrfFluidCtrlHR.Name, // Object Name
3220 9 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd + 1)); // Field Name
3221 :
3222 9 : if (!ErrorsFound) {
3223 9 : thisVrfFluidCtrlHR.OUCoolingPWRFT(NumCompSpd) = indexOUCompPwrCurve;
3224 : }
3225 : }
3226 : }
3227 : }
3228 : }
3229 :
3230 23 : cCurrentModuleObject = "ZoneHVAC:TerminalUnit:VariableRefrigerantFlow";
3231 57 : for (int VRFTUNum = 1; VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU; ++VRFTUNum) {
3232 :
3233 : // initialize local node number variables
3234 34 : int CCoilInletNodeNum = 0;
3235 34 : int CCoilOutletNodeNum = 0;
3236 34 : int HCoilInletNodeNum = 0;
3237 34 : int HCoilOutletNodeNum = 0;
3238 34 : OANodeNums = 0;
3239 :
3240 34 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3241 : cCurrentModuleObject,
3242 : VRFTUNum,
3243 : cAlphaArgs,
3244 : NumAlphas,
3245 : rNumericArgs,
3246 : NumNums,
3247 : IOStat,
3248 : lNumericFieldBlanks,
3249 : lAlphaFieldBlanks,
3250 : cAlphaFieldNames,
3251 : cNumericFieldNames);
3252 :
3253 34 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
3254 :
3255 34 : state.dataHVACVarRefFlow->VRFTUNumericFields(VRFTUNum).FieldNames.allocate(NumNums);
3256 34 : state.dataHVACVarRefFlow->VRFTUNumericFields(VRFTUNum).FieldNames = cNumericFieldNames;
3257 34 : Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
3258 :
3259 34 : auto &thisVrfTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
3260 34 : thisVrfTU.Name = cAlphaArgs(1);
3261 42 : for (int NumList = 1; NumList <= state.dataHVACVarRefFlow->NumVRFTULists; ++NumList) {
3262 41 : int ZoneTerminalUnitListNum = Util::FindItemInList(thisVrfTU.Name,
3263 41 : state.dataHVACVarRefFlow->TerminalUnitList(NumList).ZoneTUName,
3264 41 : state.dataHVACVarRefFlow->TerminalUnitList(NumList).NumTUInList);
3265 41 : if (ZoneTerminalUnitListNum > 0) {
3266 33 : thisVrfTU.IndexToTUInTUList = ZoneTerminalUnitListNum;
3267 33 : state.dataHVACVarRefFlow->TerminalUnitList(NumList).ZoneTUPtr(ZoneTerminalUnitListNum) = VRFTUNum;
3268 33 : thisVrfTU.TUListIndex = NumList;
3269 33 : break;
3270 : }
3271 : }
3272 34 : if (thisVrfTU.TUListIndex == 0) {
3273 1 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfTU.Name);
3274 2 : ShowContinueError(state, "Terminal unit not found on any ZoneTerminalUnitList.");
3275 1 : ErrorsFound = true;
3276 : }
3277 :
3278 41 : for (int NumCond = 1; NumCond <= state.dataHVACVarRefFlow->NumVRFCond; ++NumCond) {
3279 40 : if (state.dataHVACVarRefFlow->VRF(NumCond).ZoneTUListPtr != thisVrfTU.TUListIndex) continue;
3280 33 : thisVrfTU.VRFSysNum = NumCond;
3281 33 : break;
3282 : }
3283 34 : thisVrfTU.type = TUType::ConstantVolume;
3284 34 : if (lAlphaFieldBlanks(2)) {
3285 4 : thisVrfTU.availSched = Sched::GetScheduleAlwaysOn(state);
3286 30 : } else if ((thisVrfTU.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
3287 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
3288 0 : ErrorsFound = true;
3289 : }
3290 :
3291 34 : thisVrfTU.VRFTUInletNodeNum = GetOnlySingleNode(state,
3292 34 : cAlphaArgs(3),
3293 : ErrorsFound,
3294 : DataLoopNode::ConnectionObjectType::ZoneHVACTerminalUnitVariableRefrigerantFlow,
3295 34 : thisVrfTU.Name,
3296 : DataLoopNode::NodeFluidType::Air,
3297 : DataLoopNode::ConnectionType::Inlet,
3298 : NodeInputManager::CompFluidStream::Primary,
3299 : ObjectIsParent);
3300 :
3301 34 : thisVrfTU.VRFTUOutletNodeNum = GetOnlySingleNode(state,
3302 34 : cAlphaArgs(4),
3303 : ErrorsFound,
3304 : DataLoopNode::ConnectionObjectType::ZoneHVACTerminalUnitVariableRefrigerantFlow,
3305 34 : thisVrfTU.Name,
3306 : DataLoopNode::NodeFluidType::Air,
3307 : DataLoopNode::ConnectionType::Outlet,
3308 : NodeInputManager::CompFluidStream::Primary,
3309 : ObjectIsParent);
3310 :
3311 34 : thisVrfTU.MaxCoolAirVolFlow = rNumericArgs(1);
3312 34 : thisVrfTU.MaxNoCoolAirVolFlow = rNumericArgs(2);
3313 34 : thisVrfTU.MaxHeatAirVolFlow = rNumericArgs(3);
3314 34 : thisVrfTU.MaxNoHeatAirVolFlow = rNumericArgs(4);
3315 34 : thisVrfTU.CoolOutAirVolFlow = rNumericArgs(5);
3316 34 : thisVrfTU.HeatOutAirVolFlow = rNumericArgs(6);
3317 34 : thisVrfTU.NoCoolHeatOutAirVolFlow = rNumericArgs(7);
3318 :
3319 34 : if (lAlphaFieldBlanks(5)) {
3320 0 : thisVrfTU.fanOp = HVAC::FanOp::Continuous;
3321 34 : } else if ((thisVrfTU.fanOpModeSched = Sched::GetSchedule(state, cAlphaArgs(5))) == nullptr) {
3322 18 : ShowWarningItemNotFound(
3323 9 : state, eoh, cAlphaFieldNames(5), cAlphaArgs(5), "Defaulting to constant fan operating mode and simulation continues.");
3324 9 : thisVrfTU.fanOp = HVAC::FanOp::Continuous;
3325 : }
3326 :
3327 34 : thisVrfTU.fanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, cAlphaArgs(6)));
3328 34 : assert(thisVrfTU.fanPlace != HVAC::FanPlace::Invalid);
3329 :
3330 34 : if (!lAlphaFieldBlanks(7) && !lAlphaFieldBlanks(8)) {
3331 : // Get fan data
3332 34 : std::string FanName = cAlphaArgs(8);
3333 :
3334 34 : thisVrfTU.fanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, cAlphaArgs(7)));
3335 :
3336 34 : if (thisVrfTU.fanType != HVAC::FanType::OnOff && thisVrfTU.fanType != HVAC::FanType::Constant &&
3337 20 : thisVrfTU.fanType != HVAC::FanType::VAV && thisVrfTU.fanType != HVAC::FanType::SystemModel) {
3338 0 : ShowSevereInvalidKey(state,
3339 : eoh,
3340 0 : cAlphaFieldNames(7),
3341 0 : cAlphaArgs(7),
3342 : "Only types Fan:ConstantVolume, Fan:VAV, Fan:OnOff, and Fan:SystemModel are supported");
3343 0 : ErrorsFound = true;
3344 : }
3345 :
3346 34 : if ((thisVrfTU.FanIndex = Fans::GetFanIndex(state, FanName)) == 0) {
3347 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(8), FanName);
3348 0 : ErrorsFound = true;
3349 :
3350 34 : } else if (thisVrfTU.fanType != state.dataFans->fans(thisVrfTU.FanIndex)->type) {
3351 0 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfTU.Name);
3352 0 : ShowContinueError(state, "Fan type specified = " + cAlphaArgs(7));
3353 0 : ShowContinueError(state, format("Actual type of fan {} = {}", FanName, HVAC::fanTypeNames[(int)thisVrfTU.fanType]));
3354 0 : ErrorsFound = true;
3355 : }
3356 :
3357 34 : if (thisVrfTU.VRFSysNum > 0) {
3358 : // VRFTU Supply Air Fan Object Type must be Fan:VariableVolume if VRF Algorithm Type is AlgorithmTypeFluidTCtrl
3359 44 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFAlgorithmType == AlgorithmType::FluidTCtrl &&
3360 11 : !(thisVrfTU.fanType == HVAC::FanType::VAV || thisVrfTU.fanType == HVAC::FanType::SystemModel)) {
3361 0 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfTU.Name);
3362 0 : ShowContinueError(state, "Fan type specified = " + cAlphaArgs(7));
3363 0 : ShowContinueError(
3364 : state, "Fan Object Type must be Fan:VariableVolume if VRF AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl");
3365 0 : ShowContinueError(state, "is used to model VRF outdoor unit.");
3366 0 : ErrorsFound = true;
3367 : }
3368 : // VRFTU Supply Air Fan Object Type must be Fan:OnOff or Fan:ConstantVolume if VRF Algorithm Type is AlgorithmTypeSysCurve
3369 55 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFAlgorithmType == AlgorithmType::SysCurve &&
3370 22 : !(thisVrfTU.fanType == HVAC::FanType::OnOff || thisVrfTU.fanType == HVAC::FanType::Constant ||
3371 9 : thisVrfTU.fanType == HVAC::FanType::SystemModel)) {
3372 0 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfTU.Name);
3373 0 : ShowContinueError(state, "Fan type specified = " + cAlphaArgs(7));
3374 0 : ShowContinueError(state,
3375 : "Fan Object Type must be Fan:SystemModel, Fan:OnOff, or Fan:ConstantVolume if VRF "
3376 : "AirConditioner:VariableRefrigerantFlow");
3377 0 : ShowContinueError(state, "is used to model VRF outdoor unit.");
3378 0 : ErrorsFound = true;
3379 : }
3380 : }
3381 :
3382 34 : auto *fan = state.dataFans->fans(thisVrfTU.FanIndex);
3383 :
3384 34 : thisVrfTU.fanInletNode = fan->inletNodeNum;
3385 34 : thisVrfTU.fanOutletNode = fan->outletNodeNum;
3386 :
3387 34 : Real64 FanVolFlowRate = fan->maxAirFlowRate;
3388 34 : thisVrfTU.ActualFanVolFlowRate = FanVolFlowRate;
3389 34 : int FanInletNodeNum = fan->inletNodeNum;
3390 34 : int FanOutletNodeNum = fan->outletNodeNum;
3391 34 : thisVrfTU.fanAvailSched = fan->availSched;
3392 :
3393 : // Check fan's schedule for cycling fan operation if constant volume fan is used
3394 34 : if (thisVrfTU.fanOpModeSched != nullptr && thisVrfTU.fanType == HVAC::FanType::Constant) {
3395 7 : if (!thisVrfTU.fanOpModeSched->checkMinMaxVals(state, Clusive::Ex, 0.0, Clusive::In, 1.0)) {
3396 0 : Sched::ShowSevereBadMinMax(state,
3397 : eoh,
3398 0 : cAlphaFieldNames(5),
3399 0 : cAlphaArgs(5),
3400 : Clusive::Ex,
3401 : 0.0,
3402 : Clusive::In,
3403 : 1.0,
3404 0 : format("For fan type = {}, operating mode must be continuous (schedule values > 0).",
3405 0 : HVAC::fanTypeNames[(int)HVAC::FanType::Constant]));
3406 0 : ErrorsFound = true;
3407 : }
3408 : } // IF (FanType_Num == HVAC::FanType_SimpleOnOff .OR. FanType_Num == HVAC::FanType_SimpleConstVolume)THEN
3409 :
3410 : // Add TU to component sets array
3411 102 : SetUpCompSets(state,
3412 : cCurrentModuleObject,
3413 : thisVrfTU.Name,
3414 34 : HVAC::fanTypeNames[(int)thisVrfTU.fanType],
3415 : FanName,
3416 34 : state.dataLoopNodes->NodeID(FanInletNodeNum),
3417 34 : state.dataLoopNodes->NodeID(FanOutletNodeNum));
3418 :
3419 34 : } else {
3420 0 : thisVrfTU.fanPlace = HVAC::FanPlace::Invalid; // reset fan placement when fan is not used so as not to call the fan
3421 0 : thisVrfTU.fanAvailSched =
3422 0 : Sched::GetScheduleAlwaysOn(state); // A missing fan is the same as a fan that is always on for availability purposes
3423 : }
3424 :
3425 : // Get OA mixer data
3426 34 : std::string OAMixerType = cAlphaArgs(9);
3427 :
3428 34 : if (!lAlphaFieldBlanks(10)) {
3429 26 : thisVrfTU.OAMixerName = cAlphaArgs(10);
3430 26 : errFlag = false;
3431 26 : OANodeNums = GetOAMixerNodeNumbers(state, thisVrfTU.OAMixerName, errFlag);
3432 :
3433 : // OANodeNums(1) = OAMixer(OAMixerNum)%InletNode
3434 : // OANodeNums(2) = OAMixer(OAMixerNum)%RelNode
3435 : // OANodeNums(3) = OAMixer(OAMixerNum)%RetNode
3436 : // OANodeNums(4) = OAMixer(OAMixerNum)%MixNode
3437 :
3438 26 : if (errFlag) {
3439 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
3440 0 : ErrorsFound = true;
3441 : } else {
3442 26 : thisVrfTU.OAMixerUsed = true;
3443 : }
3444 26 : thisVrfTU.VRFTUOAMixerOANodeNum = OANodeNums(1);
3445 26 : thisVrfTU.VRFTUOAMixerRelNodeNum = OANodeNums(2);
3446 26 : thisVrfTU.VRFTUOAMixerRetNodeNum = OANodeNums(3);
3447 26 : thisVrfTU.VRFTUOAMixerMixedNodeNum = OANodeNums(4);
3448 : }
3449 :
3450 : // Get DX cooling coil data
3451 34 : std::string DXCoolingCoilType = cAlphaArgs(11);
3452 :
3453 34 : errFlag = false;
3454 34 : thisVrfTU.DXCoolCoilType_Num = GetCoilTypeNum(state, DXCoolingCoilType, cAlphaArgs(12), errFlag, false);
3455 34 : if (thisVrfTU.DXCoolCoilType_Num == 0) {
3456 0 : thisVrfTU.CoolingCoilPresent = false;
3457 0 : if (thisVrfTU.TUListIndex > 0 && thisVrfTU.IndexToTUInTUList > 0) {
3458 0 : state.dataHVACVarRefFlow->TerminalUnitList(thisVrfTU.TUListIndex).CoolingCoilPresent(thisVrfTU.IndexToTUInTUList) = false;
3459 : }
3460 : } else {
3461 34 : if (thisVrfTU.VRFSysNum > 0) {
3462 33 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
3463 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
3464 :
3465 11 : if (Util::SameString(HVAC::cAllCoilTypes(thisVrfTU.DXCoolCoilType_Num), HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling))) {
3466 11 : errFlag = false;
3467 11 : if (thisVrfTU.TUListIndex > 0 && thisVrfTU.IndexToTUInTUList > 0) {
3468 11 : state.dataHVACVarRefFlow->TerminalUnitList(thisVrfTU.TUListIndex).coolingCoilAvailScheds(thisVrfTU.IndexToTUInTUList) =
3469 22 : DXCoils::GetDXCoilAvailSched(state, DXCoolingCoilType, cAlphaArgs(12), errFlag);
3470 : }
3471 22 : GetDXCoilIndex(
3472 11 : state, cAlphaArgs(12), thisVrfTU.CoolCoilIndex, errFlag, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling));
3473 : CCoilInletNodeNum =
3474 11 : DXCoils::GetCoilInletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling), cAlphaArgs(12), errFlag);
3475 : CCoilOutletNodeNum =
3476 11 : DXCoils::GetCoilOutletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling), cAlphaArgs(12), errFlag);
3477 11 : thisVrfTU.coolCoilAirInNode = CCoilInletNodeNum;
3478 11 : thisVrfTU.coolCoilAirOutNode = CCoilOutletNodeNum;
3479 :
3480 11 : if (errFlag) ShowContinueError(state, "...occurs in " + cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3481 :
3482 11 : if (thisVrfTU.VRFSysNum > 0) {
3483 22 : SetDXCoolingCoilData(
3484 11 : state, thisVrfTU.CoolCoilIndex, ErrorsFound, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserType);
3485 22 : SetDXCoolingCoilData(state,
3486 : thisVrfTU.CoolCoilIndex,
3487 : ErrorsFound,
3488 : _,
3489 : _,
3490 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserNodeNum);
3491 22 : SetDXCoolingCoilData(state,
3492 : thisVrfTU.CoolCoilIndex,
3493 : ErrorsFound,
3494 : _,
3495 : _,
3496 : _,
3497 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATCCHeater);
3498 22 : SetDXCoolingCoilData(state,
3499 : thisVrfTU.CoolCoilIndex,
3500 : ErrorsFound,
3501 : _,
3502 : _,
3503 : _,
3504 : _,
3505 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MinOATCooling);
3506 22 : SetDXCoolingCoilData(state,
3507 : thisVrfTU.CoolCoilIndex,
3508 : ErrorsFound,
3509 : _,
3510 : _,
3511 : _,
3512 : _,
3513 : _,
3514 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATCooling);
3515 :
3516 11 : state.dataDXCoils->DXCoil(thisVrfTU.CoolCoilIndex).VRFIUPtr = VRFTUNum;
3517 11 : state.dataDXCoils->DXCoil(thisVrfTU.CoolCoilIndex).VRFOUPtr = thisVrfTU.VRFSysNum;
3518 11 : state.dataDXCoils->DXCoil(thisVrfTU.CoolCoilIndex).SupplyFanIndex = thisVrfTU.FanIndex;
3519 :
3520 11 : if (thisVrfTU.FanIndex > 0) {
3521 11 : state.dataDXCoils->DXCoil(thisVrfTU.CoolCoilIndex).RatedAirVolFlowRate(1) =
3522 11 : state.dataFans->fans(thisVrfTU.FanIndex)->maxAirFlowRate;
3523 : } else {
3524 0 : state.dataDXCoils->DXCoil(thisVrfTU.CoolCoilIndex).RatedAirVolFlowRate(1) = AutoSize;
3525 : }
3526 :
3527 : } else {
3528 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3529 0 : ShowContinueError(
3530 0 : state, "... when checking " + HVAC::cAllCoilTypes(thisVrfTU.DXCoolCoilType_Num) + " \"" + cAlphaArgs(12) + "\"");
3531 0 : ShowContinueError(state, "... terminal unit not connected to condenser.");
3532 0 : ShowContinueError(state, "... check that terminal unit is specified in a terminal unit list object.");
3533 0 : ShowContinueError(state,
3534 : "... also check that the terminal unit list name is specified in an "
3535 : "AirConditioner:VariableRefrigerantFlow object.");
3536 0 : ErrorsFound = true;
3537 : }
3538 : } else {
3539 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3540 0 : ShowContinueError(state, "... illegal " + cAlphaFieldNames(12) + " = " + cAlphaArgs(12));
3541 0 : ErrorsFound = true;
3542 : }
3543 :
3544 : } else {
3545 : // Algorithm Type: VRF model based on system curve
3546 :
3547 22 : if (Util::SameString(HVAC::cAllCoilTypes(thisVrfTU.DXCoolCoilType_Num), HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling))) {
3548 22 : if (thisVrfTU.TUListIndex > 0 && thisVrfTU.IndexToTUInTUList > 0) {
3549 22 : state.dataHVACVarRefFlow->TerminalUnitList(thisVrfTU.TUListIndex).coolingCoilAvailScheds(thisVrfTU.IndexToTUInTUList) =
3550 44 : DXCoils::GetDXCoilAvailSched(state, DXCoolingCoilType, cAlphaArgs(12), errFlag);
3551 : } else {
3552 0 : thisVrfTU.CoolingCoilPresent = false;
3553 : }
3554 22 : errFlag = false;
3555 22 : GetDXCoilIndex(state, cAlphaArgs(12), thisVrfTU.CoolCoilIndex, errFlag, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling));
3556 22 : CCoilInletNodeNum = DXCoils::GetCoilInletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling), cAlphaArgs(12), errFlag);
3557 22 : CCoilOutletNodeNum = DXCoils::GetCoilOutletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling), cAlphaArgs(12), errFlag);
3558 22 : thisVrfTU.coolCoilAirInNode = CCoilInletNodeNum;
3559 22 : thisVrfTU.coolCoilAirOutNode = CCoilOutletNodeNum;
3560 :
3561 22 : if (errFlag) ShowContinueError(state, "...occurs in " + cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3562 :
3563 44 : SetDXCoolingCoilData(
3564 22 : state, thisVrfTU.CoolCoilIndex, ErrorsFound, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserType);
3565 44 : SetDXCoolingCoilData(
3566 22 : state, thisVrfTU.CoolCoilIndex, ErrorsFound, _, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserNodeNum);
3567 44 : SetDXCoolingCoilData(
3568 22 : state, thisVrfTU.CoolCoilIndex, ErrorsFound, _, _, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATCCHeater);
3569 44 : SetDXCoolingCoilData(state,
3570 : thisVrfTU.CoolCoilIndex,
3571 : ErrorsFound,
3572 : _,
3573 : _,
3574 : _,
3575 : _,
3576 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MinOATCooling);
3577 44 : SetDXCoolingCoilData(state,
3578 : thisVrfTU.CoolCoilIndex,
3579 : ErrorsFound,
3580 : _,
3581 : _,
3582 : _,
3583 : _,
3584 : _,
3585 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATCooling);
3586 :
3587 : } else {
3588 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3589 0 : ShowContinueError(state, "... illegal " + cAlphaFieldNames(12) + " = " + cAlphaArgs(12));
3590 0 : ErrorsFound = true;
3591 : }
3592 : }
3593 : } else {
3594 1 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3595 1 : ShowContinueError(state, "... when checking " + HVAC::cAllCoilTypes(thisVrfTU.DXCoolCoilType_Num) + " \"" + cAlphaArgs(12) + "\"");
3596 2 : ShowContinueError(state, "... terminal unit not connected to condenser.");
3597 2 : ShowContinueError(state, "... check that terminal unit is specified in a terminal unit list object.");
3598 2 : ShowContinueError(
3599 : state, "... also check that the terminal unit list name is specified in an AirConditioner:VariableRefrigerantFlow object.");
3600 1 : ErrorsFound = true;
3601 : }
3602 : }
3603 :
3604 : // Get DX heating coil data
3605 34 : std::string DXHeatingCoilType = cAlphaArgs(13);
3606 :
3607 : // Get the heating to cooling sizing ratio input before writing to DX heating coil data
3608 34 : if (!lNumericFieldBlanks(10)) {
3609 0 : thisVrfTU.HeatingCapacitySizeRatio = rNumericArgs(10);
3610 : }
3611 :
3612 34 : errFlag = false;
3613 34 : thisVrfTU.DXHeatCoilType_Num = GetCoilTypeNum(state, DXHeatingCoilType, cAlphaArgs(14), errFlag, false);
3614 34 : if (thisVrfTU.DXHeatCoilType_Num == 0) {
3615 0 : thisVrfTU.HeatingCoilPresent = false;
3616 0 : if (thisVrfTU.TUListIndex > 0 && thisVrfTU.IndexToTUInTUList > 0) {
3617 0 : state.dataHVACVarRefFlow->TerminalUnitList(thisVrfTU.TUListIndex).HeatingCoilPresent(thisVrfTU.IndexToTUInTUList) = false;
3618 : }
3619 : } else {
3620 34 : if (thisVrfTU.VRFSysNum > 0) {
3621 33 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
3622 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
3623 :
3624 11 : if (Util::SameString(HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num), HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating))) {
3625 11 : errFlag = false;
3626 11 : if (thisVrfTU.TUListIndex > 0 && thisVrfTU.IndexToTUInTUList > 0) {
3627 11 : state.dataHVACVarRefFlow->TerminalUnitList(thisVrfTU.TUListIndex).heatingCoilAvailScheds(thisVrfTU.IndexToTUInTUList) =
3628 22 : DXCoils::GetDXCoilAvailSched(state, DXHeatingCoilType, cAlphaArgs(14), errFlag);
3629 : }
3630 22 : GetDXCoilIndex(
3631 11 : state, cAlphaArgs(14), thisVrfTU.HeatCoilIndex, errFlag, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating));
3632 : HCoilInletNodeNum =
3633 11 : DXCoils::GetCoilInletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating), cAlphaArgs(14), errFlag);
3634 : HCoilOutletNodeNum =
3635 11 : DXCoils::GetCoilOutletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating), cAlphaArgs(14), errFlag);
3636 11 : thisVrfTU.heatCoilAirInNode = HCoilInletNodeNum;
3637 11 : thisVrfTU.heatCoilAirOutNode = HCoilOutletNodeNum;
3638 :
3639 11 : if (errFlag) ShowContinueError(state, "...occurs in " + cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3640 :
3641 11 : if (thisVrfTU.VRFSysNum > 0) {
3642 22 : SetDXCoolingCoilData(
3643 11 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserType);
3644 22 : SetDXCoolingCoilData(state,
3645 : thisVrfTU.HeatCoilIndex,
3646 : ErrorsFound,
3647 : _,
3648 : _,
3649 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserNodeNum);
3650 22 : SetDXCoolingCoilData(state,
3651 : thisVrfTU.HeatCoilIndex,
3652 : ErrorsFound,
3653 : _,
3654 : _,
3655 : _,
3656 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATCCHeater);
3657 22 : SetDXCoolingCoilData(state,
3658 : thisVrfTU.HeatCoilIndex,
3659 : ErrorsFound,
3660 : _,
3661 : _,
3662 : _,
3663 : _,
3664 : _,
3665 : _,
3666 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MinOATHeating);
3667 22 : SetDXCoolingCoilData(state,
3668 : thisVrfTU.HeatCoilIndex,
3669 : ErrorsFound,
3670 : _,
3671 : _,
3672 : _,
3673 : _,
3674 : _,
3675 : _,
3676 : _,
3677 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATHeating);
3678 22 : SetDXCoolingCoilData(state,
3679 : thisVrfTU.HeatCoilIndex,
3680 : ErrorsFound,
3681 : _,
3682 : _,
3683 : _,
3684 : _,
3685 : _,
3686 : _,
3687 : _,
3688 : _,
3689 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingPerformanceOATType);
3690 : // Set defrost controls in child object to trip child object defrost calculations
3691 22 : SetDXCoolingCoilData(state,
3692 : thisVrfTU.HeatCoilIndex,
3693 : ErrorsFound,
3694 : _,
3695 : _,
3696 : _,
3697 : _,
3698 : _,
3699 : _,
3700 : _,
3701 : _,
3702 : _,
3703 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostStrategy);
3704 22 : SetDXCoolingCoilData(state,
3705 : thisVrfTU.HeatCoilIndex,
3706 : ErrorsFound,
3707 : _,
3708 : _,
3709 : _,
3710 : _,
3711 : _,
3712 : _,
3713 : _,
3714 : _,
3715 : _,
3716 : _,
3717 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostControl);
3718 22 : SetDXCoolingCoilData(state,
3719 : thisVrfTU.HeatCoilIndex,
3720 : ErrorsFound,
3721 : _,
3722 : _,
3723 : _,
3724 : _,
3725 : _,
3726 : _,
3727 : _,
3728 : _,
3729 : _,
3730 : _,
3731 : _,
3732 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostEIRPtr);
3733 22 : SetDXCoolingCoilData(state,
3734 : thisVrfTU.HeatCoilIndex,
3735 : ErrorsFound,
3736 : _,
3737 : _,
3738 : _,
3739 : _,
3740 : _,
3741 : _,
3742 : _,
3743 : _,
3744 : _,
3745 : _,
3746 : _,
3747 : _,
3748 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostFraction);
3749 22 : SetDXCoolingCoilData(state,
3750 : thisVrfTU.HeatCoilIndex,
3751 : ErrorsFound,
3752 : _,
3753 : _,
3754 : _,
3755 : _,
3756 : _,
3757 : _,
3758 : _,
3759 : _,
3760 : _,
3761 : _,
3762 : _,
3763 : _,
3764 : _,
3765 : _,
3766 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATDefrost);
3767 : // If defrost is disabled in the VRF condenser, it must be disabled in the DX coil
3768 : // Defrost primarily handled in parent object, set defrost capacity to 1 to avoid autosizing.
3769 : // Defrost capacity is used for nothing more than setting defrost power/consumption report
3770 : // variables which are not reported. The coil's defrost algorithm IS used to derate the coil
3771 33 : SetDXCoolingCoilData(state,
3772 : thisVrfTU.HeatCoilIndex,
3773 : ErrorsFound,
3774 : _,
3775 : _,
3776 : _,
3777 : _,
3778 : _,
3779 : _,
3780 : _,
3781 : _,
3782 : _,
3783 : _,
3784 : _,
3785 : _,
3786 : _,
3787 22 : 1.0); // DefrostCapacity=1.0
3788 :
3789 11 : state.dataDXCoils->DXCoil(thisVrfTU.HeatCoilIndex).VRFIUPtr = VRFTUNum;
3790 11 : state.dataDXCoils->DXCoil(thisVrfTU.HeatCoilIndex).VRFOUPtr = thisVrfTU.VRFSysNum;
3791 11 : state.dataDXCoils->DXCoil(thisVrfTU.HeatCoilIndex).SupplyFanIndex = thisVrfTU.FanIndex;
3792 :
3793 11 : if (thisVrfTU.FanIndex > 0) {
3794 11 : state.dataDXCoils->DXCoil(thisVrfTU.HeatCoilIndex).RatedAirVolFlowRate(1) =
3795 11 : state.dataFans->fans(thisVrfTU.FanIndex)->maxAirFlowRate;
3796 : } else {
3797 0 : state.dataDXCoils->DXCoil(thisVrfTU.HeatCoilIndex).RatedAirVolFlowRate(1) = AutoSize;
3798 : }
3799 :
3800 : // Terminal unit heating to cooling sizing ratio has precedence over VRF system sizing ratio
3801 11 : if (thisVrfTU.HeatingCapacitySizeRatio > 1.0) {
3802 0 : SetDXCoolingCoilData(state,
3803 : thisVrfTU.HeatCoilIndex,
3804 : ErrorsFound,
3805 : _,
3806 : _,
3807 : _,
3808 : _,
3809 : _,
3810 : _,
3811 : _,
3812 : _,
3813 : _,
3814 : _,
3815 : _,
3816 : _,
3817 : _,
3818 : _,
3819 : _,
3820 : _,
3821 : _,
3822 0 : thisVrfTU.HeatingCapacitySizeRatio);
3823 11 : } else if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingCapacitySizeRatio > 1.0) {
3824 0 : SetDXCoolingCoilData(state,
3825 : thisVrfTU.HeatCoilIndex,
3826 : ErrorsFound,
3827 : _,
3828 : _,
3829 : _,
3830 : _,
3831 : _,
3832 : _,
3833 : _,
3834 : _,
3835 : _,
3836 : _,
3837 : _,
3838 : _,
3839 : _,
3840 : _,
3841 : _,
3842 : _,
3843 : _,
3844 0 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingCapacitySizeRatio);
3845 : }
3846 : } else {
3847 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3848 0 : ShowContinueError(
3849 0 : state, "... when checking " + HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num) + " \"" + cAlphaArgs(14) + "\"");
3850 0 : ShowContinueError(state, "... terminal unit not connected to condenser.");
3851 0 : ShowContinueError(state, "... check that terminal unit is specified in a terminal unit list object.");
3852 0 : ShowContinueError(state,
3853 : "... also check that the terminal unit list name is specified in an "
3854 : "AirConditioner:VariableRefrigerantFlow object.");
3855 0 : ErrorsFound = true;
3856 : }
3857 : } else {
3858 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3859 0 : ShowContinueError(state, "... illegal " + cAlphaFieldNames(14) + " = " + cAlphaArgs(14));
3860 0 : ErrorsFound = true;
3861 : }
3862 :
3863 : } else {
3864 : // Algorithm Type: VRF model based on system curve
3865 22 : if (Util::SameString(HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num), HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating))) {
3866 22 : if (thisVrfTU.TUListIndex > 0 && thisVrfTU.IndexToTUInTUList > 0) {
3867 22 : state.dataHVACVarRefFlow->TerminalUnitList(thisVrfTU.TUListIndex).heatingCoilAvailScheds(thisVrfTU.IndexToTUInTUList) =
3868 44 : DXCoils::GetDXCoilAvailSched(state, DXHeatingCoilType, cAlphaArgs(14), errFlag);
3869 : } else {
3870 0 : thisVrfTU.HeatingCoilPresent = false;
3871 : }
3872 22 : errFlag = false;
3873 22 : GetDXCoilIndex(state, cAlphaArgs(14), thisVrfTU.HeatCoilIndex, errFlag, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating));
3874 22 : HCoilInletNodeNum = DXCoils::GetCoilInletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating), cAlphaArgs(14), errFlag);
3875 22 : HCoilOutletNodeNum = DXCoils::GetCoilOutletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating), cAlphaArgs(14), errFlag);
3876 22 : thisVrfTU.heatCoilAirInNode = HCoilInletNodeNum;
3877 22 : thisVrfTU.heatCoilAirOutNode = HCoilOutletNodeNum;
3878 :
3879 22 : if (errFlag) ShowContinueError(state, "...occurs in " + cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3880 :
3881 44 : SetDXCoolingCoilData(
3882 22 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserType);
3883 44 : SetDXCoolingCoilData(
3884 22 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, _, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserNodeNum);
3885 44 : SetDXCoolingCoilData(
3886 22 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, _, _, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATCCHeater);
3887 44 : SetDXCoolingCoilData(state,
3888 : thisVrfTU.HeatCoilIndex,
3889 : ErrorsFound,
3890 : _,
3891 : _,
3892 : _,
3893 : _,
3894 : _,
3895 : _,
3896 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MinOATHeating);
3897 44 : SetDXCoolingCoilData(state,
3898 : thisVrfTU.HeatCoilIndex,
3899 : ErrorsFound,
3900 : _,
3901 : _,
3902 : _,
3903 : _,
3904 : _,
3905 : _,
3906 : _,
3907 : _,
3908 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingPerformanceOATType);
3909 : // Set defrost controls in child object to trip child object defrost calculations
3910 44 : SetDXCoolingCoilData(state,
3911 : thisVrfTU.HeatCoilIndex,
3912 : ErrorsFound,
3913 : _,
3914 : _,
3915 : _,
3916 : _,
3917 : _,
3918 : _,
3919 : _,
3920 : _,
3921 : _,
3922 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostStrategy);
3923 44 : SetDXCoolingCoilData(state,
3924 : thisVrfTU.HeatCoilIndex,
3925 : ErrorsFound,
3926 : _,
3927 : _,
3928 : _,
3929 : _,
3930 : _,
3931 : _,
3932 : _,
3933 : _,
3934 : _,
3935 : _,
3936 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostControl);
3937 44 : SetDXCoolingCoilData(state,
3938 : thisVrfTU.HeatCoilIndex,
3939 : ErrorsFound,
3940 : _,
3941 : _,
3942 : _,
3943 : _,
3944 : _,
3945 : _,
3946 : _,
3947 : _,
3948 : _,
3949 : _,
3950 : _,
3951 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostEIRPtr);
3952 44 : SetDXCoolingCoilData(state,
3953 : thisVrfTU.HeatCoilIndex,
3954 : ErrorsFound,
3955 : _,
3956 : _,
3957 : _,
3958 : _,
3959 : _,
3960 : _,
3961 : _,
3962 : _,
3963 : _,
3964 : _,
3965 : _,
3966 : _,
3967 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostFraction);
3968 44 : SetDXCoolingCoilData(state,
3969 : thisVrfTU.HeatCoilIndex,
3970 : ErrorsFound,
3971 : _,
3972 : _,
3973 : _,
3974 : _,
3975 : _,
3976 : _,
3977 : _,
3978 : _,
3979 : _,
3980 : _,
3981 : _,
3982 : _,
3983 : _,
3984 : _,
3985 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATDefrost);
3986 : // If defrost is disabled in the VRF condenser, it must be disabled in the DX coil
3987 : // Defrost primarily handled in parent object, set defrost capacity to 1 to avoid autosizing.
3988 : // Defrost capacity is used for nothing more than setting defrost power/consumption report
3989 : // variables which are not reported. The coil's defrost algorithm IS used to derate the coil
3990 66 : SetDXCoolingCoilData(state,
3991 : thisVrfTU.HeatCoilIndex,
3992 : ErrorsFound,
3993 : _,
3994 : _,
3995 : _,
3996 : _,
3997 : _,
3998 : _,
3999 : _,
4000 : _,
4001 : _,
4002 : _,
4003 : _,
4004 : _,
4005 : _,
4006 44 : 1.0); // DefrostCapacity=1.0
4007 : // Terminal unit heating to cooling sizing ratio has precedence over VRF system sizing ratio
4008 22 : if (thisVrfTU.HeatingCapacitySizeRatio > 1.0) {
4009 0 : SetDXCoolingCoilData(state,
4010 : thisVrfTU.HeatCoilIndex,
4011 : ErrorsFound,
4012 : _,
4013 : _,
4014 : _,
4015 : _,
4016 : _,
4017 : _,
4018 : _,
4019 : _,
4020 : _,
4021 : _,
4022 : _,
4023 : _,
4024 : _,
4025 : _,
4026 : _,
4027 : _,
4028 : _,
4029 0 : thisVrfTU.HeatingCapacitySizeRatio);
4030 22 : } else if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingCapacitySizeRatio > 1.0) {
4031 0 : SetDXCoolingCoilData(state,
4032 : thisVrfTU.HeatCoilIndex,
4033 : ErrorsFound,
4034 : _,
4035 : _,
4036 : _,
4037 : _,
4038 : _,
4039 : _,
4040 : _,
4041 : _,
4042 : _,
4043 : _,
4044 : _,
4045 : _,
4046 : _,
4047 : _,
4048 : _,
4049 : _,
4050 : _,
4051 0 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingCapacitySizeRatio);
4052 : }
4053 : // Check VRF DX heating coil heating capacity as a function of temperature performance curve. Only report here for
4054 : // biquadratic curve type.
4055 44 : if (thisVrfTU.VRFSysNum > 0 && thisVrfTU.HeatCoilIndex > 0 &&
4056 22 : state.dataCurveManager->curves(GetDXCoilCapFTCurveIndex(state, thisVrfTU.HeatCoilIndex, ErrorsFound))->numDims == 2) {
4057 0 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingPerformanceOATType == HVAC::OATType::WetBulb) {
4058 0 : checkCurveIsNormalizedToOne(
4059 : state,
4060 0 : "GetDXCoils: " + HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num),
4061 0 : DXCoils::GetDXCoilName(
4062 0 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num)),
4063 : GetDXCoilCapFTCurveIndex(state, thisVrfTU.HeatCoilIndex, ErrorsFound),
4064 : "Heating Capacity Ratio Modifier Function of Temperature Curve Name",
4065 0 : Curve::GetCurveName(state, GetDXCoilCapFTCurveIndex(state, thisVrfTU.HeatCoilIndex, ErrorsFound)),
4066 : RatedInletAirTempHeat,
4067 : RatedOutdoorWetBulbTempHeat);
4068 0 : } else if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingPerformanceOATType == HVAC::OATType::DryBulb) {
4069 0 : checkCurveIsNormalizedToOne(
4070 : state,
4071 0 : "GetDXCoils: " + HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num),
4072 0 : DXCoils::GetDXCoilName(
4073 0 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num)),
4074 : GetDXCoilCapFTCurveIndex(state, thisVrfTU.HeatCoilIndex, ErrorsFound),
4075 : "Heating Capacity Ratio Modifier Function of Temperature Curve Name",
4076 0 : Curve::GetCurveName(state, GetDXCoilCapFTCurveIndex(state, thisVrfTU.HeatCoilIndex, ErrorsFound)),
4077 : RatedInletAirTempHeat,
4078 : RatedOutdoorAirTempHeat);
4079 : }
4080 : }
4081 :
4082 : } else {
4083 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4084 0 : ShowContinueError(state, "... illegal " + cAlphaFieldNames(14) + " = " + cAlphaArgs(14));
4085 0 : ErrorsFound = true;
4086 : }
4087 : }
4088 : } else {
4089 1 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4090 1 : ShowContinueError(state, "... when checking " + HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num) + " \"" + cAlphaArgs(14) + "\"");
4091 2 : ShowContinueError(state, "... terminal unit not connected to condenser.");
4092 2 : ShowContinueError(state, "... check that terminal unit is specified in a terminal unit list object.");
4093 2 : ShowContinueError(
4094 : state, "... also check that the terminal unit list name is specified in an AirConditioner:VariableRefrigerantFlow object.");
4095 1 : ErrorsFound = true;
4096 : }
4097 : }
4098 :
4099 34 : if (!thisVrfTU.CoolingCoilPresent && thisVrfTU.DXCoolCoilType_Num == 0 && !thisVrfTU.HeatingCoilPresent &&
4100 0 : thisVrfTU.DXHeatCoilType_Num == 0) {
4101 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4102 0 : ShowContinueError(state, "... no valid coils entered for this terminal unit. Simulation will not proceed.");
4103 0 : ErrorsFound = true;
4104 : }
4105 :
4106 34 : if (!lAlphaFieldBlanks(15)) {
4107 0 : thisVrfTU.AvailManagerListName = cAlphaArgs(15);
4108 : }
4109 34 : thisVrfTU.ParasiticElec = rNumericArgs(8);
4110 34 : thisVrfTU.ParasiticOffElec = rNumericArgs(9);
4111 :
4112 34 : thisVrfTU.HVACSizingIndex = 0;
4113 34 : if (!lAlphaFieldBlanks(16)) {
4114 0 : thisVrfTU.HVACSizingIndex = Util::FindItemInList(cAlphaArgs(16), state.dataSize->ZoneHVACSizing);
4115 0 : if (thisVrfTU.HVACSizingIndex == 0) {
4116 0 : ShowSevereError(state, cAlphaFieldNames(16) + " = " + cAlphaArgs(16) + " not found.");
4117 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4118 0 : ErrorsFound = true;
4119 : }
4120 : }
4121 :
4122 : // supplemental heating coil
4123 34 : if (!lAlphaFieldBlanks(17) && !lAlphaFieldBlanks(18)) {
4124 :
4125 10 : thisVrfTU.SuppHeatCoilType = cAlphaArgs(17);
4126 10 : thisVrfTU.SuppHeatCoilName = cAlphaArgs(18);
4127 :
4128 10 : errFlag = false;
4129 10 : if (Util::SameString(thisVrfTU.SuppHeatCoilType, "Coil:Heating:Water")) {
4130 1 : thisVrfTU.SuppHeatCoilType_Num = HVAC::Coil_HeatingWater;
4131 9 : } else if (Util::SameString(thisVrfTU.SuppHeatCoilType, "Coil:Heating:Steam")) {
4132 1 : thisVrfTU.SuppHeatCoilType_Num = HVAC::Coil_HeatingSteam;
4133 14 : } else if (Util::SameString(thisVrfTU.SuppHeatCoilType, "Coil:Heating:Fuel") ||
4134 14 : Util::SameString(thisVrfTU.SuppHeatCoilType, "Coil:Heating:Electric")) {
4135 8 : thisVrfTU.SuppHeatCoilType_Num =
4136 8 : HeatingCoils::GetHeatingCoilTypeNum(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, errFlag);
4137 : }
4138 :
4139 10 : thisVrfTU.SuppHeatingCoilPresent = true;
4140 :
4141 10 : if (thisVrfTU.SuppHeatCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || thisVrfTU.SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric) {
4142 8 : errFlag = false;
4143 8 : thisVrfTU.SuppHeatCoilType_Num =
4144 8 : HeatingCoils::GetHeatingCoilTypeNum(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, errFlag);
4145 8 : if (errFlag) {
4146 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4147 0 : ErrorsFound = true;
4148 : } else {
4149 8 : ValidateComponent(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, IsNotOK, cCurrentModuleObject);
4150 8 : if (IsNotOK) {
4151 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4152 0 : ErrorsFound = true;
4153 : } else { // mine data from supplemental heating coil
4154 : // Get the supplemental heating coil index
4155 8 : thisVrfTU.SuppHeatCoilIndex =
4156 8 : HeatingCoils::GetHeatingCoilIndex(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, IsNotOK);
4157 8 : if (IsNotOK) {
4158 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4159 0 : ErrorsFound = true;
4160 : }
4161 : // Get the design supplemental heating capacity
4162 8 : errFlag = false;
4163 8 : thisVrfTU.DesignSuppHeatingCapacity =
4164 8 : HeatingCoils::GetCoilCapacity(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, errFlag);
4165 8 : if (errFlag) {
4166 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4167 0 : ErrorsFound = true;
4168 : }
4169 : // Get the supplemental heating Coil air inlet node
4170 8 : errFlag = false;
4171 8 : thisVrfTU.SuppHeatCoilAirInletNode =
4172 8 : HeatingCoils::GetCoilInletNode(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, errFlag);
4173 8 : if (errFlag) {
4174 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4175 0 : ErrorsFound = true;
4176 : }
4177 : // Get the supplemental heating Coil air outlet node
4178 8 : errFlag = false;
4179 8 : thisVrfTU.SuppHeatCoilAirOutletNode =
4180 8 : HeatingCoils::GetCoilOutletNode(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, errFlag);
4181 8 : if (errFlag) {
4182 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4183 0 : ErrorsFound = true;
4184 : }
4185 : } // IF (IsNotOK) THEN
4186 : }
4187 :
4188 2 : } else if (thisVrfTU.SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
4189 :
4190 1 : ValidateComponent(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, IsNotOK, cCurrentModuleObject);
4191 1 : if (IsNotOK) {
4192 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4193 0 : ErrorsFound = true;
4194 : } else { // mine data from heating coil object
4195 :
4196 : // Get the supplemental heating coil water Inlet or control node number
4197 1 : errFlag = false;
4198 1 : thisVrfTU.SuppHeatCoilFluidInletNode =
4199 1 : WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", thisVrfTU.SuppHeatCoilName, errFlag);
4200 1 : if (errFlag) {
4201 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4202 0 : ErrorsFound = true;
4203 : }
4204 : // Get the supplemental heating coil hot water max volume flow rate
4205 1 : errFlag = false;
4206 1 : thisVrfTU.SuppHeatCoilFluidMaxFlow =
4207 1 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", thisVrfTU.SuppHeatCoilName, errFlag);
4208 1 : if (errFlag) {
4209 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4210 0 : ErrorsFound = true;
4211 : }
4212 : // Get the supplemental heating Coil air inlet node
4213 1 : errFlag = false;
4214 1 : thisVrfTU.SuppHeatCoilAirInletNode =
4215 1 : WaterCoils::GetCoilInletNode(state, "Coil:Heating:Water", thisVrfTU.SuppHeatCoilName, errFlag);
4216 1 : if (errFlag) {
4217 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4218 0 : ErrorsFound = true;
4219 : }
4220 : // Get the supplemental heating coil air outlet node
4221 1 : errFlag = false;
4222 1 : thisVrfTU.SuppHeatCoilAirOutletNode =
4223 1 : WaterCoils::GetCoilOutletNode(state, "Coil:Heating:Water", thisVrfTU.SuppHeatCoilName, errFlag);
4224 1 : if (errFlag) {
4225 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4226 0 : ErrorsFound = true;
4227 : }
4228 : }
4229 :
4230 1 : } else if (thisVrfTU.SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
4231 :
4232 1 : ValidateComponent(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, IsNotOK, cCurrentModuleObject);
4233 1 : if (IsNotOK) {
4234 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4235 0 : ErrorsFound = true;
4236 : } else { // mine data from supplemental heating coil object
4237 1 : errFlag = false;
4238 1 : thisVrfTU.SuppHeatCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", thisVrfTU.SuppHeatCoilName, errFlag);
4239 1 : if (thisVrfTU.SuppHeatCoilIndex == 0) {
4240 0 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfTU.Name);
4241 0 : ErrorsFound = true;
4242 : }
4243 : // Get the supplemental heating Coil steam inlet node number
4244 1 : errFlag = false;
4245 1 : thisVrfTU.SuppHeatCoilFluidInletNode =
4246 2 : SteamCoils::GetCoilSteamInletNode(state, "Coil:Heating:Steam", thisVrfTU.SuppHeatCoilName, errFlag);
4247 1 : if (errFlag) {
4248 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4249 0 : ErrorsFound = true;
4250 : }
4251 : // Get the supplemental heating coil steam max volume flow rate
4252 1 : thisVrfTU.SuppHeatCoilFluidMaxFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, thisVrfTU.SuppHeatCoilIndex, errFlag);
4253 1 : if (thisVrfTU.SuppHeatCoilFluidMaxFlow > 0.0) {
4254 0 : Real64 TempSteamIn = 100.0;
4255 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, RoutineName);
4256 0 : thisVrfTU.SuppHeatCoilFluidMaxFlow =
4257 0 : SteamCoils::GetCoilMaxSteamFlowRate(state, thisVrfTU.SuppHeatCoilIndex, errFlag) * SteamDensity;
4258 : }
4259 : // Get the supplemental heating coil air inlet node
4260 1 : errFlag = false;
4261 1 : thisVrfTU.SuppHeatCoilAirInletNode =
4262 1 : SteamCoils::GetCoilAirInletNode(state, thisVrfTU.SuppHeatCoilIndex, thisVrfTU.SuppHeatCoilName, errFlag);
4263 1 : if (errFlag) {
4264 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4265 0 : ErrorsFound = true;
4266 : }
4267 : // Get the supplemental heating coil air outlet node
4268 1 : errFlag = false;
4269 1 : thisVrfTU.SuppHeatCoilAirOutletNode =
4270 1 : SteamCoils::GetCoilAirOutletNode(state, thisVrfTU.SuppHeatCoilIndex, thisVrfTU.SuppHeatCoilName, errFlag);
4271 1 : if (errFlag) {
4272 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4273 0 : ErrorsFound = true;
4274 : }
4275 : }
4276 : }
4277 : } else { // if (!lAlphaFieldBlanks(17) && !lAlphaFieldBlanks(18)) {
4278 24 : if (!lAlphaFieldBlanks(17) && lAlphaFieldBlanks(18)) {
4279 0 : ShowWarningError(state, cCurrentModuleObject + " = " + thisVrfTU.Name + "\"");
4280 0 : ShowContinueError(state, "...Supplemental heating coil type = " + cAlphaArgs(17));
4281 0 : ShowContinueError(state, "...But missing the associated supplemental heating coil name. ");
4282 0 : ShowContinueError(state, "...The supplemental heating coil will not be simulated. ");
4283 : }
4284 24 : if (lAlphaFieldBlanks(17) && !lAlphaFieldBlanks(18)) {
4285 0 : ShowWarningError(state, cCurrentModuleObject + " = " + thisVrfTU.Name + "\"");
4286 0 : ShowContinueError(state, "...Supplemental heating coil name = " + cAlphaArgs(18));
4287 0 : ShowContinueError(state, "...But missing the associated supplemental heating coil type. ");
4288 0 : ShowContinueError(state, "...The supplemental heating coil will not be simulated. ");
4289 : }
4290 : }
4291 :
4292 34 : if (!lAlphaFieldBlanks(19)) {
4293 0 : thisVrfTU.ZoneNum = Util::FindItemInList(cAlphaArgs(19), state.dataHeatBal->Zone);
4294 0 : if (thisVrfTU.ZoneNum == 0) {
4295 0 : ShowSevereError(state, cCurrentModuleObject + " = " + cAlphaArgs(1));
4296 0 : ShowContinueError(state, "Illegal " + cAlphaFieldNames(19) + " = " + cAlphaArgs(19));
4297 0 : ErrorsFound = true;
4298 : }
4299 : }
4300 :
4301 34 : auto &vrfTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
4302 34 : if (!lAlphaFieldBlanks(20) && !lAlphaFieldBlanks(21)) {
4303 0 : vrfTU.DesignSpecMultispeedHPType = cAlphaArgs(20);
4304 0 : vrfTU.DesignSpecMultispeedHPName = cAlphaArgs(21);
4305 0 : vrfTU.DesignSpecMSHPIndex = UnitarySystems::getDesignSpecMSHPIndex(state, cAlphaArgs(21));
4306 0 : auto const &designSpecFan = state.dataUnitarySystems->designSpecMSHP[vrfTU.DesignSpecMSHPIndex];
4307 0 : if (vrfTU.DXCoolCoilType_Num == HVAC::CoilVRF_Cooling) {
4308 0 : int NumSpeeds = designSpecFan.numOfSpeedCooling;
4309 0 : vrfTU.NumOfSpeedCooling = NumSpeeds;
4310 0 : vrfTU.CoolVolumeFlowRate.resize(NumSpeeds + 1);
4311 0 : vrfTU.CoolMassFlowRate.resize(NumSpeeds + 1);
4312 0 : if (vrfTU.MaxCoolAirVolFlow != DataSizing::AutoSize) {
4313 0 : Real64 AirFlowRate = vrfTU.MaxCoolAirVolFlow;
4314 0 : for (int i = 1; i <= vrfTU.NumOfSpeedCooling; ++i) {
4315 0 : if (state.dataUnitarySystems->designSpecMSHP[vrfTU.DesignSpecMSHPIndex].coolingVolFlowRatio[i] == DataSizing::AutoSize) {
4316 0 : vrfTU.CoolVolumeFlowRate[i] = double(i) / double(vrfTU.NumOfSpeedCooling) * AirFlowRate;
4317 : } else {
4318 0 : vrfTU.CoolVolumeFlowRate[i] =
4319 0 : state.dataUnitarySystems->designSpecMSHP[vrfTU.DesignSpecMSHPIndex].coolingVolFlowRatio[i] * AirFlowRate;
4320 : }
4321 0 : vrfTU.CoolMassFlowRate[i] = vrfTU.CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
4322 : }
4323 : }
4324 : }
4325 0 : if (vrfTU.DXHeatCoilType_Num == HVAC::CoilVRF_Heating) {
4326 0 : int NumSpeeds = designSpecFan.numOfSpeedHeating;
4327 0 : vrfTU.NumOfSpeedHeating = NumSpeeds;
4328 0 : vrfTU.HeatVolumeFlowRate.resize(NumSpeeds + 1);
4329 0 : vrfTU.HeatMassFlowRate.resize(NumSpeeds + 1);
4330 0 : if (vrfTU.MaxHeatAirVolFlow != DataSizing::AutoSize) {
4331 0 : Real64 AirFlowRate = vrfTU.MaxHeatAirVolFlow;
4332 0 : for (int i = 1; i <= vrfTU.NumOfSpeedHeating; ++i) {
4333 0 : if (state.dataUnitarySystems->designSpecMSHP[vrfTU.DesignSpecMSHPIndex].heatingVolFlowRatio[i] == DataSizing::AutoSize) {
4334 0 : vrfTU.HeatVolumeFlowRate[i] = double(i) / double(vrfTU.NumOfSpeedHeating) * AirFlowRate;
4335 : } else {
4336 0 : vrfTU.HeatVolumeFlowRate[i] =
4337 0 : state.dataUnitarySystems->designSpecMSHP[vrfTU.DesignSpecMSHPIndex].heatingVolFlowRatio[i] * AirFlowRate;
4338 : }
4339 0 : vrfTU.HeatMassFlowRate[i] = vrfTU.HeatVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
4340 : }
4341 : }
4342 : }
4343 : } else {
4344 34 : if (vrfTU.fanType == HVAC::FanType::SystemModel) {
4345 20 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(vrfTU.FanIndex));
4346 20 : assert(fanSystem != nullptr);
4347 :
4348 20 : if (fanSystem->speedControl == Fans::SpeedControl::Discrete) {
4349 11 : if (fanSystem->numSpeeds > 1) {
4350 2 : if (vrfTU.DXCoolCoilType_Num == HVAC::CoilVRF_Cooling) {
4351 2 : vrfTU.NumOfSpeedCooling = fanSystem->numSpeeds;
4352 2 : vrfTU.CoolVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
4353 2 : vrfTU.CoolMassFlowRate.resize(fanSystem->numSpeeds + 1);
4354 : }
4355 2 : if (vrfTU.DXHeatCoilType_Num == HVAC::CoilVRF_Heating) {
4356 2 : vrfTU.NumOfSpeedHeating = fanSystem->numSpeeds;
4357 2 : vrfTU.HeatVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
4358 2 : vrfTU.HeatMassFlowRate.resize(fanSystem->numSpeeds + 1);
4359 : }
4360 4 : ShowWarningError(state,
4361 4 : cCurrentModuleObject + " = " + thisVrfTU.Name + " with Fan:SystemModel is used in " + cAlphaArgs(8) + "\"");
4362 2 : ShowContinueError(state, format("...The number of speed = {:.0R}.", double(fanSystem->numSpeeds)));
4363 6 : ShowContinueError(state, "...Multiple speed fan will be applied to this unit. The speed number is determined by load.");
4364 : }
4365 : }
4366 : }
4367 : }
4368 :
4369 : // set supplemental heating coil operation temperature limits
4370 34 : if (thisVrfTU.SuppHeatingCoilPresent) {
4371 : // Set maximum supply air temperature for supplemental heating coil
4372 10 : if (NumNums < 11) {
4373 0 : thisVrfTU.MaxSATFromSuppHeatCoil = DataSizing::AutoSize;
4374 : } else {
4375 10 : thisVrfTU.MaxSATFromSuppHeatCoil = rNumericArgs(11);
4376 : }
4377 : // set maximum outdoor dry-bulb temperature for supplemental heating coil operation
4378 10 : if (NumNums < 12) {
4379 0 : thisVrfTU.MaxOATSuppHeatingCoil = 21.0;
4380 : } else {
4381 10 : thisVrfTU.MaxOATSuppHeatingCoil = rNumericArgs(12);
4382 : }
4383 : }
4384 :
4385 : // Add cooling coil to component sets array
4386 34 : if (thisVrfTU.CoolingCoilPresent) {
4387 :
4388 68 : SetUpCompSets(state,
4389 : cCurrentModuleObject,
4390 : thisVrfTU.Name,
4391 34 : HVAC::cAllCoilTypes(thisVrfTU.DXCoolCoilType_Num),
4392 34 : cAlphaArgs(12),
4393 34 : state.dataLoopNodes->NodeID(CCoilInletNodeNum),
4394 34 : state.dataLoopNodes->NodeID(CCoilOutletNodeNum));
4395 : // set heating coil present flag
4396 68 : SetDXCoolingCoilData(
4397 34 : state, thisVrfTU.CoolCoilIndex, ErrorsFound, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, thisVrfTU.HeatingCoilPresent);
4398 :
4399 : // check that curve types are present in VRF Condenser if cooling coil is present in terminal unit (can be blank)
4400 : // all curves are checked for correct type if a curve name is entered in the VRF condenser object. Check that the
4401 : // curve is present if the corresponding coil is entered in the terminal unit.
4402 34 : if (thisVrfTU.VRFSysNum > 0) {
4403 :
4404 33 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFAlgorithmType != AlgorithmType::FluidTCtrl) {
4405 :
4406 35 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CoolingCapacity <= 0 &&
4407 13 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CoolingCapacity != AutoSize) {
4408 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4409 0 : ShowContinueError(state,
4410 : "...This terminal unit contains a cooling coil and rated cooling capacity is also required in the "
4411 : "associated condenser object.");
4412 0 : ShowContinueError(state,
4413 0 : "...Rated Cooling Capacity must also be specified for condenser = " +
4414 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFSystemTypeNum)) + " \"" +
4415 0 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).Name + "\".");
4416 0 : ErrorsFound = true;
4417 : }
4418 : }
4419 : }
4420 : }
4421 :
4422 : // Add heating coil to component sets array
4423 34 : if (thisVrfTU.HeatingCoilPresent) {
4424 :
4425 68 : SetUpCompSets(state,
4426 : cCurrentModuleObject,
4427 : thisVrfTU.Name,
4428 34 : HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num),
4429 34 : cAlphaArgs(14),
4430 34 : state.dataLoopNodes->NodeID(HCoilInletNodeNum),
4431 34 : state.dataLoopNodes->NodeID(HCoilOutletNodeNum));
4432 : // set cooling coil present flag
4433 68 : SetDXCoolingCoilData(
4434 34 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, thisVrfTU.CoolingCoilPresent);
4435 :
4436 34 : if (thisVrfTU.VRFSysNum > 0) {
4437 :
4438 33 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFAlgorithmType != AlgorithmType::FluidTCtrl) {
4439 :
4440 41 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingCapacity <= 0 &&
4441 19 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingCapacity != AutoSize) {
4442 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4443 0 : ShowContinueError(state,
4444 : "...This terminal unit contains a heating coil and rated heating capacity is also required in the "
4445 : "associated condenser object.");
4446 0 : ShowContinueError(state,
4447 0 : "...Rated Heating Capacity must also be specified for condenser = " +
4448 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFSystemTypeNum)) + " \"" +
4449 0 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).Name + "\".");
4450 0 : ErrorsFound = true;
4451 : }
4452 :
4453 22 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatCapFT == 0) {
4454 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4455 0 : ShowContinueError(state,
4456 : "...This terminal unit contains a heating coil and heating performance curves are also required in the "
4457 : "associated condenser object.");
4458 0 : ShowContinueError(
4459 : state,
4460 0 : "...Heating Capacity Ratio Modifier Function of Low Temperature Curve must also be specified for condenser = " +
4461 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFSystemTypeNum)) + " \"" +
4462 0 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).Name + "\".");
4463 0 : ErrorsFound = true;
4464 : }
4465 :
4466 22 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatEIRFT == 0) {
4467 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4468 0 : ShowContinueError(state,
4469 : "...This terminal unit contains a heating coil and heating performance curves are also required in the "
4470 : "associated condenser object.");
4471 0 : ShowContinueError(
4472 : state,
4473 0 : "...Heating Energy Input Ratio Modifier Function of Low Temperature Curve must also be specified for condenser = " +
4474 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFSystemTypeNum)) + " \"" +
4475 0 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).Name + "\".");
4476 0 : ErrorsFound = true;
4477 : }
4478 :
4479 22 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatEIRFPLR1 == 0) {
4480 1 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4481 2 : ShowContinueError(state,
4482 : "...This terminal unit contains a heating coil and heating performance curves are also required in the "
4483 : "associated condenser object.");
4484 2 : ShowContinueError(state,
4485 : "...Heating Energy Input Ratio Modifier Function of Low Part-Load Ratio Curve must also be specified "
4486 2 : "for condenser = " +
4487 4 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFSystemTypeNum)) + " \"" +
4488 4 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).Name + "\".");
4489 : }
4490 : }
4491 : }
4492 : }
4493 :
4494 : // Add supplemental heating coil to component sets array
4495 34 : if (thisVrfTU.SuppHeatingCoilPresent) {
4496 30 : SetUpCompSets(state,
4497 : cCurrentModuleObject,
4498 : thisVrfTU.Name,
4499 10 : HVAC::cAllCoilTypes(thisVrfTU.SuppHeatCoilType_Num),
4500 : thisVrfTU.SuppHeatCoilName,
4501 10 : state.dataLoopNodes->NodeID(thisVrfTU.SuppHeatCoilAirInletNode),
4502 10 : state.dataLoopNodes->NodeID(thisVrfTU.SuppHeatCoilAirOutletNode));
4503 : }
4504 : // Set up component set for OA mixer - use OA node and Mixed air node
4505 34 : if (thisVrfTU.OAMixerUsed)
4506 52 : SetUpCompSets(state,
4507 : cCurrentModuleObject,
4508 : thisVrfTU.Name,
4509 : "UNDEFINED",
4510 : thisVrfTU.OAMixerName,
4511 26 : state.dataLoopNodes->NodeID(OANodeNums(1)),
4512 26 : state.dataLoopNodes->NodeID(OANodeNums(4)));
4513 :
4514 : // Get AirTerminal mixer data
4515 34 : GetATMixer(state,
4516 34 : thisVrfTU.Name,
4517 34 : thisVrfTU.ATMixerName,
4518 34 : thisVrfTU.ATMixerIndex,
4519 34 : thisVrfTU.ATMixerType,
4520 34 : thisVrfTU.ATMixerPriNode,
4521 34 : thisVrfTU.ATMixerSecNode,
4522 34 : thisVrfTU.ATMixerOutNode,
4523 : thisVrfTU.VRFTUOutletNodeNum);
4524 34 : if (thisVrfTU.ATMixerType == HVAC::MixerType::InletSide || thisVrfTU.ATMixerType == HVAC::MixerType::SupplySide) {
4525 4 : thisVrfTU.ATMixerExists = true;
4526 : }
4527 : // check that the VRF TU have local outside air and DOA
4528 34 : if (thisVrfTU.ATMixerExists && OANodeNums(4) > 0) {
4529 0 : ShowSevereError(
4530 0 : state, cCurrentModuleObject + " = \"" + thisVrfTU.Name + "\". VRF terminal unit has local as well as central outdoor air specified");
4531 0 : ErrorsFound = true;
4532 : }
4533 :
4534 : // for ZoneHVAC check that TU inlet node is a zone exhaust node otherwise ZoneAirNode and ZoneNum = 0
4535 34 : if (!thisVrfTU.ATMixerExists || thisVrfTU.ATMixerType == HVAC::MixerType::SupplySide) {
4536 100 : for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
4537 68 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
4538 107 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumExhaustNodes; ++NodeNum) {
4539 68 : if (thisVrfTU.VRFTUInletNodeNum == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ExhaustNode(NodeNum)) {
4540 29 : thisVrfTU.ZoneAirNode = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ZoneNode;
4541 29 : thisVrfTU.ZoneNum = CtrlZone;
4542 29 : break;
4543 : }
4544 : }
4545 : }
4546 34 : } else if (thisVrfTU.ATMixerType == HVAC::MixerType::InletSide) {
4547 4 : for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
4548 2 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
4549 2 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) {
4550 2 : if (thisVrfTU.VRFTUOutletNodeNum == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) {
4551 2 : thisVrfTU.ZoneAirNode = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ZoneNode;
4552 2 : thisVrfTU.ZoneNum = CtrlZone;
4553 2 : break;
4554 : }
4555 : }
4556 : }
4557 : }
4558 34 : CheckVRFTUNodeConnections(state, VRFTUNum, ErrorsFound);
4559 34 : } // end Number of VRF Terminal Unit Loop
4560 :
4561 : // perform additional error checking
4562 50 : for (auto const &thisTUList : state.dataHVACVarRefFlow->TerminalUnitList) {
4563 61 : for (int VRFTUNum = 1; VRFTUNum <= thisTUList.NumTUInList; ++VRFTUNum) {
4564 34 : int const tuPtr = thisTUList.ZoneTUPtr(VRFTUNum);
4565 34 : if (tuPtr == 0) {
4566 : // TU name in zone terminal unit list not found
4567 1 : ShowSevereError(state, format("ZoneTerminalUnitList \"{}\"", thisTUList.Name));
4568 1 : ShowContinueError(state, format("...Zone Terminal Unit = {} improperly connected to system.", thisTUList.ZoneTUName(VRFTUNum)));
4569 2 : ShowContinueError(state, "...either the ZoneHVAC:TerminalUnit:VariableRefrigerantFlow object does not exist,");
4570 2 : ShowContinueError(state, "...the ZoneHVAC:TerminalUnit:VariableRefrigerantFlow object name is misspelled,");
4571 2 : ShowContinueError(state, "...or the ZoneTerminalUnitList object is not named in an AirConditioner:VariableRefrigerantFlow object.");
4572 1 : ErrorsFound = true;
4573 : } else {
4574 33 : int const sysNum = state.dataHVACVarRefFlow->VRFTU(tuPtr).VRFSysNum;
4575 33 : if (sysNum > 0) {
4576 33 : auto &thisVRFSys = state.dataHVACVarRefFlow->VRF(sysNum);
4577 33 : if (thisTUList.NumTUInList == 1 && thisVRFSys.VRFAlgorithmType == AlgorithmType::SysCurve) {
4578 15 : if (thisVRFSys.HeatRecoveryUsed) {
4579 1 : ShowWarningError(state, format("ZoneTerminalUnitList \"{}\"", thisTUList.Name));
4580 2 : ShowWarningError(state, "...Only 1 Terminal Unit connected to system and heat recovery is selected.");
4581 1 : ShowContinueError(state, format("...Heat recovery will be disabled for {}.", thisVRFSys.Name));
4582 1 : thisVRFSys.HeatRecoveryUsed = false;
4583 : }
4584 : }
4585 : }
4586 : }
4587 : }
4588 : }
4589 :
4590 : // warn when number of ZoneTerminalUnitList different from number of AirConditioner:VariableRefrigerantFlow
4591 23 : if (state.dataHVACVarRefFlow->NumVRFTULists != state.dataHVACVarRefFlow->NumVRFCond) {
4592 0 : ShowSevereError(state,
4593 0 : format("The number of AirConditioner:VariableRefrigerantFlow objects ({}) does not match the number of "
4594 : "ZoneTerminalUnitList objects ({}).",
4595 0 : state.dataHVACVarRefFlow->NumVRFCond,
4596 0 : state.dataHVACVarRefFlow->NumVRFTULists));
4597 0 : for (int NumCond = 1; NumCond <= state.dataHVACVarRefFlow->NumVRFCond; ++NumCond) {
4598 0 : if (state.dataHVACVarRefFlow->VRF(NumCond).ZoneTUListPtr > 0) {
4599 0 : ShowContinueError(state,
4600 0 : format("...AirConditioner:VariableRefrigerantFlow = {} specifies Zone Terminal Unit List Name = {}",
4601 0 : state.dataHVACVarRefFlow->VRF(NumCond).Name,
4602 0 : state.dataHVACVarRefFlow->TerminalUnitList(state.dataHVACVarRefFlow->VRF(NumCond).ZoneTUListPtr).Name));
4603 : } else {
4604 0 : ShowContinueError(state,
4605 0 : format("...AirConditioner:VariableRefrigerantFlow = {} Zone Terminal Unit List Name not found.",
4606 0 : state.dataHVACVarRefFlow->VRF(NumCond).Name));
4607 : }
4608 : }
4609 0 : ShowContinueError(state, "...listing ZoneTerminalUnitList objects.");
4610 0 : for (int NumList = 1; NumList <= state.dataHVACVarRefFlow->NumVRFTULists; ++NumList) {
4611 0 : ShowContinueError(state, "...ZoneTerminalUnitList = " + state.dataHVACVarRefFlow->TerminalUnitList(NumList).Name);
4612 : }
4613 0 : ErrorsFound = true;
4614 : }
4615 :
4616 : // Set up output variables
4617 57 : for (int VRFTUNum = 1; VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU; ++VRFTUNum) {
4618 34 : auto &thisVrfTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
4619 34 : if (thisVrfTU.CoolingCoilPresent) {
4620 68 : SetupOutputVariable(state,
4621 : "Zone VRF Air Terminal Cooling Electricity Rate",
4622 : Constant::Units::W,
4623 34 : thisVrfTU.ParasiticCoolElecPower,
4624 : OutputProcessor::TimeStepType::System,
4625 : OutputProcessor::StoreType::Average,
4626 34 : thisVrfTU.Name);
4627 68 : SetupOutputVariable(state,
4628 : "Zone VRF Air Terminal Cooling Electricity Energy",
4629 : Constant::Units::J,
4630 34 : thisVrfTU.ParasiticElecCoolConsumption,
4631 : OutputProcessor::TimeStepType::System,
4632 : OutputProcessor::StoreType::Sum,
4633 34 : thisVrfTU.Name,
4634 : Constant::eResource::Electricity,
4635 : OutputProcessor::Group::HVAC,
4636 : OutputProcessor::EndUseCat::Cooling);
4637 68 : SetupOutputVariable(state,
4638 : "Zone VRF Air Terminal Total Cooling Rate",
4639 : Constant::Units::W,
4640 34 : thisVrfTU.TotalCoolingRate,
4641 : OutputProcessor::TimeStepType::System,
4642 : OutputProcessor::StoreType::Average,
4643 34 : thisVrfTU.Name);
4644 68 : SetupOutputVariable(state,
4645 : "Zone VRF Air Terminal Sensible Cooling Rate",
4646 : Constant::Units::W,
4647 34 : thisVrfTU.SensibleCoolingRate,
4648 : OutputProcessor::TimeStepType::System,
4649 : OutputProcessor::StoreType::Average,
4650 34 : thisVrfTU.Name);
4651 68 : SetupOutputVariable(state,
4652 : "Zone VRF Air Terminal Latent Cooling Rate",
4653 : Constant::Units::W,
4654 34 : thisVrfTU.LatentCoolingRate,
4655 : OutputProcessor::TimeStepType::System,
4656 : OutputProcessor::StoreType::Average,
4657 34 : thisVrfTU.Name);
4658 68 : SetupOutputVariable(state,
4659 : "Zone VRF Air Terminal Total Cooling Energy",
4660 : Constant::Units::J,
4661 34 : thisVrfTU.TotalCoolingEnergy,
4662 : OutputProcessor::TimeStepType::System,
4663 : OutputProcessor::StoreType::Sum,
4664 34 : thisVrfTU.Name);
4665 68 : SetupOutputVariable(state,
4666 : "Zone VRF Air Terminal Sensible Cooling Energy",
4667 : Constant::Units::J,
4668 34 : thisVrfTU.SensibleCoolingEnergy,
4669 : OutputProcessor::TimeStepType::System,
4670 : OutputProcessor::StoreType::Sum,
4671 34 : thisVrfTU.Name);
4672 68 : SetupOutputVariable(state,
4673 : "Zone VRF Air Terminal Latent Cooling Energy",
4674 : Constant::Units::J,
4675 34 : thisVrfTU.LatentCoolingEnergy,
4676 : OutputProcessor::TimeStepType::System,
4677 : OutputProcessor::StoreType::Sum,
4678 34 : thisVrfTU.Name);
4679 : }
4680 34 : if (thisVrfTU.HeatingCoilPresent) {
4681 68 : SetupOutputVariable(state,
4682 : "Zone VRF Air Terminal Heating Electricity Rate",
4683 : Constant::Units::W,
4684 34 : thisVrfTU.ParasiticHeatElecPower,
4685 : OutputProcessor::TimeStepType::System,
4686 : OutputProcessor::StoreType::Average,
4687 34 : thisVrfTU.Name);
4688 68 : SetupOutputVariable(state,
4689 : "Zone VRF Air Terminal Heating Electricity Energy",
4690 : Constant::Units::J,
4691 34 : thisVrfTU.ParasiticElecHeatConsumption,
4692 : OutputProcessor::TimeStepType::System,
4693 : OutputProcessor::StoreType::Sum,
4694 34 : thisVrfTU.Name,
4695 : Constant::eResource::Electricity,
4696 : OutputProcessor::Group::HVAC,
4697 : OutputProcessor::EndUseCat::Heating);
4698 68 : SetupOutputVariable(state,
4699 : "Zone VRF Air Terminal Total Heating Rate",
4700 : Constant::Units::W,
4701 34 : thisVrfTU.TotalHeatingRate,
4702 : OutputProcessor::TimeStepType::System,
4703 : OutputProcessor::StoreType::Average,
4704 34 : thisVrfTU.Name);
4705 68 : SetupOutputVariable(state,
4706 : "Zone VRF Air Terminal Sensible Heating Rate",
4707 : Constant::Units::W,
4708 34 : thisVrfTU.SensibleHeatingRate,
4709 : OutputProcessor::TimeStepType::System,
4710 : OutputProcessor::StoreType::Average,
4711 34 : thisVrfTU.Name);
4712 68 : SetupOutputVariable(state,
4713 : "Zone VRF Air Terminal Latent Heating Rate",
4714 : Constant::Units::W,
4715 34 : thisVrfTU.LatentHeatingRate,
4716 : OutputProcessor::TimeStepType::System,
4717 : OutputProcessor::StoreType::Average,
4718 34 : thisVrfTU.Name);
4719 68 : SetupOutputVariable(state,
4720 : "Zone VRF Air Terminal Total Heating Energy",
4721 : Constant::Units::J,
4722 34 : thisVrfTU.TotalHeatingEnergy,
4723 : OutputProcessor::TimeStepType::System,
4724 : OutputProcessor::StoreType::Sum,
4725 34 : thisVrfTU.Name);
4726 68 : SetupOutputVariable(state,
4727 : "Zone VRF Air Terminal Sensible Heating Energy",
4728 : Constant::Units::J,
4729 34 : thisVrfTU.SensibleHeatingEnergy,
4730 : OutputProcessor::TimeStepType::System,
4731 : OutputProcessor::StoreType::Sum,
4732 34 : thisVrfTU.Name);
4733 68 : SetupOutputVariable(state,
4734 : "Zone VRF Air Terminal Latent Heating Energy",
4735 : Constant::Units::J,
4736 34 : thisVrfTU.LatentHeatingEnergy,
4737 : OutputProcessor::TimeStepType::System,
4738 : OutputProcessor::StoreType::Sum,
4739 34 : thisVrfTU.Name);
4740 : }
4741 34 : SetupOutputVariable(state,
4742 : "Zone VRF Air Terminal Fan Availability Status",
4743 : Constant::Units::None,
4744 34 : (int &)thisVrfTU.availStatus,
4745 : OutputProcessor::TimeStepType::System,
4746 : OutputProcessor::StoreType::Average,
4747 34 : thisVrfTU.Name);
4748 34 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
4749 0 : SetupEMSActuator(state,
4750 : "Variable Refrigerant Flow Terminal Unit",
4751 : thisVrfTU.Name,
4752 : "Part Load Ratio",
4753 : "[fraction]",
4754 0 : thisVrfTU.EMSOverridePartLoadFrac,
4755 0 : thisVrfTU.EMSValueForPartLoadFrac);
4756 : }
4757 34 : if (thisVrfTU.NumOfSpeedCooling > 1 || thisVrfTU.NumOfSpeedHeating > 1) {
4758 4 : SetupOutputVariable(state,
4759 : "Zone VRF Air Terminal Multispeed Fan Cycling Ratio",
4760 : Constant::Units::None,
4761 2 : thisVrfTU.CycRatio,
4762 : OutputProcessor::TimeStepType::System,
4763 : OutputProcessor::StoreType::Average,
4764 2 : thisVrfTU.Name);
4765 4 : SetupOutputVariable(state,
4766 : "Zone VRF Air Terminal Multispeed Fan Speed Ratio",
4767 : Constant::Units::None,
4768 2 : thisVrfTU.SpeedRatio,
4769 : OutputProcessor::TimeStepType::System,
4770 : OutputProcessor::StoreType::Average,
4771 2 : thisVrfTU.Name);
4772 2 : SetupOutputVariable(state,
4773 : "Zone VRF Air Terminal Multispeed Fan Speed Level",
4774 : Constant::Units::None,
4775 2 : thisVrfTU.SpeedNum,
4776 : OutputProcessor::TimeStepType::System,
4777 : OutputProcessor::StoreType::Average,
4778 2 : thisVrfTU.Name);
4779 : }
4780 : }
4781 :
4782 50 : for (int NumCond = 1; NumCond <= state.dataHVACVarRefFlow->NumVRFCond; ++NumCond) {
4783 27 : auto &thisVrf = state.dataHVACVarRefFlow->VRF(NumCond);
4784 27 : std::string_view const sFuelType = Constant::eFuelNames[static_cast<int>(thisVrf.fuel)];
4785 54 : SetupOutputVariable(state,
4786 : "VRF Heat Pump Total Cooling Rate",
4787 : Constant::Units::W,
4788 27 : thisVrf.TotalCoolingCapacity,
4789 : OutputProcessor::TimeStepType::System,
4790 : OutputProcessor::StoreType::Average,
4791 27 : thisVrf.Name);
4792 54 : SetupOutputVariable(state,
4793 : "VRF Heat Pump Total Heating Rate",
4794 : Constant::Units::W,
4795 27 : thisVrf.TotalHeatingCapacity,
4796 : OutputProcessor::TimeStepType::System,
4797 : OutputProcessor::StoreType::Average,
4798 27 : thisVrf.Name);
4799 81 : SetupOutputVariable(state,
4800 54 : format("VRF Heat Pump Cooling {} Rate", sFuelType),
4801 : Constant::Units::W,
4802 27 : thisVrf.ElecCoolingPower,
4803 : OutputProcessor::TimeStepType::System,
4804 : OutputProcessor::StoreType::Average,
4805 27 : thisVrf.Name);
4806 81 : SetupOutputVariable(state,
4807 54 : format("VRF Heat Pump Cooling {} Energy", sFuelType),
4808 : Constant::Units::J,
4809 27 : thisVrf.CoolElecConsumption,
4810 : OutputProcessor::TimeStepType::System,
4811 : OutputProcessor::StoreType::Sum,
4812 27 : thisVrf.Name,
4813 27 : Constant::eFuel2eResource[(int)thisVrf.fuel],
4814 : OutputProcessor::Group::HVAC,
4815 : OutputProcessor::EndUseCat::Cooling);
4816 81 : SetupOutputVariable(state,
4817 54 : format("VRF Heat Pump Heating {} Rate", sFuelType),
4818 : Constant::Units::W,
4819 27 : thisVrf.ElecHeatingPower,
4820 : OutputProcessor::TimeStepType::System,
4821 : OutputProcessor::StoreType::Average,
4822 27 : thisVrf.Name);
4823 81 : SetupOutputVariable(state,
4824 54 : format("VRF Heat Pump Heating {} Energy", sFuelType),
4825 : Constant::Units::J,
4826 27 : thisVrf.HeatElecConsumption,
4827 : OutputProcessor::TimeStepType::System,
4828 : OutputProcessor::StoreType::Sum,
4829 27 : thisVrf.Name,
4830 27 : Constant::eFuel2eResource[(int)thisVrf.fuel],
4831 : OutputProcessor::Group::HVAC,
4832 : OutputProcessor::EndUseCat::Heating);
4833 :
4834 54 : SetupOutputVariable(state,
4835 : "VRF Heat Pump Cooling COP",
4836 : Constant::Units::None,
4837 27 : thisVrf.OperatingCoolingCOP,
4838 : OutputProcessor::TimeStepType::System,
4839 : OutputProcessor::StoreType::Average,
4840 27 : thisVrf.Name);
4841 54 : SetupOutputVariable(state,
4842 : "VRF Heat Pump Heating COP",
4843 : Constant::Units::None,
4844 27 : thisVrf.OperatingHeatingCOP,
4845 : OutputProcessor::TimeStepType::System,
4846 : OutputProcessor::StoreType::Average,
4847 27 : thisVrf.Name);
4848 54 : SetupOutputVariable(state,
4849 : "VRF Heat Pump COP",
4850 : Constant::Units::None,
4851 27 : thisVrf.OperatingCOP,
4852 : OutputProcessor::TimeStepType::System,
4853 : OutputProcessor::StoreType::Average,
4854 27 : thisVrf.Name);
4855 :
4856 27 : if (thisVrf.VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
4857 : // For VRF_FluidTCtrl Model
4858 18 : SetupOutputVariable(state,
4859 : "VRF Heat Pump Compressor Electricity Rate",
4860 : Constant::Units::W,
4861 9 : thisVrf.Ncomp,
4862 : OutputProcessor::TimeStepType::System,
4863 : OutputProcessor::StoreType::Average,
4864 9 : thisVrf.Name);
4865 18 : SetupOutputVariable(state,
4866 : "VRF Heat Pump Outdoor Unit Fan Power",
4867 : Constant::Units::W,
4868 9 : thisVrf.OUFanPower,
4869 : OutputProcessor::TimeStepType::System,
4870 : OutputProcessor::StoreType::Average,
4871 9 : thisVrf.Name);
4872 18 : SetupOutputVariable(state,
4873 : "VRF Heat Pump Compressor Rotating Speed",
4874 : Constant::Units::rev_min,
4875 9 : thisVrf.CompActSpeed,
4876 : OutputProcessor::TimeStepType::System,
4877 : OutputProcessor::StoreType::Average,
4878 9 : thisVrf.Name);
4879 18 : SetupOutputVariable(state,
4880 : "VRF Heat Pump Indoor Unit Evaporating Temperature",
4881 : Constant::Units::C,
4882 9 : thisVrf.IUEvaporatingTemp,
4883 : OutputProcessor::TimeStepType::System,
4884 : OutputProcessor::StoreType::Average,
4885 9 : thisVrf.Name);
4886 18 : SetupOutputVariable(state,
4887 : "VRF Heat Pump Outdoor Unit Condensing Temperature",
4888 : Constant::Units::C,
4889 9 : thisVrf.CondensingTemp,
4890 : OutputProcessor::TimeStepType::System,
4891 : OutputProcessor::StoreType::Average,
4892 9 : thisVrf.Name);
4893 18 : SetupOutputVariable(state,
4894 : "VRF Heat Pump Indoor Unit Condensing Temperature",
4895 : Constant::Units::C,
4896 9 : thisVrf.IUCondensingTemp,
4897 : OutputProcessor::TimeStepType::System,
4898 : OutputProcessor::StoreType::Average,
4899 9 : thisVrf.Name);
4900 18 : SetupOutputVariable(state,
4901 : "VRF Heat Pump Outdoor Unit Evaporating Temperature",
4902 : Constant::Units::C,
4903 9 : thisVrf.EvaporatingTemp,
4904 : OutputProcessor::TimeStepType::System,
4905 : OutputProcessor::StoreType::Average,
4906 9 : thisVrf.Name);
4907 18 : SetupOutputVariable(state,
4908 : "VRF Heat Pump Cooling Capacity at Max Compressor Speed",
4909 : Constant::Units::W,
4910 9 : thisVrf.CoolingCapacity,
4911 : OutputProcessor::TimeStepType::System,
4912 : OutputProcessor::StoreType::Average,
4913 9 : thisVrf.Name);
4914 18 : SetupOutputVariable(state,
4915 : "VRF Heat Pump Heating Capacity at Max Compressor Speed",
4916 : Constant::Units::W,
4917 9 : thisVrf.HeatingCapacity,
4918 : OutputProcessor::TimeStepType::System,
4919 : OutputProcessor::StoreType::Average,
4920 9 : thisVrf.Name);
4921 18 : SetupOutputVariable(state,
4922 : "VRF Heat Pump Indoor Unit Piping Correction for Cooling",
4923 : Constant::Units::None,
4924 9 : thisVrf.PipingCorrectionCooling,
4925 : OutputProcessor::TimeStepType::System,
4926 : OutputProcessor::StoreType::Average,
4927 9 : thisVrf.Name);
4928 18 : SetupOutputVariable(state,
4929 : "VRF Heat Pump Indoor Unit Piping Correction for Heating",
4930 : Constant::Units::None,
4931 9 : thisVrf.PipingCorrectionHeating,
4932 : OutputProcessor::TimeStepType::System,
4933 : OutputProcessor::StoreType::Average,
4934 9 : thisVrf.Name);
4935 18 : SetupOutputVariable(state,
4936 : "VRF Heat Pump Outdoor Unit Evaporator Heat Extract Rate",
4937 : Constant::Units::W,
4938 9 : thisVrf.OUEvapHeatRate,
4939 : OutputProcessor::TimeStepType::System,
4940 : OutputProcessor::StoreType::Average,
4941 9 : thisVrf.Name);
4942 18 : SetupOutputVariable(state,
4943 : "VRF Heat Pump Outdoor Unit Condenser Heat Release Rate",
4944 : Constant::Units::W,
4945 9 : thisVrf.OUCondHeatRate,
4946 : OutputProcessor::TimeStepType::System,
4947 : OutputProcessor::StoreType::Average,
4948 9 : thisVrf.Name);
4949 :
4950 : } else {
4951 : // For VRF_SysCurve Model
4952 36 : SetupOutputVariable(state,
4953 : "VRF Heat Pump Maximum Capacity Cooling Rate",
4954 : Constant::Units::W,
4955 18 : state.dataHVACVarRefFlow->MaxCoolingCapacity(NumCond),
4956 : OutputProcessor::TimeStepType::System,
4957 : OutputProcessor::StoreType::Average,
4958 18 : thisVrf.Name);
4959 36 : SetupOutputVariable(state,
4960 : "VRF Heat Pump Maximum Capacity Heating Rate",
4961 : Constant::Units::W,
4962 18 : state.dataHVACVarRefFlow->MaxHeatingCapacity(NumCond),
4963 : OutputProcessor::TimeStepType::System,
4964 : OutputProcessor::StoreType::Average,
4965 18 : thisVrf.Name);
4966 : }
4967 :
4968 27 : if (thisVrf.DefrostStrategy == StandardRatings::DefrostStrat::Resistive ||
4969 15 : (thisVrf.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle && thisVrf.fuel == Constant::eFuel::Electricity)) {
4970 54 : SetupOutputVariable(state,
4971 : "VRF Heat Pump Defrost Electricity Rate",
4972 : Constant::Units::W,
4973 27 : thisVrf.DefrostPower,
4974 : OutputProcessor::TimeStepType::System,
4975 : OutputProcessor::StoreType::Average,
4976 27 : thisVrf.Name);
4977 54 : SetupOutputVariable(state,
4978 : "VRF Heat Pump Defrost Electricity Energy",
4979 : Constant::Units::J,
4980 27 : thisVrf.DefrostConsumption,
4981 : OutputProcessor::TimeStepType::System,
4982 : OutputProcessor::StoreType::Sum,
4983 27 : thisVrf.Name,
4984 : Constant::eResource::Electricity,
4985 : OutputProcessor::Group::HVAC,
4986 : OutputProcessor::EndUseCat::Heating);
4987 :
4988 : } else { // defrost energy applied to fuel type
4989 0 : SetupOutputVariable(state,
4990 0 : format("VRF Heat Pump Defrost {} Rate", sFuelType),
4991 : Constant::Units::W,
4992 0 : thisVrf.DefrostPower,
4993 : OutputProcessor::TimeStepType::System,
4994 : OutputProcessor::StoreType::Average,
4995 0 : thisVrf.Name);
4996 0 : SetupOutputVariable(state,
4997 0 : format("VRF Heat Pump Defrost {} Energy", sFuelType),
4998 : Constant::Units::J,
4999 0 : thisVrf.DefrostConsumption,
5000 : OutputProcessor::TimeStepType::System,
5001 : OutputProcessor::StoreType::Sum,
5002 0 : thisVrf.Name,
5003 0 : Constant::eFuel2eResource[(int)thisVrf.fuel],
5004 : OutputProcessor::Group::HVAC,
5005 : OutputProcessor::EndUseCat::Heating);
5006 : }
5007 :
5008 54 : SetupOutputVariable(state,
5009 : "VRF Heat Pump Part Load Ratio",
5010 : Constant::Units::None,
5011 27 : thisVrf.VRFCondPLR,
5012 : OutputProcessor::TimeStepType::System,
5013 : OutputProcessor::StoreType::Average,
5014 27 : thisVrf.Name);
5015 54 : SetupOutputVariable(state,
5016 : "VRF Heat Pump Runtime Fraction",
5017 : Constant::Units::None,
5018 27 : thisVrf.VRFCondRTF,
5019 : OutputProcessor::TimeStepType::System,
5020 : OutputProcessor::StoreType::Average,
5021 27 : thisVrf.Name);
5022 54 : SetupOutputVariable(state,
5023 : "VRF Heat Pump Cycling Ratio",
5024 : Constant::Units::None,
5025 27 : thisVrf.VRFCondCyclingRatio,
5026 : OutputProcessor::TimeStepType::System,
5027 : OutputProcessor::StoreType::Average,
5028 27 : thisVrf.Name);
5029 :
5030 27 : SetupOutputVariable(state,
5031 : "VRF Heat Pump Operating Mode",
5032 : Constant::Units::None,
5033 27 : thisVrf.OperatingMode,
5034 : OutputProcessor::TimeStepType::System,
5035 : OutputProcessor::StoreType::Average,
5036 27 : thisVrf.Name);
5037 54 : SetupOutputVariable(state,
5038 : "VRF Heat Pump Condenser Inlet Temperature",
5039 : Constant::Units::C,
5040 27 : thisVrf.CondenserInletTemp,
5041 : OutputProcessor::TimeStepType::System,
5042 : OutputProcessor::StoreType::Average,
5043 27 : thisVrf.Name);
5044 :
5045 54 : SetupOutputVariable(state,
5046 : "VRF Heat Pump Crankcase Heater Electricity Rate",
5047 : Constant::Units::W,
5048 27 : thisVrf.CrankCaseHeaterPower,
5049 : OutputProcessor::TimeStepType::System,
5050 : OutputProcessor::StoreType::Average,
5051 27 : thisVrf.Name);
5052 54 : SetupOutputVariable(state,
5053 : "VRF Heat Pump Crankcase Heater Electricity Energy",
5054 : Constant::Units::J,
5055 27 : thisVrf.CrankCaseHeaterElecConsumption,
5056 : OutputProcessor::TimeStepType::System,
5057 : OutputProcessor::StoreType::Sum,
5058 27 : thisVrf.Name,
5059 : Constant::eResource::Electricity,
5060 : OutputProcessor::Group::HVAC,
5061 : OutputProcessor::EndUseCat::Cooling);
5062 54 : SetupOutputVariable(state,
5063 : "VRF Heat Pump Terminal Unit Cooling Load Rate",
5064 : Constant::Units::W,
5065 27 : thisVrf.TUCoolingLoad,
5066 : OutputProcessor::TimeStepType::System,
5067 : OutputProcessor::StoreType::Average,
5068 27 : thisVrf.Name);
5069 54 : SetupOutputVariable(state,
5070 : "VRF Heat Pump Terminal Unit Heating Load Rate",
5071 : Constant::Units::W,
5072 27 : thisVrf.TUHeatingLoad,
5073 : OutputProcessor::TimeStepType::System,
5074 : OutputProcessor::StoreType::Average,
5075 27 : thisVrf.Name);
5076 27 : if (thisVrf.HeatRecoveryUsed) {
5077 8 : SetupOutputVariable(state,
5078 : "VRF Heat Pump Heat Recovery Status Change Multiplier",
5079 : Constant::Units::None,
5080 4 : thisVrf.SUMultiplier,
5081 : OutputProcessor::TimeStepType::System,
5082 : OutputProcessor::StoreType::Average,
5083 4 : thisVrf.Name);
5084 8 : SetupOutputVariable(state,
5085 : "VRF Heat Pump Simultaneous Cooling and Heating Efficiency",
5086 : Constant::Units::Btu_h_W,
5087 4 : thisVrf.SCHE,
5088 : OutputProcessor::TimeStepType::System,
5089 : OutputProcessor::StoreType::Average,
5090 4 : thisVrf.Name);
5091 8 : SetupOutputVariable(state,
5092 : "VRF Heat Pump Heat Recovery Rate",
5093 : Constant::Units::W,
5094 4 : thisVrf.VRFHeatRec,
5095 : OutputProcessor::TimeStepType::System,
5096 : OutputProcessor::StoreType::Average,
5097 4 : thisVrf.Name);
5098 8 : SetupOutputVariable(state,
5099 : "VRF Heat Pump Heat Recovery Energy",
5100 : Constant::Units::J,
5101 4 : thisVrf.VRFHeatEnergyRec,
5102 : OutputProcessor::TimeStepType::System,
5103 : OutputProcessor::StoreType::Sum,
5104 4 : thisVrf.Name,
5105 : Constant::eResource::EnergyTransfer,
5106 : OutputProcessor::Group::Plant,
5107 : OutputProcessor::EndUseCat::HeatRecovery);
5108 : }
5109 :
5110 27 : if (thisVrf.CondenserType == DataHeatBalance::RefrigCondenserType::Evap) {
5111 0 : SetupOutputVariable(state,
5112 : "VRF Heat Pump Evaporative Condenser Water Use Volume",
5113 : Constant::Units::m3,
5114 0 : thisVrf.EvapWaterConsumpRate,
5115 : OutputProcessor::TimeStepType::System,
5116 : OutputProcessor::StoreType::Sum,
5117 0 : thisVrf.Name,
5118 : Constant::eResource::Water,
5119 : OutputProcessor::Group::HVAC,
5120 : OutputProcessor::EndUseCat::Cooling);
5121 0 : SetupOutputVariable(state,
5122 : "VRF Heat Pump Evaporative Condenser Pump Electricity Rate",
5123 : Constant::Units::W,
5124 0 : thisVrf.EvapCondPumpElecPower,
5125 : OutputProcessor::TimeStepType::System,
5126 : OutputProcessor::StoreType::Average,
5127 0 : thisVrf.Name);
5128 0 : SetupOutputVariable(state,
5129 : "VRF Heat Pump Evaporative Condenser Pump Electricity Energy",
5130 : Constant::Units::J,
5131 0 : thisVrf.EvapCondPumpElecConsumption,
5132 : OutputProcessor::TimeStepType::System,
5133 : OutputProcessor::StoreType::Sum,
5134 0 : thisVrf.Name,
5135 : Constant::eResource::Electricity,
5136 : OutputProcessor::Group::HVAC,
5137 : OutputProcessor::EndUseCat::Cooling);
5138 :
5139 0 : if (thisVrf.BasinHeaterPowerFTempDiff > 0.0) {
5140 0 : SetupOutputVariable(state,
5141 : "VRF Heat Pump Basin Heater Electricity Rate",
5142 : Constant::Units::W,
5143 0 : thisVrf.BasinHeaterPower,
5144 : OutputProcessor::TimeStepType::System,
5145 : OutputProcessor::StoreType::Average,
5146 0 : thisVrf.Name);
5147 0 : SetupOutputVariable(state,
5148 : "VRF Heat Pump Basin Heater Electricity Energy",
5149 : Constant::Units::J,
5150 0 : thisVrf.BasinHeaterConsumption,
5151 : OutputProcessor::TimeStepType::System,
5152 : OutputProcessor::StoreType::Sum,
5153 0 : thisVrf.Name,
5154 : Constant::eResource::Electricity,
5155 : OutputProcessor::Group::HVAC,
5156 : OutputProcessor::EndUseCat::Cooling);
5157 : }
5158 :
5159 27 : } else if (thisVrf.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
5160 2 : SetupOutputVariable(state,
5161 : "VRF Heat Pump Condenser Outlet Temperature",
5162 : Constant::Units::C,
5163 1 : thisVrf.CondenserSideOutletTemp,
5164 : OutputProcessor::TimeStepType::System,
5165 : OutputProcessor::StoreType::Average,
5166 1 : thisVrf.Name);
5167 2 : SetupOutputVariable(state,
5168 : "VRF Heat Pump Condenser Mass Flow Rate",
5169 : Constant::Units::kg_s,
5170 1 : thisVrf.WaterCondenserMassFlow,
5171 : OutputProcessor::TimeStepType::System,
5172 : OutputProcessor::StoreType::Average,
5173 1 : thisVrf.Name);
5174 2 : SetupOutputVariable(state,
5175 : "VRF Heat Pump Condenser Heat Transfer Rate",
5176 : Constant::Units::W,
5177 1 : thisVrf.QCondenser,
5178 : OutputProcessor::TimeStepType::System,
5179 : OutputProcessor::StoreType::Average,
5180 1 : thisVrf.Name);
5181 2 : SetupOutputVariable(state,
5182 : "VRF Heat Pump Condenser Heat Transfer Energy",
5183 : Constant::Units::J,
5184 1 : thisVrf.QCondEnergy,
5185 : OutputProcessor::TimeStepType::System,
5186 : OutputProcessor::StoreType::Sum,
5187 1 : thisVrf.Name);
5188 : }
5189 :
5190 27 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
5191 0 : SetupEMSActuator(state,
5192 : "Variable Refrigerant Flow Heat Pump",
5193 : thisVrf.Name,
5194 : "Operating Mode",
5195 : "[integer]",
5196 0 : thisVrf.EMSOverrideHPOperatingMode,
5197 0 : thisVrf.EMSValueForHPOperatingMode);
5198 : }
5199 : }
5200 23 : }
5201 :
5202 48 : void CheckVRFTUNodeConnections(EnergyPlusData &state, int const VRFTUNum, bool &ErrorsFound)
5203 : {
5204 :
5205 : constexpr static std::string_view cTerminalUnitType("ZoneHVAC:TerminalUnit:VariableRefrigerantFlow");
5206 48 : auto const &nodeID = state.dataLoopNodes->NodeID;
5207 48 : auto &vrfTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
5208 48 : std::string const cTUName(vrfTU.Name);
5209 48 : bool const CoolingCoilPresent = vrfTU.CoolingCoilPresent;
5210 48 : bool const HeatingCoilPresent = vrfTU.HeatingCoilPresent;
5211 48 : bool const SuppHeatingCoilPresent = vrfTU.SuppHeatingCoilPresent;
5212 48 : HVAC::FanPlace const fanPlace = vrfTU.fanPlace;
5213 48 : bool const FanPresent = fanPlace != HVAC::FanPlace::Invalid;
5214 48 : bool const OAMixerUsed = vrfTU.OAMixerUsed;
5215 48 : int const VRFTUInletNodeNum = vrfTU.VRFTUInletNodeNum;
5216 48 : int const VRFTUOutletNodeNum = vrfTU.VRFTUOutletNodeNum;
5217 48 : int const coolCoilAirInNode = vrfTU.coolCoilAirInNode;
5218 48 : int const coolCoilAirOutNode = vrfTU.coolCoilAirOutNode;
5219 48 : int const heatCoilAirInNode = vrfTU.heatCoilAirInNode;
5220 48 : int const heatCoilAirOutNode = vrfTU.heatCoilAirOutNode;
5221 48 : int const fanInletNode = vrfTU.fanInletNode;
5222 48 : int const fanOutletNode = vrfTU.fanOutletNode;
5223 48 : int const SuppHeatCoilAirInletNode = vrfTU.SuppHeatCoilAirInletNode;
5224 48 : int const SuppHeatCoilAirOutletNode = vrfTU.SuppHeatCoilAirOutletNode;
5225 48 : int const VRFTUOAMixerRetNodeNum = vrfTU.VRFTUOAMixerRetNodeNum;
5226 48 : int const VRFTUOAMixerMixedNodeNum = vrfTU.VRFTUOAMixerMixedNodeNum;
5227 :
5228 : // check that TU object internal nodes (TU inlet to TU outlet) are correctly connected
5229 : // the following is checked regardless of fan placement
5230 48 : if (CoolingCoilPresent && HeatingCoilPresent) {
5231 48 : if (coolCoilAirOutNode != heatCoilAirInNode) {
5232 8 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5233 8 : ShowContinueError(state, "The cooling coil air outlet node name must match the heating coil air inlet node name.");
5234 4 : if (coolCoilAirOutNode > 0 && heatCoilAirInNode > 0) {
5235 4 : ShowContinueError(state, format("... Cooling coil air outlet node = {}", nodeID(coolCoilAirOutNode)));
5236 4 : ShowContinueError(state, format("... Heating coil air inlet node = {}", nodeID(heatCoilAirInNode)));
5237 : }
5238 4 : ErrorsFound = true;
5239 : }
5240 : }
5241 :
5242 : // check the TU inlet node name with the first component
5243 48 : if (fanPlace == HVAC::FanPlace::DrawThru || !FanPresent) {
5244 38 : if (OAMixerUsed) {
5245 30 : if (VRFTUInletNodeNum != VRFTUOAMixerRetNodeNum) {
5246 10 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5247 10 : ShowContinueError(state,
5248 : "... For draw thru or no fan when an OA mixer is specified the terminal unit "
5249 : "inlet node name must match the OA mixer return air stream node name.");
5250 5 : if (VRFTUInletNodeNum > 0 && VRFTUOAMixerRetNodeNum > 0) {
5251 5 : ShowContinueError(state, format("... Terminal unit inlet node name = {}.", nodeID(VRFTUInletNodeNum)));
5252 5 : ShowContinueError(state, format("... OA mixer return air stream node name = {}.", nodeID(VRFTUOAMixerRetNodeNum)));
5253 : }
5254 5 : ErrorsFound = true;
5255 : }
5256 : // check mixer outlet with next component
5257 30 : if (CoolingCoilPresent) {
5258 30 : if (VRFTUOAMixerMixedNodeNum != coolCoilAirInNode) {
5259 6 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5260 6 : ShowContinueError(state,
5261 : "... For draw thru or no fan when an OA mixer is specified and a cooling coil is present "
5262 : "the OA mixer mixed air node name must match the cooling coil inlet node name.");
5263 3 : if (VRFTUOAMixerMixedNodeNum > 0 && coolCoilAirInNode > 0) {
5264 2 : ShowContinueError(state, format("... OA mixer mixed air node name = {}.", nodeID(VRFTUOAMixerMixedNodeNum)));
5265 2 : ShowContinueError(state, format("... Cooling coil inlet node name = {}.", nodeID(coolCoilAirInNode)));
5266 : }
5267 3 : ErrorsFound = true;
5268 : }
5269 0 : } else if (HeatingCoilPresent) {
5270 0 : if (VRFTUOAMixerMixedNodeNum != heatCoilAirInNode) {
5271 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5272 0 : ShowContinueError(state,
5273 : "... For draw thru or no fan when an OA mixer is specified and a cooling coil is not present "
5274 : "the OA mixer mixed air node name must match the heating coil inlet node name.");
5275 0 : if (VRFTUOAMixerMixedNodeNum > 0 && heatCoilAirInNode > 0) {
5276 0 : ShowContinueError(state, format("... OA mixer mixed air node name = {}.", nodeID(VRFTUOAMixerMixedNodeNum)));
5277 0 : ShowContinueError(state, format("... Heating coil inlet node name = {}.", nodeID(heatCoilAirInNode)));
5278 : }
5279 0 : ErrorsFound = true;
5280 : }
5281 : }
5282 : } else { // OAMixer not used
5283 8 : if (CoolingCoilPresent) {
5284 8 : if (VRFTUInletNodeNum != coolCoilAirInNode) {
5285 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5286 0 : ShowContinueError(
5287 : state,
5288 : "... For draw thru or no fan when no OA mixer is specified and a cooling coil is present the terminal unit inlet "
5289 : "node name must match the cooling coil inlet node name.");
5290 0 : if (VRFTUInletNodeNum > 0 && coolCoilAirInNode > 0) {
5291 0 : ShowContinueError(state, format("... Terminal unit inlet node name = {}.", nodeID(VRFTUInletNodeNum)));
5292 0 : ShowContinueError(state, format("... Cooling coil inlet node name = {}.", nodeID(coolCoilAirInNode)));
5293 : }
5294 0 : ErrorsFound = true;
5295 : }
5296 0 : } else if (HeatingCoilPresent) {
5297 0 : if (VRFTUInletNodeNum != heatCoilAirInNode) {
5298 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5299 0 : ShowContinueError(state,
5300 : "... For draw thru or no fan when no cooling coil or OA mixer is specified the terminal unit inlet "
5301 : "node name must match the heating coil inlet node name.");
5302 0 : if (VRFTUInletNodeNum > 0 && heatCoilAirInNode > 0) {
5303 0 : ShowContinueError(state, format("... Terminal unit inlet node name = {}.", nodeID(VRFTUInletNodeNum)));
5304 0 : ShowContinueError(state, format("... Heating coil inlet node name = {}.", nodeID(heatCoilAirInNode)));
5305 : }
5306 0 : ErrorsFound = true;
5307 : }
5308 : }
5309 : }
5310 : }
5311 48 : if (fanPlace == HVAC::FanPlace::BlowThru && !OAMixerUsed) {
5312 0 : if (VRFTUInletNodeNum != fanInletNode) {
5313 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5314 0 : ShowContinueError(state,
5315 : "... For blow thru fan when no OA mixer is specified the terminal unit inlet "
5316 : "node name must match the fan inlet node name.");
5317 0 : if (VRFTUInletNodeNum > 0 && fanInletNode > 0) {
5318 0 : ShowContinueError(state, format("... Terminal unit inlet node name = {}.", nodeID(VRFTUInletNodeNum)));
5319 0 : ShowContinueError(state, format("... Fan inlet node name = {}.", nodeID(fanInletNode)));
5320 : }
5321 0 : ErrorsFound = true;
5322 : }
5323 48 : } else if (OAMixerUsed) { // when OA mixer is used TU inlet = OAMixer return node regardless of fan placement
5324 40 : if (VRFTUInletNodeNum != VRFTUOAMixerRetNodeNum) {
5325 12 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5326 12 : ShowContinueError(state,
5327 : "... When an OA mixer is specified the terminal unit inlet "
5328 : "node name must match the OA mixer return node name.");
5329 6 : if (VRFTUInletNodeNum > 0 && VRFTUOAMixerRetNodeNum > 0) {
5330 6 : ShowContinueError(state, format("... Terminal unit inlet node name = {}.", nodeID(VRFTUInletNodeNum)));
5331 6 : ShowContinueError(state, format("... Fan inlet node name = {}.", nodeID(VRFTUOAMixerRetNodeNum)));
5332 : }
5333 6 : ErrorsFound = true;
5334 : }
5335 : }
5336 : // check the next component
5337 48 : if (CoolingCoilPresent) {
5338 48 : if (fanPlace == HVAC::FanPlace::BlowThru) {
5339 10 : if (fanOutletNode != coolCoilAirInNode) {
5340 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5341 0 : ShowContinueError(state,
5342 : "... For blow thru fan when a cooling coil is present "
5343 : "fan outlet node name must match the cooling coil inlet node name.");
5344 0 : if (fanOutletNode > 0 && coolCoilAirInNode > 0) {
5345 0 : ShowContinueError(state, format("... The fan outlet node name = {}.", nodeID(fanOutletNode)));
5346 0 : ShowContinueError(state, format("... Cooling coil inlet node name = {}.", nodeID(coolCoilAirInNode)));
5347 : }
5348 0 : ErrorsFound = true;
5349 : }
5350 : }
5351 48 : if (!HeatingCoilPresent && fanPlace == HVAC::FanPlace::DrawThru) {
5352 0 : if (coolCoilAirOutNode != fanInletNode) {
5353 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5354 0 : ShowContinueError(state,
5355 : "... For draw thru fan when a heating coil is not present "
5356 : "the cooling coil outlet node name must match the fan inlet node name.");
5357 0 : if (coolCoilAirOutNode > 0 && fanInletNode > 0) {
5358 0 : ShowContinueError(state, format("... Cooling coil outlet node name = {}.", nodeID(coolCoilAirOutNode)));
5359 0 : ShowContinueError(state, format("... The fan inlet node name = {}.", nodeID(fanInletNode)));
5360 : }
5361 0 : ErrorsFound = true;
5362 : }
5363 : }
5364 : }
5365 48 : if (HeatingCoilPresent) {
5366 48 : if (fanPlace == HVAC::FanPlace::DrawThru) {
5367 32 : if (heatCoilAirOutNode != fanInletNode) {
5368 4 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5369 4 : ShowContinueError(state,
5370 : "... For draw thru fan when a heating coil is present "
5371 : "the heating coil outlet node name must match the fan inlet node name.");
5372 2 : if (heatCoilAirOutNode > 0 && fanInletNode > 0) {
5373 1 : ShowContinueError(state, format("... Heating coil outlet node name = {}.", nodeID(heatCoilAirOutNode)));
5374 1 : ShowContinueError(state, format("... The fan inlet node name = {}.", nodeID(fanInletNode)));
5375 : }
5376 2 : ErrorsFound = true;
5377 : }
5378 : }
5379 : }
5380 48 : if (SuppHeatingCoilPresent) {
5381 10 : if (SuppHeatCoilAirOutletNode != VRFTUOutletNodeNum) {
5382 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5383 0 : ShowContinueError(state, "... The supplemental heating coil outlet node name must match the terminal unit outlet node name.");
5384 0 : if (SuppHeatCoilAirOutletNode > 0 && VRFTUOutletNodeNum > 0) {
5385 0 : ShowContinueError(state, format("... Supplemental heating coil outlet node name = {}.", nodeID(SuppHeatCoilAirOutletNode)));
5386 0 : ShowContinueError(state, format("... Terminal unit outlet node name = {}.", nodeID(VRFTUOutletNodeNum)));
5387 : }
5388 0 : ErrorsFound = true;
5389 : }
5390 10 : if (fanPlace == HVAC::FanPlace::DrawThru) {
5391 9 : if (fanOutletNode != SuppHeatCoilAirInletNode) {
5392 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5393 0 : ShowContinueError(state,
5394 : "... For draw thru fan when a supplemental heating coil is present "
5395 : "the fan outlet node name must match the supplemental heating coil inlet node name.");
5396 0 : if (fanOutletNode > 0 && SuppHeatCoilAirInletNode > 0) {
5397 0 : ShowContinueError(state, format("... Fan outlet node name = {}.", nodeID(fanOutletNode)));
5398 0 : ShowContinueError(state, format("... Supplemental heating coil inlet node name = {}.", nodeID(SuppHeatCoilAirInletNode)));
5399 : }
5400 0 : ErrorsFound = true;
5401 : }
5402 : } else {
5403 1 : if (heatCoilAirOutNode != SuppHeatCoilAirInletNode) {
5404 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5405 0 : ShowContinueError(state,
5406 : "... For blow thru or no fan when a supplemental heating coil is present the heating "
5407 : "coil outlet node name must match the supplemental heating coil inlet node name.");
5408 0 : if (heatCoilAirOutNode > 0 && SuppHeatCoilAirInletNode > 0) {
5409 0 : ShowContinueError(state, format("... Heating coil outlet node name = {}.", nodeID(heatCoilAirOutNode)));
5410 0 : ShowContinueError(state, format("... Supplemental heating coil inlet node name = {}.", nodeID(SuppHeatCoilAirInletNode)));
5411 : }
5412 0 : ErrorsFound = true;
5413 : }
5414 : }
5415 38 : } else if (CoolingCoilPresent && !HeatingCoilPresent && (fanPlace == HVAC::FanPlace::BlowThru || !FanPresent)) {
5416 0 : if (coolCoilAirOutNode != VRFTUOutletNodeNum) {
5417 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5418 0 : ShowContinueError(state,
5419 : "... For blow through or no fan and no heating or supplemental heating coil the cooling coil outlet node name must "
5420 : "match the terminal unit outlet node name.");
5421 0 : if (coolCoilAirOutNode > 0 && VRFTUOutletNodeNum > 0) {
5422 0 : ShowContinueError(state, format("... Cooling coil outlet node name = {}.", nodeID(coolCoilAirOutNode)));
5423 0 : ShowContinueError(state, format("... Terminal unit outlet node name = {}.", nodeID(VRFTUOutletNodeNum)));
5424 : }
5425 0 : ErrorsFound = true;
5426 : }
5427 0 : if (fanPlace == HVAC::FanPlace::DrawThru) {
5428 0 : if (fanOutletNode != VRFTUOutletNodeNum) {
5429 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5430 0 : ShowContinueError(state,
5431 : "... For draw through fan and no supplemental heating coil the fan outlet node name must "
5432 : "match the terminal unit outlet node name.");
5433 0 : if (fanOutletNode > 0 && VRFTUOutletNodeNum > 0) {
5434 0 : ShowContinueError(state, format("... Fan outlet node name = {}.", nodeID(fanOutletNode)));
5435 0 : ShowContinueError(state, format("... Terminal unit outlet node name = {}.", nodeID(VRFTUOutletNodeNum)));
5436 : }
5437 0 : ErrorsFound = true;
5438 : }
5439 : }
5440 38 : } else if (fanPlace == HVAC::FanPlace::DrawThru) {
5441 23 : if (fanOutletNode != VRFTUOutletNodeNum) {
5442 2 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5443 2 : ShowContinueError(state,
5444 : "... For draw through fan and no supplemental heating coil the fan outlet node name must "
5445 : "match the terminal unit outlet node name.");
5446 1 : if (fanOutletNode > 0 && VRFTUOutletNodeNum > 0) {
5447 1 : ShowContinueError(state, format("... Fan outlet node name = {}.", nodeID(fanOutletNode)));
5448 1 : ShowContinueError(state, format("... Terminal unit outlet node name = {}.", nodeID(VRFTUOutletNodeNum)));
5449 : }
5450 1 : ErrorsFound = true;
5451 : }
5452 : }
5453 48 : }
5454 :
5455 7115 : void InitVRF(EnergyPlusData &state, int const VRFTUNum, int const ZoneNum, bool const FirstHVACIteration, Real64 &OnOffAirFlowRatio, Real64 &QZnReq)
5456 : {
5457 :
5458 : // SUBROUTINE INFORMATION:
5459 : // AUTHOR Richard Raustad, FSEC
5460 : // DATE WRITTEN August 2010
5461 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
5462 : // RE-ENGINEERED na
5463 :
5464 : // PURPOSE OF THIS SUBROUTINE:
5465 : // This subroutine is for initializations of the VRF Components.
5466 :
5467 : // METHODOLOGY EMPLOYED:
5468 : // Uses the status flags to trigger initializations.
5469 :
5470 : using DataSizing::AutoSize;
5471 : using DataZoneEquipment::CheckZoneEquipmentList;
5472 :
5473 : using PlantUtilities::InitComponentNodes;
5474 : using SingleDuct::SimATMixer;
5475 :
5476 : static constexpr std::string_view RoutineName("InitVRF");
5477 :
5478 : int InNode; // TU inlet node
5479 : int OutNode; // TU outlet node
5480 : int OutsideAirNode; // TU mixer outside air inlet node
5481 : int NumTULoop; // loop counter, number of TU's in list
5482 : int ELLoop; // loop counter, number of zone equipment lists
5483 : int ListLoop; // loop counter, number of equipment is each list
5484 : int VRFCond; // index to VRF condenser
5485 : int TUIndex; // index to TU
5486 : int TUListNum; // index to VRF AC system terminal unit list
5487 : int TUListIndex; // pointer to TU list for this VRF system
5488 : int IndexToTUInTUList; // index to TU in TerminalUnilList
5489 : Real64 RhoAir; // air density at InNode
5490 : Real64 CurrentEndTime; // end time of current time step
5491 7115 : Real64 TimeStepSysLast(0.0); // system time step on last time step
5492 : Real64 TempOutput; // Sensible output of TU
5493 : Real64 LoadToCoolingSP; // thermostat load to cooling setpoint (W)
5494 : Real64 LoadToHeatingSP; // thermostat load to heating setpoint (W)
5495 : bool EnableSystem; // use to turn on secondary operating mode if OA temp limits exceeded
5496 : bool ErrorsFound; // flag returned from mining call
5497 : Real64 rho; // density of water (kg/m3)
5498 : Real64 OutsideDryBulbTemp; // Outdoor air temperature at external node height
5499 : bool errFlag; // local error flag
5500 : Real64 SuppHeatCoilLoad; // additional heating required by supplemental heater (W)
5501 : Real64 SuppHeatCoilCapacity; // supplemental heating coil size (W)
5502 :
5503 : // ALLOCATE and Initialize subroutine variables
5504 7115 : if (state.dataHVACVarRefFlow->MyOneTimeFlag) {
5505 :
5506 13 : state.dataHVACVarRefFlow->MyEnvrnFlag.allocate(state.dataHVACVarRefFlow->NumVRFTU);
5507 13 : state.dataHVACVarRefFlow->MySizeFlag.allocate(state.dataHVACVarRefFlow->NumVRFTU);
5508 13 : state.dataHVACVarRefFlow->MyVRFFlag.allocate(state.dataHVACVarRefFlow->NumVRFTU);
5509 13 : state.dataHVACVarRefFlow->MyZoneEqFlag.allocate(state.dataHVACVarRefFlow->NumVRFTU);
5510 13 : state.dataHVACVarRefFlow->MyBeginTimeStepFlag.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5511 13 : state.dataHVACVarRefFlow->MaxDeltaT.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5512 13 : state.dataHVACVarRefFlow->MinDeltaT.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5513 13 : state.dataHVACVarRefFlow->LastModeCooling.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5514 13 : state.dataHVACVarRefFlow->LastModeHeating.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5515 13 : state.dataHVACVarRefFlow->HeatingLoad.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5516 13 : state.dataHVACVarRefFlow->CoolingLoad.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5517 13 : state.dataHVACVarRefFlow->NumCoolingLoads.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5518 13 : state.dataHVACVarRefFlow->SumCoolingLoads.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5519 13 : state.dataHVACVarRefFlow->NumHeatingLoads.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5520 13 : state.dataHVACVarRefFlow->SumHeatingLoads.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5521 13 : state.dataHVACVarRefFlow->MyVRFCondFlag.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5522 13 : state.dataHVACVarRefFlow->MyEnvrnFlag = true;
5523 13 : state.dataHVACVarRefFlow->MySizeFlag = true;
5524 13 : state.dataHVACVarRefFlow->MyVRFFlag = true;
5525 13 : state.dataHVACVarRefFlow->MyZoneEqFlag = true;
5526 13 : state.dataHVACVarRefFlow->MyBeginTimeStepFlag = true;
5527 13 : state.dataHVACVarRefFlow->MaxDeltaT = 0.0;
5528 13 : state.dataHVACVarRefFlow->MinDeltaT = 0.0;
5529 13 : state.dataHVACVarRefFlow->LastModeCooling = false;
5530 13 : state.dataHVACVarRefFlow->LastModeHeating = true;
5531 13 : state.dataHVACVarRefFlow->NumCoolingLoads = 0;
5532 13 : state.dataHVACVarRefFlow->SumCoolingLoads = 0.0;
5533 13 : state.dataHVACVarRefFlow->NumHeatingLoads = 0;
5534 13 : state.dataHVACVarRefFlow->SumHeatingLoads = 0.0;
5535 :
5536 13 : state.dataHVACVarRefFlow->MyOneTimeFlag = false;
5537 13 : state.dataHVACVarRefFlow->MyVRFCondFlag = true;
5538 :
5539 : } // IF (MyOneTimeFlag) THEN
5540 :
5541 : // identify VRF condenser connected to this TU
5542 7115 : VRFCond = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum;
5543 7115 : TUListIndex = state.dataHVACVarRefFlow->VRF(VRFCond).ZoneTUListPtr;
5544 7115 : InNode = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum;
5545 7115 : OutNode = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum;
5546 7115 : OutsideAirNode = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum;
5547 7115 : IndexToTUInTUList = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).IndexToTUInTUList;
5548 :
5549 7115 : SuppHeatCoilCapacity = 0.0;
5550 7115 : SuppHeatCoilLoad = 0.0;
5551 7115 : LoadToCoolingSP = 0.0;
5552 7115 : LoadToHeatingSP = 0.0;
5553 7115 : ErrorsFound = false;
5554 7115 : bool SetPointErrorFlag = false;
5555 :
5556 : // set condenser inlet temp, used as surrogate for OAT (used to check limits of operation)
5557 7115 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
5558 5 : OutsideDryBulbTemp = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRF(VRFCond).CondenserNodeNum).Temp;
5559 : } else {
5560 7110 : if (OutsideAirNode == 0) {
5561 1 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
5562 : } else {
5563 7109 : OutsideDryBulbTemp = state.dataLoopNodes->Node(OutsideAirNode).Temp;
5564 : }
5565 : }
5566 :
5567 7115 : if (allocated(state.dataAvail->ZoneComp)) {
5568 7083 : auto &availMgr = state.dataAvail->ZoneComp(DataZoneEquipment::ZoneEquipType::VariableRefrigerantFlowTerminal).ZoneCompAvailMgrs(VRFTUNum);
5569 7083 : if (state.dataHVACVarRefFlow->MyZoneEqFlag(VRFTUNum)) { // initialize the name of each availability manager list and zone number
5570 4 : availMgr.AvailManagerListName = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).AvailManagerListName;
5571 4 : availMgr.ZoneNum = ZoneNum;
5572 4 : state.dataHVACVarRefFlow->MyZoneEqFlag(VRFTUNum) = false;
5573 : }
5574 7083 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).availStatus = availMgr.availStatus;
5575 : }
5576 :
5577 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MySuppCoilPlantScanFlag && allocated(state.dataPlnt->PlantLoop)) {
5578 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
5579 : // hot water supplemental heating coil
5580 0 : errFlag = false;
5581 0 : PlantUtilities::ScanPlantLoopsForObject(state,
5582 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
5583 : PlantEquipmentType::CoilWaterSimpleHeating,
5584 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc,
5585 : errFlag,
5586 : _,
5587 : _,
5588 : _,
5589 : _,
5590 : _);
5591 :
5592 0 : WaterCoils::SetCoilDesFlow(state,
5593 0 : HVAC::cAllCoilTypes(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num),
5594 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
5595 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow,
5596 : errFlag);
5597 :
5598 0 : if (errFlag) {
5599 0 : ShowFatalError(state, format("{}: Program terminated for previous conditions.", RoutineName));
5600 : }
5601 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow = WaterCoils::GetCoilMaxWaterFlowRate(
5602 0 : state, "Coil:Heating:Water", state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName, ErrorsFound);
5603 :
5604 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow > 0.0) {
5605 0 : rho = state.dataPlnt->PlantLoop(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc.loopNum)
5606 0 : .glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
5607 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow =
5608 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow * rho;
5609 : }
5610 :
5611 : // fill fluid outlet node for hot water coil SuppHeatCoilFluidOutletNode
5612 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode =
5613 0 : DataPlant::CompData::getPlantComponent(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc).NodeNumOut;
5614 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MySuppCoilPlantScanFlag = false;
5615 :
5616 5 : } else if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
5617 : // steam supplemental heating coil
5618 0 : errFlag = false;
5619 0 : PlantUtilities::ScanPlantLoopsForObject(state,
5620 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
5621 : PlantEquipmentType::CoilSteamAirHeating,
5622 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc,
5623 : errFlag,
5624 : _,
5625 : _,
5626 : _,
5627 : _,
5628 : _);
5629 0 : if (errFlag) {
5630 0 : ShowFatalError(state, format("{}: Program terminated for previous conditions.", RoutineName));
5631 : }
5632 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow =
5633 0 : SteamCoils::GetCoilMaxSteamFlowRate(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex, ErrorsFound);
5634 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow > 0.0) {
5635 0 : Real64 TempSteamIn = 100.0;
5636 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, RoutineName);
5637 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow =
5638 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow * SteamDensity;
5639 : }
5640 :
5641 : // fill fluid outlet node for steam coil SuppHeatCoilFluidOutletNode
5642 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode =
5643 0 : DataPlant::CompData::getPlantComponent(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc).NodeNumOut;
5644 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MySuppCoilPlantScanFlag = false;
5645 :
5646 : } else { // VRF terminal unit not connected to plant
5647 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MySuppCoilPlantScanFlag = false;
5648 : }
5649 7110 : } else if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MySuppCoilPlantScanFlag && !state.dataGlobal->AnyPlantInModel) {
5650 10 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MySuppCoilPlantScanFlag = false;
5651 : }
5652 :
5653 : // one-time check to see if VRF TU's are on ZoneHVAC:EquipmentList or AirloopHVAC or issue warning
5654 7115 : if (state.dataHVACVarRefFlow->ZoneEquipmentListNotChecked) {
5655 19 : if (state.dataAirLoop->AirLoopInputsFilled) state.dataHVACVarRefFlow->ZoneEquipmentListNotChecked = false;
5656 19 : bool AirLoopFound = false;
5657 19 : bool errorsFound = false;
5658 19 : bool AirNodeFound = false;
5659 19 : int ctrlZoneNum = 0;
5660 19 : std::string const cCurrentModuleObject = "ZoneHVAC:TerminalUnit:VariableRefrigerantFlow";
5661 38 : for (TUListNum = 1; TUListNum <= state.dataHVACVarRefFlow->NumVRFTULists; ++TUListNum) {
5662 40 : for (NumTULoop = 1; NumTULoop <= state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList; ++NumTULoop) {
5663 21 : AirLoopFound = false; // reset for next TU
5664 21 : ctrlZoneNum = 0; // reset for next TU
5665 21 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTULoop);
5666 21 : std::string const thisObjectName = state.dataHVACVarRefFlow->VRFTU(TUIndex).Name;
5667 21 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).isInZone) goto EquipList_exit; // already found previously
5668 23 : for (ELLoop = 1; ELLoop <= state.dataGlobal->NumOfZones; ++ELLoop) { // NumOfZoneEquipLists
5669 21 : if (state.dataZoneEquip->ZoneEquipList(ELLoop).Name == "") continue; // dimensioned by NumOfZones. Only valid ones have names.
5670 20 : for (ListLoop = 1; ListLoop <= state.dataZoneEquip->ZoneEquipList(ELLoop).NumOfEquipTypes; ++ListLoop) {
5671 16 : if (!Util::SameString(state.dataZoneEquip->ZoneEquipList(ELLoop).EquipTypeName(ListLoop),
5672 16 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(TUIndex).type]))
5673 1 : continue;
5674 15 : if (!Util::SameString(state.dataZoneEquip->ZoneEquipList(ELLoop).EquipName(ListLoop),
5675 15 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name))
5676 2 : continue;
5677 13 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum = ELLoop;
5678 13 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isInZone = true;
5679 13 : if (state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFSysNum).MasterZonePtr == ELLoop) {
5680 4 : state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFSysNum).MasterZoneTUIndex = TUIndex;
5681 : }
5682 13 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneAirNode == 0) {
5683 0 : bool ZoneNodeNotFound = true;
5684 0 : for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
5685 0 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
5686 0 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumExhaustNodes; ++NodeNum) {
5687 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum ==
5688 0 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ExhaustNode(NodeNum)) {
5689 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneAirNode =
5690 0 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ZoneNode;
5691 0 : ZoneNodeNotFound = false;
5692 0 : break;
5693 : }
5694 : }
5695 0 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) {
5696 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum ==
5697 0 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) {
5698 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneAirNode =
5699 0 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ZoneNode;
5700 0 : ZoneNodeNotFound = false;
5701 0 : break;
5702 : }
5703 : }
5704 0 : if (!ZoneNodeNotFound) break;
5705 : }
5706 0 : if (ZoneNodeNotFound) {
5707 0 : ShowSevereError(state,
5708 0 : format("ZoneHVAC:TerminalUnit:VariableRefrigerantFlow \"{}\" Zone terminal unit air inlet node name "
5709 : "must be the same as a zone inlet or exhaust node name.",
5710 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
5711 0 : ShowContinueError(state,
5712 : "... Zone inlet and exhaust node name is specified in ZoneHVAC:EquipmentConnections object.");
5713 0 : ShowContinueError(state,
5714 0 : format("... Zone terminal unit inlet node name = {}",
5715 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum)));
5716 0 : ShowContinueError(state,
5717 0 : format("... Zone terminal unit outlet node name = {}",
5718 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum)));
5719 : }
5720 : }
5721 13 : goto EquipList_exit;
5722 : }
5723 : }
5724 : // check if the TU is connected to an air loop
5725 2 : if (!state.dataHVACVarRefFlow->VRFTU(TUIndex).isInAirLoop) {
5726 2 : for (int AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
5727 1 : for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) {
5728 1 : for (int CompNum = 1;
5729 1 : CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents;
5730 : ++CompNum) {
5731 1 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).Name,
5732 2 : thisObjectName) &&
5733 1 : Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).TypeOf,
5734 : cCurrentModuleObject)) {
5735 1 : state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum = AirLoopNum;
5736 1 : AirLoopFound = true;
5737 1 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isInAirLoop = true;
5738 2 : BranchNodeConnections::TestCompSet(
5739 : state,
5740 : cCurrentModuleObject,
5741 : thisObjectName,
5742 1 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum),
5743 1 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum),
5744 : "Air Nodes");
5745 1 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum > 0) {
5746 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneAirNode =
5747 0 : state.dataZoneEquip->ZoneEquipConfig(state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum).ZoneNode;
5748 0 : int ControlledZoneNum = state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum;
5749 0 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
5750 0 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum !=
5751 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum)
5752 0 : continue;
5753 0 : state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFSysNum).MasterZoneTUIndex =
5754 : TUIndex;
5755 0 : AirNodeFound = true;
5756 0 : ctrlZoneNum = ControlledZoneNum;
5757 0 : goto EquipList_exit;
5758 : }
5759 0 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
5760 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum !=
5761 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum)
5762 0 : continue;
5763 0 : state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFSysNum).MasterZoneTUIndex =
5764 : TUIndex;
5765 0 : AirNodeFound = true;
5766 0 : ctrlZoneNum = ControlledZoneNum;
5767 0 : goto EquipList_exit;
5768 : }
5769 0 : if (!AirNodeFound && state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum > 0) {
5770 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
5771 0 : ShowContinueError(state, "Did not find Air node (Zone with Thermostat or Thermal Comfort Thermostat).");
5772 : // ShowContinueError(state, format("specified Controlling Zone or Thermostat Location name = {}{}", //,
5773 : // loc_controlZoneName));
5774 0 : errorsFound = true;
5775 : }
5776 1 : } else if (AirLoopFound) { // control zone name not entered in TU object input
5777 1 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled = true;
5778 : }
5779 : }
5780 1 : if (AirLoopFound) break;
5781 : }
5782 1 : if (AirLoopFound) break;
5783 : }
5784 1 : if (AirLoopFound) break;
5785 : }
5786 : }
5787 :
5788 : // check if the TU is connected to an outside air system
5789 2 : if (!AirLoopFound && !state.dataHVACVarRefFlow->VRFTU(TUIndex).isInOASys) {
5790 1 : for (int OASysNum = 1; OASysNum <= state.dataAirLoop->NumOASystems; ++OASysNum) {
5791 0 : for (int OACompNum = 1; OACompNum <= state.dataAirLoop->OutsideAirSys(OASysNum).NumComponents; ++OACompNum) {
5792 0 : if (!Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentName(OACompNum),
5793 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name) ||
5794 0 : !Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentType(OACompNum), cCurrentModuleObject))
5795 0 : continue;
5796 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum = 0; // need air loop number here?
5797 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isInOASys = true;
5798 0 : AirLoopFound = true;
5799 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled = true;
5800 : // user may have inadvertently entered a zone name in the OA system TU object
5801 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum = 0;
5802 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneAirNode = 0;
5803 0 : BranchNodeConnections::TestCompSet(
5804 : state,
5805 : cCurrentModuleObject,
5806 : thisObjectName,
5807 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum),
5808 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum),
5809 : "Air Nodes");
5810 0 : goto EquipList_exit;
5811 : }
5812 : }
5813 : }
5814 1 : EquipList_exit:;
5815 21 : if (ctrlZoneNum > 0) {
5816 0 : int inletNodeADUNum = 0;
5817 0 : DataZoneEquipment::ZoneEquipType sysType_Num = DataZoneEquipment::ZoneEquipType::Invalid;
5818 0 : std::string sysName = "";
5819 0 : for (int inletNode = 1; inletNode <= state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).NumInletNodes; inletNode++) {
5820 0 : if (state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).InletNodeAirLoopNum(inletNode) !=
5821 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5822 0 : continue;
5823 0 : inletNodeADUNum = state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).InletNodeADUNum(inletNode);
5824 0 : if (inletNodeADUNum > 0 && inletNodeADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size()) {
5825 0 : sysType_Num = DataZoneEquipment::ZoneEquipType::AirDistributionUnit;
5826 0 : sysName = state.dataDefineEquipment->AirDistUnit(inletNodeADUNum).Name;
5827 0 : break;
5828 : }
5829 : }
5830 0 : if (inletNodeADUNum > 0) {
5831 0 : if (state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).EquipListIndex > 0) {
5832 0 : for (int EquipNum = 1;
5833 0 : EquipNum <=
5834 0 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).EquipListIndex).NumOfEquipTypes;
5835 : ++EquipNum) {
5836 0 : if ((state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).EquipListIndex)
5837 0 : .EquipType(EquipNum) != sysType_Num) ||
5838 0 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).EquipListIndex)
5839 0 : .EquipName(EquipNum) != sysName)
5840 0 : continue;
5841 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).zoneSequenceCoolingNum =
5842 0 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).EquipListIndex)
5843 0 : .CoolingPriority(EquipNum);
5844 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).zoneSequenceHeatingNum =
5845 0 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).EquipListIndex)
5846 0 : .HeatingPriority(EquipNum);
5847 0 : break;
5848 : }
5849 : }
5850 : } else {
5851 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
5852 0 : ShowContinueError(state, "Did not find ZoneHVAC:EquipmentList connected to this VRF terminal unit.");
5853 0 : errorsFound = true;
5854 : }
5855 0 : }
5856 :
5857 : // Find the number of zones (zone Inlet nodes) attached to an air loop from the air loop number
5858 21 : if (AirLoopFound || state.dataHVACVarRefFlow->VRFTU(TUIndex).isInAirLoop) {
5859 1 : int NumAirLoopZones = 0;
5860 1 : bool initLoadBasedControlFlowFracFlagReady = false;
5861 1 : Real64 initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax = 0.0;
5862 1 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum > 0)
5863 0 : NumAirLoopZones = state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum).NumZonesCooled +
5864 0 : state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum).NumZonesHeated;
5865 1 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo)) {
5866 0 : initLoadBasedControlFlowFracFlagReady = true;
5867 0 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
5868 : // zone inlet nodes for cooling
5869 0 : if (state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum).NumZonesCooled > 0) {
5870 0 : if (state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5871 0 : .TermUnitCoolInletNodes(ZoneInSysIndex) == -999) {
5872 : // the data structure for the zones inlet nodes has not been filled
5873 0 : initLoadBasedControlFlowFracFlagReady = false;
5874 : } else {
5875 0 : int ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5876 0 : .TermUnitCoolInletNodes(ZoneInSysIndex);
5877 0 : if (state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax == -999.0) {
5878 : // the node mass flow rate has not been set
5879 0 : initLoadBasedControlFlowFracFlagReady = false;
5880 : }
5881 : }
5882 : }
5883 : // zone inlet nodes for heating
5884 0 : if (state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum).NumZonesHeated > 0) {
5885 0 : if (state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5886 0 : .TermUnitHeatInletNodes(ZoneInSysIndex) == -999) {
5887 : // the data structure for the zones inlet nodes has not been filled
5888 0 : initLoadBasedControlFlowFracFlagReady = false;
5889 : } else {
5890 0 : int ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5891 0 : .TermUnitHeatInletNodes(ZoneInSysIndex);
5892 0 : if (state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax == -999.0) {
5893 : // the node mass flow rate has not been set
5894 0 : initLoadBasedControlFlowFracFlagReady = false;
5895 : }
5896 : }
5897 : }
5898 : }
5899 : }
5900 1 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && initLoadBasedControlFlowFracFlagReady) {
5901 0 : Real64 SumOfMassFlowRateMax = 0.0; // initialize the sum of the maximum flows
5902 0 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
5903 0 : int ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5904 0 : .TermUnitCoolInletNodes(ZoneInSysIndex);
5905 0 : SumOfMassFlowRateMax += state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
5906 0 : if (state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5907 0 : .CoolCtrlZoneNums(ZoneInSysIndex) == state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum) {
5908 0 : initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax =
5909 0 : state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
5910 : }
5911 : }
5912 0 : if (SumOfMassFlowRateMax != 0.0 && state.dataAirLoop->AirLoopInputsFilled) {
5913 0 : if (initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax >= HVAC::SmallAirVolFlow) {
5914 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).controlZoneMassFlowFrac =
5915 0 : initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax / SumOfMassFlowRateMax;
5916 0 : BaseSizer::reportSizerOutput(state,
5917 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(TUIndex).type],
5918 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name,
5919 : "Fraction of Supply Air Flow That Goes Through the Controlling Zone",
5920 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).controlZoneMassFlowFrac);
5921 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled = false; // redundant
5922 : } else {
5923 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).isInAirLoop && state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum == 0 &&
5924 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneAirNode == 0) {
5925 : // TU must be set point controlled and use constant fan mode (or coil out T won't change with PLR/air flow)
5926 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled = true;
5927 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanOpModeSched != nullptr) {
5928 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanOpModeSched->getCurrentVal() == 0.0) {
5929 0 : ShowSevereError(state,
5930 0 : format("{} = {}",
5931 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(TUIndex).type],
5932 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
5933 0 : ShowContinueError(state,
5934 : "When using set point control, fan operating mode must be continuous (fan "
5935 : "operating mode schedule values > 0).");
5936 0 : ShowContinueError(state,
5937 0 : format("Error found in Supply Air Fan Operating Mode Schedule Name = {}",
5938 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).fanOpModeSched->Name));
5939 0 : ShowContinueError(state, "...schedule values must be (>0., <=1.)");
5940 0 : ErrorsFound = true;
5941 : }
5942 : }
5943 : } else {
5944 0 : ShowSevereError(state,
5945 0 : format("{} = {}",
5946 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(TUIndex).type],
5947 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
5948 0 : ShowContinueError(state, " The Fraction of Supply Air Flow That Goes Through the Controlling Zone is set to 1.");
5949 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).controlZoneMassFlowFrac = 1.0;
5950 0 : BaseSizer::reportSizerOutput(state,
5951 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(TUIndex).type],
5952 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name,
5953 : "Fraction of Supply Air Flow That Goes Through the Controlling Zone",
5954 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).controlZoneMassFlowFrac);
5955 : }
5956 : }
5957 0 : } else if (state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum == 0) {
5958 : // TU must be set point controlled and use constant fan mode (or coil outlet T won't change with PLR/air flow rate)
5959 : // TU inlet air flow rate is also determined by OA system, not TU
5960 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled = true;
5961 : }
5962 : }
5963 : }
5964 :
5965 21 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).isInZone && state.dataAirLoop->AirLoopInputsFilled) {
5966 13 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanPlace == HVAC::FanPlace::Invalid) {
5967 0 : ShowSevereError(state,
5968 0 : format("ZoneHVAC:TerminalUnit:VariableRefrigerantFlow = {}", state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
5969 0 : ShowContinueError(state, "Illegal Supply Air Fan Placement.");
5970 0 : ErrorsFound = true;
5971 : }
5972 13 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).FanIndex == 0) {
5973 0 : ShowSevereError(state,
5974 0 : format("ZoneHVAC:TerminalUnit:VariableRefrigerantFlow = {}", state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
5975 0 : ShowContinueError(state, "VRF Terminal Unit fan is required when used as zone equipment.");
5976 0 : ErrorsFound = true;
5977 : }
5978 : }
5979 :
5980 21 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled && state.dataAirLoop->AirLoopInputsFilled) {
5981 1 : bool missingSetPoint = false;
5982 1 : Real64 TUOutNodeSP = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum).TempSetPoint;
5983 1 : Real64 coolCoilOutNodeSP = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirOutNode).TempSetPoint;
5984 1 : Real64 heatCoilOutNodeSP = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirOutNode).TempSetPoint;
5985 : // SP can be at outlet of TU or at outlet of coils
5986 : // if supp heat coil is present, a SP must be at the outlet of the TU
5987 1 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).SuppHeatingCoilPresent) {
5988 0 : if (TUOutNodeSP == DataLoopNode::SensedNodeFlagValue) missingSetPoint = true;
5989 : } else {
5990 1 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanPlace == HVAC::FanPlace::DrawThru) {
5991 : // then SP must be at TU outlet
5992 0 : if (TUOutNodeSP == DataLoopNode::SensedNodeFlagValue) missingSetPoint = true;
5993 : // or at coil outlet nodes
5994 0 : if (missingSetPoint) {
5995 0 : if (coolCoilOutNodeSP != DataLoopNode::SensedNodeFlagValue && heatCoilOutNodeSP != DataLoopNode::SensedNodeFlagValue)
5996 0 : missingSetPoint = false;
5997 : }
5998 : } else {
5999 : // else fan is blow thru or missing
6000 1 : if (TUOutNodeSP == DataLoopNode::SensedNodeFlagValue) missingSetPoint = true;
6001 : }
6002 : }
6003 1 : if (missingSetPoint) {
6004 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
6005 0 : ShowSevereError(state,
6006 0 : format("ZoneHVAC:TerminalUnit:VariableRefrigerantFlow: Missing temperature setpoint for {}",
6007 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
6008 0 : ShowContinueError(state, "...use a Setpoint Manager to establish a setpoint at the TU or coil(s) outlet node.");
6009 0 : ErrorsFound = true;
6010 0 : } else if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
6011 0 : bool SPNotFound = false;
6012 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(
6013 0 : state, state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum, HVAC::CtrlVarType::Temp, SetPointErrorFlag);
6014 0 : SPNotFound = SPNotFound || SetPointErrorFlag;
6015 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(
6016 0 : state, state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirOutNode, HVAC::CtrlVarType::Temp, SetPointErrorFlag);
6017 0 : SPNotFound = SPNotFound || SetPointErrorFlag;
6018 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(
6019 0 : state, state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirOutNode, HVAC::CtrlVarType::Temp, SetPointErrorFlag);
6020 0 : SPNotFound = SPNotFound || SetPointErrorFlag;
6021 :
6022 : // We disable the check at end (if API), because one of the nodes is enough, so there's an almost certainty
6023 : // that it will throw as you're unlikely going to actuate all three nodes
6024 : // It's not ideal, but it's better to let slide a bad condition rather than throw false positives...
6025 0 : state.dataLoopNodes->NodeSetpointCheck(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum)
6026 0 : .needsSetpointChecking = false;
6027 0 : state.dataLoopNodes->NodeSetpointCheck(state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirOutNode)
6028 0 : .needsSetpointChecking = false;
6029 0 : state.dataLoopNodes->NodeSetpointCheck(state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirOutNode)
6030 0 : .needsSetpointChecking = false;
6031 :
6032 0 : if (SPNotFound && state.dataAirLoop->AirLoopInputsFilled) {
6033 0 : ShowSevereError(
6034 : state,
6035 0 : format("ZoneHVAC:TerminalUnit:VariableRefrigerantFlow: Missing temperature setpoint for unitary system = {}",
6036 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
6037 0 : ShowContinueError(state, "...use a Setpoint Manager to establish a setpoint at the TU or coil(s) outlet node.");
6038 0 : ShowContinueError(state, "...or use an EMS actuator to establish a temperature setpoint at the coil control node.");
6039 0 : ErrorsFound = true;
6040 : }
6041 : }
6042 : }
6043 : }
6044 :
6045 41 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).isInAirLoop || state.dataHVACVarRefFlow->VRFTU(TUIndex).isInOASys ||
6046 20 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isInZone)
6047 20 : continue;
6048 1 : if (!state.dataAirLoop->AirLoopInputsFilled) continue;
6049 2 : ShowSevereError(state,
6050 2 : format("InitVRF: VRF Terminal Unit = [{},{}] is not on any ZoneHVAC:EquipmentList, AirloopHVAC or "
6051 : "AirLoopHVAC:OutdoorAirSystem:EquipmentList. It will not be simulated.",
6052 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(TUIndex).type],
6053 1 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
6054 2 : ShowContinueError(state, "...The VRF AC System associated with this terminal unit may also not be simulated.");
6055 21 : }
6056 : }
6057 :
6058 : // TU inlet node must be the same as a zone exhaust node and the OA Mixer return node
6059 : // check that TU inlet node is a zone exhaust node.
6060 36 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone &&
6061 17 : (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists ||
6062 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerType == HVAC::MixerType::SupplySide)) {
6063 17 : bool ZoneNodeNotFound = true;
6064 17 : for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
6065 17 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
6066 17 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumExhaustNodes; ++NodeNum) {
6067 17 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum ==
6068 17 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ExhaustNode(NodeNum)) {
6069 17 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneAirNode = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ZoneNode;
6070 17 : ZoneNodeNotFound = false;
6071 17 : break;
6072 : }
6073 : }
6074 17 : if (!ZoneNodeNotFound) break;
6075 : }
6076 17 : if (ZoneNodeNotFound && !state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInAirLoop) {
6077 0 : ShowSevereError(state,
6078 0 : format("{} \"{}\" Zone terminal unit air inlet node name must be the same as a zone exhaust node name.",
6079 : cCurrentModuleObject,
6080 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6081 0 : ShowContinueError(state, "... Zone exhaust node name is specified in ZoneHVAC:EquipmentConnections object.");
6082 0 : ShowContinueError(state,
6083 0 : format("... Zone terminal unit inlet node name = {}",
6084 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum)));
6085 0 : ErrorsFound = true;
6086 : }
6087 : }
6088 : // check OA Mixer return node
6089 36 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone && !state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists &&
6090 17 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6091 16 : Array1D_int OANodeNums = MixedAir::GetOAMixerNodeNumbers(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, errFlag);
6092 16 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum != OANodeNums(3)) {
6093 0 : ShowSevereError(
6094 : state,
6095 0 : format("{} \"{}\" Zone terminal unit air inlet node name must be the same as the OutdoorAir:Mixer return air node name.",
6096 : cCurrentModuleObject,
6097 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6098 0 : ShowContinueError(state,
6099 0 : format("... Zone terminal unit air inlet node name = {}",
6100 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum)));
6101 0 : ShowContinueError(state, format("... OutdoorAir:Mixer return air node name = {}", state.dataLoopNodes->NodeID(OANodeNums(3))));
6102 0 : ErrorsFound = true;
6103 : }
6104 16 : }
6105 : // check that TU outlet node is a zone inlet node.
6106 36 : if ((state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone &&
6107 17 : (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists ||
6108 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerType == HVAC::MixerType::InletSide))) {
6109 17 : bool ZoneNodeNotFound = true;
6110 17 : for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
6111 17 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
6112 17 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) {
6113 17 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum ==
6114 17 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) {
6115 17 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneAirNode = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ZoneNode;
6116 17 : ZoneNodeNotFound = false;
6117 17 : break;
6118 : }
6119 : }
6120 17 : if (!ZoneNodeNotFound) break;
6121 : }
6122 17 : if (ZoneNodeNotFound) {
6123 0 : ShowSevereError(state,
6124 0 : format("{} \"{}\" Zone terminal unit air outlet node name must be the same as a zone inlet node name.",
6125 : cCurrentModuleObject,
6126 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6127 0 : ShowContinueError(state, "... Zone inlet node name is specified in ZoneHVAC:EquipmentConnections object.");
6128 0 : ShowContinueError(state,
6129 0 : format("... Zone terminal unit outlet node name = {}",
6130 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum)));
6131 0 : ErrorsFound = true;
6132 : }
6133 : }
6134 :
6135 19 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone && state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists) {
6136 : // check that OA flow in cooling must be set to zero when connected to DOAS
6137 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow != 0) {
6138 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6139 0 : ShowContinueError(state, format(".. Cooling Outdoor Air Flow Rate must be zero when {}", cCurrentModuleObject));
6140 0 : ShowContinueError(state, "..object is connected to central dedicated outdoor air system via AirTerminal:SingleDuct:Mixer");
6141 0 : ShowContinueError(state, ".. Cooling Outdoor Air Flow Rate is set to 0 and simulation continues.");
6142 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow = 0;
6143 : }
6144 : // check that OA flow in heating must be set to zero when connected to DOAS
6145 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow != 0) {
6146 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6147 0 : ShowContinueError(state, format(".. Heating Outdoor Air Flow Rate must be zero when {}", cCurrentModuleObject));
6148 0 : ShowContinueError(state, "..object is connected to central dedicated outdoor air system via AirTerminal:SingleDuct:Mixer");
6149 0 : ShowContinueError(state, ".. Heating Outdoor Air Flow Rate is set to 0 and simulation continues.");
6150 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow = 0;
6151 : }
6152 : // check that OA flow in no cooling and no heating must be set to zero when connected to DOAS
6153 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow != 0) {
6154 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6155 0 : ShowContinueError(state, format(".. No Load Outdoor Air Flow Rate must be zero when {}", cCurrentModuleObject));
6156 0 : ShowContinueError(state, "..object is connected to central dedicated outdoor air system via AirTerminal:SingleDuct:Mixer");
6157 0 : ShowContinueError(state, ".. No Load Outdoor Air Flow Rate is set to 0 and simulation continues.");
6158 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow = 0;
6159 : }
6160 : }
6161 19 : } // IF(ZoneEquipmentListNotChecked)THEN
6162 :
6163 : // Size TU
6164 7115 : if (state.dataHVACVarRefFlow->MySizeFlag(VRFTUNum)) {
6165 18 : if (!state.dataGlobal->ZoneSizingCalc && !state.dataGlobal->SysSizingCalc) {
6166 13 : SizeVRF(state, VRFTUNum);
6167 13 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).TerminalUnitNotSizedYet(IndexToTUInTUList) = false;
6168 13 : state.dataHVACVarRefFlow->MySizeFlag(VRFTUNum) = false;
6169 : } // IF ( .NOT. ZoneSizingCalc) THEN
6170 : } // IF (MySizeFlag(VRFTUNum)) THEN
6171 :
6172 : // Do the Begin Environment initializations
6173 7115 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHVACVarRefFlow->MyEnvrnFlag(VRFTUNum)) {
6174 :
6175 : // Change the Volume Flow Rates to Mass Flow Rates
6176 :
6177 24 : RhoAir = state.dataEnvrn->StdRhoAir;
6178 : // set the mass flow rates from the input volume flow rates
6179 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow = RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow;
6180 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow = RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow;
6181 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow = RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow;
6182 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow = RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow;
6183 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow = RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow;
6184 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow = RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow;
6185 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow =
6186 24 : RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow;
6187 : // set the node max and min mass flow rates
6188 : // outside air mixer is optional, check that node num > 0
6189 24 : if (OutsideAirNode > 0) {
6190 23 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMax =
6191 23 : max(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow);
6192 23 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMin = 0.0;
6193 23 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = 0.0;
6194 : }
6195 24 : state.dataLoopNodes->Node(OutNode).MassFlowRateMax =
6196 24 : max(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow);
6197 24 : state.dataLoopNodes->Node(OutNode).MassFlowRateMin = 0.0;
6198 24 : state.dataLoopNodes->Node(OutNode).MassFlowRateMinAvail = 0.0;
6199 24 : state.dataLoopNodes->Node(InNode).MassFlowRateMax =
6200 24 : max(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow);
6201 24 : state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
6202 24 : state.dataLoopNodes->Node(InNode).MassFlowRateMinAvail = 0.0;
6203 24 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRelNodeNum > 0) {
6204 23 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRelNodeNum).MassFlowRateMinAvail = 0.0;
6205 : }
6206 :
6207 24 : state.dataHVACVarRefFlow->MyEnvrnFlag(VRFTUNum) = false;
6208 :
6209 24 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
6210 1 : rho = state.dataPlnt->PlantLoop(state.dataHVACVarRefFlow->VRF(VRFCond).SourcePlantLoc.loopNum)
6211 1 : .glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
6212 1 : state.dataHVACVarRefFlow->VRF(VRFCond).WaterCondenserDesignMassFlow = state.dataHVACVarRefFlow->VRF(VRFCond).WaterCondVolFlowRate * rho;
6213 :
6214 3 : InitComponentNodes(state,
6215 : 0.0,
6216 1 : state.dataHVACVarRefFlow->VRF(VRFCond).WaterCondenserDesignMassFlow,
6217 1 : state.dataHVACVarRefFlow->VRF(VRFCond).CondenserNodeNum,
6218 1 : state.dataHVACVarRefFlow->VRF(VRFCond).CondenserOutletNodeNum);
6219 : }
6220 : // IF(MyVRFCondFlag(VRFCond))THEN
6221 24 : state.dataHVACVarRefFlow->VRF(VRFCond).HRTimer = 0.0;
6222 24 : state.dataHVACVarRefFlow->VRF(VRFCond).ModeChange = false;
6223 24 : state.dataHVACVarRefFlow->VRF(VRFCond).HRModeChange = false;
6224 24 : state.dataHVACVarRefFlow->MyVRFCondFlag(VRFCond) = false;
6225 : // END IF
6226 :
6227 24 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode > 0) {
6228 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
6229 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow == DataSizing::AutoSize) {
6230 0 : WaterCoils::SimulateWaterCoilComponents(state,
6231 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
6232 : FirstHVACIteration,
6233 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex);
6234 : // design hot water volume flow rate
6235 0 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
6236 0 : state, "Coil:Heating:Water", state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName, ErrorsFound);
6237 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
6238 0 : rho = state.dataPlnt->PlantLoop(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc.loopNum)
6239 0 : .glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
6240 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow = CoilMaxVolFlowRate * rho;
6241 : }
6242 : }
6243 : }
6244 :
6245 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
6246 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow == DataSizing::AutoSize) {
6247 0 : SteamCoils::SimulateSteamCoilComponents(state,
6248 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
6249 : FirstHVACIteration,
6250 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex,
6251 0 : 1.0);
6252 : // design steam volume flow rate
6253 : Real64 CoilMaxVolFlowRate =
6254 0 : SteamCoils::GetCoilMaxSteamFlowRate(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex, ErrorsFound);
6255 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
6256 0 : Real64 TempSteamIn = 100.0;
6257 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, RoutineName);
6258 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow = CoilMaxVolFlowRate * SteamDensity;
6259 : }
6260 : }
6261 : }
6262 : // init water/steam coils min and max flow rates
6263 0 : InitComponentNodes(state,
6264 : 0.0,
6265 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow,
6266 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode,
6267 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode);
6268 : }
6269 :
6270 : // the first time an air loop VRF TU is simulated set isSimulated = true so that the TU initialization
6271 : // will occur with the first TU simulated this time step. Zone VRF TUs are called during sizing which, if air
6272 : // loop TUs are included, alters when all TUs appear to have been simulated. Also, BeginEnvrnFlag is true multiple
6273 : // times during the simulation, reset each time to avoid a different order during sizing and simulation
6274 24 : if (state.dataHVACVarRefFlow->TerminalUnitList(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex).reset_isSimulatedFlags) {
6275 : // if no TUs are in the air loop or outdoor air system they will all be simulated during ManageZoneEquipment
6276 : // and there is no need to adjust the order of simulation (i.e., when isSimulated are all true for a given system)
6277 24 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInAirLoop || state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInOASys) {
6278 1 : state.dataHVACVarRefFlow->TerminalUnitList(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex).IsSimulated = true;
6279 1 : state.dataHVACVarRefFlow->TerminalUnitList(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex).reset_isSimulatedFlags = false;
6280 : }
6281 : }
6282 :
6283 : } // IF (BeginEnvrnFlag .and. MyEnvrnFlag(VRFTUNum)) THEN
6284 :
6285 : // reset environment flag for next environment
6286 7115 : if (!state.dataGlobal->BeginEnvrnFlag) {
6287 7021 : state.dataHVACVarRefFlow->MyEnvrnFlag(VRFTUNum) = true;
6288 7021 : state.dataHVACVarRefFlow->MyVRFCondFlag(VRFCond) = true;
6289 7021 : state.dataHVACVarRefFlow->TerminalUnitList(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex).reset_isSimulatedFlags = true;
6290 : }
6291 :
6292 : // If all VRF Terminal Units on this VRF AC System have been simulated, reset the IsSimulated flag
6293 : // The condenser will be simulated after all terminal units have been simulated (see Sub SimulateVRF)
6294 7115 : if (all(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).IsSimulated)) {
6295 : // this should be the first time through on the next iteration. All TU's and condenser have been simulated.
6296 : // reset simulation flag for each terminal unit
6297 7094 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).IsSimulated = false;
6298 : // after all TU's have been simulated, reset operating mode flag if necessary
6299 7094 : if (state.dataHVACVarRefFlow->LastModeHeating(VRFCond) && state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
6300 11 : state.dataHVACVarRefFlow->LastModeCooling(VRFCond) = true;
6301 11 : state.dataHVACVarRefFlow->LastModeHeating(VRFCond) = false;
6302 : // SwitchedMode(VRFCond) = .TRUE.
6303 : }
6304 7094 : if (state.dataHVACVarRefFlow->LastModeCooling(VRFCond) && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
6305 6 : state.dataHVACVarRefFlow->LastModeHeating(VRFCond) = true;
6306 6 : state.dataHVACVarRefFlow->LastModeCooling(VRFCond) = false;
6307 : // SwitchedMode(VRFCond) = .TRUE.
6308 : }
6309 : } // IF(ALL(TerminalUnitList(VRFTU(VRFTUNum)%TUListIndex)%IsSimulated))THEN
6310 :
6311 : // get operating capacity of water and steam coil
6312 7115 : if (FirstHVACIteration) {
6313 3588 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode > 0) {
6314 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
6315 : // set hot water full flow rate for sizing
6316 0 : Real64 mdot = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow;
6317 0 : PlantUtilities::SetComponentFlowRate(state,
6318 : mdot,
6319 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode,
6320 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode,
6321 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc);
6322 :
6323 : // simulate water coil to find operating capacity
6324 0 : WaterCoils::SimulateWaterCoilComponents(state,
6325 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
6326 : FirstHVACIteration,
6327 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex,
6328 : SuppHeatCoilCapacity);
6329 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSuppHeatingCapacity = SuppHeatCoilCapacity;
6330 : } // from iF VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingWater
6331 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
6332 : // set hot water full flow rate for sizing
6333 0 : Real64 mdot = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow;
6334 0 : PlantUtilities::SetComponentFlowRate(state,
6335 : mdot,
6336 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode,
6337 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode,
6338 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc);
6339 :
6340 : // simulate steam coil to find operating capacity
6341 0 : SteamCoils::SimulateSteamCoilComponents(state,
6342 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
6343 : FirstHVACIteration,
6344 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex,
6345 0 : 1.0,
6346 : ErrorsFound); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
6347 0 : SuppHeatCoilCapacity =
6348 0 : SteamCoils::GetCoilCapacity(state, "Coil:Heating:Steam", state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName, ErrorsFound);
6349 :
6350 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSuppHeatingCapacity = SuppHeatCoilCapacity;
6351 : } // from if VRFTU( VRFTUNum ).SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam
6352 : }
6353 : }
6354 : // initialize water/steam coil inlet flow rate to zero
6355 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode > 0) {
6356 0 : Real64 mdot = 0.0;
6357 0 : PlantUtilities::SetComponentFlowRate(state,
6358 : mdot,
6359 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode,
6360 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode,
6361 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc);
6362 : }
6363 :
6364 : // one-time checks of flow rate vs fan flow rate
6365 7115 : if (state.dataHVACVarRefFlow->MyVRFFlag(VRFTUNum)) {
6366 22 : if (!state.dataGlobal->ZoneSizingCalc && !state.dataGlobal->SysSizingCalc) {
6367 17 : auto &vrfTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
6368 17 : if (vrfTU.fanPlace != HVAC::FanPlace::Invalid) { // was > 0 (is 0 invalid?)
6369 16 : if (vrfTU.ActualFanVolFlowRate != AutoSize) {
6370 :
6371 5 : if (vrfTU.fanType == HVAC::FanType::SystemModel) {
6372 3 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(vrfTU.FanIndex));
6373 6 : if (fanSystem->speedControl == Fans::SpeedControl::Discrete &&
6374 3 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex < 0) {
6375 3 : if (fanSystem->numSpeeds > 1) {
6376 2 : if (vrfTU.DXCoolCoilType_Num == HVAC::CoilVRF_Cooling) {
6377 2 : if (vrfTU.MaxCoolAirVolFlow != DataSizing::AutoSize) {
6378 6 : for (int i = 1; i <= vrfTU.NumOfSpeedCooling; ++i) {
6379 4 : vrfTU.CoolMassFlowRate[i] = fanSystem->massFlowAtSpeed[i - 1];
6380 : }
6381 : }
6382 : }
6383 2 : if (vrfTU.DXHeatCoilType_Num == HVAC::CoilVRF_Heating) {
6384 2 : if (vrfTU.MaxHeatAirVolFlow != DataSizing::AutoSize) {
6385 6 : for (int i = 1; i <= vrfTU.NumOfSpeedCooling; ++i) {
6386 4 : vrfTU.HeatMassFlowRate[i] = fanSystem->massFlowAtSpeed[i - 1];
6387 : }
6388 : }
6389 : }
6390 : }
6391 : }
6392 : }
6393 :
6394 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow >
6395 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate) {
6396 0 : ShowWarningError(state,
6397 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6398 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6399 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6400 0 : ShowContinueError(state, "... has Supply Air Flow Rate During Cooling Operation > Max Fan Volume Flow Rate, should be <=");
6401 0 : ShowContinueError(state,
6402 0 : format("... Supply Air Flow Rate During Cooling Operation = {:.4R} m3/s",
6403 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow));
6404 0 : ShowContinueError(state,
6405 0 : format("... Max Fan Volume Flow Rate = {:.4R} m3/s",
6406 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate));
6407 0 : ShowContinueError(
6408 : state, "...the supply air flow rate during cooling operation will be reduced to match and the simulation continues.");
6409 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6410 : }
6411 :
6412 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow >
6413 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate) {
6414 0 : ShowWarningError(state,
6415 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6416 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6417 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6418 0 : ShowContinueError(state, "... has Supply Air Flow Rate When No Cooling is Needed > Max Fan Volume Flow Rate, should be <=");
6419 0 : ShowContinueError(state,
6420 0 : format("... Supply Air Flow Rate When No Cooling is Needed = {:.4R} m3/s",
6421 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow));
6422 0 : ShowContinueError(state,
6423 0 : format("... Max Fan Volume Flow Rate = {:.4R} m3/s",
6424 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate));
6425 0 : ShowContinueError(
6426 : state, "...the supply air flow rate when no cooling is needed will be reduced to match and the simulation continues.");
6427 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow =
6428 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6429 : }
6430 :
6431 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow > state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow) {
6432 0 : ShowWarningError(state,
6433 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6434 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6435 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6436 0 : ShowContinueError(
6437 : state,
6438 : "...The Outdoor Air Flow Rate During Cooling Operation exceeds the Supply Air Flow Rate During Cooling Operation.");
6439 0 : ShowContinueError(state,
6440 0 : format("...Outdoor Air Flow Rate During Cooling Operation = {:.4R} m3/s",
6441 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow));
6442 0 : ShowContinueError(state,
6443 0 : format("... Supply Air Flow Rate During Cooling Operation = {:.4R} m3/s",
6444 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow));
6445 0 : ShowContinueError(state, "...the outdoor air flow rate will be reduced to match and the simulation continues.");
6446 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow;
6447 : }
6448 :
6449 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow >
6450 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate) {
6451 0 : ShowWarningError(state,
6452 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6453 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6454 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6455 0 : ShowContinueError(state, "... has Supply Air Flow Rate During Heating Operation > Max Fan Volume Flow Rate, should be <=");
6456 0 : ShowContinueError(state,
6457 0 : format("... Supply Air Flow Rate During Heating Operation = {:.4R} m3/s",
6458 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow));
6459 0 : ShowContinueError(state,
6460 0 : format("... Max Fan Volume Flow Rate = {:.4R} m3/s",
6461 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate));
6462 0 : ShowContinueError(
6463 : state, "...the supply air flow rate during cooling operation will be reduced to match and the simulation continues.");
6464 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6465 : }
6466 :
6467 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow >
6468 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate) {
6469 0 : ShowWarningError(state,
6470 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6471 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6472 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6473 0 : ShowContinueError(state, "... has Supply Air Flow Rate When No Heating is Needed > Max Fan Volume Flow Rate, should be <=");
6474 0 : ShowContinueError(state,
6475 0 : format("... Supply Air Flow Rate When No Heating is Needed = {:.4R} m3/s",
6476 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow));
6477 0 : ShowContinueError(state,
6478 0 : format("... Max Fan Volume Flow Rate = {:.4R} m3/s",
6479 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate));
6480 0 : ShowContinueError(
6481 : state, "...the supply air flow rate when no cooling is needed will be reduced to match and the simulation continues.");
6482 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow =
6483 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6484 : }
6485 :
6486 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow > state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow) {
6487 0 : ShowWarningError(state,
6488 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6489 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6490 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6491 0 : ShowContinueError(
6492 : state,
6493 : "...The Outdoor Air Flow Rate During Heating Operation exceeds the Supply Air Flow Rate During Heating Operation.");
6494 0 : ShowContinueError(state,
6495 0 : format("...Outdoor Air Flow Rate During Heating Operation = {:.4R} m3/s",
6496 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow));
6497 0 : ShowContinueError(state,
6498 0 : format("... Supply Air Flow Rate During Heating Operation = {:.4R} m3/s",
6499 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow));
6500 0 : ShowContinueError(state, "...the outdoor air flow rate will be reduced to match and the simulation continues.");
6501 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow;
6502 : }
6503 :
6504 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow >
6505 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate) {
6506 0 : ShowWarningError(state,
6507 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6508 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6509 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6510 0 : ShowContinueError(
6511 : state, "... has a Outdoor Air Flow Rate When No Cooling or Heating is Needed > Max Fan Volume Flow Rate, should be <=");
6512 0 : ShowContinueError(state,
6513 0 : format("... Outdoor Air Flow Rate When No Cooling or Heating is Needed = {:.4R} m3/s",
6514 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow));
6515 0 : ShowContinueError(state,
6516 0 : format("... Max Fan Volume Flow Rate = {:.4R} m3/s",
6517 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate));
6518 0 : ShowContinueError(state,
6519 : "...the outdoor air flow rate when no cooling or heating is needed will be reduced to match and the "
6520 : "simulation continues.");
6521 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow =
6522 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6523 : }
6524 :
6525 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate > 0.0) {
6526 10 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow /
6527 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6528 10 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow /
6529 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6530 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio =
6531 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow /
6532 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6533 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio =
6534 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow /
6535 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6536 : }
6537 :
6538 5 : state.dataHVACVarRefFlow->MyVRFFlag(VRFTUNum) = false;
6539 : } else {
6540 11 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate =
6541 11 : state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex)->maxAirFlowRate;
6542 : }
6543 : } else {
6544 1 : state.dataHVACVarRefFlow->MyVRFFlag(VRFTUNum) = false;
6545 : }
6546 : }
6547 : } // IF(MyVRFFlag(VRFTUNum))THEN
6548 :
6549 : // calculate end time of current time step to determine if max capacity reset is required
6550 7115 : CurrentEndTime = double((state.dataGlobal->DayOfSim - 1) * 24) + state.dataGlobal->CurrentTime - state.dataGlobal->TimeStepZone +
6551 7115 : state.dataHVACGlobal->SysTimeElapsed;
6552 :
6553 : // Initialize the maximum allowed terminal unit capacity. Total terminal unit capacity must not
6554 : // exceed the available condenser capacity. This variable is used to limit the terminal units
6555 : // providing more capacity than allowed. Example: TU loads are 1-ton, 2-ton, 3-ton, and 4-ton connected
6556 : // to a condenser having only 9-tons available. This variable will be set to 3-tons and the 4-ton
6557 : // terminal unit will be limited to 3-tons (see SimVRFCondenser where this variable is calculated).
6558 7214 : if (CurrentEndTime > state.dataHVACVarRefFlow->CurrentEndTimeLast || TimeStepSysLast > state.dataHVACGlobal->TimeStepSys ||
6559 99 : (FirstHVACIteration && state.dataHVACVarRefFlow->MyBeginTimeStepFlag(VRFCond))) {
6560 3540 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond) = Constant::MaxCap;
6561 3540 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) = Constant::MaxCap;
6562 3540 : state.dataHVACVarRefFlow->MyBeginTimeStepFlag(VRFCond) = false;
6563 : }
6564 :
6565 7115 : if (!FirstHVACIteration) state.dataHVACVarRefFlow->MyBeginTimeStepFlag(VRFCond) = true;
6566 :
6567 : // Do the following initializations (every time step).
6568 :
6569 7115 : TimeStepSysLast = state.dataHVACGlobal->TimeStepSys;
6570 7115 : state.dataHVACVarRefFlow->CurrentEndTimeLast = CurrentEndTime;
6571 :
6572 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOpModeSched != nullptr) {
6573 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOpModeSched->getCurrentVal() == 0.0) {
6574 2387 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp = HVAC::FanOp::Cycling;
6575 : } else {
6576 4728 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp = HVAC::FanOp::Continuous;
6577 : }
6578 : }
6579 :
6580 : // if condenser is off, all terminal unit coils are off
6581 7115 : if (state.dataHVACVarRefFlow->VRF(VRFCond).availSched->getCurrentVal() == 0.0) {
6582 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
6583 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
6584 : } else {
6585 :
6586 : //*** Operating Mode Initialization done at beginning of each iteration ***!
6587 : //*** assumes all TU's and Condenser were simulated last iteration ***!
6588 : //*** this code is done ONCE each iteration when all TU's IsSimulated flag is FALSE ***!
6589 : // Determine operating mode prior to simulating any terminal units connected to a VRF condenser
6590 : // this should happen at the beginning of a time step where all TU's are polled to see what
6591 : // mode the heat pump condenser will operate in
6592 7115 : if (!any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).IsSimulated)) {
6593 7115 : InitializeOperatingMode(state, FirstHVACIteration, VRFCond, TUListIndex, OnOffAirFlowRatio);
6594 : }
6595 : //*** End of Operating Mode Initialization done at beginning of each iteration ***!
6596 :
6597 : // disable VRF system when outside limits of operation based on OAT
6598 7115 : EnableSystem = false; // flag used to switch operating modes when OAT is outside operating limits
6599 7115 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
6600 3490 : if ((OutsideDryBulbTemp < state.dataHVACVarRefFlow->VRF(VRFCond).MinOATCooling ||
6601 3492 : OutsideDryBulbTemp > state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATCooling) &&
6602 2 : any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).CoolingCoilPresent)) {
6603 2 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
6604 : // test if heating load exists, account for thermostat control type
6605 2 : switch (state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority) {
6606 2 : case ThermostatCtrlType::LoadPriority:
6607 : case ThermostatCtrlType::ZonePriority: {
6608 2 : if (state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) > 0.0) EnableSystem = true;
6609 2 : } break;
6610 0 : case ThermostatCtrlType::ThermostatOffsetPriority: {
6611 0 : if (state.dataHVACVarRefFlow->MinDeltaT(VRFCond) < 0.0) EnableSystem = true;
6612 0 : } break;
6613 0 : case ThermostatCtrlType::ScheduledPriority:
6614 : case ThermostatCtrlType::MasterThermostatPriority: {
6615 : // can't switch modes if scheduled (i.e., would be switching to unscheduled mode)
6616 : // or master TSTAT used (i.e., master zone only has a specific load - can't switch)
6617 0 : } break;
6618 0 : default:
6619 0 : break;
6620 : }
6621 2 : if (EnableSystem) {
6622 0 : if ((OutsideDryBulbTemp >= state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeating &&
6623 0 : OutsideDryBulbTemp <= state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeating) &&
6624 0 : any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HeatingCoilPresent)) {
6625 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
6626 : } else {
6627 0 : if (any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).CoolingCoilAvailable)) {
6628 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CoolingMaxTempLimitIndex == 0) {
6629 0 : ShowWarningMessage(state,
6630 0 : format("{} \"{}\".",
6631 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
6632 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name));
6633 0 : ShowContinueError(state,
6634 : "...InitVRF: VRF Heat Pump Min/Max Operating Temperature in Cooling Mode Limits have been "
6635 : "exceeded and VRF system is disabled.");
6636 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
6637 0 : ShowContinueError(state,
6638 0 : format("... Outdoor Unit Inlet Water Temperature = {:.3T}", OutsideDryBulbTemp));
6639 : } else {
6640 0 : ShowContinueError(state,
6641 0 : format("... Outdoor Unit Inlet Air Temperature = {:.3T}", OutsideDryBulbTemp));
6642 : }
6643 0 : ShowContinueError(state,
6644 0 : format("... Cooling Minimum Outdoor Unit Inlet Temperature = {:.3T}",
6645 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MinOATCooling));
6646 0 : ShowContinueError(state,
6647 0 : format("... Cooling Maximum Outdoor Unit Inlet Temperature = {:.3T}",
6648 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATCooling));
6649 0 : ShowContinueErrorTimeStamp(state, "... Check VRF Heat Pump Min/Max Outdoor Temperature in Cooling Mode limits.");
6650 : }
6651 0 : ShowRecurringWarningErrorAtEnd(state,
6652 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)) + " \"" +
6653 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name +
6654 : "\" -- Exceeded VRF Heat Pump min/max cooling temperature limit error continues...",
6655 0 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingMaxTempLimitIndex,
6656 : OutsideDryBulbTemp,
6657 : OutsideDryBulbTemp);
6658 : }
6659 : }
6660 : } else {
6661 2 : if (any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).CoolingCoilAvailable)) {
6662 2 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CoolingMaxTempLimitIndex == 0) {
6663 2 : ShowWarningMessage(state,
6664 2 : format("{} \"{}\".",
6665 1 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
6666 1 : state.dataHVACVarRefFlow->VRF(VRFCond).Name));
6667 2 : ShowContinueError(state,
6668 : "...InitVRF: VRF Heat Pump Min/Max Operating Temperature in Cooling Mode Limits have been exceeded "
6669 : "and VRF system is disabled.");
6670 1 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
6671 0 : ShowContinueError(state, format("... Outdoor Unit Inlet Water Temperature = {:.3T}", OutsideDryBulbTemp));
6672 : } else {
6673 2 : ShowContinueError(state,
6674 2 : format("... Outdoor Unit Inlet Air Temperature = {:.3T}", OutsideDryBulbTemp));
6675 : }
6676 2 : ShowContinueError(state,
6677 2 : format("... Cooling Minimum Outdoor Unit Inlet Temperature = {:.3T}",
6678 1 : state.dataHVACVarRefFlow->VRF(VRFCond).MinOATCooling));
6679 2 : ShowContinueError(state,
6680 2 : format("... Cooling Maximum Outdoor Unit Inlet Temperature = {:.3T}",
6681 1 : state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATCooling));
6682 3 : ShowContinueErrorTimeStamp(state, "... Check VRF Heat Pump Min/Max Outdoor Temperature in Cooling Mode limits.");
6683 : }
6684 16 : ShowRecurringWarningErrorAtEnd(state,
6685 4 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)) + " \"" +
6686 8 : state.dataHVACVarRefFlow->VRF(VRFCond).Name +
6687 : "\" -- Exceeded VRF Heat Pump min/max cooling temperature limit error continues...",
6688 2 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingMaxTempLimitIndex,
6689 : OutsideDryBulbTemp,
6690 : OutsideDryBulbTemp);
6691 : }
6692 : }
6693 : }
6694 3625 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
6695 3497 : if ((OutsideDryBulbTemp < state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeating ||
6696 3503 : OutsideDryBulbTemp > state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeating) &&
6697 6 : any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HeatingCoilPresent)) {
6698 6 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
6699 : // test if cooling load exists, account for thermostat control type
6700 6 : switch (state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority) {
6701 4 : case ThermostatCtrlType::LoadPriority:
6702 : case ThermostatCtrlType::ZonePriority: {
6703 4 : if (state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) < 0.0) EnableSystem = true;
6704 4 : } break;
6705 2 : case ThermostatCtrlType::ThermostatOffsetPriority: {
6706 2 : if (state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) > 0.0) EnableSystem = true;
6707 2 : } break;
6708 0 : case ThermostatCtrlType::ScheduledPriority:
6709 : case ThermostatCtrlType::MasterThermostatPriority: {
6710 0 : } break;
6711 0 : default:
6712 0 : break;
6713 : }
6714 6 : if (EnableSystem) {
6715 0 : if ((OutsideDryBulbTemp >= state.dataHVACVarRefFlow->VRF(VRFCond).MinOATCooling &&
6716 0 : OutsideDryBulbTemp <= state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATCooling) &&
6717 0 : any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).CoolingCoilPresent)) {
6718 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
6719 : } else {
6720 0 : if (any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HeatingCoilAvailable)) {
6721 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatingMaxTempLimitIndex == 0) {
6722 0 : ShowWarningMessage(state,
6723 0 : format("{} \"{}\".",
6724 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
6725 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name));
6726 0 : ShowContinueError(state,
6727 : "...InitVRF: VRF Heat Pump Min/Max Operating Temperature in Heating Mode Limits have been "
6728 : "exceeded and VRF system is disabled.");
6729 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
6730 0 : ShowContinueError(state,
6731 0 : format("... Outdoor Unit Inlet Water Temperature = {:.3T}", OutsideDryBulbTemp));
6732 : } else {
6733 0 : ShowContinueError(state,
6734 0 : format("... Outdoor Unit Inlet Air Temperature = {:.3T}", OutsideDryBulbTemp));
6735 : }
6736 0 : ShowContinueError(state,
6737 0 : format("... Heating Minimum Outdoor Unit Inlet Temperature = {:.3T}",
6738 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeating));
6739 0 : ShowContinueError(state,
6740 0 : format("... Heating Maximum Outdoor Unit Inlet Temperature = {:.3T}",
6741 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeating));
6742 0 : ShowContinueErrorTimeStamp(state, "... Check VRF Heat Pump Min/Max Outdoor Temperature in Heating Mode limits.");
6743 : }
6744 0 : ShowRecurringWarningErrorAtEnd(state,
6745 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)) + " \"" +
6746 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name +
6747 : "\" -- Exceeded VRF Heat Pump min/max heating temperature limit error continues...",
6748 0 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingMaxTempLimitIndex,
6749 : OutsideDryBulbTemp,
6750 : OutsideDryBulbTemp);
6751 : }
6752 : }
6753 : } else {
6754 6 : if (any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HeatingCoilAvailable)) {
6755 6 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatingMaxTempLimitIndex == 0) {
6756 6 : ShowWarningMessage(state,
6757 6 : format("{} \"{}\".",
6758 3 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
6759 3 : state.dataHVACVarRefFlow->VRF(VRFCond).Name));
6760 6 : ShowContinueError(state,
6761 : "...InitVRF: VRF Heat Pump Min/Max Operating Temperature in Heating Mode Limits have been exceeded "
6762 : "and VRF system is disabled.");
6763 3 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
6764 1 : ShowContinueError(state, format("... Outdoor Unit Inlet Water Temperature = {:.3T}", OutsideDryBulbTemp));
6765 : } else {
6766 2 : ShowContinueError(state, format("... Outdoor Unit Inlet Air Temperature = {:.3T}", OutsideDryBulbTemp));
6767 : }
6768 6 : ShowContinueError(state,
6769 6 : format("... Heating Minimum Outdoor Unit Inlet Temperature = {:.3T}",
6770 3 : state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeating));
6771 6 : ShowContinueError(state,
6772 6 : format("... Heating Maximum Outdoor Unit Inlet Temperature = {:.3T}",
6773 3 : state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeating));
6774 9 : ShowContinueErrorTimeStamp(state, "... Check VRF Heat Pump Min/Max Outdoor Temperature in Heating Mode limits.");
6775 : }
6776 48 : ShowRecurringWarningErrorAtEnd(state,
6777 12 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)) + " \"" +
6778 24 : state.dataHVACVarRefFlow->VRF(VRFCond).Name +
6779 : "\" -- Exceeded VRF Heat Pump min/max heating temperature limit error continues...",
6780 6 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingMaxTempLimitIndex,
6781 : OutsideDryBulbTemp,
6782 : OutsideDryBulbTemp);
6783 : }
6784 : }
6785 : }
6786 : }
6787 :
6788 : } // IF (GetCurrentScheduleValue(state, VRF(VRFCond)%SchedPtr) .EQ. 0.0) THEN
6789 :
6790 : // initialize terminal unit flow rate
6791 10739 : if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) ||
6792 3624 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
6793 1 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList))) {
6794 3491 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6795 3491 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
6796 3491 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
6797 3491 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
6798 : } else {
6799 0 : if (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInOASys)
6800 0 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
6801 : }
6802 3760 : } else if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) ||
6803 136 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
6804 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList))) {
6805 3488 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6806 3487 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
6807 3487 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
6808 3487 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
6809 : } else {
6810 1 : if (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInOASys)
6811 1 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
6812 : }
6813 : } else {
6814 136 : if (state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
6815 39 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6816 39 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
6817 39 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
6818 39 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
6819 : } else {
6820 0 : if (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInOASys)
6821 0 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
6822 : }
6823 97 : } else if (state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
6824 97 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6825 97 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
6826 97 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
6827 97 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
6828 : } else {
6829 0 : if (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInOASys)
6830 0 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
6831 : }
6832 : }
6833 : }
6834 :
6835 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists) {
6836 : // There is an air terminal mixer
6837 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
6838 : // set the primary air inlet mass flow rate
6839 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerPriNode).MassFlowRate =
6840 0 : min(state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerPriNode).MassFlowRateMaxAvail,
6841 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum).MassFlowRate);
6842 : // now calculate the the mixer outlet air conditions (and the secondary air inlet flow rate). The mixer outlet flow rate has already
6843 : // been set above (it is the "inlet" node flow rate)
6844 0 : SimATMixer(state,
6845 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerName,
6846 : FirstHVACIteration,
6847 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerIndex);
6848 : }
6849 : } else {
6850 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed)
6851 7114 : MixedAir::SimOAMixer(
6852 7114 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
6853 : }
6854 7115 : OnOffAirFlowRatio = 1.0;
6855 :
6856 : // these flags are used in Subroutine CalcVRF to turn on the correct coil (heating or cooling)
6857 : // valid operating modes
6858 : // Heat Pump (heat recovery flags are set to FALSE):
6859 : // CoolingLoad(VRFCond) - TU can only operate in this mode if heat recovery is not used and there is a cooling load
6860 : // HeatingLoad(VRFCond) - TU can only operate in this mode if heat recovery is not used and there is a heating load
6861 : // Heat Recovery (heat pump flags are set same as for Heat Pump operation):
6862 : // TerminalUnitList(TUListIndex)%HRCoolRequest(IndexToTUInTUList) - TU will operate in this mode if heat recovery is used
6863 : // TerminalUnitList(TUListIndex)%HRHeatRequest(IndexToTUInTUList) - TU will operate in this mode if heat recovery is used
6864 :
6865 7115 : getVRFTUZoneLoad(state, VRFTUNum, QZnReq, LoadToHeatingSP, LoadToCoolingSP, false);
6866 :
6867 7115 : if (std::abs(QZnReq) < HVAC::SmallLoad) QZnReq = 0.0;
6868 : // set initial terminal unit operating mode for heat recovery
6869 : // operating mode for non-heat recovery set above using CoolingLoad(VRFCond) or HeatingLoad(VRFCond) variables
6870 : // first turn off terminal unit
6871 7115 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
6872 7115 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
6873 : // then set according to LoadToXXXXingSP variables
6874 7115 : if (LoadToCoolingSP < -1.0 * HVAC::SmallLoad) {
6875 3494 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) ||
6876 7 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) { // don't allow heat recovery if control logic dictates unit is off
6877 3480 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
6878 : }
6879 : }
6880 7115 : if (LoadToHeatingSP > HVAC::SmallLoad) {
6881 6988 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) ||
6882 3493 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) { // don't allow heat recovery if control logic dictates unit is off
6883 3489 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
6884 : }
6885 : }
6886 7115 : if (LoadToCoolingSP > 0.0 && LoadToHeatingSP < 0.0) QZnReq = 0.0;
6887 :
6888 : // next check for overshoot when constant fan mode is used
6889 : // check operating load to see if OA will overshoot setpoint temperature when constant fan mode is used
6890 11843 : if ((state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Continuous || state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists) &&
6891 4728 : !state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isSetPointControlled) {
6892 4721 : SetCompFlowRate(state, VRFTUNum, VRFCond, true);
6893 :
6894 4721 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
6895 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
6896 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
6897 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
6898 : } else {
6899 : // Algorithm Type: VRF model based on system curve
6900 4721 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
6901 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
6902 : }
6903 :
6904 : // If the Terminal Unit has a net cooling capacity (TempOutput < 0) and
6905 : // the zone temp is above the Tstat heating setpoint (QToHeatSetPt < 0)
6906 : // see if the terminal unit operation will exceed the setpoint
6907 : // 4 tests here to cover all possibilities:
6908 : // IF(TempOutput < 0.0d0 .AND. LoadToHeatingSP .LT. 0.0d0)THEN
6909 : // ELSE IF(TempOutput .GT. 0.0d0 .AND. LoadToCoolingSP .GT. 0.0d0)THEN
6910 : // ELSE IF(TempOutput .GT. 0.0d0 .AND. LoadToCoolingSP .LT. 0.0d0)THEN
6911 : // ELSE IF(TempOutput < 0.0d0 .AND. LoadToHeatingSP .GT. 0.0d0)THEN
6912 : // END IF
6913 : // could compress these to 2 complex IF's but logic inside each would get more complex
6914 4721 : if (TempOutput < 0.0 && LoadToHeatingSP < 0.0) {
6915 : // If the net cooling capacity overshoots the heating setpoint count as heating load
6916 41 : if (TempOutput < LoadToHeatingSP) {
6917 : // Don't count as heating load unless mode is allowed. Also check for floating zone.
6918 8 : if (state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleCool &&
6919 4 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::Uncontrolled) {
6920 4 : if (!state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
6921 : // system last operated in cooling mode, change air flows and repeat coil off capacity test
6922 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6923 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
6924 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
6925 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum).MassFlowRate =
6926 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
6927 0 : MixedAir::SimOAMixer(
6928 0 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
6929 : } else {
6930 0 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
6931 : }
6932 :
6933 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
6934 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
6935 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
6936 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
6937 : } else {
6938 : // Algorithm Type: VRF model based on system curve
6939 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
6940 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
6941 : }
6942 :
6943 : // if zone temp will overshoot, pass the LoadToHeatingSP as the load to meet
6944 0 : if (TempOutput < LoadToHeatingSP) {
6945 0 : QZnReq = LoadToHeatingSP;
6946 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
6947 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
6948 : }
6949 : } else {
6950 : // last mode was heating, zone temp will overshoot heating setpoint, reset QznReq to LoadtoHeatingSP
6951 4 : QZnReq = LoadToHeatingSP;
6952 4 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
6953 4 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
6954 : }
6955 : }
6956 37 : } else if (TempOutput > LoadToCoolingSP && LoadToCoolingSP < 0.0) {
6957 : // If the net cooling capacity does not meet the zone cooling load enable cooling
6958 1 : QZnReq = LoadToCoolingSP;
6959 1 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
6960 1 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
6961 36 : } else if (TempOutput < LoadToCoolingSP && LoadToCoolingSP < 0.0) {
6962 : // If the net cooling capacity meets the zone cooling load but does not overshoot heating setpoint
6963 0 : QZnReq = 0.0;
6964 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
6965 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
6966 : }
6967 : // If the terminal unit has a net heating capacity and the zone temp is below the Tstat cooling setpoint
6968 : // see if the terminal unit operation will exceed the setpoint
6969 4680 : } else if (TempOutput > 0.0 && LoadToCoolingSP > 0.0) {
6970 : // If the net heating capacity overshoots the cooling setpoint count as cooling load
6971 2351 : if (TempOutput > LoadToCoolingSP) {
6972 : // Don't count as cooling load unless mode is allowed. Also check for floating zone.
6973 12 : if (state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleHeat &&
6974 6 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::Uncontrolled) {
6975 6 : if (!state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
6976 4 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6977 4 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
6978 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
6979 4 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum).MassFlowRate =
6980 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
6981 4 : MixedAir::SimOAMixer(
6982 4 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
6983 : } else {
6984 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum).MassFlowRate =
6985 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
6986 : }
6987 :
6988 4 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
6989 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
6990 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
6991 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
6992 : } else {
6993 : // Algorithm Type: VRF model based on system curve
6994 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
6995 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
6996 : }
6997 :
6998 : // if zone temp will overshoot, pass the LoadToCoolingSP as the load to meet
6999 4 : if (TempOutput > LoadToCoolingSP) {
7000 4 : QZnReq = LoadToCoolingSP;
7001 4 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
7002 4 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7003 : }
7004 : } else {
7005 2 : QZnReq = LoadToCoolingSP;
7006 2 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
7007 2 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7008 : }
7009 : }
7010 2345 : } else if (TempOutput < LoadToHeatingSP) {
7011 : // Don't count as heating load unless mode is allowed. Also check for floating zone.
7012 4634 : if (state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleCool &&
7013 2317 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::Uncontrolled) {
7014 2317 : if (!state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
7015 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
7016 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
7017 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7018 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum).MassFlowRate =
7019 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7020 0 : MixedAir::SimOAMixer(
7021 0 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
7022 : } else {
7023 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum).MassFlowRate =
7024 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7025 : }
7026 :
7027 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
7028 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
7029 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
7030 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7031 : } else {
7032 : // Algorithm Type: VRF model based on system curve
7033 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
7034 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7035 : }
7036 :
7037 : // if zone temp will overshoot, pass the LoadToHeatingSP as the load to meet
7038 0 : if (TempOutput < LoadToHeatingSP) {
7039 0 : QZnReq = LoadToHeatingSP;
7040 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7041 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7042 : }
7043 : } else {
7044 2317 : QZnReq = LoadToHeatingSP;
7045 2317 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7046 2317 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7047 : }
7048 : }
7049 28 : } else if (TempOutput > LoadToHeatingSP && TempOutput < LoadToCoolingSP) {
7050 : // If the net capacity does not overshoot either setpoint
7051 28 : QZnReq = 0.0;
7052 28 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7053 28 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7054 : } else {
7055 : // If the net heating capacity meets the zone heating load but does not overshoot cooling setpoint
7056 0 : QZnReq = 0.0;
7057 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7058 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7059 : }
7060 : // If the terminal unit has a net heating capacity and the zone temp is above the Tstat cooling setpoint
7061 : // see if the terminal unit operation will exceed the setpoint
7062 2329 : } else if (TempOutput > 0.0 && LoadToCoolingSP < 0.0) {
7063 : // If the net heating capacity overshoots the cooling setpoint count as cooling load
7064 : // Don't count as cooling load unless mode is allowed. Also check for floating zone.
7065 6906 : if (state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleHeat &&
7066 2302 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::Uncontrolled) {
7067 2302 : if (!state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
7068 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
7069 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
7070 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7071 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum).MassFlowRate =
7072 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7073 0 : MixedAir::SimOAMixer(
7074 0 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
7075 : } else {
7076 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum).MassFlowRate =
7077 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7078 : }
7079 :
7080 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
7081 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
7082 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
7083 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7084 : } else {
7085 : // Algorithm Type: VRF model based on system curve
7086 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
7087 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7088 : }
7089 :
7090 : // if zone temp will overshoot, pass the LoadToCoolingSP as the load to meet
7091 0 : if (TempOutput > LoadToCoolingSP) {
7092 0 : QZnReq = LoadToCoolingSP;
7093 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
7094 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7095 : }
7096 : // last mode was cooling, zone temp will overshoot cooling setpoint, reset QznReq to LoadtoCoolingSP
7097 : } else {
7098 2302 : QZnReq = LoadToCoolingSP;
7099 2302 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
7100 2302 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7101 : }
7102 : }
7103 : // If the Terminal Unit has a net cooling capacity (TempOutput < 0) and
7104 : // the zone temp is below the Tstat heating setpoint (QToHeatSetPt > 0)
7105 : // see if the terminal unit operation will exceed the setpoint
7106 27 : } else if (TempOutput < 0.0 && LoadToHeatingSP > 0.0) {
7107 : // Don't count as heating load unless mode is allowed. Also check for floating zone.
7108 10 : if (state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleCool &&
7109 5 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::Uncontrolled) {
7110 5 : if (!state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
7111 : // system last operated in cooling mode, change air flows and repeat coil off capacity test
7112 2 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
7113 2 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
7114 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7115 2 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum).MassFlowRate =
7116 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7117 2 : MixedAir::SimOAMixer(
7118 2 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
7119 : } else {
7120 0 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7121 : }
7122 :
7123 2 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
7124 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
7125 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
7126 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7127 : } else {
7128 : // Algorithm Type: VRF model based on system curve
7129 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
7130 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7131 : }
7132 :
7133 : // if zone temp will overshoot, pass the LoadToHeatingSP as the load to meet
7134 2 : if (TempOutput < LoadToHeatingSP) {
7135 2 : QZnReq = LoadToHeatingSP;
7136 2 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7137 2 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7138 : }
7139 : } else {
7140 : // last mode was heating, zone temp will overshoot heating setpoint, reset QznReq to LoadtoHeatingSP
7141 3 : QZnReq = LoadToHeatingSP;
7142 3 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7143 3 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7144 : }
7145 : }
7146 : }
7147 : // test that the system is active if constant fan logic enables system when thermostat control logic did not
7148 4721 : if (!state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && !state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
7149 85 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) &&
7150 85 : OutsideDryBulbTemp >= state.dataHVACVarRefFlow->VRF(VRFCond).MinOATCooling &&
7151 0 : OutsideDryBulbTemp <= state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATCooling) {
7152 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
7153 85 : } else if (state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) &&
7154 86 : OutsideDryBulbTemp >= state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeating &&
7155 1 : OutsideDryBulbTemp <= state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeating) {
7156 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
7157 : }
7158 : }
7159 : } // IF(VRFTU(VRFTUNum)%fanOp == HVAC::FanOp::Continuous)THEN
7160 :
7161 7115 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed) {
7162 2 : if (OutsideDryBulbTemp < state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeatRecovery ||
7163 1 : OutsideDryBulbTemp > state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeatRecovery) {
7164 2 : if ((any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest) && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) ||
7165 1 : (any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest) && state.dataHVACVarRefFlow->CoolingLoad(VRFCond))) {
7166 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HRMaxTempLimitIndex == 0) {
7167 0 : ShowWarningMessage(state,
7168 0 : format("{} \"{}\".",
7169 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
7170 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name));
7171 0 : ShowContinueError(state,
7172 : "...InitVRF: VRF Heat Pump Min/Max Outdoor Temperature in Heat Recovery Mode Limits have been exceeded and "
7173 : "VRF heat recovery is disabled.");
7174 0 : ShowContinueError(state, format("... Outdoor Dry-Bulb Temperature = {:.3T}", OutsideDryBulbTemp));
7175 0 : ShowContinueError(state,
7176 0 : format("... Heat Recovery Minimum Outdoor Dry-Bulb Temperature = {:.3T}",
7177 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeatRecovery));
7178 0 : ShowContinueError(state,
7179 0 : format("... Heat Recovery Maximum Outdoor Dry-Bulb Temperature = {:.3T}",
7180 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeatRecovery));
7181 0 : ShowContinueErrorTimeStamp(state, "... Check VRF Heat Pump Min/Max Outdoor Temperature in Heat Recovery Mode limits.");
7182 0 : ShowContinueError(state, "...the system will operate in heat pump mode when applicable.");
7183 : }
7184 0 : ShowRecurringWarningErrorAtEnd(state,
7185 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)) + " \"" +
7186 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name +
7187 : "\" -- Exceeded VRF Heat Recovery min/max outdoor temperature limit error continues...",
7188 0 : state.dataHVACVarRefFlow->VRF(VRFCond).HRMaxTempLimitIndex,
7189 : OutsideDryBulbTemp,
7190 : OutsideDryBulbTemp);
7191 : }
7192 : // Allow heat pump mode to operate if within limits
7193 2 : if (OutsideDryBulbTemp < state.dataHVACVarRefFlow->VRF(VRFCond).MinOATCooling ||
7194 1 : OutsideDryBulbTemp > state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATCooling) {
7195 : // Disable cooling mode only, heating model will still be allowed
7196 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7197 : }
7198 2 : if (OutsideDryBulbTemp < state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeating ||
7199 1 : OutsideDryBulbTemp > state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeating) {
7200 : // Disable heating mode only, cooling model will still be allowed
7201 1 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7202 : }
7203 : }
7204 : } else {
7205 7114 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest = false;
7206 7114 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest = false;
7207 : }
7208 :
7209 : // Override operating mode when using EMS
7210 : // this logic seems suspect, uses a "just run it on" mentality. Nee to test using EMS.
7211 7115 : if (state.dataHVACVarRefFlow->VRF(VRFCond).EMSOverrideHPOperatingMode) {
7212 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).EMSValueForHPOperatingMode == 0.0) { // Off
7213 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
7214 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
7215 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7216 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7217 0 : } else if (state.dataHVACVarRefFlow->VRF(VRFCond).EMSValueForHPOperatingMode == 1.0) { // Cooling
7218 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
7219 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
7220 0 : QZnReq = LoadToCoolingSP;
7221 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed) {
7222 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7223 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
7224 : }
7225 0 : } else if (state.dataHVACVarRefFlow->VRF(VRFCond).EMSValueForHPOperatingMode == 2.0) { // Heating
7226 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
7227 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
7228 0 : QZnReq = LoadToHeatingSP;
7229 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed) {
7230 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7231 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7232 : }
7233 : } else {
7234 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HPOperatingModeErrorIndex == 0) {
7235 0 : ShowWarningMessage(state,
7236 0 : format("{} \"{}\".",
7237 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
7238 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name));
7239 0 : ShowContinueError(
7240 : state,
7241 0 : format("...InitVRF: Illegal HP operating mode = {:.0T}", state.dataHVACVarRefFlow->VRF(VRFCond).EMSValueForHPOperatingMode));
7242 0 : ShowContinueError(state, "...InitVRF: VRF HP operating mode will not be controlled by EMS.");
7243 : }
7244 0 : ShowRecurringWarningErrorAtEnd(state,
7245 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)) + " \"" +
7246 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name + "\" -- Illegal HP operating mode error continues...",
7247 0 : state.dataHVACVarRefFlow->VRF(VRFCond).HPOperatingModeErrorIndex,
7248 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EMSValueForHPOperatingMode,
7249 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EMSValueForHPOperatingMode);
7250 : }
7251 : }
7252 :
7253 : // set the TU flow rate. Check for heat recovery operation first, these will be FALSE if HR is not used.
7254 7115 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList)) {
7255 1 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7256 1 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7257 1 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7258 1 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7259 1 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7260 1 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7261 7114 : } else if (state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList)) {
7262 0 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7263 0 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7264 0 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7265 0 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7266 0 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio;
7267 0 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7268 7114 : } else if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && QZnReq != 0.0) {
7269 3487 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7270 3487 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7271 3487 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7272 3487 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7273 3487 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7274 3487 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7275 3627 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && QZnReq != 0.0) {
7276 3491 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7277 3491 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7278 3491 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7279 3491 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7280 3491 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio;
7281 3491 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7282 : } else {
7283 136 : if (state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
7284 39 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7285 39 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7286 39 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7287 39 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7288 39 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7289 : }
7290 136 : if (state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
7291 97 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7292 97 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7293 97 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7294 97 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7295 97 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7296 : }
7297 136 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7298 : }
7299 :
7300 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Cycling) {
7301 2387 : state.dataHVACVarRefFlow->CompOffMassFlow = 0.0;
7302 2387 : state.dataHVACVarRefFlow->OACompOffMassFlow = 0.0;
7303 2387 : state.dataHVACVarRefFlow->CompOffFlowRatio = 0.0;
7304 : }
7305 :
7306 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating > 0 || state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling > 0) {
7307 4712 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SpeedNum = 0;
7308 4712 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SpeedRatio = 0.0;
7309 4712 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CycRatio = 0.0;
7310 : }
7311 :
7312 7115 : SetAverageAirFlow(state, VRFTUNum, 0.0, OnOffAirFlowRatio);
7313 :
7314 7115 : if (ErrorsFound) {
7315 0 : ShowFatalError(state,
7316 0 : format("{}: Errors found in getting ZoneHVAC:TerminalUnit:VariableRefrigerantFlow system input. Preceding condition(s) "
7317 : "causes termination.",
7318 : RoutineName));
7319 : }
7320 7115 : }
7321 :
7322 9435 : void SetCompFlowRate(EnergyPlusData &state, int const VRFTUNum, int const VRFCond, bool const UseCurrentMode)
7323 : {
7324 :
7325 : // SUBROUTINE INFORMATION:
7326 : // AUTHOR Richard Raustad, FSEC
7327 : // DATE WRITTEN June 2011
7328 : // MODIFIED na
7329 : // RE-ENGINEERED na
7330 :
7331 : // PURPOSE OF THIS SUBROUTINE:
7332 : // This subroutine is for calling VRF terminal units during Init to initialize flow rate
7333 : // while looping through all terminal units connected to a specific condenser.
7334 : // This allows polling of capacities for all terminal units.
7335 : // Since the heat pump can only heat or cool, a single operating mode is chosen for each condenser.
7336 :
7337 : // METHODOLOGY EMPLOYED:
7338 : // Initializes flow rates for a specific terminal unit.
7339 :
7340 : int IndexToTUInTUList; // - index to TU in specific list for this VRF system
7341 : int TUListIndex; // index to TU list for this VRF system
7342 :
7343 9435 : IndexToTUInTUList = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).IndexToTUInTUList;
7344 9435 : TUListIndex = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex;
7345 :
7346 : // uses current operating mode to set flow rate (after mode is set)
7347 9435 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList)) {
7348 2303 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7349 2303 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7350 2303 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7351 2303 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7352 2303 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7353 2303 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7354 7132 : } else if (state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList)) {
7355 2323 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7356 2323 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7357 2323 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7358 2323 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7359 2323 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio;
7360 2323 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7361 4809 : } else if (UseCurrentMode) { // uses current operating mode to set flow rate (after mode is set)
7362 95 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
7363 6 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7364 6 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7365 6 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7366 6 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7367 6 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7368 6 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7369 89 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
7370 4 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7371 4 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7372 4 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7373 4 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7374 4 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio;
7375 4 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7376 85 : } else if (state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) { // if NOT cooling or heating then use last mode
7377 36 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7378 36 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7379 36 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7380 36 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7381 36 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7382 36 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7383 49 : } else if (state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) { // if NOT cooling or heating then use last mode
7384 49 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7385 49 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7386 49 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7387 49 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7388 49 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio;
7389 49 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7390 : } else { // should not happen so just set to cooling flow rate
7391 0 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7392 0 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7393 0 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7394 0 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7395 0 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7396 0 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7397 : }
7398 : } else { // uses previous operating mode to set flow rate (used for looping through each TU in Init before mode is set)
7399 4714 : if (state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
7400 2342 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7401 2342 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7402 2342 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7403 2342 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7404 2342 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7405 2342 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7406 2372 : } else if (state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
7407 2372 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7408 2372 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7409 2372 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7410 2372 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7411 2372 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio;
7412 2372 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7413 : } else { // should not happen so just set to cooling flow rate
7414 0 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7415 0 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7416 0 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7417 0 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7418 0 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7419 0 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7420 : }
7421 : }
7422 :
7423 9435 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Cycling) {
7424 0 : state.dataHVACVarRefFlow->CompOffMassFlow = 0.0;
7425 0 : state.dataHVACVarRefFlow->OACompOffMassFlow = 0.0;
7426 0 : state.dataHVACVarRefFlow->CompOffFlowRatio = 0.0;
7427 : }
7428 9435 : }
7429 :
7430 13 : void SizeVRF(EnergyPlusData &state, int const VRFTUNum)
7431 : {
7432 :
7433 : // SUBROUTINE INFORMATION:
7434 : // AUTHOR Richard Raustad, FSEC
7435 : // DATE WRITTEN August 2010
7436 : // MODIFIED August 2013 Daeho Kang, add component sizing table entries
7437 : // B Nigusse, FSEC, added scalable sizing
7438 : // RE-ENGINEERED na
7439 :
7440 : // PURPOSE OF THIS SUBROUTINE:
7441 : // This subroutine is for sizing VRF Components for which inputs have not been
7442 : // specified in the input.
7443 :
7444 : // METHODOLOGY EMPLOYED:
7445 : // Obtains flow rates from the zone or system sizing arrays.
7446 :
7447 : using namespace DataSizing;
7448 : using Curve::CurveValue;
7449 : using HVAC::CoolingAirflowSizing;
7450 : using HVAC::CoolingCapacitySizing;
7451 : using HVAC::HeatingAirflowSizing;
7452 : using HVAC::HeatingCapacitySizing;
7453 :
7454 : using PlantUtilities::RegisterPlantCompDesignFlow;
7455 :
7456 : static constexpr std::string_view RoutineName("SizeVRF: "); // include trailing blank space
7457 :
7458 13 : auto &CheckVRFCombinationRatio = state.dataHVACVarRefFlow->CheckVRFCombinationRatio;
7459 : Real64 TUCoolingCapacity; // total terminal unit cooling capacity
7460 : Real64 TUHeatingCapacity; // total terminal unit heating capacity
7461 : int VRFCond; // index to VRF condenser
7462 : Real64 OnOffAirFlowRat; // temporary variable used when sizing coils
7463 : Real64 DXCoilCap; // capacity of DX cooling coil (W)
7464 : bool IsAutoSize; // Indicator to autosize
7465 : Real64 MaxCoolAirVolFlowDes; // Autosized supply air during cooling for reporting
7466 : Real64 MaxCoolAirVolFlowUser; // Hardsized supply air during cooling for reporting
7467 : Real64 MaxHeatAirVolFlowDes; // Autosized supply air during heating for reporting
7468 : Real64 MaxHeatAirVolFlowUser; // Hardsized supply air during heating for reporting
7469 : Real64 MaxNoCoolAirVolFlowDes; // Autosized supply air flow when no cooling is needed for reporting
7470 : Real64 MaxNoCoolAirVolFlowUser; // Hardsized supply air flow when no cooling is needed for reporting
7471 : Real64 MaxNoHeatAirVolFlowDes; // Autosized supply air flow when no heating is needed for reporting
7472 : Real64 MaxNoHeatAirVolFlowUser; // Hardsized supply air flow when no heating is needed for reporting
7473 : Real64 CoolOutAirVolFlowDes; // Autosized outdoor air flow during cooling for reporting
7474 : Real64 CoolOutAirVolFlowUser; // Hardsized outdoor air flow during cooling for reporting
7475 : Real64 HeatOutAirVolFlowDes; // Autosized outdoor air flow during heating for reporting
7476 : Real64 HeatOutAirVolFlowUser; // Hardsized outdoor air flow during heating for reporting
7477 : Real64 NoCoolHeatOutAirVolFlowDes; // Autosized outdoor air when unconditioned for reporting
7478 : Real64 NoCoolHeatOutAirVolFlowUser; // Hardsized outdoor air when unconditioned for reporting
7479 : Real64 CoolingCapacityDes; // Autosized cooling capacity for reporting
7480 : Real64 CoolingCapacityUser; // Hardsized cooling capacity for reporting
7481 : Real64 HeatingCapacityDes; // Autosized heating capacity for reporting
7482 : Real64 HeatingCapacityUser; // Hardsized heating capacity for reporting
7483 : Real64 DefrostCapacityDes; // Autosized defrost heater capacity for reporting
7484 : Real64 DefrostCapacityUser; // Hardsized defrost heater capacity for reporting
7485 : Real64 EvapCondAirVolFlowRateDes; // Autosized evaporative condenser flow for reporting
7486 : Real64 EvapCondAirVolFlowRateUser; // Hardsized evaporative condenser flow for reporting
7487 : Real64 EvapCondPumpPowerDes; // Autosized evaporative condenser pump power for reporting
7488 : Real64 EvapCondPumpPowerUser; // Hardsized evaporative condenser pump power for reporting
7489 :
7490 13 : std::string CompName; // component name
7491 13 : std::string CompType; // component type
7492 13 : std::string SizingString; // input field sizing description (e.g., Nominal Capacity)
7493 : Real64 TempSize; // autosized value of coil input field
7494 13 : int FieldNum = 2; // IDD numeric field number where input field description is found
7495 13 : bool PrintFlag = true; // TRUE when sizing information is reported in the eio file
7496 :
7497 13 : auto &ZoneEqSizing = state.dataSize->ZoneEqSizing;
7498 :
7499 13 : DataSizing::ZoneEqSizingData *select_EqSizing(nullptr);
7500 :
7501 : // sweep specific data into one pointer to avoid if statements throughout this subroutine
7502 13 : if (state.dataSize->CurOASysNum > 0) {
7503 0 : select_EqSizing = &state.dataSize->OASysEqSizing(state.dataSize->CurOASysNum);
7504 13 : } else if (state.dataSize->CurSysNum > 0) {
7505 1 : select_EqSizing = &state.dataSize->UnitarySysEqSizing(state.dataSize->CurSysNum);
7506 12 : } else if (state.dataSize->CurZoneEqNum > 0) {
7507 12 : select_EqSizing = &ZoneEqSizing(state.dataSize->CurZoneEqNum);
7508 12 : state.dataSize->ZoneEqUnitarySys = true;
7509 : } else {
7510 0 : assert(false);
7511 : }
7512 : // Object Data, points to specific array
7513 13 : DataSizing::ZoneEqSizingData &EqSizing(*select_EqSizing);
7514 :
7515 : // can't hurt to initialize these going in, probably redundant
7516 13 : EqSizing.AirFlow = false;
7517 13 : EqSizing.CoolingAirFlow = false;
7518 13 : EqSizing.HeatingAirFlow = false;
7519 13 : EqSizing.AirVolFlow = 0.0;
7520 13 : EqSizing.CoolingAirVolFlow = 0.0;
7521 13 : EqSizing.HeatingAirVolFlow = 0.0;
7522 13 : EqSizing.Capacity = false;
7523 13 : EqSizing.CoolingCapacity = false;
7524 13 : EqSizing.HeatingCapacity = false;
7525 13 : EqSizing.DesCoolingLoad = 0.0;
7526 13 : EqSizing.DesHeatingLoad = 0.0;
7527 13 : EqSizing.OAVolFlow = 0.0;
7528 :
7529 13 : VRFCond = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum;
7530 13 : MaxCoolAirVolFlowDes = 0.0;
7531 13 : MaxCoolAirVolFlowUser = 0.0;
7532 13 : MaxHeatAirVolFlowDes = 0.0;
7533 13 : MaxHeatAirVolFlowUser = 0.0;
7534 13 : MaxNoCoolAirVolFlowDes = 0.0;
7535 13 : MaxNoCoolAirVolFlowUser = 0.0;
7536 13 : MaxNoHeatAirVolFlowDes = 0.0;
7537 13 : MaxNoHeatAirVolFlowUser = 0.0;
7538 13 : CoolOutAirVolFlowDes = 0.0;
7539 13 : CoolOutAirVolFlowUser = 0.0;
7540 13 : HeatOutAirVolFlowDes = 0.0;
7541 13 : HeatOutAirVolFlowUser = 0.0;
7542 13 : NoCoolHeatOutAirVolFlowDes = 0.0;
7543 13 : NoCoolHeatOutAirVolFlowUser = 0.0;
7544 13 : CoolingCapacityDes = 0.0;
7545 13 : CoolingCapacityUser = 0.0;
7546 13 : HeatingCapacityDes = 0.0;
7547 13 : HeatingCapacityUser = 0.0;
7548 13 : DefrostCapacityDes = 0.0;
7549 13 : DefrostCapacityUser = 0.0;
7550 13 : EvapCondAirVolFlowRateDes = 0.0;
7551 13 : EvapCondAirVolFlowRateUser = 0.0;
7552 13 : EvapCondPumpPowerDes = 0.0;
7553 13 : EvapCondPumpPowerUser = 0.0;
7554 :
7555 13 : state.dataSize->DataScalableSizingON = false;
7556 13 : state.dataSize->DataScalableCapSizingON = false;
7557 13 : state.dataSize->DataFracOfAutosizedCoolingAirflow = 1.0;
7558 13 : state.dataSize->DataFracOfAutosizedHeatingAirflow = 1.0;
7559 13 : state.dataSize->DataFracOfAutosizedCoolingCapacity = 1.0;
7560 13 : state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
7561 13 : state.dataSize->SuppHeatCap = 0.0;
7562 :
7563 13 : if (state.dataHVACVarRefFlow->MyOneTimeSizeFlag) {
7564 : // initialize the environment and sizing flags
7565 11 : CheckVRFCombinationRatio.dimension(state.dataHVACVarRefFlow->NumVRFCond, true);
7566 11 : state.dataHVACVarRefFlow->MyOneTimeSizeFlag = false;
7567 : }
7568 :
7569 13 : CompType = tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type];
7570 13 : CompName = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name;
7571 13 : state.dataSize->DataZoneNumber = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum;
7572 :
7573 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex > 0) {
7574 12 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone) {
7575 12 : state.dataSize->DataFanType = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType;
7576 12 : state.dataSize->DataFanIndex = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex;
7577 12 : state.dataSize->DataFanPlacement = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanPlace;
7578 0 : } else if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInAirLoop) {
7579 0 : state.dataAirSystemsData->PrimaryAirSystems(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).airLoopNum).supFanType =
7580 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType;
7581 0 : state.dataAirSystemsData->PrimaryAirSystems(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).airLoopNum).supFanNum =
7582 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex;
7583 0 : state.dataAirSystemsData->PrimaryAirSystems(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).airLoopNum).supFanPlace =
7584 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanPlace;
7585 : }
7586 : }
7587 :
7588 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HVACSizingIndex > 0) {
7589 : // initialize OA flow for sizing other inputs (e.g., capacity)
7590 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow == AutoSize) {
7591 0 : EqSizing.OAVolFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
7592 : } else {
7593 0 : EqSizing.OAVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow;
7594 : }
7595 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow != AutoSize) {
7596 0 : EqSizing.OAVolFlow = max(EqSizing.OAVolFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow);
7597 : }
7598 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists &&
7599 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone) { // set up ATMixer conditions for scalable capacity sizing
7600 0 : EqSizing.OAVolFlow = 0.0; // Equipment OA flow should always be 0 when ATMixer is used
7601 0 : SingleDuct::setATMixerSizingProperties(state,
7602 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerIndex,
7603 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum,
7604 0 : state.dataSize->CurZoneEqNum);
7605 : }
7606 :
7607 0 : int zoneHVACIndex = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HVACSizingIndex;
7608 :
7609 : // Integer representation of sizing method name (e.g., CoolingAirflowSizing, HeatingAirflowSizing, CoolingCapacitySizing,
7610 : // HeatingCapacitySizing, etc.)
7611 0 : int SizingMethod = CoolingAirflowSizing;
7612 0 : PrintFlag = true;
7613 0 : bool errorsFound = false;
7614 : // supply air flow rate sizing method (SupplyAirFlowRate, FlowPerFloorArea, FractionOfAutosizedCoolingAirflow,
7615 : // FractionOfAutosizedHeatingAirflow ...)
7616 0 : int SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingSAFMethod;
7617 0 : EqSizing.SizingMethod(SizingMethod) = SAFMethod;
7618 0 : if (SAFMethod == SupplyAirFlowRate || SAFMethod == FlowPerFloorArea || SAFMethod == FractionOfAutosizedCoolingAirflow) {
7619 0 : if (SAFMethod == SupplyAirFlowRate) {
7620 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow > 0.0) {
7621 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
7622 0 : EqSizing.SystemAirFlow = true;
7623 : }
7624 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
7625 0 : } else if (SAFMethod == FlowPerFloorArea) {
7626 0 : EqSizing.SystemAirFlow = true;
7627 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow *
7628 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
7629 0 : TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow;
7630 0 : state.dataSize->DataScalableSizingON = true;
7631 0 : } else if (SAFMethod == FractionOfAutosizedCoolingAirflow) {
7632 0 : state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
7633 0 : TempSize = AutoSize;
7634 0 : state.dataSize->DataScalableSizingON = true;
7635 : } else {
7636 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
7637 : }
7638 :
7639 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
7640 0 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
7641 0 : if (state.dataGlobal->isEpJSON) stringOverride = "cooling_supply_air_flow_rate [m3/s]";
7642 0 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
7643 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7644 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7645 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7646 :
7647 0 : } else if (SAFMethod == FlowPerCoolingCapacity) {
7648 0 : SizingMethod = CoolingCapacitySizing; // either this isn't needed or needs to be assigned to EqSizing
7649 0 : TempSize = AutoSize;
7650 0 : PrintFlag = false;
7651 0 : state.dataSize->DataScalableSizingON = true;
7652 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow;
7653 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingCapMethod == FractionOfAutosizedCoolingCapacity) {
7654 0 : state.dataSize->DataFracOfAutosizedCoolingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
7655 : }
7656 0 : CoolingCapacitySizer sizerCoolingCapacity;
7657 0 : sizerCoolingCapacity.overrideSizingString(SizingString);
7658 0 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7659 0 : state.dataSize->DataAutosizedCoolingCapacity = sizerCoolingCapacity.size(state, TempSize, errorsFound);
7660 0 : state.dataSize->DataFlowPerCoolingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
7661 0 : PrintFlag = true;
7662 0 : TempSize = AutoSize;
7663 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
7664 0 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
7665 0 : if (state.dataGlobal->isEpJSON) stringOverride = "cooling_supply_air_flow_rate [m3/s]";
7666 0 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
7667 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7668 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7669 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7670 0 : }
7671 : // Multispeed Fan cooling flow sizing
7672 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling > 0) {
7673 0 : Real64 AirFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow;
7674 0 : for (int i = 1; i <= state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling; ++i) {
7675 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex > -1) {
7676 0 : if (state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
7677 0 : .coolingVolFlowRatio[i] == DataSizing::AutoSize) {
7678 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] =
7679 0 : double(i) / double(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling) * AirFlowRate;
7680 : } else {
7681 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] =
7682 0 : state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
7683 0 : .coolingVolFlowRatio[i] *
7684 : AirFlowRate;
7685 : }
7686 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] =
7687 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
7688 : } else {
7689 0 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex));
7690 0 : assert(fanSystem != nullptr);
7691 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] == 0.0 && !fanSystem->massFlowAtSpeed.empty()) {
7692 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] = fanSystem->massFlowAtSpeed[i - 1];
7693 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] =
7694 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] / state.dataEnvrn->StdRhoAir;
7695 : }
7696 : }
7697 : }
7698 : }
7699 :
7700 0 : SizingMethod = HeatingAirflowSizing;
7701 0 : FieldNum = 3; // N3, \field Supply Air Flow Rate During Heating Operation
7702 0 : PrintFlag = true;
7703 0 : SizingString = state.dataHVACVarRefFlow->VRFTUNumericFields(VRFTUNum).FieldNames(FieldNum) + " [m3/s]";
7704 0 : SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingSAFMethod;
7705 0 : EqSizing.SizingMethod(SizingMethod) = SAFMethod;
7706 0 : if (SAFMethod == SupplyAirFlowRate || SAFMethod == FlowPerFloorArea || SAFMethod == FractionOfAutosizedHeatingAirflow) {
7707 0 : if (SAFMethod == SupplyAirFlowRate) {
7708 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow > 0.0) {
7709 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
7710 0 : EqSizing.SystemAirFlow = true;
7711 : }
7712 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
7713 0 : } else if (SAFMethod == FlowPerFloorArea) {
7714 0 : EqSizing.SystemAirFlow = true;
7715 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow *
7716 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
7717 0 : TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow;
7718 0 : state.dataSize->DataScalableSizingON = true;
7719 0 : } else if (SAFMethod == FractionOfAutosizedHeatingAirflow) {
7720 0 : state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
7721 0 : TempSize = AutoSize;
7722 0 : state.dataSize->DataScalableSizingON = true;
7723 : } else {
7724 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
7725 : }
7726 0 : errorsFound = false;
7727 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
7728 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
7729 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7730 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7731 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
7732 0 : } else if (SAFMethod == FlowPerHeatingCapacity) {
7733 0 : SizingMethod = HeatingCapacitySizing; // either this isn't needed or needs to be assigned to EqSizing
7734 0 : TempSize = AutoSize;
7735 0 : PrintFlag = false;
7736 0 : state.dataSize->DataScalableSizingON = true;
7737 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatVolFlow;
7738 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod == FractionOfAutosizedHeatingCapacity) {
7739 0 : state.dataSize->DataFracOfAutosizedHeatingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
7740 : }
7741 0 : errorsFound = false;
7742 0 : HeatingCapacitySizer sizerHeatingCapacity;
7743 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
7744 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7745 0 : state.dataSize->DataAutosizedHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
7746 0 : state.dataSize->DataFlowPerHeatingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
7747 0 : SizingMethod = HeatingAirflowSizing; // either this isn't needed or needs to be assigned to EqSizing
7748 0 : PrintFlag = true;
7749 0 : TempSize = AutoSize;
7750 0 : errorsFound = false;
7751 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
7752 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
7753 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7754 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7755 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
7756 0 : }
7757 : // Multispeed Fan heating flow sizing
7758 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating > 0) {
7759 0 : Real64 AirFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow;
7760 0 : for (int i = 1; i <= state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating; ++i) {
7761 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex > -1) {
7762 0 : if (state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
7763 0 : .heatingVolFlowRatio[i] == DataSizing::AutoSize) {
7764 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] =
7765 0 : double(i) / double(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating) * AirFlowRate;
7766 : } else {
7767 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] =
7768 0 : state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
7769 0 : .heatingVolFlowRatio[i] *
7770 : AirFlowRate;
7771 : }
7772 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] =
7773 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
7774 : } else {
7775 0 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex));
7776 0 : assert(fanSystem != nullptr);
7777 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] == 0.0 && !fanSystem->massFlowAtSpeed.empty()) {
7778 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] = fanSystem->massFlowAtSpeed[i - 1];
7779 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] =
7780 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] / state.dataEnvrn->StdRhoAir;
7781 : }
7782 : }
7783 : }
7784 : }
7785 :
7786 0 : PrintFlag = true;
7787 0 : SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).NoCoolHeatSAFMethod;
7788 0 : EqSizing.SizingMethod(SizingMethod) = SAFMethod;
7789 0 : if ((SAFMethod == SupplyAirFlowRate) || (SAFMethod == FlowPerFloorArea) || (SAFMethod == FractionOfAutosizedHeatingAirflow) ||
7790 : (SAFMethod == FractionOfAutosizedCoolingAirflow)) {
7791 0 : if (SAFMethod == SupplyAirFlowRate) {
7792 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow > 0.0) {
7793 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7794 0 : EqSizing.SystemAirFlow = true;
7795 : }
7796 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7797 0 : } else if (SAFMethod == FlowPerFloorArea) {
7798 0 : EqSizing.SystemAirFlow = true;
7799 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow *
7800 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
7801 0 : TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow;
7802 0 : state.dataSize->DataScalableSizingON = true;
7803 0 : } else if (SAFMethod == FractionOfAutosizedCoolingAirflow) {
7804 0 : state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7805 0 : state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7806 0 : TempSize = AutoSize;
7807 0 : state.dataSize->DataScalableSizingON = true;
7808 0 : } else if (SAFMethod == FractionOfAutosizedHeatingAirflow) {
7809 0 : state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7810 0 : state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7811 0 : TempSize = AutoSize;
7812 0 : state.dataSize->DataScalableSizingON = true;
7813 : } else {
7814 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7815 : }
7816 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
7817 0 : std::string stringOverride = "No Cooling Supply Air Flow Rate [m3/s]";
7818 0 : if (state.dataGlobal->isEpJSON) stringOverride = "no_cooling_supply_air_flow_rate [m3/s]";
7819 0 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
7820 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7821 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7822 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling > 0) {
7823 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[1];
7824 0 : sizingCoolingAirFlow.reportSizerOutput(state,
7825 : sizingCoolingAirFlow.compType,
7826 : sizingCoolingAirFlow.compName,
7827 0 : "Design Size " + stringOverride,
7828 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow);
7829 : } else {
7830 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7831 : }
7832 0 : }
7833 :
7834 0 : SizingMethod = HeatingAirflowSizing;
7835 0 : FieldNum = 4; // N4, \field Supply Air Flow Rate When No Heating is Needed
7836 0 : PrintFlag = true;
7837 0 : SizingString = state.dataHVACVarRefFlow->VRFTUNumericFields(VRFTUNum).FieldNames(FieldNum) + " [m3/s]";
7838 0 : SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).NoCoolHeatSAFMethod;
7839 0 : EqSizing.SizingMethod(SizingMethod) = SAFMethod;
7840 0 : if ((SAFMethod == SupplyAirFlowRate) || (SAFMethod == FlowPerFloorArea) || (SAFMethod == FractionOfAutosizedHeatingAirflow) ||
7841 : (SAFMethod == FractionOfAutosizedCoolingAirflow)) {
7842 0 : if (SAFMethod == SupplyAirFlowRate) {
7843 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow > 0.0) {
7844 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7845 0 : EqSizing.SystemAirFlow = true;
7846 : }
7847 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7848 0 : } else if (SAFMethod == FlowPerFloorArea) {
7849 0 : EqSizing.SystemAirFlow = true;
7850 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow *
7851 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
7852 0 : TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow;
7853 0 : state.dataSize->DataScalableSizingON = true;
7854 0 : } else if (SAFMethod == FractionOfAutosizedHeatingAirflow) {
7855 0 : state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7856 0 : state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7857 0 : TempSize = AutoSize;
7858 0 : state.dataSize->DataScalableSizingON = true;
7859 0 : } else if (SAFMethod == FractionOfAutosizedCoolingAirflow) {
7860 0 : state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7861 0 : state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7862 0 : TempSize = AutoSize;
7863 0 : state.dataSize->DataScalableSizingON = true;
7864 : } else {
7865 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7866 : }
7867 0 : errorsFound = false;
7868 0 : HeatingAirFlowSizer sizingNoHeatingAirFlow;
7869 0 : sizingNoHeatingAirFlow.overrideSizingString(SizingString);
7870 : // sizingNoHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7871 0 : sizingNoHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7872 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating > 0) {
7873 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[1];
7874 0 : sizingNoHeatingAirFlow.reportSizerOutput(state,
7875 : sizingNoHeatingAirFlow.compType,
7876 : sizingNoHeatingAirFlow.compName,
7877 0 : "Design Size " + SizingString,
7878 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow);
7879 : } else {
7880 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow = sizingNoHeatingAirFlow.size(state, TempSize, errorsFound);
7881 : }
7882 0 : }
7883 :
7884 : // initialize capacity sizing variables: cooling
7885 0 : initCapSizingVars(state,
7886 : CoolingCapacitySizing,
7887 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingCapMethod,
7888 : EqSizing.SizingMethod(SizingMethod),
7889 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity,
7890 0 : EqSizing.CoolingCapacity,
7891 0 : EqSizing.DesCoolingLoad,
7892 0 : state.dataSize->DataScalableCapSizingON,
7893 0 : state.dataSize->DataFracOfAutosizedCoolingCapacity);
7894 :
7895 : // initialize capacity sizing variables: heating
7896 0 : initCapSizingVars(state,
7897 : HeatingCapacitySizing,
7898 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod,
7899 : EqSizing.SizingMethod(SizingMethod),
7900 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity,
7901 0 : EqSizing.HeatingCapacity,
7902 0 : EqSizing.DesHeatingLoad,
7903 0 : state.dataSize->DataScalableCapSizingON,
7904 0 : state.dataSize->DataFracOfAutosizedHeatingCapacity);
7905 :
7906 : } else {
7907 : // no scalable sizing method has been specified. Sizing proceeds using the method
7908 : // specified in the zoneHVAC object
7909 :
7910 13 : PrintFlag = true;
7911 :
7912 13 : TempSize = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow;
7913 13 : bool errorsFound = false;
7914 13 : CoolingAirFlowSizer sizingCoolingAirFlow;
7915 13 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
7916 13 : if (state.dataGlobal->isEpJSON) stringOverride = "cooling_supply_air_flow_rate [m3/s]";
7917 13 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
7918 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7919 13 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7920 13 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7921 : // Multispeed Fan cooling flow sizing
7922 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling > 0) {
7923 2 : Real64 AirFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow;
7924 6 : for (int i = 1; i <= state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling; ++i) {
7925 4 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex > -1) {
7926 0 : if (state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
7927 0 : .coolingVolFlowRatio[i] == DataSizing::AutoSize) {
7928 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] =
7929 0 : double(i) / double(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling) * AirFlowRate;
7930 : } else {
7931 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] =
7932 0 : state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
7933 0 : .coolingVolFlowRatio[i] *
7934 : AirFlowRate;
7935 : }
7936 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] =
7937 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
7938 : } else {
7939 4 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex));
7940 4 : assert(fanSystem != nullptr);
7941 4 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] == 0.0 && !fanSystem->massFlowAtSpeed.empty()) {
7942 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] = fanSystem->massFlowAtSpeed[i - 1];
7943 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] =
7944 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] / state.dataEnvrn->StdRhoAir;
7945 : }
7946 : }
7947 : }
7948 : }
7949 :
7950 13 : FieldNum = 3; // N3, \field Supply Air Flow Rate During Heating Operation
7951 13 : SizingString = state.dataHVACVarRefFlow->VRFTUNumericFields(VRFTUNum).FieldNames(FieldNum) + " [m3/s]";
7952 13 : TempSize = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow;
7953 13 : errorsFound = false;
7954 13 : HeatingAirFlowSizer sizingHeatingAirFlow;
7955 13 : sizingHeatingAirFlow.overrideSizingString(SizingString);
7956 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7957 13 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7958 13 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
7959 : // Multispeed Fan heating flow sizing
7960 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating > 0) {
7961 2 : Real64 AirFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow;
7962 6 : for (int i = 1; i <= state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating; ++i) {
7963 4 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex > -1) {
7964 0 : if (state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
7965 0 : .heatingVolFlowRatio[i] == DataSizing::AutoSize) {
7966 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] =
7967 0 : double(i) / double(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating) * AirFlowRate;
7968 : } else {
7969 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] =
7970 0 : state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
7971 0 : .heatingVolFlowRatio[i] *
7972 : AirFlowRate;
7973 : }
7974 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] =
7975 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
7976 : } else {
7977 4 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex));
7978 4 : assert(fanSystem != nullptr);
7979 4 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] == 0.0 && !fanSystem->massFlowAtSpeed.empty()) {
7980 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] = fanSystem->massFlowAtSpeed[i - 1];
7981 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] =
7982 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] / state.dataEnvrn->StdRhoAir;
7983 : }
7984 : }
7985 : }
7986 : }
7987 :
7988 13 : errorsFound = false;
7989 13 : SystemAirFlowSizer sizerSystemAirFlow;
7990 13 : std::string sizingString = "No Cooling Supply Air Flow Rate [m3/s]";
7991 13 : sizerSystemAirFlow.overrideSizingString(sizingString);
7992 13 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7993 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling > 0) {
7994 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[1];
7995 6 : sizerSystemAirFlow.reportSizerOutput(state,
7996 : sizerSystemAirFlow.compType,
7997 : sizerSystemAirFlow.compName,
7998 2 : "Design Size " + sizingString,
7999 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow);
8000 : } else {
8001 11 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow =
8002 11 : sizerSystemAirFlow.size(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow, errorsFound);
8003 : }
8004 :
8005 13 : SystemAirFlowSizer sizerSystemAirFlow2;
8006 13 : sizingString = "No Heating Supply Air Flow Rate [m3/s]";
8007 13 : sizerSystemAirFlow2.overrideSizingString(sizingString);
8008 13 : sizerSystemAirFlow2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8009 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating > 0) {
8010 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[1];
8011 6 : sizerSystemAirFlow.reportSizerOutput(state,
8012 : sizerSystemAirFlow.compType,
8013 : sizerSystemAirFlow.compName,
8014 2 : "Design Size " + sizingString,
8015 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow);
8016 : } else {
8017 11 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow =
8018 11 : sizerSystemAirFlow2.size(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow, errorsFound);
8019 : }
8020 13 : }
8021 13 : IsAutoSize = false;
8022 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow == AutoSize) {
8023 5 : IsAutoSize = true;
8024 : }
8025 13 : if (state.dataSize->CurZoneEqNum > 0) {
8026 12 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // Simulation continue
8027 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow > 0.0) {
8028 0 : BaseSizer::reportSizerOutput(state,
8029 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8030 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8031 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
8032 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow);
8033 : }
8034 : } else {
8035 12 : CheckZoneSizing(state, tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type], state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name);
8036 12 : CoolOutAirVolFlowDes =
8037 12 : min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow);
8038 12 : if (CoolOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
8039 9 : CoolOutAirVolFlowDes = 0.0;
8040 : }
8041 :
8042 12 : if (IsAutoSize) {
8043 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow = CoolOutAirVolFlowDes;
8044 8 : BaseSizer::reportSizerOutput(state,
8045 4 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8046 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8047 : "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]",
8048 : CoolOutAirVolFlowDes);
8049 : } else {
8050 8 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow > 0.0 && CoolOutAirVolFlowDes > 0.0) {
8051 1 : CoolOutAirVolFlowUser = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow;
8052 2 : BaseSizer::reportSizerOutput(state,
8053 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8054 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8055 : "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]",
8056 : CoolOutAirVolFlowDes,
8057 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
8058 : CoolOutAirVolFlowUser);
8059 1 : if (state.dataGlobal->DisplayExtraWarnings) {
8060 0 : if ((std::abs(CoolOutAirVolFlowDes - CoolOutAirVolFlowUser) / CoolOutAirVolFlowUser) >
8061 0 : state.dataSize->AutoVsHardSizingThreshold) {
8062 0 : ShowMessage(state,
8063 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8064 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8065 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
8066 0 : ShowContinueError(
8067 : state,
8068 0 : format("User-Specified Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]", CoolOutAirVolFlowUser));
8069 0 : ShowContinueError(state,
8070 0 : format("differs from Design Size Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]",
8071 : CoolOutAirVolFlowDes));
8072 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8073 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8074 : }
8075 : }
8076 : }
8077 : }
8078 : }
8079 : } else {
8080 1 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow == DataSizing::AutoSize) {
8081 1 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).OASysExists) {
8082 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow = 0.0;
8083 : } else {
8084 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow =
8085 0 : min(state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesOutAirVolFlow,
8086 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow);
8087 : }
8088 2 : BaseSizer::reportSizerOutput(state,
8089 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8090 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8091 : "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]",
8092 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow);
8093 : }
8094 : }
8095 :
8096 13 : IsAutoSize = false;
8097 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow == AutoSize) {
8098 5 : IsAutoSize = true;
8099 : }
8100 13 : if (state.dataSize->CurZoneEqNum > 0) {
8101 12 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // Simulation continue
8102 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow > 0.0) {
8103 0 : BaseSizer::reportSizerOutput(state,
8104 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8105 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8106 : "Outdoor Air Flow Rate During Heating Operation [m3/s]",
8107 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow);
8108 : }
8109 : } else {
8110 12 : CheckZoneSizing(state, tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type], state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name);
8111 12 : HeatOutAirVolFlowDes =
8112 12 : min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow);
8113 12 : if (HeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
8114 9 : HeatOutAirVolFlowDes = 0.0;
8115 : }
8116 :
8117 12 : if (IsAutoSize) {
8118 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow = HeatOutAirVolFlowDes;
8119 8 : BaseSizer::reportSizerOutput(state,
8120 4 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8121 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8122 : "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]",
8123 : HeatOutAirVolFlowDes);
8124 : } else {
8125 8 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow > 0.0 && HeatOutAirVolFlowDes > 0.0) {
8126 1 : HeatOutAirVolFlowUser = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow;
8127 2 : BaseSizer::reportSizerOutput(state,
8128 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8129 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8130 : "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]",
8131 : HeatOutAirVolFlowDes,
8132 : "User-Specified Outdoor Air Flow Rate During Heating Operation [m3/s]",
8133 : HeatOutAirVolFlowUser);
8134 1 : if (state.dataGlobal->DisplayExtraWarnings) {
8135 0 : if ((std::abs(HeatOutAirVolFlowDes - HeatOutAirVolFlowUser) / HeatOutAirVolFlowUser) >
8136 0 : state.dataSize->AutoVsHardSizingThreshold) {
8137 0 : ShowMessage(state,
8138 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8139 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8140 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
8141 0 : ShowContinueError(
8142 : state,
8143 0 : format("User-Specified Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]", HeatOutAirVolFlowUser));
8144 0 : ShowContinueError(state,
8145 0 : format("differs from Design Size Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]",
8146 : HeatOutAirVolFlowDes));
8147 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8148 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8149 : }
8150 : }
8151 : }
8152 : }
8153 : }
8154 : } else {
8155 1 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow == DataSizing::AutoSize) {
8156 1 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).OASysExists) {
8157 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow = 0.0;
8158 : } else {
8159 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow =
8160 0 : min(state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesOutAirVolFlow,
8161 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow);
8162 : }
8163 2 : BaseSizer::reportSizerOutput(state,
8164 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8165 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8166 : "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]",
8167 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow);
8168 : }
8169 : }
8170 13 : EqSizing.OAVolFlow =
8171 13 : max(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow);
8172 :
8173 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists &&
8174 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone) { // set up ATMixer conditions for use in component sizing
8175 0 : EqSizing.OAVolFlow = 0.0; // Equipment OA flow should always be 0 when ATMixer is used
8176 0 : SingleDuct::setATMixerSizingProperties(state,
8177 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerIndex,
8178 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum,
8179 0 : state.dataSize->CurZoneEqNum);
8180 : }
8181 :
8182 13 : IsAutoSize = false;
8183 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow == AutoSize) {
8184 4 : IsAutoSize = true;
8185 : }
8186 13 : if (state.dataSize->CurZoneEqNum > 0) {
8187 12 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // Simulation continue
8188 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow > 0.0) {
8189 0 : BaseSizer::reportSizerOutput(state,
8190 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8191 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8192 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
8193 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow);
8194 : }
8195 : } else {
8196 12 : CheckZoneSizing(state, tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type], state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name);
8197 12 : NoCoolHeatOutAirVolFlowDes = min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA,
8198 12 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow,
8199 12 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow);
8200 12 : if (NoCoolHeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
8201 9 : NoCoolHeatOutAirVolFlowDes = 0.0;
8202 : }
8203 :
8204 12 : if (IsAutoSize) {
8205 3 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow = NoCoolHeatOutAirVolFlowDes;
8206 6 : BaseSizer::reportSizerOutput(state,
8207 3 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8208 3 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8209 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
8210 : NoCoolHeatOutAirVolFlowDes);
8211 : } else {
8212 9 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow > 0.0 && NoCoolHeatOutAirVolFlowDes > 0.0) {
8213 1 : NoCoolHeatOutAirVolFlowUser = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow;
8214 2 : BaseSizer::reportSizerOutput(state,
8215 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8216 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8217 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
8218 : NoCoolHeatOutAirVolFlowDes,
8219 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
8220 : NoCoolHeatOutAirVolFlowUser);
8221 1 : if (state.dataGlobal->DisplayExtraWarnings) {
8222 0 : if ((std::abs(NoCoolHeatOutAirVolFlowDes - NoCoolHeatOutAirVolFlowUser) / NoCoolHeatOutAirVolFlowUser) >
8223 0 : state.dataSize->AutoVsHardSizingThreshold) {
8224 0 : ShowMessage(state,
8225 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8226 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8227 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
8228 0 : ShowContinueError(state,
8229 0 : format("User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
8230 : NoCoolHeatOutAirVolFlowUser));
8231 0 : ShowContinueError(
8232 : state,
8233 0 : format("differs from Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
8234 : NoCoolHeatOutAirVolFlowDes));
8235 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8236 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8237 : }
8238 : }
8239 : }
8240 : }
8241 : }
8242 : } else {
8243 1 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow == DataSizing::AutoSize) {
8244 1 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).OASysExists) {
8245 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow = 0.0;
8246 : } else {
8247 0 : if (!(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling > 0 &&
8248 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating > 0)) {
8249 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow =
8250 0 : min(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow);
8251 : } else {
8252 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex > -1) {
8253 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow =
8254 0 : min(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[1],
8255 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[1]);
8256 : }
8257 : }
8258 : }
8259 2 : BaseSizer::reportSizerOutput(state,
8260 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8261 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8262 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating Heating is Needed [m3/s]",
8263 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow);
8264 : }
8265 : }
8266 :
8267 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatingCoilPresent) {
8268 4 : bool ErrorsFound = false;
8269 4 : TempSize = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxSATFromSuppHeatCoil;
8270 4 : MaxHeaterOutletTempSizer sizerMaxHeaterOutTemp;
8271 4 : std::string stringOverride = "Maximum Supply Air Temperature from Supplemental Heater [C]";
8272 4 : if (state.dataGlobal->isEpJSON) stringOverride = "maximum_supply_air_temperature_from_supplemental_heater [C]";
8273 4 : sizerMaxHeaterOutTemp.overrideSizingString(stringOverride);
8274 4 : sizerMaxHeaterOutTemp.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8275 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxSATFromSuppHeatCoil = sizerMaxHeaterOutTemp.size(state, TempSize, ErrorsFound);
8276 4 : }
8277 :
8278 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
8279 0 : bool ErrorsFound = false;
8280 0 : WaterCoils::SetCoilDesFlow(state,
8281 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType,
8282 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
8283 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow,
8284 : ErrorsFound);
8285 : }
8286 :
8287 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatingCoilPresent) {
8288 4 : CompType = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType;
8289 4 : CompName = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName;
8290 4 : PrintFlag = false; // why isn't this being reported?
8291 4 : TempSize = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSuppHeatingCapacity;
8292 4 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
8293 : // sizing result should always be reported
8294 0 : if (TempSize == DataSizing::AutoSize) {
8295 0 : WaterHeatingCapacitySizer sizerWaterHeatingCapacity;
8296 0 : bool ErrorsFound = false;
8297 0 : std::string stringOverride = "Supplemental Heating Coil Nominal Capacity [W]";
8298 0 : if (state.dataGlobal->isEpJSON) stringOverride = "supplemental_heating_coil_nominal_capacity [W]";
8299 0 : sizerWaterHeatingCapacity.overrideSizingString(stringOverride);
8300 0 : sizerWaterHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8301 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSuppHeatingCapacity = sizerWaterHeatingCapacity.size(state, TempSize, ErrorsFound);
8302 0 : }
8303 : } else {
8304 4 : SizingString = "Supplemental Heating Coil Nominal Capacity [W]";
8305 4 : if (TempSize == DataSizing::AutoSize) {
8306 0 : bool errorsFound = false;
8307 0 : HeatingCapacitySizer sizerHeatingCapacity;
8308 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
8309 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8310 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSuppHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
8311 0 : }
8312 : }
8313 : }
8314 :
8315 13 : EqSizing.CoolingAirFlow = true;
8316 13 : EqSizing.CoolingAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow;
8317 13 : EqSizing.HeatingAirFlow = true;
8318 13 : EqSizing.HeatingAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow;
8319 :
8320 13 : if (CheckVRFCombinationRatio(VRFCond)) {
8321 13 : OnOffAirFlowRat = 1.0;
8322 : // set up the outside air data for sizing the DX coils
8323 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone) state.dataSize->ZoneEqDXCoil = true;
8324 13 : if (state.dataSize->CurZoneEqNum > 0) {
8325 21 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow > 0.0 ||
8326 9 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow > 0.0) {
8327 3 : EqSizing.OAVolFlow =
8328 3 : max(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow);
8329 : } else {
8330 9 : EqSizing.OAVolFlow = 0.0;
8331 : }
8332 : } else {
8333 1 : EqSizing.OAVolFlow = 0.0;
8334 : }
8335 :
8336 13 : Real64 SuppHeatCoilLoad = 0.0;
8337 : // simulate the TU to size the coils
8338 13 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
8339 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
8340 6 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
8341 : state, VRFTUNum, true, 0.0, TUCoolingCapacity, OnOffAirFlowRat, SuppHeatCoilLoad);
8342 : } else {
8343 : // Algorithm Type: VRF model based on system curve
8344 7 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(state, VRFTUNum, true, 0.0, TUCoolingCapacity, OnOffAirFlowRat, SuppHeatCoilLoad);
8345 : }
8346 :
8347 : // ZoneEqDXCoil = .FALSE.
8348 13 : TUCoolingCapacity = 0.0;
8349 13 : TUHeatingCapacity = 0.0;
8350 13 : bool FoundAll = true;
8351 : bool errFlag; // temporary variable used for error checking
8352 13 : int TUListNum = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex;
8353 28 : for (int NumTU = 1; NumTU <= state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList; ++NumTU) {
8354 17 : int TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
8355 17 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex > 0) {
8356 51 : DXCoilCap = DXCoils::GetCoilCapacityByIndexType(state,
8357 17 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex,
8358 17 : state.dataHVACVarRefFlow->VRFTU(TUIndex).DXCoolCoilType_Num,
8359 : errFlag);
8360 17 : TUCoolingCapacity += DXCoilCap;
8361 17 : if (DXCoilCap == AutoSize) {
8362 2 : FoundAll = false;
8363 2 : break;
8364 : }
8365 : }
8366 15 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex > 0) {
8367 45 : DXCoilCap = DXCoils::GetCoilCapacityByIndexType(state,
8368 15 : state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex,
8369 15 : state.dataHVACVarRefFlow->VRFTU(TUIndex).DXHeatCoilType_Num,
8370 : errFlag);
8371 15 : TUHeatingCapacity += DXCoilCap;
8372 15 : if (DXCoilCap == AutoSize) {
8373 0 : FoundAll = false;
8374 0 : break;
8375 : }
8376 : }
8377 : }
8378 :
8379 13 : if (FoundAll && (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::SysCurve)) {
8380 : // Size VRF rated cooling/heating capacity (VRF-SysCurve Model)
8381 :
8382 : // Size VRF( VRFCond ).CoolingCapacity
8383 7 : IsAutoSize = false;
8384 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity == AutoSize) {
8385 5 : IsAutoSize = true;
8386 : }
8387 7 : CoolingCapacityDes = TUCoolingCapacity;
8388 7 : if (IsAutoSize) {
8389 5 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity = CoolingCapacityDes;
8390 15 : BaseSizer::reportSizerOutput(state,
8391 15 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8392 5 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8393 : "Design Size Rated Total Cooling Capacity (gross) [W]",
8394 : CoolingCapacityDes);
8395 : } else {
8396 2 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity > 0.0 && CoolingCapacityDes > 0.0) {
8397 2 : CoolingCapacityUser = state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity;
8398 6 : BaseSizer::reportSizerOutput(state,
8399 6 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8400 2 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8401 : "Design Size Rated Total Cooling Capacity (gross) [W]",
8402 : CoolingCapacityDes,
8403 : "User-Specified Rated Total Cooling Capacity (gross) [W]",
8404 : CoolingCapacityUser);
8405 2 : if (state.dataGlobal->DisplayExtraWarnings) {
8406 0 : if ((std::abs(CoolingCapacityDes - CoolingCapacityUser) / CoolingCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8407 0 : ShowMessage(state,
8408 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8409 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8410 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8411 0 : ShowContinueError(state,
8412 0 : format("User-Specified Rated Total Cooling Capacity (gross) of {:.2R} [W]", CoolingCapacityUser));
8413 0 : ShowContinueError(
8414 0 : state, format("differs from Design Size Rated Total Cooling Capacity (gross) of {:.2R} [W]", CoolingCapacityDes));
8415 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8416 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8417 : }
8418 : }
8419 : }
8420 : }
8421 :
8422 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity > 0.0) {
8423 7 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCombinationRatio =
8424 7 : TUCoolingCapacity / state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity;
8425 : }
8426 :
8427 : // Size VRF( VRFCond ).HeatingCapacity
8428 7 : IsAutoSize = false;
8429 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity == AutoSize) {
8430 5 : IsAutoSize = true;
8431 : }
8432 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).LockHeatingCapacity) {
8433 0 : HeatingCapacityDes =
8434 0 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity * state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacitySizeRatio;
8435 : } else {
8436 7 : HeatingCapacityDes = TUHeatingCapacity;
8437 : }
8438 7 : if (IsAutoSize) {
8439 5 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity = HeatingCapacityDes;
8440 15 : BaseSizer::reportSizerOutput(state,
8441 15 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8442 5 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8443 : "Design Size Rated Total Heating Capacity [W]",
8444 : HeatingCapacityDes);
8445 : } else {
8446 2 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity > 0.0 && HeatingCapacityDes > 0.0) {
8447 2 : HeatingCapacityUser = state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity;
8448 6 : BaseSizer::reportSizerOutput(state,
8449 6 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8450 2 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8451 : "Design Size Rated Total Heating Capacity [W]",
8452 : HeatingCapacityDes,
8453 : "User-Specified Rated Total Heating Capacity [W]",
8454 : HeatingCapacityUser);
8455 2 : if (state.dataGlobal->DisplayExtraWarnings) {
8456 0 : if ((std::abs(HeatingCapacityDes - HeatingCapacityUser) / HeatingCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8457 0 : ShowMessage(state,
8458 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8459 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8460 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8461 0 : ShowContinueError(state, format("User-Specified Rated Total Heating Capacity of {:.2R} [W]", HeatingCapacityUser));
8462 0 : ShowContinueError(state,
8463 0 : format("differs from Design Size Rated Total Heating Capacity of {:.2R} [W]", HeatingCapacityDes));
8464 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8465 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8466 : }
8467 : }
8468 : }
8469 : }
8470 :
8471 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity > 0.0) {
8472 7 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCombinationRatio =
8473 7 : TUHeatingCapacity / state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity;
8474 : }
8475 :
8476 : // calculate the piping correction factors only once
8477 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthCoolPtr > 0) {
8478 : {
8479 6 : if (state.dataCurveManager->curves(state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthCoolPtr)->numDims == 2) {
8480 6 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionCooling =
8481 6 : min(1.0,
8482 : max(0.5,
8483 24 : CurveValue(state,
8484 6 : state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthCoolPtr,
8485 6 : state.dataHVACVarRefFlow->VRF(VRFCond).EquivPipeLngthCool,
8486 6 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCombinationRatio) +
8487 6 : state.dataHVACVarRefFlow->VRF(VRFCond).VertPipeLngth * state.dataHVACVarRefFlow->VRF(VRFCond).PCFHeightCool));
8488 : } else {
8489 0 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionCooling =
8490 0 : min(1.0,
8491 : max(0.5,
8492 0 : CurveValue(state,
8493 0 : state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthCoolPtr,
8494 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EquivPipeLngthCool) +
8495 0 : state.dataHVACVarRefFlow->VRF(VRFCond).VertPipeLngth * state.dataHVACVarRefFlow->VRF(VRFCond).PCFHeightCool));
8496 : }
8497 : }
8498 : } else {
8499 1 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionCooling = min(
8500 : 1.0,
8501 1 : max(0.5, (1.0 + state.dataHVACVarRefFlow->VRF(VRFCond).VertPipeLngth * state.dataHVACVarRefFlow->VRF(VRFCond).PCFHeightCool)));
8502 : }
8503 :
8504 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthHeatPtr > 0) {
8505 : {
8506 0 : if (state.dataCurveManager->curves(state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthHeatPtr)->numDims == 2) {
8507 0 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionHeating =
8508 0 : min(1.0,
8509 : max(0.5,
8510 0 : CurveValue(state,
8511 0 : state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthHeatPtr,
8512 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EquivPipeLngthHeat,
8513 0 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCombinationRatio) +
8514 0 : state.dataHVACVarRefFlow->VRF(VRFCond).VertPipeLngth * state.dataHVACVarRefFlow->VRF(VRFCond).PCFHeightHeat));
8515 : } else {
8516 0 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionHeating =
8517 0 : min(1.0,
8518 : max(0.5,
8519 0 : CurveValue(state,
8520 0 : state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthHeatPtr,
8521 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EquivPipeLngthHeat) +
8522 0 : state.dataHVACVarRefFlow->VRF(VRFCond).VertPipeLngth * state.dataHVACVarRefFlow->VRF(VRFCond).PCFHeightHeat));
8523 : }
8524 : }
8525 : } else {
8526 7 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionHeating = min(
8527 : 1.0,
8528 7 : max(0.5, (1.0 + state.dataHVACVarRefFlow->VRF(VRFCond).VertPipeLngth * state.dataHVACVarRefFlow->VRF(VRFCond).PCFHeightHeat)));
8529 : }
8530 :
8531 7 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedCoolingPower =
8532 7 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity / state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCOP;
8533 7 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedHeatingPower =
8534 7 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity / state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCOP;
8535 :
8536 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CoolCombRatioPTR > 0) {
8537 6 : state.dataHVACVarRefFlow->CoolCombinationRatio(VRFCond) = CurveValue(
8538 6 : state, state.dataHVACVarRefFlow->VRF(VRFCond).CoolCombRatioPTR, state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCombinationRatio);
8539 : } else {
8540 1 : state.dataHVACVarRefFlow->CoolCombinationRatio(VRFCond) = 1.0;
8541 : }
8542 :
8543 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatCombRatioPTR > 0) {
8544 6 : state.dataHVACVarRefFlow->HeatCombinationRatio(VRFCond) = CurveValue(
8545 6 : state, state.dataHVACVarRefFlow->VRF(VRFCond).HeatCombRatioPTR, state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCombinationRatio);
8546 : } else {
8547 1 : state.dataHVACVarRefFlow->HeatCombinationRatio(VRFCond) = 1.0;
8548 : }
8549 : }
8550 :
8551 13 : if (FoundAll && (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl)) {
8552 : // Size VRF rated evaporative capacity (VRF-FluidTCtrl Model)
8553 : // Set piping correction factors to 1.0 here for reporting to eio output - recalculated every time step in
8554 : // VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl
8555 4 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionCooling = 1.0;
8556 4 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionHeating = 1.0;
8557 :
8558 : // Size VRF( VRFCond ).RatedEvapCapacity
8559 4 : IsAutoSize = false;
8560 4 : if (state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity == AutoSize) {
8561 2 : IsAutoSize = true;
8562 : }
8563 :
8564 4 : CoolingCapacityDes = TUCoolingCapacity;
8565 4 : HeatingCapacityDes = TUHeatingCapacity;
8566 :
8567 4 : if (IsAutoSize) {
8568 : // RatedEvapCapacity
8569 2 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity =
8570 2 : max(CoolingCapacityDes, HeatingCapacityDes / (1 + state.dataHVACVarRefFlow->VRF(VRFCond).RatedCompPowerPerCapcity));
8571 :
8572 : // Other parameters dependent on RatedEvapCapacity
8573 2 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedCompPower =
8574 2 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedCompPowerPerCapcity * state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity;
8575 2 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedOUFanPower =
8576 2 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedOUFanPowerPerCapcity * state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity;
8577 2 : state.dataHVACVarRefFlow->VRF(VRFCond).OUAirFlowRate =
8578 2 : state.dataHVACVarRefFlow->VRF(VRFCond).OUAirFlowRatePerCapcity * state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity;
8579 :
8580 2 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity = state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity;
8581 2 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity =
8582 2 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity * (1 + state.dataHVACVarRefFlow->VRF(VRFCond).RatedCompPowerPerCapcity);
8583 :
8584 6 : BaseSizer::reportSizerOutput(state,
8585 6 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8586 2 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8587 : "Design Size Rated Total Heating Capacity [W]",
8588 2 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity);
8589 6 : BaseSizer::reportSizerOutput(state,
8590 6 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8591 2 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8592 : "Design Size Rated Total Cooling Capacity (gross) [W]",
8593 2 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity);
8594 : } else {
8595 2 : CoolingCapacityUser = state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity;
8596 2 : HeatingCapacityUser = state.dataHVACVarRefFlow->VRF(VRFCond).RatedHeatCapacity;
8597 :
8598 6 : BaseSizer::reportSizerOutput(state,
8599 6 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8600 2 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8601 : "Design Size Rated Total Cooling Capacity (gross) [W]",
8602 : CoolingCapacityDes,
8603 : "User-Specified Rated Total Cooling Capacity (gross) [W]",
8604 : CoolingCapacityUser);
8605 6 : BaseSizer::reportSizerOutput(state,
8606 6 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8607 2 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8608 : "Design Size Rated Total Heating Capacity [W]",
8609 : HeatingCapacityDes,
8610 : "User-Specified Rated Total Heating Capacity [W]",
8611 : HeatingCapacityUser);
8612 :
8613 2 : if (state.dataGlobal->DisplayExtraWarnings) {
8614 0 : if ((std::abs(CoolingCapacityDes - CoolingCapacityUser) / CoolingCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8615 0 : ShowMessage(state,
8616 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8617 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8618 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8619 0 : ShowContinueError(state, format("User-Specified Rated Total Cooling Capacity (gross) of {:.2R} [W]", CoolingCapacityUser));
8620 0 : ShowContinueError(state,
8621 0 : format("differs from Design Size Rated Total Cooling Capacity (gross) of {:.2R} [W]", CoolingCapacityDes));
8622 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8623 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8624 : }
8625 :
8626 0 : if ((std::abs(HeatingCapacityDes - HeatingCapacityUser) / HeatingCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8627 0 : ShowMessage(state,
8628 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8629 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8630 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8631 0 : ShowContinueError(state, format("User-Specified Rated Total Heating Capacity of {:.2R} [W]", HeatingCapacityUser));
8632 0 : ShowContinueError(state, format("differs from Design Size Rated Total Heating Capacity of {:.2R} [W]", HeatingCapacityDes));
8633 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8634 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8635 : }
8636 : }
8637 : }
8638 : }
8639 :
8640 13 : if (FoundAll) {
8641 : // autosize resistive defrost heater capacity
8642 11 : IsAutoSize = false;
8643 11 : if (state.dataHVACVarRefFlow->VRF(VRFCond).DefrostCapacity == AutoSize) {
8644 5 : IsAutoSize = true;
8645 : }
8646 11 : if (state.dataHVACVarRefFlow->VRF(VRFCond).DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
8647 2 : DefrostCapacityDes = state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity;
8648 : } else {
8649 9 : DefrostCapacityDes = 0.0;
8650 : }
8651 11 : if (IsAutoSize) {
8652 5 : state.dataHVACVarRefFlow->VRF(VRFCond).DefrostCapacity = DefrostCapacityDes;
8653 15 : BaseSizer::reportSizerOutput(state,
8654 15 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8655 5 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8656 : "Design Size Resistive Defrost Heater Capacity [W]",
8657 : DefrostCapacityDes);
8658 : } else {
8659 6 : if (state.dataHVACVarRefFlow->VRF(VRFCond).DefrostCapacity > 0.0 && DefrostCapacityDes > 0.0) {
8660 0 : DefrostCapacityUser = state.dataHVACVarRefFlow->VRF(VRFCond).DefrostCapacity;
8661 0 : BaseSizer::reportSizerOutput(state,
8662 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8663 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8664 : "Design Size Resistive Defrost Heater Capacity [W]",
8665 : DefrostCapacityDes,
8666 : "User-Specified Resistive Defrost Heater Capacity",
8667 : DefrostCapacityUser);
8668 0 : if (state.dataGlobal->DisplayExtraWarnings) {
8669 0 : if ((std::abs(DefrostCapacityDes - DefrostCapacityUser) / DefrostCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8670 0 : ShowMessage(state,
8671 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8672 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8673 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8674 0 : ShowContinueError(state, format("User-Specified Resistive Defrost Heater Capacity of {:.2R} [W]", DefrostCapacityUser));
8675 0 : ShowContinueError(state,
8676 0 : format("differs from Design Size Resistive Defrost Heater Capacity of {:.2R} [W]", DefrostCapacityDes));
8677 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8678 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8679 : }
8680 : }
8681 : }
8682 : }
8683 :
8684 11 : IsAutoSize = false;
8685 11 : if (state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondAirVolFlowRate == AutoSize) {
8686 0 : IsAutoSize = true;
8687 : }
8688 : // Auto-size condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
8689 11 : EvapCondAirVolFlowRateDes = state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity * 0.000114;
8690 11 : if (IsAutoSize) {
8691 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondAirVolFlowRate = EvapCondAirVolFlowRateDes;
8692 0 : BaseSizer::reportSizerOutput(state,
8693 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8694 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8695 : "Design Size Evaporative Condenser Air Flow Rate [m3/s]",
8696 : EvapCondAirVolFlowRateDes);
8697 : } else {
8698 11 : if (state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondAirVolFlowRate > 0.0 && EvapCondAirVolFlowRateDes > 0.0) {
8699 0 : EvapCondAirVolFlowRateUser = state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondAirVolFlowRate;
8700 0 : BaseSizer::reportSizerOutput(state,
8701 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8702 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8703 : "Design Size Evaporative Condenser Air Flow Rate [m3/s]",
8704 : EvapCondAirVolFlowRateDes,
8705 : "User-Specified Evaporative Condenser Air Flow Rate [m3/s]",
8706 : EvapCondAirVolFlowRateUser);
8707 0 : if (state.dataGlobal->DisplayExtraWarnings) {
8708 0 : if ((std::abs(EvapCondAirVolFlowRateDes - EvapCondAirVolFlowRateUser) / EvapCondAirVolFlowRateUser) >
8709 0 : state.dataSize->AutoVsHardSizingThreshold) {
8710 0 : ShowMessage(state,
8711 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8712 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8713 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8714 0 : ShowContinueError(
8715 0 : state, format("User-Specified Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", EvapCondAirVolFlowRateUser));
8716 0 : ShowContinueError(
8717 : state,
8718 0 : format("differs from Design Size Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", EvapCondAirVolFlowRateDes));
8719 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8720 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8721 : }
8722 : }
8723 : }
8724 : }
8725 :
8726 11 : IsAutoSize = false;
8727 11 : if (state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondPumpPower == AutoSize) {
8728 0 : IsAutoSize = true;
8729 : }
8730 : // Auto-size evap condenser pump power to Total Capacity * 0.004266 w/w (15 w/ton)
8731 11 : EvapCondPumpPowerDes = state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity * 0.004266;
8732 11 : if (IsAutoSize) {
8733 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondPumpPower = EvapCondPumpPowerDes;
8734 0 : BaseSizer::reportSizerOutput(state,
8735 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8736 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8737 : "Design Size Evaporative Condenser Pump Rated Power Consumption [W]",
8738 : EvapCondPumpPowerDes);
8739 :
8740 : } else {
8741 11 : if (state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondPumpPower > 0.0 && EvapCondPumpPowerDes > 0.0) {
8742 0 : EvapCondPumpPowerUser = state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondPumpPower;
8743 0 : BaseSizer::reportSizerOutput(state,
8744 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8745 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8746 : "Design Size Evaporative Condenser Pump Rated Power Consumption [W]",
8747 : EvapCondPumpPowerDes,
8748 : "User-Specified Evaporative Condenser Pump Rated Power Consumption [W]",
8749 : EvapCondPumpPowerUser);
8750 0 : if (state.dataGlobal->DisplayExtraWarnings) {
8751 0 : if ((std::abs(EvapCondPumpPowerDes - EvapCondPumpPowerUser) / EvapCondPumpPowerUser) >
8752 0 : state.dataSize->AutoVsHardSizingThreshold) {
8753 0 : ShowMessage(state,
8754 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8755 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8756 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8757 0 : ShowContinueError(
8758 : state,
8759 0 : format("User-Specified Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]", EvapCondPumpPowerUser));
8760 0 : ShowContinueError(state,
8761 0 : format("differs from Design Size Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]",
8762 : EvapCondPumpPowerDes));
8763 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8764 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8765 : }
8766 : }
8767 : }
8768 : }
8769 :
8770 : // Report to eio other information not related to autosizing
8771 11 : if (state.dataHVACVarRefFlow->MyOneTimeEIOFlag) {
8772 : static constexpr std::string_view Format_990(
8773 : "! <VRF System Information>, VRF System Type, VRF System Name, VRF System Cooling Combination Ratio, VRF "
8774 : "System Heating Combination Ratio, VRF System Cooling Piping Correction Factor, VRF System Heating Piping "
8775 : "Correction Factor\n");
8776 11 : print(state.files.eio, Format_990);
8777 11 : state.dataHVACVarRefFlow->MyOneTimeEIOFlag = false;
8778 : }
8779 : static constexpr std::string_view Format_991(" VRF System Information, {}, {}, {:.5R}, {:.5R}, {:.5R}, {:.5R}\n");
8780 11 : print(state.files.eio,
8781 : Format_991,
8782 11 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8783 11 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8784 11 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCombinationRatio,
8785 11 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCombinationRatio,
8786 11 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionCooling,
8787 11 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionHeating);
8788 :
8789 11 : CheckVRFCombinationRatio(VRFCond) = false;
8790 : }
8791 : }
8792 :
8793 13 : state.dataSize->DataScalableCapSizingON = false;
8794 13 : }
8795 :
8796 6 : void initCapSizingVars(EnergyPlusData &state,
8797 : int sizingMethod,
8798 : int capSizingMethod,
8799 : int &eqSizingMethod,
8800 : Real64 scaledCapacity,
8801 : bool &modeCapacity,
8802 : Real64 &designLoad,
8803 : bool &scalableCapSizingOn,
8804 : Real64 &fracOfAutosizedCapacity)
8805 : {
8806 : using namespace DataSizing;
8807 : using HVAC::CoolingCapacitySizing;
8808 : using HVAC::HeatingCapacitySizing;
8809 :
8810 6 : eqSizingMethod = capSizingMethod;
8811 6 : if (capSizingMethod == CoolingDesignCapacity || capSizingMethod == HeatingDesignCapacity || capSizingMethod == CapacityPerFloorArea ||
8812 2 : capSizingMethod == FractionOfAutosizedCoolingCapacity || capSizingMethod == FractionOfAutosizedHeatingCapacity) {
8813 5 : if ((capSizingMethod == CoolingDesignCapacity && sizingMethod == CoolingCapacitySizing) ||
8814 1 : (capSizingMethod == HeatingDesignCapacity && sizingMethod == HeatingCapacitySizing)) {
8815 2 : if (scaledCapacity > 0.0) {
8816 2 : modeCapacity = true;
8817 2 : designLoad = scaledCapacity;
8818 : }
8819 3 : } else if (capSizingMethod == CapacityPerFloorArea) {
8820 1 : modeCapacity = true;
8821 1 : designLoad = scaledCapacity * state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
8822 1 : scalableCapSizingOn = true;
8823 2 : } else if ((capSizingMethod == FractionOfAutosizedCoolingCapacity && sizingMethod == CoolingCapacitySizing) ||
8824 1 : (capSizingMethod == FractionOfAutosizedHeatingCapacity && sizingMethod == HeatingCapacitySizing)) {
8825 2 : fracOfAutosizedCapacity = scaledCapacity;
8826 2 : scalableCapSizingOn = true;
8827 : }
8828 : }
8829 6 : }
8830 :
8831 1 : void VRFCondenserEquipment::SizeVRFCondenser(EnergyPlusData &state)
8832 : {
8833 :
8834 : // SUBROUTINE INFORMATION:
8835 : // AUTHOR Richard Raustad, FSEC
8836 : // DATE WRITTEN August 2012
8837 : // MODIFIED na
8838 : // RE-ENGINEERED na
8839 :
8840 : // PURPOSE OF THIS SUBROUTINE:
8841 : // This subroutine is for sizing VRF Condenser.
8842 :
8843 : // METHODOLOGY EMPLOYED:
8844 : // Set water-cooled plant flow rates.
8845 :
8846 : static constexpr std::string_view RoutineName("SizeVRFCondenser");
8847 :
8848 : Real64 rho; // local fluid density [kg/m3]
8849 : Real64 Cp; // local fluid specific heat [J/kg-k]
8850 : Real64 tmpCondVolFlowRate; // local condenser design volume flow rate [m3/s]
8851 :
8852 : // save the design water flow rate for use by the water loop sizing algorithms
8853 1 : if (this->CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
8854 :
8855 1 : bool ErrorsFound = false;
8856 1 : if (this->WaterCondVolFlowRate == DataSizing::AutoSize) {
8857 1 : int PltSizCondNum = 0;
8858 1 : if (this->SourcePlantLoc.loopNum > 0) PltSizCondNum = state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).PlantSizNum;
8859 1 : if (PltSizCondNum > 0) {
8860 1 : rho = state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum)
8861 1 : .glycol->getDensity(state, state.dataSize->PlantSizData(PltSizCondNum).ExitTemp, RoutineName);
8862 :
8863 1 : Cp = state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum)
8864 1 : .glycol->getSpecificHeat(state, state.dataSize->PlantSizData(PltSizCondNum).ExitTemp, RoutineName);
8865 1 : tmpCondVolFlowRate =
8866 1 : max(this->CoolingCapacity, this->HeatingCapacity) / (state.dataSize->PlantSizData(PltSizCondNum).DeltaT * Cp * rho);
8867 1 : if (this->HeatingCapacity != DataSizing::AutoSize && this->CoolingCapacity != DataSizing::AutoSize) {
8868 1 : this->WaterCondVolFlowRate = tmpCondVolFlowRate;
8869 1 : BaseSizer::reportSizerOutput(state,
8870 : "AirConditioner:VariableRefrigerantFlow",
8871 : this->Name,
8872 : "Design Condenser Water Flow Rate [m3/s]",
8873 : this->WaterCondVolFlowRate);
8874 : }
8875 :
8876 1 : rho = state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
8877 1 : this->WaterCondenserDesignMassFlow = this->WaterCondVolFlowRate * rho;
8878 1 : PlantUtilities::InitComponentNodes(
8879 : state, 0.0, this->WaterCondenserDesignMassFlow, this->CondenserNodeNum, this->CondenserOutletNodeNum);
8880 :
8881 : } else {
8882 0 : ShowSevereError(state, "Autosizing of condenser water flow rate requires a condenser loop Sizing:Plant object");
8883 0 : ShowContinueError(state, format("... occurs in AirConditioner:VariableRefrigerantFlow object={}", this->Name));
8884 0 : ShowContinueError(state, "... plant loop name must be referenced in Sizing:Plant object");
8885 0 : ErrorsFound = true;
8886 : }
8887 : }
8888 :
8889 1 : if (ErrorsFound) {
8890 0 : ShowFatalError(state, "Preceding sizing errors cause program termination");
8891 : }
8892 :
8893 1 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->CondenserNodeNum, this->WaterCondVolFlowRate);
8894 : }
8895 1 : }
8896 :
8897 7118 : void SimVRF(EnergyPlusData &state,
8898 : int const VRFTUNum,
8899 : bool const FirstHVACIteration,
8900 : Real64 &OnOffAirFlowRatio,
8901 : Real64 &SysOutputProvided,
8902 : Real64 &LatOutputProvided,
8903 : Real64 const QZnReq)
8904 : {
8905 :
8906 : // SUBROUTINE INFORMATION:
8907 : // AUTHOR Richard Raustad, FSEC
8908 : // DATE WRITTEN August 2010
8909 : // MODIFIED na
8910 : // RE-ENGINEERED na
8911 :
8912 : // PURPOSE OF THIS SUBROUTINE:
8913 : // This subroutine simulates the VRF TU's.
8914 :
8915 : // METHODOLOGY EMPLOYED:
8916 : // Simulate terminal unit to meet zone load.
8917 :
8918 7118 : Real64 PartLoadRatio(1.0);
8919 7118 : Real64 SuppHeatCoilLoad(0.0); // supplemental heating coil load (W)
8920 :
8921 7118 : if (state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
8922 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
8923 2378 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ControlVRF_FluidTCtrl(
8924 : state, VRFTUNum, QZnReq, FirstHVACIteration, PartLoadRatio, OnOffAirFlowRatio, SuppHeatCoilLoad);
8925 2378 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
8926 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, SysOutputProvided, OnOffAirFlowRatio, SuppHeatCoilLoad, LatOutputProvided);
8927 2378 : if (PartLoadRatio ==
8928 : 0.0) { // set coil inlet conditions when coil does not operate. Inlet conditions are set in ControlVRF_FluidTCtrl when PLR=1
8929 44 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingCoilPresent) {
8930 44 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coilInNodeT =
8931 44 : state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolCoilIndex).AirInNode).Temp;
8932 44 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coilInNodeW =
8933 44 : state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolCoilIndex).AirInNode).HumRat;
8934 : } else {
8935 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coilInNodeT =
8936 0 : state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatCoilIndex).AirInNode).Temp;
8937 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coilInNodeW =
8938 0 : state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatCoilIndex).AirInNode).HumRat;
8939 : }
8940 : }
8941 : // CalcVRF( VRFTUNum, FirstHVACIteration, PartLoadRatio, SysOutputProvided, OnOffAirFlowRatio, LatOutputProvided );
8942 : } else {
8943 : // Algorithm Type: VRF model based on system curve
8944 4740 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ControlVRF(
8945 : state, VRFTUNum, QZnReq, FirstHVACIteration, PartLoadRatio, OnOffAirFlowRatio, SuppHeatCoilLoad);
8946 4740 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
8947 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, SysOutputProvided, OnOffAirFlowRatio, SuppHeatCoilLoad, LatOutputProvided);
8948 : }
8949 :
8950 7118 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TerminalUnitSensibleRate = SysOutputProvided;
8951 7118 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TerminalUnitLatentRate = LatOutputProvided;
8952 7118 : }
8953 :
8954 4740 : void VRFTerminalUnitEquipment::ControlVRF(EnergyPlusData &state,
8955 : int const VRFTUNum, // Index to VRF terminal unit
8956 : Real64 const QZnReq, // Index to zone number
8957 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
8958 : Real64 &PartLoadRatio, // unit part load ratio
8959 : Real64 &OnOffAirFlowRatio, // ratio of compressor ON airflow to AVERAGE airflow over timestep
8960 : Real64 &SuppHeatCoilLoad // supplemental heating coil load (W)
8961 : )
8962 : {
8963 :
8964 : // SUBROUTINE INFORMATION:
8965 : // AUTHOR Richard Raustad
8966 : // DATE WRITTEN July 2005
8967 :
8968 : // PURPOSE OF THIS SUBROUTINE:
8969 : // Determine the part load fraction of the heat pump for this time step.
8970 :
8971 : // METHODOLOGY EMPLOYED:
8972 : // Use RegulaFalsi technique to iterate on part-load ratio until convergence is achieved.
8973 :
8974 4740 : PartLoadRatio = 0.0;
8975 4740 : state.dataHVACVarRefFlow->LoopDXCoolCoilRTF = 0.0;
8976 4740 : state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = 0.0;
8977 4740 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatPartLoadRatio = 0.0;
8978 :
8979 : // The RETURNS here will jump back to SimVRF where the CalcVRF routine will simulate with latest PLR
8980 :
8981 : // do nothing else if TU is scheduled off
8982 4740 : if (this->availSched->getCurrentVal() == 0.0) return;
8983 :
8984 : // do nothing if TU has no load (TU will be modeled using PLR=0)
8985 4740 : if (QZnReq == 0.0) return;
8986 :
8987 : // Set EMS value for PLR and return
8988 4659 : if (this->EMSOverridePartLoadFrac) {
8989 0 : PartLoadRatio = this->EMSValueForPartLoadFrac;
8990 0 : return;
8991 : }
8992 :
8993 : // Get result when DX coil is operating at the minimum PLR (1E-20) if not otherwise specified
8994 4659 : PartLoadRatio = this->MinOperatingPLR;
8995 :
8996 4659 : this->ControlVRFToLoad(state, VRFTUNum, QZnReq, FirstHVACIteration, PartLoadRatio, OnOffAirFlowRatio, SuppHeatCoilLoad);
8997 : }
8998 :
8999 4659 : void VRFTerminalUnitEquipment::ControlVRFToLoad(EnergyPlusData &state,
9000 : int const VRFTUNum,
9001 : Real64 const QZnReq,
9002 : bool const FirstHVACIteration,
9003 : Real64 &PartLoadRatio,
9004 : Real64 &OnOffAirFlowRatio,
9005 : Real64 &SuppHeatCoilLoad)
9006 : {
9007 :
9008 4659 : int constexpr MaxIte(500); // maximum number of iterations
9009 4659 : Real64 constexpr MinPLF(0.0); // minimum part load factor allowed
9010 4659 : Real64 constexpr ErrorTol(0.001); // tolerance for RegulaFalsi iterations
9011 :
9012 4659 : int VRFCond = this->VRFSysNum;
9013 4659 : Real64 FullOutput = 0.0; // unit full output when compressor is operating [W]
9014 4659 : Real64 TempOutput = 0.0; // unit output when iteration limit exceeded [W]
9015 4659 : Real64 TempMinPLR = 0.0; // min PLR used in Regula Falsi call
9016 4659 : Real64 TempMaxPLR = 0.0; // max PLR used in Regula Falsi call
9017 4659 : Real64 NoCompOutput = 0.0; // output when no active compressor [W]
9018 4659 : bool VRFCoolingMode = state.dataHVACVarRefFlow->CoolingLoad(VRFCond);
9019 4659 : bool VRFHeatingMode = state.dataHVACVarRefFlow->HeatingLoad(VRFCond);
9020 4659 : int IndexToTUInTUList = this->IndexToTUInTUList;
9021 4659 : auto &thisVRFCond = state.dataHVACVarRefFlow->VRF(VRFCond);
9022 4659 : int TUListIndex = thisVRFCond.ZoneTUListPtr;
9023 4659 : bool HRCoolingMode = state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList);
9024 4659 : bool HRHeatingMode = state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList);
9025 4659 : auto &thisVRFTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
9026 :
9027 4659 : if (thisVRFCond.VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
9028 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9029 0 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, PartLoadRatio, NoCompOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9030 : } else {
9031 : // Algorithm Type: VRF model based on system curve
9032 4659 : this->CalcVRF(state, VRFTUNum, FirstHVACIteration, PartLoadRatio, NoCompOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9033 : }
9034 :
9035 4659 : bool DXCoolingCoilOprCtrl = true;
9036 :
9037 4659 : if (VRFCoolingMode && HRHeatingMode) {
9038 : // IF the system is in cooling mode, but the terminal unit requests heating (heat recovery)
9039 0 : if (NoCompOutput >= QZnReq) {
9040 0 : PartLoadRatio = 0.0;
9041 16 : return;
9042 : }
9043 4659 : } else if (VRFHeatingMode && HRCoolingMode) {
9044 : // IF the system is in heating mode, but the terminal unit requests cooling (heat recovery)
9045 0 : if (NoCompOutput <= QZnReq) {
9046 0 : PartLoadRatio = 0.0;
9047 0 : return;
9048 : }
9049 4659 : } else if (VRFCoolingMode || HRCoolingMode) {
9050 : // IF the system is in cooling mode and/or the terminal unit requests cooling
9051 2316 : if (NoCompOutput <= QZnReq) {
9052 0 : DXCoolingCoilOprCtrl = false;
9053 0 : if (!this->SuppHeatingCoilPresent || HRCoolingMode) {
9054 0 : PartLoadRatio = 0.0;
9055 0 : return;
9056 : }
9057 : }
9058 2343 : } else if (VRFHeatingMode || HRHeatingMode) {
9059 : // IF the system is in heating mode and/or the terminal unit requests heating
9060 2333 : if (NoCompOutput >= QZnReq) {
9061 1 : PartLoadRatio = 0.0;
9062 1 : return;
9063 : }
9064 : }
9065 :
9066 : // Otherwise the coil needs to turn on. Get full load result
9067 4658 : PartLoadRatio = 1.0;
9068 4658 : if (!DXCoolingCoilOprCtrl) PartLoadRatio = 0.0;
9069 4658 : if (thisVRFCond.VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
9070 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9071 0 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, PartLoadRatio, FullOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9072 : } else {
9073 : // Algorithm Type: VRF model based on system curve
9074 4658 : if (this->NumOfSpeedHeating > 0 && VRFHeatingMode) {
9075 2324 : this->SpeedNum = this->NumOfSpeedHeating;
9076 2324 : this->SpeedRatio = 1.0;
9077 2324 : this->CycRatio = 1.0;
9078 : }
9079 4658 : if (this->NumOfSpeedCooling > 0 && VRFCoolingMode) {
9080 2308 : this->SpeedNum = this->NumOfSpeedCooling;
9081 2308 : this->SpeedRatio = 1.0;
9082 2308 : this->CycRatio = 1.0;
9083 : }
9084 4658 : this->CalcVRF(state, VRFTUNum, FirstHVACIteration, PartLoadRatio, FullOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9085 : }
9086 :
9087 : // set supplemental heating coil calculation if the condition requires
9088 4658 : if (this->SuppHeatingCoilPresent) {
9089 0 : if (this->isSetPointControlled) {
9090 0 : auto const &thisSuppHeatCoilAirInletNode = state.dataLoopNodes->Node(this->SuppHeatCoilAirInletNode);
9091 0 : if (this->suppTempSetPoint > thisSuppHeatCoilAirInletNode.Temp) {
9092 0 : Real64 mDot = thisSuppHeatCoilAirInletNode.MassFlowRate;
9093 0 : Real64 Tin = thisSuppHeatCoilAirInletNode.Temp;
9094 0 : Real64 Win = thisSuppHeatCoilAirInletNode.HumRat;
9095 0 : Real64 CpAirIn = Psychrometrics::PsyCpAirFnW(Win);
9096 0 : SuppHeatCoilLoad = mDot * CpAirIn * (this->suppTempSetPoint - Tin);
9097 0 : this->SuppHeatingCoilLoad = SuppHeatCoilLoad;
9098 : } else {
9099 0 : SuppHeatCoilLoad = 0.0;
9100 : }
9101 : } else {
9102 : // not sure why FirstHVAC has anything to do with this but that was already here
9103 : // another branch should test removing FirstHVACIteration to get same answer each iteration
9104 0 : if (!FirstHVACIteration &&
9105 0 : ((QZnReq > HVAC::SmallLoad && QZnReq > FullOutput) || (((QZnReq - NoCompOutput) > HVAC::SmallLoad) && QZnReq <= 0.0))) {
9106 0 : Real64 ZoneLoad = 0.0;
9107 0 : Real64 LoadToHeatingSP = 0.0;
9108 0 : Real64 LoadToCoolingSP = 0.0;
9109 0 : getVRFTUZoneLoad(state, VRFTUNum, ZoneLoad, LoadToHeatingSP, LoadToCoolingSP, false);
9110 0 : if ((QZnReq - NoCompOutput) > HVAC::SmallLoad && QZnReq <= 0.0) {
9111 0 : if (LoadToHeatingSP < 0.0 && QZnReq == 0.0) {
9112 0 : SuppHeatCoilLoad = max(0.0, LoadToHeatingSP - FullOutput);
9113 : } else {
9114 0 : SuppHeatCoilLoad = max(0.0, QZnReq - FullOutput);
9115 : }
9116 0 : } else if (FullOutput < (LoadToHeatingSP - HVAC::SmallLoad) && LoadToHeatingSP > 0.0) {
9117 0 : if (QZnReq > 0.0 && (NoCompOutput - QZnReq) >= HVAC::SmallLoad) {
9118 0 : SuppHeatCoilLoad = 0.0;
9119 : } else {
9120 0 : SuppHeatCoilLoad = max(0.0, LoadToHeatingSP - FullOutput);
9121 : }
9122 : } else {
9123 0 : SuppHeatCoilLoad = 0.0;
9124 : }
9125 0 : } else {
9126 0 : SuppHeatCoilLoad = 0.0;
9127 : }
9128 : }
9129 0 : if (this->DesignSuppHeatingCapacity > 0.0) {
9130 0 : this->SuppHeatPartLoadRatio = min(1.0, SuppHeatCoilLoad / this->DesignSuppHeatingCapacity);
9131 : }
9132 : } else { // does it matter what these are if there is no supp heater?
9133 4658 : SuppHeatCoilLoad = 0.0;
9134 4658 : this->SuppHeatPartLoadRatio = 0.0;
9135 : }
9136 :
9137 4658 : if ((VRFCoolingMode && !thisVRFCond.HeatRecoveryUsed) || (thisVRFCond.HeatRecoveryUsed && HRCoolingMode)) {
9138 : // Since we are cooling, we expect FullOutput < NoCompOutput
9139 : // If the QZnReq <= FullOutput the unit needs to run full out
9140 2316 : if (QZnReq <= FullOutput) {
9141 : // if no coil present in terminal unit, no need to reset PLR?
9142 2 : if (thisVRFTU.CoolingCoilPresent && DXCoolingCoilOprCtrl) {
9143 2 : PartLoadRatio = 1.0;
9144 : // the zone set point could be exceeded if set point control is used so protect against that
9145 2 : if (this->isSetPointControlled) {
9146 0 : if (state.dataLoopNodes->Node(this->coolCoilAirOutNode).Temp > this->coilTempSetPoint) return;
9147 : } else {
9148 2 : return;
9149 : }
9150 : } else {
9151 0 : PartLoadRatio = 0.0;
9152 0 : return;
9153 : }
9154 : }
9155 2342 : } else if ((VRFHeatingMode && !thisVRFCond.HeatRecoveryUsed) || (thisVRFCond.HeatRecoveryUsed && HRHeatingMode)) {
9156 : // Since we are heating, we expect FullOutput > NoCompOutput
9157 : // If the QZnReq >= FullOutput the unit needs to run full out
9158 2332 : if (QZnReq >= FullOutput) {
9159 : // if no coil present in terminal unit, no need reset PLR?
9160 3 : if (this->HeatingCoilPresent) {
9161 3 : PartLoadRatio = 1.0;
9162 : // the zone set point could be exceeded if set point control is used so protect against that
9163 3 : if (this->isSetPointControlled) {
9164 0 : if (state.dataLoopNodes->Node(this->heatCoilAirOutNode).Temp < this->coilTempSetPoint) return;
9165 : } else {
9166 3 : return;
9167 : }
9168 : } else {
9169 0 : PartLoadRatio = 0.0;
9170 0 : return;
9171 : }
9172 : }
9173 : } else {
9174 : // VRF terminal unit is off
9175 : // shouldn't actually get here
9176 10 : PartLoadRatio = 0.0;
9177 10 : return;
9178 : }
9179 :
9180 : // The coil will not operate at PLR=0 or PLR=1, calculate the operating part-load ratio
9181 :
9182 4643 : if ((VRFHeatingMode || HRHeatingMode) || ((VRFCoolingMode && DXCoolingCoilOprCtrl) || HRCoolingMode)) {
9183 :
9184 4643 : int NumOfSpeed = 1;
9185 4643 : if (this->NumOfSpeedHeating > 1 && ((VRFHeatingMode || HRHeatingMode))) {
9186 2324 : NumOfSpeed = this->NumOfSpeedHeating;
9187 : }
9188 4643 : if (this->NumOfSpeedCooling > 1 && ((VRFCoolingMode || HRCoolingMode))) {
9189 2306 : NumOfSpeed = this->NumOfSpeedCooling;
9190 : }
9191 :
9192 5827 : for (int SpeedNum = 1; SpeedNum <= NumOfSpeed; ++SpeedNum) {
9193 :
9194 5817 : if (NumOfSpeed > 1) {
9195 5804 : this->SpeedNum = SpeedNum;
9196 5804 : this->CalcVRF(state, VRFTUNum, FirstHVACIteration, 1.0, FullOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9197 6966 : if ((VRFHeatingMode || HRHeatingMode) && QZnReq >= FullOutput) continue;
9198 5802 : if ((VRFCoolingMode || HRCoolingMode) && QZnReq <= FullOutput) continue;
9199 : }
9200 :
9201 4653 : if (SpeedNum == 1) {
9202 3479 : this->SpeedRatio = 0.0;
9203 : }
9204 4653 : int SolFla = 0; // Flag of RegulaFalsi solver
9205 24832 : auto f = [&state, VRFTUNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio](Real64 const PartLoadRatio) {
9206 20179 : Real64 QZnReqTemp = QZnReq; // denominator representing zone load (W)
9207 : Real64 ActualOutput; // delivered capacity of VRF terminal unit
9208 20179 : Real64 SuppHeatCoilLoad = 0.0;
9209 20179 : bool setPointControlled = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isSetPointControlled;
9210 20179 : Real64 nonConstOnOffAirFlowRatio = OnOffAirFlowRatio;
9211 :
9212 20179 : if (state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum).VRFAlgorithmType ==
9213 : AlgorithmType::FluidTCtrl) {
9214 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9215 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
9216 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, ActualOutput, nonConstOnOffAirFlowRatio, SuppHeatCoilLoad);
9217 : } else {
9218 : // Algorithm Type: VRF model based on system curve
9219 20179 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
9220 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, ActualOutput, nonConstOnOffAirFlowRatio, SuppHeatCoilLoad);
9221 : }
9222 :
9223 20179 : if (setPointControlled) {
9224 10 : Real64 outletNodeT = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum).Temp;
9225 10 : return (outletNodeT - state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coilTempSetPoint);
9226 : } else {
9227 20169 : if (std::abs(QZnReq) < 100.0) QZnReqTemp = sign(100.0, QZnReq);
9228 20169 : return (ActualOutput - QZnReq) / QZnReqTemp;
9229 : }
9230 4653 : };
9231 4653 : General::SolveRoot(state, ErrorTol, MaxIte, SolFla, PartLoadRatio, f, 0.0, 1.0);
9232 4653 : if (SpeedNum == 1) {
9233 3479 : if (this->NumOfSpeedCooling > 1 || this->NumOfSpeedHeating > 1) {
9234 3466 : this->CycRatio = PartLoadRatio;
9235 : }
9236 3479 : this->SpeedRatio = 0.0;
9237 4643 : if (SolFla > 0 && PartLoadRatio <= 1.0) break;
9238 : } else {
9239 1174 : this->CycRatio = 1.0;
9240 1174 : this->SpeedRatio = PartLoadRatio;
9241 1174 : if (SolFla > 0 && PartLoadRatio <= 1.0) break;
9242 : }
9243 :
9244 20 : if (SolFla == -1) {
9245 : // Very low loads may not converge quickly. Tighten PLR boundary and try again.
9246 0 : TempMaxPLR = -0.1;
9247 0 : bool ContinueIter = true;
9248 0 : while (ContinueIter && TempMaxPLR < 1.0) {
9249 0 : TempMaxPLR += 0.1;
9250 :
9251 0 : if (thisVRFCond.VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
9252 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9253 0 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, TempMaxPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9254 : } else {
9255 : // Algorithm Type: VRF model based on system curve
9256 0 : this->CalcVRF(state, VRFTUNum, FirstHVACIteration, TempMaxPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9257 : }
9258 :
9259 0 : if (VRFHeatingMode && TempOutput > QZnReq) ContinueIter = false;
9260 0 : if (VRFCoolingMode && TempOutput < QZnReq) ContinueIter = false;
9261 : }
9262 0 : TempMinPLR = TempMaxPLR;
9263 0 : ContinueIter = true;
9264 0 : while (ContinueIter && TempMinPLR > 0.0) {
9265 0 : TempMaxPLR = TempMinPLR;
9266 0 : TempMinPLR -= 0.01;
9267 :
9268 0 : if (thisVRFCond.VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
9269 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9270 0 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, TempMinPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9271 : } else {
9272 : // Algorithm Type: VRF model based on system curve
9273 0 : this->CalcVRF(state, VRFTUNum, FirstHVACIteration, TempMinPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9274 : }
9275 :
9276 0 : if (VRFHeatingMode && TempOutput < QZnReq) ContinueIter = false;
9277 0 : if (VRFCoolingMode && TempOutput > QZnReq) ContinueIter = false;
9278 : }
9279 0 : General::SolveRoot(state, ErrorTol, MaxIte, SolFla, PartLoadRatio, f, TempMinPLR, TempMaxPLR);
9280 0 : if (SolFla == -1) {
9281 0 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
9282 0 : if (this->IterLimitExceeded == 0) {
9283 0 : ShowWarningMessage(state, format("{} \"{}\"", tuTypeNames[(int)this->type], this->Name));
9284 0 : ShowContinueError(
9285 : state,
9286 0 : format(" Iteration limit exceeded calculating terminal unit part-load ratio, maximum iterations = {}", MaxIte));
9287 0 : ShowContinueErrorTimeStamp(state, format(" Part-load ratio returned = {:.3R}", PartLoadRatio));
9288 :
9289 0 : if (thisVRFCond.VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
9290 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9291 0 : this->CalcVRF_FluidTCtrl(
9292 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9293 : } else {
9294 : // Algorithm Type: VRF model based on system curve
9295 0 : this->CalcVRF(state, VRFTUNum, FirstHVACIteration, PartLoadRatio, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9296 : }
9297 :
9298 0 : ShowContinueError(state, format(" Load requested = {:.5T}, Load delivered = {:.5T}", QZnReq, TempOutput));
9299 0 : ShowRecurringWarningErrorAtEnd(state,
9300 0 : format("{} \"{}\" -- Terminal unit Iteration limit exceeded error continues...",
9301 0 : tuTypeNames[(int)this->type],
9302 0 : this->Name),
9303 0 : this->IterLimitExceeded);
9304 : } else {
9305 0 : ShowRecurringWarningErrorAtEnd(state,
9306 0 : format("{} \"{}\" -- Terminal unit Iteration limit exceeded error continues...",
9307 0 : tuTypeNames[(int)this->type],
9308 0 : this->Name),
9309 0 : this->IterLimitExceeded);
9310 : }
9311 : }
9312 0 : } else if (SolFla == -2) {
9313 0 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
9314 0 : if (thisVRFTU.FirstIterfailed == 0) {
9315 0 : ShowWarningMessage(state, format("{} \"{}\"", tuTypeNames[(int)this->type], this->Name));
9316 0 : ShowContinueError(state, "Terminal unit part-load ratio calculation failed: PLR limits of 0 to 1 exceeded");
9317 0 : ShowContinueError(state, "Please fill out a bug report and forward to the EnergyPlus support group.");
9318 0 : ShowContinueErrorTimeStamp(state, "");
9319 0 : ShowRecurringWarningErrorAtEnd(
9320 : state,
9321 0 : format("{} \"{}\" -- Terminal unit part-load ratio limits of 0 to 1 exceeded error continues...",
9322 0 : tuTypeNames[(int)this->type],
9323 0 : this->Name),
9324 0 : this->FirstIterfailed);
9325 : } else {
9326 0 : ShowRecurringWarningErrorAtEnd(
9327 : state,
9328 0 : format("{} \"{}\" -- Terminal unit part-load ratio limits of 0 to 1 exceeded error continues...",
9329 0 : tuTypeNames[(int)this->type],
9330 0 : this->Name),
9331 0 : thisVRFTU.FirstIterfailed);
9332 : }
9333 : }
9334 0 : PartLoadRatio = max(MinPLF, std::abs(QZnReq - NoCompOutput) / std::abs(FullOutput - NoCompOutput));
9335 : }
9336 20 : } else if (SolFla == -2) {
9337 20 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
9338 0 : if (thisVRFTU.FirstIterfailed == 0) {
9339 0 : ShowWarningMessage(state, format("{} \"{}\"", tuTypeNames[(int)this->type], this->Name));
9340 :
9341 0 : ShowContinueError(state, "Terminal unit part-load ratio calculation failed: PLR limits of 0 to 1 exceeded");
9342 0 : ShowContinueError(state, "Please fill out a bug report and forward to the EnergyPlus support group.");
9343 0 : ShowContinueErrorTimeStamp(state, "");
9344 0 : ShowRecurringWarningErrorAtEnd(
9345 : state,
9346 0 : format("{} \"{}\" -- Terminal unit part-load ratio limits of 0 to 1 exceeded error continues...",
9347 0 : tuTypeNames[(int)this->type],
9348 0 : " \"" + this->Name),
9349 0 : this->FirstIterfailed);
9350 : } else {
9351 0 : ShowRecurringWarningErrorAtEnd(
9352 : state,
9353 0 : format("{} \"{}\" -- Terminal unit part-load ratio limits of 0 to 1 exceeded error continues...",
9354 0 : tuTypeNames[(int)this->type],
9355 0 : this->Name),
9356 0 : this->FirstIterfailed);
9357 : }
9358 : }
9359 20 : if (FullOutput - NoCompOutput == 0.0) {
9360 0 : PartLoadRatio = 0.0;
9361 : } else {
9362 20 : PartLoadRatio = min(1.0, max(MinPLF, std::abs(QZnReq - NoCompOutput) / std::abs(FullOutput - NoCompOutput)));
9363 : }
9364 : }
9365 : }
9366 : }
9367 : }
9368 :
9369 49492 : void VRFTerminalUnitEquipment::CalcVRF(EnergyPlusData &state,
9370 : int const VRFTUNum, // Unit index in VRF terminal unit array
9371 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
9372 : Real64 const PartLoadRatio, // compressor part load fraction
9373 : Real64 &LoadMet, // load met by unit (W)
9374 : Real64 &OnOffAirFlowRatio, // ratio of ON air flow to average air flow
9375 : Real64 &SuppHeatCoilLoad, // supplemental heating coil load (W)
9376 : ObjexxFCL::Optional<Real64> LatOutputProvided // delivered latent capacity (kgWater/s)
9377 : )
9378 : {
9379 :
9380 : // SUBROUTINE INFORMATION:
9381 : // AUTHOR Richard Raustad
9382 : // DATE WRITTEN July 2005
9383 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
9384 : // RE-ENGINEERED na
9385 :
9386 : // PURPOSE OF THIS SUBROUTINE:
9387 : // Simulate the components making up the VRF terminal unit.
9388 :
9389 : // METHODOLOGY EMPLOYED:
9390 : // Simulates the unit components sequentially in the air flow direction.
9391 :
9392 : using DXCoils::SimDXCoil;
9393 : using SingleDuct::SimATMixer;
9394 : using SteamCoils::SimulateSteamCoilComponents;
9395 : using WaterCoils::SimulateWaterCoilComponents;
9396 :
9397 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9398 : int VRFTUOutletNodeNum; // TU air outlet node
9399 : int VRFTUInletNodeNum; // TU air inlet node
9400 : Real64 AirMassFlow; // total supply air mass flow [m3/s]
9401 : HVAC::FanOp fanOp; // fan operating mode, HVAC::FanOp::Cycling or HVAC::FanOp::Continuous
9402 : int VRFCond; // index to VRF condenser
9403 49492 : Real64 SpecHumOut(0.0); // specific humidity ratio at outlet node
9404 49492 : Real64 SpecHumIn(0.0); // specific humidity ratio at inlet node
9405 : int TUListIndex; // index to TU list for this VRF system
9406 : int IndexToTUInTUList; // index to TU in specific list for the VRF system
9407 : int ZoneNode; // Zone node of VRFTU is serving
9408 :
9409 49492 : VRFCond = this->VRFSysNum;
9410 49492 : TUListIndex = state.dataHVACVarRefFlow->VRF(VRFCond).ZoneTUListPtr;
9411 49492 : IndexToTUInTUList = this->IndexToTUInTUList;
9412 49492 : VRFTUOutletNodeNum = this->VRFTUOutletNodeNum;
9413 49492 : VRFTUInletNodeNum = this->VRFTUInletNodeNum;
9414 49492 : fanOp = this->fanOp;
9415 49492 : ZoneNode = this->ZoneAirNode;
9416 :
9417 : // Set inlet air mass flow rate based on PLR and compressor on/off air flow rates
9418 49492 : SetAverageAirFlow(state, VRFTUNum, PartLoadRatio, OnOffAirFlowRatio);
9419 :
9420 49492 : AirMassFlow = state.dataLoopNodes->Node(VRFTUInletNodeNum).MassFlowRate;
9421 49492 : if (this->ATMixerExists) {
9422 : // There is an air terminal mixer
9423 16 : state.dataHVACVarRefFlow->ATMixOutNode = this->ATMixerOutNode;
9424 16 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
9425 : // set the primary air inlet mass flow rate
9426 8 : state.dataLoopNodes->Node(this->ATMixerPriNode).MassFlowRate =
9427 8 : min(state.dataLoopNodes->Node(this->ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(VRFTUInletNodeNum).MassFlowRate);
9428 : // now calculate the the mixer outlet air conditions (and the secondary air inlet flow rate). The mixer outlet flow rate has already
9429 : // been set above (it is the "inlet" node flow rate)
9430 8 : SimATMixer(state, this->ATMixerName, FirstHVACIteration, this->ATMixerIndex);
9431 : }
9432 : } else {
9433 : // ATMixOutNode = 0;
9434 49476 : if (this->OAMixerUsed) MixedAir::SimOAMixer(state, this->OAMixerName, this->OAMixerIndex);
9435 : }
9436 : // if blow through, simulate fan then coils
9437 49492 : if (this->fanPlace == HVAC::FanPlace::BlowThru) {
9438 2 : if (this->fanType == HVAC::FanType::SystemModel) {
9439 0 : if (OnOffAirFlowRatio > 0.0) {
9440 0 : state.dataFans->fans(this->FanIndex)->simulate(state, FirstHVACIteration, _, _);
9441 : } else {
9442 0 : state.dataFans->fans(this->FanIndex)->simulate(state, FirstHVACIteration, _, _, PartLoadRatio);
9443 : }
9444 : } else {
9445 2 : state.dataFans->fans(this->FanIndex)->simulate(state, FirstHVACIteration, state.dataHVACVarRefFlow->FanSpeedRatio);
9446 : }
9447 : }
9448 :
9449 49492 : if (this->CoolingCoilPresent) {
9450 : // above condition for heat pump mode, below condition for heat recovery mode
9451 73069 : if ((!state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed && state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) ||
9452 23577 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
9453 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList))) {
9454 51830 : SimDXCoil(state,
9455 : "",
9456 : HVAC::CompressorOp::On,
9457 : FirstHVACIteration,
9458 25915 : this->CoolCoilIndex,
9459 : fanOp,
9460 : PartLoadRatio,
9461 : OnOffAirFlowRatio,
9462 : _,
9463 25915 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond),
9464 25915 : state.dataHVACVarRefFlow->VRF(this->VRFSysNum).VRFCondCyclingRatio);
9465 : } else { // cooling coil is off
9466 23577 : SimDXCoil(state, "", HVAC::CompressorOp::Off, FirstHVACIteration, this->CoolCoilIndex, fanOp, 0.0, OnOffAirFlowRatio);
9467 : }
9468 49492 : state.dataHVACVarRefFlow->LoopDXCoolCoilRTF = state.dataAirLoop->LoopDXCoilRTF;
9469 : } else {
9470 0 : state.dataHVACVarRefFlow->LoopDXCoolCoilRTF = 0.0;
9471 : }
9472 :
9473 49492 : if (this->HeatingCoilPresent) {
9474 : // above condition for heat pump mode, below condition for heat recovery mode
9475 80321 : if ((!state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) ||
9476 30829 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
9477 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList))) {
9478 55989 : SimDXCoil(state,
9479 : "",
9480 : HVAC::CompressorOp::Off,
9481 : FirstHVACIteration,
9482 18663 : this->HeatCoilIndex,
9483 : fanOp,
9484 : PartLoadRatio,
9485 : OnOffAirFlowRatio,
9486 : _,
9487 18663 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
9488 : } else {
9489 30829 : SimDXCoil(state, "", HVAC::CompressorOp::Off, FirstHVACIteration, this->HeatCoilIndex, fanOp, 0.0, OnOffAirFlowRatio, _);
9490 : }
9491 49492 : state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = state.dataAirLoop->LoopDXCoilRTF;
9492 : } else {
9493 0 : state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = 0.0;
9494 : }
9495 :
9496 : // if draw through, simulate coils then fan
9497 49492 : if (this->fanPlace == HVAC::FanPlace::DrawThru) {
9498 49430 : if (this->fanType == HVAC::FanType::SystemModel) {
9499 49310 : if (OnOffAirFlowRatio > 0.0) {
9500 44656 : state.dataFans->fans(this->FanIndex)->simulate(state, FirstHVACIteration, _, _);
9501 : } else {
9502 4654 : state.dataFans->fans(this->FanIndex)->simulate(state, FirstHVACIteration, _, _, PartLoadRatio);
9503 : }
9504 :
9505 : } else {
9506 120 : state.dataFans->fans(this->FanIndex)->simulate(state, FirstHVACIteration, state.dataHVACVarRefFlow->FanSpeedRatio);
9507 : }
9508 : }
9509 :
9510 : // track fan power per terminal unit for calculating COP
9511 49492 : this->FanPower = (this->FanIndex == 0) ? 0.0 : state.dataFans->fans(this->FanIndex)->totalPower;
9512 :
9513 : // run supplemental heating coil
9514 49492 : if (this->SuppHeatingCoilPresent) {
9515 0 : Real64 SuppPLR = this->SuppHeatPartLoadRatio;
9516 0 : this->CalcVRFSuppHeatingCoil(state, VRFTUNum, FirstHVACIteration, SuppPLR, SuppHeatCoilLoad);
9517 0 : if ((state.dataLoopNodes->Node(this->SuppHeatCoilAirOutletNode).Temp > this->MaxSATFromSuppHeatCoil) && SuppPLR > 0.0) {
9518 : // adjust the heating load to maximum allowed
9519 0 : Real64 MaxHeatCoilLoad = this->HeatingCoilCapacityLimit(state, this->SuppHeatCoilAirInletNode, this->MaxSATFromSuppHeatCoil);
9520 0 : this->CalcVRFSuppHeatingCoil(state, VRFTUNum, FirstHVACIteration, SuppPLR, MaxHeatCoilLoad);
9521 0 : SuppHeatCoilLoad = MaxHeatCoilLoad;
9522 : }
9523 : }
9524 :
9525 49492 : Real64 LatentLoadMet = 0.0; // latent load delivered [kgWater/s]
9526 49492 : Real64 TempOut = 0.0;
9527 49492 : Real64 TempIn = 0.0;
9528 49492 : if (this->ATMixerExists) {
9529 16 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
9530 : // Air terminal supply side mixer, calculate supply side mixer output
9531 8 : SimATMixer(state, this->ATMixerName, FirstHVACIteration, this->ATMixerIndex);
9532 8 : TempOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->ATMixOutNode).Temp;
9533 8 : SpecHumOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->ATMixOutNode).HumRat;
9534 8 : AirMassFlow = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->ATMixOutNode).MassFlowRate;
9535 : } else {
9536 : // Air terminal inlet side mixer
9537 8 : TempOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).Temp;
9538 8 : SpecHumOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).HumRat;
9539 : }
9540 16 : TempIn = state.dataLoopNodes->Node(ZoneNode).Temp;
9541 16 : SpecHumIn = state.dataLoopNodes->Node(ZoneNode).HumRat;
9542 : } else {
9543 49476 : TempOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).Temp;
9544 49476 : SpecHumOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).HumRat;
9545 49476 : if (ZoneNode > 0) {
9546 49446 : TempIn = state.dataLoopNodes->Node(ZoneNode).Temp;
9547 49446 : SpecHumIn = state.dataLoopNodes->Node(ZoneNode).HumRat;
9548 : } else {
9549 30 : TempIn = state.dataLoopNodes->Node(VRFTUInletNodeNum).Temp;
9550 30 : SpecHumIn = state.dataLoopNodes->Node(VRFTUInletNodeNum).HumRat;
9551 : }
9552 : }
9553 : // calculate sensible load met using delta enthalpy
9554 49492 : Real64 TotalOutput = AirMassFlow * (Psychrometrics::PsyHFnTdbW(TempOut, SpecHumOut) -
9555 49492 : Psychrometrics::PsyHFnTdbW(TempIn, SpecHumIn)); // total addition/removal rate, {W};
9556 49492 : LoadMet = AirMassFlow * PsyDeltaHSenFnTdb2W2Tdb1W1(TempOut, SpecHumOut, TempIn, SpecHumIn); // sensible {W}
9557 49492 : LatentLoadMet = TotalOutput - LoadMet;
9558 49492 : if (present(LatOutputProvided)) {
9559 : // CR9155 Remove specific humidity calculations
9560 4740 : LatOutputProvided = LatentLoadMet;
9561 : }
9562 49492 : }
9563 :
9564 7091 : void ReportVRFTerminalUnit(EnergyPlusData &state, int const VRFTUNum) // index to VRF terminal unit
9565 : {
9566 :
9567 : // SUBROUTINE INFORMATION:
9568 : // AUTHOR Richard Raustad, FSEC
9569 : // DATE WRITTEN August 2010
9570 : // MODIFIED na
9571 : // RE-ENGINEERED na
9572 :
9573 : // PURPOSE OF THIS SUBROUTINE:
9574 : // This subroutine updates the report variables for the VRF Terminal Units.
9575 :
9576 : using namespace DataSizing;
9577 :
9578 : Real64 TotalConditioning; // - sum of sensible and latent rates
9579 : Real64 SensibleConditioning; // - sensible rate
9580 : Real64 LatentConditioning; // - latent rate
9581 : Real64 ReportingConstant; // - used to convert watts to joules
9582 : int VRFCond; // - index to VRF condenser
9583 : int TUListIndex; // - index to terminal unit list
9584 : int IndexToTUInTUList; // - index to the TU in the list
9585 : bool HRHeatRequestFlag; // - indicates TU could be in heat mode
9586 : bool HRCoolRequestFlag; // - indicates TU could be in cool mode
9587 :
9588 7091 : VRFCond = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum;
9589 7091 : TUListIndex = state.dataHVACVarRefFlow->VRF(VRFCond).ZoneTUListPtr;
9590 7091 : IndexToTUInTUList = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).IndexToTUInTUList;
9591 7091 : HRHeatRequestFlag = state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList);
9592 7091 : HRCoolRequestFlag = state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList);
9593 7091 : ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
9594 :
9595 : // account for terminal unit parasitic On/Off power use
9596 : // account for heat recovery first since these flags will be FALSE otherwise, each TU may have different operating mode
9597 :
9598 7091 : if (HRCoolRequestFlag) {
9599 1 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingCoilPresent) {
9600 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower =
9601 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElec * state.dataHVACVarRefFlow->LoopDXCoolCoilRTF +
9602 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec * (1.0 - state.dataHVACVarRefFlow->LoopDXCoolCoilRTF);
9603 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption =
9604 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower * ReportingConstant;
9605 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower = 0.0;
9606 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption = 0.0;
9607 : } else {
9608 : // cooling parasitic power report variable is not even available when there is no cooling coil, report for heating
9609 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec;
9610 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption =
9611 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower * ReportingConstant;
9612 : }
9613 7090 : } else if (HRHeatRequestFlag) {
9614 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingCoilPresent) {
9615 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower = 0.0;
9616 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption = 0.0;
9617 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower =
9618 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElec * state.dataHVACVarRefFlow->LoopDXHeatCoilRTF +
9619 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec * (1.0 - state.dataHVACVarRefFlow->LoopDXHeatCoilRTF);
9620 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption =
9621 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower * ReportingConstant;
9622 : } else {
9623 : // heating parasitic power report variable is not even available when there is no heating coil, report for cooling
9624 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec;
9625 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption =
9626 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower * ReportingConstant;
9627 : }
9628 10700 : } else if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) ||
9629 3610 : (!state.dataHVACVarRefFlow->HeatingLoad(VRFCond) &&
9630 125 : state.dataHVACVarRefFlow->LastModeCooling(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum))) {
9631 3516 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingCoilPresent) {
9632 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower =
9633 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElec * state.dataHVACVarRefFlow->LoopDXCoolCoilRTF +
9634 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec * (1.0 - state.dataHVACVarRefFlow->LoopDXCoolCoilRTF);
9635 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption =
9636 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower * ReportingConstant;
9637 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower = 0.0;
9638 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption = 0.0;
9639 : } else {
9640 : // cooling parasitic power report variable is not even available when there is no cooling coil, report for heating
9641 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec;
9642 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption =
9643 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower * ReportingConstant;
9644 : }
9645 3663 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) ||
9646 89 : (!state.dataHVACVarRefFlow->CoolingLoad(VRFCond) &&
9647 89 : state.dataHVACVarRefFlow->LastModeHeating(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum))) {
9648 3574 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingCoilPresent) {
9649 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower = 0.0;
9650 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption = 0.0;
9651 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower =
9652 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElec * state.dataHVACVarRefFlow->LoopDXHeatCoilRTF +
9653 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec * (1.0 - state.dataHVACVarRefFlow->LoopDXHeatCoilRTF);
9654 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption =
9655 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower * ReportingConstant;
9656 : } else {
9657 : // heating parasitic power report variable is not even available when there is no heating coil, report for cooling
9658 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec;
9659 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption =
9660 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower * ReportingConstant;
9661 : }
9662 : } else {
9663 : // happens when there is no cooling or heating load
9664 0 : if (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingCoilPresent) {
9665 : // report all for heating
9666 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec;
9667 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption =
9668 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower * ReportingConstant;
9669 0 : } else if (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingCoilPresent) {
9670 : // report all for cooling
9671 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec;
9672 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption =
9673 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower * ReportingConstant;
9674 : } else {
9675 : // split parasitic between both reporting variables
9676 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec / 2.0;
9677 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption =
9678 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower * ReportingConstant;
9679 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec / 2.0;
9680 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption =
9681 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower * ReportingConstant;
9682 : }
9683 : }
9684 :
9685 7091 : SensibleConditioning = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TerminalUnitSensibleRate;
9686 7091 : LatentConditioning = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TerminalUnitLatentRate;
9687 7091 : Real64 TempOut = 0.0;
9688 7091 : Real64 TempIn = 0.0;
9689 7091 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists) {
9690 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerType == HVAC::MixerType::SupplySide) {
9691 : // Air terminal supply side mixer
9692 0 : TempOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerOutNode).Temp;
9693 0 : TempIn = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneAirNode).Temp;
9694 : } else {
9695 : // Air terminal inlet side mixer
9696 0 : TempOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum).Temp;
9697 0 : TempIn = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneAirNode).Temp;
9698 : }
9699 : } else {
9700 7091 : TempOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum).Temp;
9701 7091 : TempIn = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum).Temp;
9702 : }
9703 7091 : TotalConditioning = SensibleConditioning + LatentConditioning;
9704 :
9705 7091 : if (TotalConditioning <= 0.0) {
9706 3567 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalCoolingRate = std::abs(TotalConditioning);
9707 3567 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalHeatingRate = 0.0;
9708 : } else {
9709 3524 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalCoolingRate = 0.0;
9710 3524 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalHeatingRate = TotalConditioning;
9711 : }
9712 7091 : if (SensibleConditioning <= 0.0) {
9713 3568 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleCoolingRate = std::abs(SensibleConditioning);
9714 3568 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleHeatingRate = 0.0;
9715 : } else {
9716 3523 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleCoolingRate = 0.0;
9717 3523 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleHeatingRate = SensibleConditioning;
9718 : }
9719 7091 : if (LatentConditioning <= 0.0) {
9720 4426 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentCoolingRate = std::abs(LatentConditioning);
9721 4426 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentHeatingRate = 0.0;
9722 : } else {
9723 2665 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentCoolingRate = 0.0;
9724 2665 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentHeatingRate = LatentConditioning;
9725 : }
9726 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalCoolingEnergy = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalCoolingRate * ReportingConstant;
9727 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleCoolingEnergy =
9728 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleCoolingRate * ReportingConstant;
9729 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentCoolingEnergy = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentCoolingRate * ReportingConstant;
9730 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalHeatingEnergy = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalHeatingRate * ReportingConstant;
9731 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleHeatingEnergy =
9732 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleHeatingRate * ReportingConstant;
9733 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentHeatingEnergy = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentHeatingRate * ReportingConstant;
9734 :
9735 7091 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).firstPass) {
9736 15 : if (!state.dataHVACVarRefFlow->MySizeFlag(VRFTUNum)) {
9737 12 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, 0, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).firstPass);
9738 : }
9739 : }
9740 :
9741 : // reset to 1 in case blow through fan configuration (fan resets to 1, but for blow thru fans coil sets back down < 1)
9742 7091 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
9743 7091 : }
9744 :
9745 7087 : void ReportVRFCondenser(EnergyPlusData &state, int const VRFCond) // index to VRF condensing unit
9746 : {
9747 :
9748 : // SUBROUTINE INFORMATION:
9749 : // AUTHOR Richard Raustad, FSEC
9750 : // DATE WRITTEN August 2010
9751 : // MODIFIED na
9752 : // RE-ENGINEERED na
9753 :
9754 : // PURPOSE OF THIS SUBROUTINE:
9755 : // This subroutine updates the report variables for the VRF Condenser.
9756 :
9757 : Real64 ReportingConstant; // - conversion constant for energy
9758 :
9759 7087 : ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
9760 :
9761 : // calculate VRF condenser power/energy use
9762 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolElecConsumption = state.dataHVACVarRefFlow->VRF(VRFCond).ElecCoolingPower * ReportingConstant;
9763 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatElecConsumption = state.dataHVACVarRefFlow->VRF(VRFCond).ElecHeatingPower * ReportingConstant;
9764 :
9765 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).DefrostConsumption = state.dataHVACVarRefFlow->VRF(VRFCond).DefrostPower * ReportingConstant;
9766 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).BasinHeaterConsumption = state.dataHVACVarRefFlow->VRF(VRFCond).BasinHeaterPower * ReportingConstant;
9767 :
9768 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondPumpElecConsumption =
9769 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondPumpElecPower * ReportingConstant;
9770 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).CrankCaseHeaterElecConsumption =
9771 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).CrankCaseHeaterPower * ReportingConstant;
9772 :
9773 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).QCondEnergy = state.dataHVACVarRefFlow->VRF(VRFCond).QCondenser * ReportingConstant;
9774 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).VRFHeatEnergyRec = state.dataHVACVarRefFlow->VRF(VRFCond).VRFHeatRec * ReportingConstant;
9775 7087 : }
9776 :
9777 5 : void UpdateVRFCondenser(EnergyPlusData &state, int const VRFCond) // index to VRF condensing unit
9778 : {
9779 :
9780 : // SUBROUTINE INFORMATION:
9781 : // AUTHOR Richard Raustad, FSEC
9782 : // DATE WRITTEN May 2012
9783 : // MODIFIED na
9784 : // RE-ENGINEERED na
9785 :
9786 : // PURPOSE OF THIS SUBROUTINE:
9787 : // This subroutine updates the node data for the VRF Condenser.
9788 :
9789 : int CondenserOutletNode; // - outlet node for VRF water-cooled condenser
9790 :
9791 5 : CondenserOutletNode = state.dataHVACVarRefFlow->VRF(VRFCond).CondenserOutletNodeNum;
9792 :
9793 5 : state.dataLoopNodes->Node(CondenserOutletNode).Temp = state.dataHVACVarRefFlow->VRF(VRFCond).CondenserSideOutletTemp;
9794 :
9795 5 : state.dataLoopNodes->Node(CondenserOutletNode).MassFlowRate = state.dataHVACVarRefFlow->CondenserWaterMassFlowRate;
9796 5 : state.dataLoopNodes->Node(CondenserOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(CondenserOutletNode).MassFlowRateMaxAvail;
9797 5 : state.dataLoopNodes->Node(CondenserOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(CondenserOutletNode).MassFlowRateMinAvail;
9798 5 : }
9799 :
9800 0 : void isVRFCoilPresent(EnergyPlusData &state, std::string_view VRFTUName, bool &CoolCoilPresent, bool &HeatCoilPresent)
9801 : {
9802 :
9803 0 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
9804 0 : GetVRFInput(state);
9805 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
9806 : }
9807 :
9808 : int WhichVRFTU =
9809 0 : Util::FindItemInList(VRFTUName, state.dataHVACVarRefFlow->VRFTU, &VRFTerminalUnitEquipment::Name, state.dataHVACVarRefFlow->NumVRFTU);
9810 0 : if (WhichVRFTU != 0) {
9811 0 : CoolCoilPresent = state.dataHVACVarRefFlow->VRFTU(WhichVRFTU).CoolingCoilPresent;
9812 0 : HeatCoilPresent = state.dataHVACVarRefFlow->VRFTU(WhichVRFTU).HeatingCoilPresent;
9813 : } else {
9814 0 : ShowSevereError(state, format("isVRFCoilPresent: Could not find VRF TU = \"{}\"", VRFTUName));
9815 : }
9816 0 : }
9817 :
9818 : // End of Reporting subroutines for the Module
9819 : // *****************************************************************************
9820 :
9821 : // Utility subroutines for the Module
9822 :
9823 151813 : void SetAverageAirFlow(EnergyPlusData &state,
9824 : int const VRFTUNum, // Unit index
9825 : Real64 const PartLoadRatio, // unit part load ratio
9826 : Real64 &OnOffAirFlowRatio // ratio of compressor ON airflow to average airflow over timestep
9827 : )
9828 : {
9829 :
9830 : // SUBROUTINE INFORMATION:
9831 : // AUTHOR Richard Raustad
9832 : // DATE WRITTEN August 2010
9833 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
9834 : // RE-ENGINEERED na
9835 :
9836 : // PURPOSE OF THIS SUBROUTINE:
9837 : // Set the average air mass flow rates using the part load fraction of the heat pump for this time step
9838 : // Set OnOffAirFlowRatio to be used by DX coils
9839 151813 : auto &s_vrf = state.dataHVACVarRefFlow;
9840 151813 : auto &vrfTu = s_vrf->VRFTU(VRFTUNum);
9841 :
9842 : int InletNode; // inlet node number
9843 : int OutsideAirNode; // outside air node number
9844 : int AirRelNode; // relief air node number
9845 151813 : Real64 AverageUnitMassFlow(0.0); // average supply air mass flow rate over time step
9846 151813 : Real64 AverageOAMassFlow(0.0); // average outdoor air mass flow rate over time step
9847 :
9848 151813 : InletNode = vrfTu.VRFTUInletNodeNum;
9849 151813 : OutsideAirNode = vrfTu.VRFTUOAMixerOANodeNum;
9850 151813 : AirRelNode = vrfTu.VRFTUOAMixerRelNodeNum;
9851 :
9852 151813 : if (vrfTu.fanOp == HVAC::FanOp::Cycling && vrfTu.SpeedNum == 0) {
9853 97646 : Real64 partLoadRat = PartLoadRatio;
9854 97646 : if (partLoadRat == 0.0 && vrfTu.SuppHeatPartLoadRatio > 0.0) {
9855 2 : partLoadRat = vrfTu.SuppHeatPartLoadRatio;
9856 : }
9857 97646 : AverageUnitMassFlow = (partLoadRat * s_vrf->CompOnMassFlow) + ((1 - partLoadRat) * s_vrf->CompOffMassFlow);
9858 97646 : AverageOAMassFlow = (partLoadRat * s_vrf->OACompOnMassFlow) + ((1 - partLoadRat) * s_vrf->OACompOffMassFlow);
9859 151813 : } else if (vrfTu.SpeedNum == 0) {
9860 9747 : if (PartLoadRatio == 0.0) {
9861 : // set the average OA air flow to off compressor values if the compressor PartLoadRatio is zero
9862 5024 : AverageUnitMassFlow = s_vrf->CompOffMassFlow;
9863 5024 : AverageOAMassFlow = s_vrf->OACompOffMassFlow;
9864 : } else {
9865 4723 : AverageUnitMassFlow = s_vrf->CompOnMassFlow;
9866 4723 : AverageOAMassFlow = s_vrf->OACompOnMassFlow;
9867 : }
9868 44420 : } else if (vrfTu.SpeedNum == 1) {
9869 29256 : if (s_vrf->CoolingLoad(vrfTu.VRFSysNum)) {
9870 11880 : AverageUnitMassFlow = vrfTu.CoolMassFlowRate[vrfTu.SpeedNum] * PartLoadRatio + (1.0 - PartLoadRatio) * s_vrf->CompOffMassFlow;
9871 17376 : } else if (s_vrf->HeatingLoad(vrfTu.VRFSysNum)) {
9872 13916 : AverageUnitMassFlow = vrfTu.HeatMassFlowRate[vrfTu.SpeedNum] * PartLoadRatio + (1.0 - PartLoadRatio) * s_vrf->CompOffMassFlow;
9873 : }
9874 15164 : } else if (s_vrf->CoolingLoad(vrfTu.VRFSysNum)) {
9875 11626 : AverageUnitMassFlow =
9876 11626 : vrfTu.CoolMassFlowRate[vrfTu.SpeedNum] * PartLoadRatio + (1.0 - PartLoadRatio) * vrfTu.CoolMassFlowRate[vrfTu.SpeedNum - 1];
9877 3538 : } else if (s_vrf->HeatingLoad(vrfTu.VRFSysNum)) {
9878 2354 : AverageUnitMassFlow =
9879 2354 : vrfTu.HeatMassFlowRate[vrfTu.SpeedNum] * PartLoadRatio + (1.0 - PartLoadRatio) * vrfTu.HeatMassFlowRate[vrfTu.SpeedNum - 1];
9880 : }
9881 :
9882 151813 : if (vrfTu.SpeedNum == 0) {
9883 107393 : if (s_vrf->CompOffFlowRatio > 0.0) {
9884 9634 : s_vrf->FanSpeedRatio = (PartLoadRatio * s_vrf->CompOnFlowRatio) + ((1 - PartLoadRatio) * s_vrf->CompOffFlowRatio);
9885 : } else {
9886 97759 : s_vrf->FanSpeedRatio = s_vrf->CompOnFlowRatio;
9887 : }
9888 : }
9889 :
9890 : // if the terminal unit and fan are scheduled on then set flow rate
9891 303625 : if (vrfTu.availSched->getCurrentVal() > 0.0 && (vrfTu.fanAvailSched->getCurrentVal() > 0.0 || state.dataHVACGlobal->TurnFansOn) &&
9892 151812 : !state.dataHVACGlobal->TurnFansOff) {
9893 :
9894 : // so for sure OA system TUs should use inlet node flow rate, don't overwrite inlet node flow rate
9895 : // could there be a reason for air loops to use inlet node flow? Possibly when VAV TUs used?
9896 151811 : if (!vrfTu.isInOASys) state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
9897 151811 : if (!vrfTu.isInOASys) state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AverageUnitMassFlow;
9898 151811 : if (OutsideAirNode > 0) {
9899 151675 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = AverageOAMassFlow;
9900 151675 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = AverageOAMassFlow;
9901 151675 : state.dataLoopNodes->Node(AirRelNode).MassFlowRate = AverageOAMassFlow;
9902 151675 : state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = AverageOAMassFlow;
9903 : }
9904 151811 : if (AverageUnitMassFlow > 0.0) {
9905 139957 : OnOffAirFlowRatio = s_vrf->CompOnMassFlow / AverageUnitMassFlow;
9906 : } else {
9907 11854 : OnOffAirFlowRatio = 0.0;
9908 : }
9909 :
9910 : } else { // terminal unit and/or fan is off
9911 2 : if (!vrfTu.isInOASys) {
9912 2 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
9913 2 : OnOffAirFlowRatio = 0.0;
9914 : }
9915 2 : if (OutsideAirNode > 0) {
9916 2 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = 0.0;
9917 2 : state.dataLoopNodes->Node(AirRelNode).MassFlowRate = 0.0;
9918 : }
9919 : }
9920 151813 : }
9921 :
9922 7115 : void InitializeOperatingMode(EnergyPlusData &state,
9923 : bool const FirstHVACIteration, // flag for first time through HVAC systems
9924 : int const VRFCond, // Condenser Unit index
9925 : int const TUListNum, // Condenser Unit terminal unit list
9926 : Real64 &OnOffAirFlowRatio // ratio of on to off flow rate
9927 : )
9928 : {
9929 :
9930 : // SUBROUTINE INFORMATION:
9931 : // AUTHOR Richard Raustad
9932 : // DATE WRITTEN July 2012 (Moved from InitVRF)
9933 : // MODIFIED na
9934 : // RE-ENGINEERED na
9935 :
9936 : // PURPOSE OF THIS SUBROUTINE:
9937 : // Scans each zone coil and determines the load based on control
9938 : // Moved from Init to clean up and localize code segments
9939 :
9940 : Real64 ZoneDeltaT; // zone temperature difference from setpoint
9941 : Real64 SPTempHi; // thermostat setpoint high
9942 : Real64 SPTempLo; // thermostat setpoint low
9943 : int NumTU; // loop counter, number of TU's in list
9944 : Real64 ZoneLoad; // current zone load (W)
9945 : Real64 LoadToCoolingSP; // thermostat load to cooling setpoint (W)
9946 : Real64 LoadToHeatingSP; // thermostat load to heating setpoint (W)
9947 : Real64 TempOutput; // terminal unit output [W]
9948 : Real64 SuppHeatCoilLoad; // supplemental heating coil load
9949 :
9950 7115 : state.dataHVACVarRefFlow->MaxDeltaT = 0.0;
9951 7115 : state.dataHVACVarRefFlow->MinDeltaT = 0.0;
9952 7115 : state.dataHVACVarRefFlow->NumCoolingLoads = 0;
9953 7115 : state.dataHVACVarRefFlow->SumCoolingLoads = 0.0;
9954 7115 : state.dataHVACVarRefFlow->NumHeatingLoads = 0;
9955 7115 : state.dataHVACVarRefFlow->SumHeatingLoads = 0.0;
9956 7115 : SuppHeatCoilLoad = 0.0;
9957 :
9958 7115 : state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond) = 0;
9959 7115 : state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond) = 0;
9960 7115 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) = 0.0;
9961 7115 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) = 0.0;
9962 7115 : state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = 0.0;
9963 7115 : state.dataHVACVarRefFlow->MinDeltaT(VRFCond) = 0.0;
9964 7115 : ZoneDeltaT = 0.0;
9965 7115 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
9966 7115 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
9967 7115 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).CoolingCoilAvailable = false;
9968 7115 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HeatingCoilAvailable = false;
9969 : // loop through all TU's to find operating mode. Be careful not to mix loop counters with current TU/Cond index
9970 14225 : for (NumTU = 1; NumTU <= state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList; ++NumTU) {
9971 : // make sure TU's have been sized before looping through each one of them to determine operating mode
9972 7117 : if (any(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TerminalUnitNotSizedYet)) break;
9973 7110 : int TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
9974 :
9975 : // check to see if coil is present
9976 7110 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).CoolingCoilPresent(NumTU)) {
9977 : // now check to see if coil is scheduled off
9978 7110 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).coolingCoilAvailScheds(NumTU)->getCurrentVal() > 0.0) {
9979 7110 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).CoolingCoilAvailable(NumTU) = true;
9980 : }
9981 : }
9982 :
9983 : // check to see if coil is present
9984 7110 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HeatingCoilPresent(NumTU)) {
9985 : // now check to see if coil is scheduled off
9986 7110 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).heatingCoilAvailScheds(NumTU)->getCurrentVal() > 0.0) {
9987 7110 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HeatingCoilAvailable(NumTU) = true;
9988 : }
9989 : }
9990 :
9991 7110 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled) {
9992 : // set point temperature may only reside at the TU outlet node
9993 7 : Real64 coolCoilTempSetPoint = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum).TempSetPoint;
9994 7 : state.dataHVACVarRefFlow->VRFTU(TUIndex).suppTempSetPoint = coolCoilTempSetPoint;
9995 7 : Real64 heatCoilTempSetPoint = coolCoilTempSetPoint;
9996 : // adjust coil control for fan heat when set point is at outlet node
9997 7 : Real64 coolfanDeltaT = 0.0;
9998 7 : Real64 heatfanDeltaT = 0.0;
9999 7 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanPlace == HVAC::FanPlace::DrawThru) {
10000 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanOutletNode > 0)
10001 0 : coolfanDeltaT = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).fanOutletNode).Temp -
10002 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).fanInletNode).Temp;
10003 : }
10004 7 : heatfanDeltaT = coolfanDeltaT;
10005 : // or the set point could be placed at either or both coils, update both if necessary
10006 7 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolingCoilPresent) {
10007 7 : if (state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirOutNode).TempSetPoint !=
10008 : DataLoopNode::SensedNodeFlagValue) {
10009 0 : coolCoilTempSetPoint = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirOutNode).TempSetPoint;
10010 : //// should we adjust for fan heat or not? What if it's a mixed air SP that already adjusts for fan heat?
10011 : // coolfanDeltaT = 0.0;
10012 : }
10013 : }
10014 7 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatingCoilPresent) {
10015 7 : if (state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirOutNode).TempSetPoint !=
10016 : DataLoopNode::SensedNodeFlagValue) {
10017 7 : heatCoilTempSetPoint = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirOutNode).TempSetPoint;
10018 : //// should we adjust for fan heat or not? What if it's a mixed air SP that already adjusts for fan heat?
10019 : // heatfanDeltaT = 0.0;
10020 : }
10021 : }
10022 : // set a flow rate and simulate ATMixer/OASystem if needed
10023 7 : if (FirstHVACIteration) {
10024 7 : SetAverageAirFlow(state, TUIndex, 1.0, OnOffAirFlowRatio);
10025 7 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).ATMixerExists) {
10026 : // There is an air terminal mixer
10027 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).ATMixerType ==
10028 : HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
10029 : // set the primary air inlet mass flow rate
10030 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).ATMixerPriNode).MassFlowRate =
10031 0 : min(state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).ATMixerPriNode).MassFlowRateMaxAvail,
10032 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum).MassFlowRate);
10033 : // now calculate the the mixer outlet air conditions (and the secondary air inlet flow rate). The mixer outlet flow rate
10034 : // has already been set above (it is the "inlet" node flow rate)
10035 0 : SingleDuct::SimATMixer(state,
10036 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ATMixerName,
10037 : FirstHVACIteration,
10038 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ATMixerIndex);
10039 : }
10040 : } else {
10041 : // simulate OA Mixer
10042 7 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerUsed)
10043 7 : MixedAir::SimOAMixer(
10044 7 : state, state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerName, state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerIndex);
10045 : }
10046 : }
10047 : // identify a coil inlet temperature
10048 7 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolingCoilPresent) {
10049 7 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coilInNodeT =
10050 7 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirInNode).Temp;
10051 7 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coilInNodeW =
10052 7 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirInNode).HumRat;
10053 : } else {
10054 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coilInNodeT =
10055 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirInNode).Temp;
10056 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coilInNodeW =
10057 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirInNode).HumRat;
10058 : }
10059 7 : Real64 coilInletTemp = state.dataHVACVarRefFlow->VRFTU(TUIndex).coilInNodeT;
10060 7 : Real64 coilInletHumRat = state.dataHVACVarRefFlow->VRFTU(TUIndex).coilInNodeW;
10061 7 : Real64 coilInletMassFlow = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum).MassFlowRate;
10062 7 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coolSPActive = false;
10063 7 : state.dataHVACVarRefFlow->VRFTU(TUIndex).heatSPActive = false;
10064 :
10065 7 : if ((heatCoilTempSetPoint - coilInletTemp - heatfanDeltaT) > HVAC::SmallTempDiff) { // heating
10066 3 : Real64 CpAirIn = Psychrometrics::PsyCpAirFnW(coilInletHumRat);
10067 3 : ZoneLoad = coilInletMassFlow * CpAirIn * (heatCoilTempSetPoint - coilInletTemp - heatfanDeltaT);
10068 3 : state.dataHVACVarRefFlow->VRFTU(TUIndex).heatSPActive = true;
10069 3 : state.dataHVACVarRefFlow->VRFTU(TUIndex).heatLoadToSP = ZoneLoad;
10070 3 : ++state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond);
10071 3 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) += ZoneLoad;
10072 3 : state.dataHVACVarRefFlow->MinDeltaT(VRFCond) = min(state.dataHVACVarRefFlow->MinDeltaT(VRFCond), -1.0);
10073 3 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coilTempSetPoint = heatCoilTempSetPoint - heatfanDeltaT;
10074 4 : } else if ((coilInletTemp - coolCoilTempSetPoint - coolfanDeltaT) > HVAC::SmallTempDiff) { // cooling
10075 4 : Real64 CpAirIn = Psychrometrics::PsyCpAirFnW(coilInletHumRat);
10076 4 : ZoneLoad = coilInletMassFlow * CpAirIn * (coolCoilTempSetPoint - coilInletTemp - coolfanDeltaT);
10077 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coolSPActive = true;
10078 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coolLoadToSP = ZoneLoad;
10079 4 : ++state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond);
10080 4 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) += ZoneLoad;
10081 4 : state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = max(state.dataHVACVarRefFlow->MaxDeltaT(VRFCond), 1.0);
10082 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coilTempSetPoint = coolCoilTempSetPoint - coolfanDeltaT;
10083 : }
10084 : } else { // else is not set point controlled
10085 : // Constant fan systems are tested for ventilation load to determine if load to be met changes.
10086 : // more logic may be needed here, what is the OA flow rate, was last mode heating or cooling, what control is used, etc...
10087 :
10088 7103 : int ThisZoneNum = state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum;
10089 7103 : getVRFTUZoneLoad(state, TUIndex, ZoneLoad, LoadToHeatingSP, LoadToCoolingSP, true);
10090 :
10091 7103 : if (state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority == ThermostatCtrlType::ThermostatOffsetPriority) {
10092 : // for TSTATPriority, just check difference between zone temp and thermostat setpoint
10093 5 : if (ThisZoneNum > 0) {
10094 5 : auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ThisZoneNum);
10095 5 : auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ThisZoneNum);
10096 5 : SPTempHi = zoneTstatSetpt.setptHi;
10097 5 : SPTempLo = zoneTstatSetpt.setptLo;
10098 :
10099 5 : switch (state.dataHeatBalFanSys->TempControlType(ThisZoneNum)) {
10100 0 : case HVAC::SetptType::Uncontrolled:
10101 : // MaxDeltaT denotes cooling, MinDeltaT denotes heating
10102 0 : break;
10103 0 : case HVAC::SetptType::SingleHeat:
10104 : // if heating load, ZoneDeltaT will be negative
10105 0 : ZoneDeltaT = min(0.0, thisZoneHB.ZT - SPTempLo);
10106 0 : state.dataHVACVarRefFlow->MinDeltaT(VRFCond) = min(state.dataHVACVarRefFlow->MinDeltaT(VRFCond), ZoneDeltaT);
10107 0 : break;
10108 0 : case HVAC::SetptType::SingleCool:
10109 : // if cooling load, ZoneDeltaT will be positive
10110 0 : ZoneDeltaT = max(0.0, thisZoneHB.ZT - SPTempHi);
10111 0 : state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = max(state.dataHVACVarRefFlow->MaxDeltaT(VRFCond), ZoneDeltaT);
10112 0 : break;
10113 0 : case HVAC::SetptType::SingleHeatCool:
10114 0 : ZoneDeltaT = thisZoneHB.ZT - SPTempHi; //- SPTempHi and SPTempLo are same value
10115 0 : if (ZoneDeltaT > 0.0) {
10116 0 : state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = max(state.dataHVACVarRefFlow->MaxDeltaT(VRFCond), ZoneDeltaT);
10117 : } else {
10118 0 : state.dataHVACVarRefFlow->MinDeltaT(VRFCond) = min(state.dataHVACVarRefFlow->MinDeltaT(VRFCond), ZoneDeltaT);
10119 : }
10120 0 : break;
10121 5 : case HVAC::SetptType::DualHeatCool:
10122 5 : if (thisZoneHB.ZT - SPTempHi > 0.0) {
10123 1 : ZoneDeltaT = max(0.0, thisZoneHB.ZT - SPTempHi);
10124 1 : state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = max(state.dataHVACVarRefFlow->MaxDeltaT(VRFCond), ZoneDeltaT);
10125 4 : } else if (SPTempLo - thisZoneHB.ZT > 0.0) {
10126 4 : ZoneDeltaT = min(0.0, thisZoneHB.ZT - SPTempLo);
10127 4 : state.dataHVACVarRefFlow->MinDeltaT(VRFCond) = min(state.dataHVACVarRefFlow->MinDeltaT(VRFCond), ZoneDeltaT);
10128 : }
10129 5 : break;
10130 0 : default:
10131 0 : break;
10132 : }
10133 : }
10134 7098 : } else if (state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority == ThermostatCtrlType::LoadPriority ||
10135 0 : state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority == ThermostatCtrlType::ZonePriority) {
10136 7098 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanOp == HVAC::FanOp::Continuous) {
10137 4714 : SetCompFlowRate(state, TUIndex, VRFCond);
10138 :
10139 4714 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
10140 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
10141 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CalcVRF_FluidTCtrl(
10142 : state, TUIndex, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
10143 : } else {
10144 : // Algorithm Type: VRF model based on system curve
10145 4714 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CalcVRF(
10146 : state, TUIndex, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
10147 : }
10148 :
10149 : // If the Terminal Unit has a net cooling capacity (NoCompOutput < 0) and
10150 : // the zone temp is above the Tstat heating setpoint (QToHeatSetPt < 0)
10151 4714 : if (TempOutput < 0.0 && LoadToHeatingSP < 0.0) {
10152 : // If the net cooling capacity overshoots the heating setpoint count as heating load
10153 41 : if (TempOutput < LoadToHeatingSP) {
10154 : // Don't count as heating load unless mode is allowed. Also check for floating zone.
10155 8 : if (state.dataHeatBalFanSys->TempControlType(ThisZoneNum) != HVAC::SetptType::SingleCool &&
10156 4 : state.dataHeatBalFanSys->TempControlType(ThisZoneNum) != HVAC::SetptType::Uncontrolled) {
10157 4 : if (!state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
10158 : // if last mode was cooling, make sure heating flow rate is used
10159 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerUsed) {
10160 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOAMixerRetNodeNum).MassFlowRate =
10161 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).MaxHeatAirMassFlow;
10162 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOAMixerOANodeNum).MassFlowRate =
10163 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatOutAirMassFlow;
10164 0 : MixedAir::SimOAMixer(state,
10165 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerName,
10166 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerIndex);
10167 : } else {
10168 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum).MassFlowRate =
10169 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).MaxHeatAirMassFlow;
10170 : }
10171 :
10172 : // recalculate using correct flow rate
10173 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
10174 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
10175 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CalcVRF_FluidTCtrl(
10176 : state, TUIndex, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
10177 : } else {
10178 : // Algorithm Type: VRF model based on system curve
10179 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CalcVRF(
10180 : state, TUIndex, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
10181 : }
10182 :
10183 0 : if (TempOutput < LoadToHeatingSP) {
10184 0 : ++state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond);
10185 : // sum heating load on condenser, not total zone heating load
10186 0 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) += (LoadToHeatingSP - TempOutput);
10187 : }
10188 : } else {
10189 4 : ++state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond);
10190 : // sum heating load on condenser, not total zone heating load
10191 4 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) += (LoadToHeatingSP - TempOutput);
10192 : }
10193 : }
10194 37 : } else if (TempOutput < ZoneLoad) {
10195 : // If the net cooling capacity meets the zone cooling load but does not overshoot heating setpoint, turn
10196 : // off coil do nothing, the zone will float
10197 1 : } else if (ZoneLoad < 0.0) {
10198 : // still a cooling load
10199 1 : ++state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond);
10200 : // sum cooling load on condenser, not total zone cooling load
10201 1 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) += (LoadToCoolingSP - TempOutput);
10202 : }
10203 :
10204 : // If the terminal unit has a net heating capacity and the zone temp is below the Tstat cooling setpoint
10205 4673 : } else if (TempOutput > 0.0 && LoadToCoolingSP > 0.0) {
10206 : // If the net heating capacity overshoots the cooling setpoint count as cooling load
10207 34 : if (TempOutput > LoadToCoolingSP) {
10208 : // Don't count as cooling load unless mode is allowed. Also check for floating zone.
10209 12 : if (state.dataHeatBalFanSys->TempControlType(ThisZoneNum) != HVAC::SetptType::SingleHeat &&
10210 6 : state.dataHeatBalFanSys->TempControlType(ThisZoneNum) != HVAC::SetptType::Uncontrolled) {
10211 6 : if (!state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
10212 4 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerUsed) {
10213 4 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOAMixerRetNodeNum).MassFlowRate =
10214 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).MaxCoolAirMassFlow;
10215 4 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOAMixerOANodeNum).MassFlowRate =
10216 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolOutAirMassFlow;
10217 4 : MixedAir::SimOAMixer(state,
10218 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerName,
10219 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerIndex);
10220 : } else {
10221 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum).MassFlowRate =
10222 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).MaxCoolAirMassFlow;
10223 : }
10224 :
10225 4 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
10226 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
10227 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CalcVRF_FluidTCtrl(
10228 : state, TUIndex, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
10229 : } else {
10230 : // Algorithm Type: VRF model based on system curve
10231 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CalcVRF(
10232 : state, TUIndex, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
10233 : }
10234 :
10235 4 : if (TempOutput > LoadToCoolingSP) {
10236 4 : ++state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond);
10237 4 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) += (LoadToCoolingSP - TempOutput);
10238 : }
10239 : } else {
10240 2 : ++state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond);
10241 2 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) += (LoadToCoolingSP - TempOutput);
10242 : }
10243 : }
10244 28 : } else if (TempOutput > ZoneLoad) {
10245 : // do nothing, zone will float
10246 0 : } else if (ZoneLoad > 0.0) {
10247 0 : ++state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond);
10248 0 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) += ZoneLoad;
10249 : }
10250 : // ELSE there is no overshoot and the zone has a valid cooling load
10251 4639 : } else if (ZoneLoad < 0.0) {
10252 2302 : ++state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond);
10253 2302 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) += ZoneLoad;
10254 : // ELSE there is no overshoot and the zone has a valid heating load
10255 2337 : } else if (ZoneLoad > 0.0) {
10256 2322 : ++state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond);
10257 2322 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) += ZoneLoad;
10258 : }
10259 : } else { // is cycling fan
10260 2384 : if (ZoneLoad > 0.0) {
10261 1166 : ++state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond);
10262 1166 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) += ZoneLoad;
10263 1218 : } else if (ZoneLoad < 0.0) {
10264 1177 : ++state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond);
10265 1177 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) += ZoneLoad;
10266 : }
10267 : }
10268 : }
10269 : }
10270 : }
10271 :
10272 : // Determine operating mode based on VRF type and thermostat control selection
10273 7115 : switch (state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority) {
10274 5 : case ThermostatCtrlType::ThermostatOffsetPriority: {
10275 6 : if (state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) > std::abs(state.dataHVACVarRefFlow->MinDeltaT(VRFCond)) &&
10276 1 : state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) > 0.0) {
10277 1 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10278 1 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
10279 8 : } else if (state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) < std::abs(state.dataHVACVarRefFlow->MinDeltaT(VRFCond)) &&
10280 4 : state.dataHVACVarRefFlow->MinDeltaT(VRFCond) < 0.0) {
10281 4 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
10282 4 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10283 : } else {
10284 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10285 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10286 : }
10287 5 : } break;
10288 7110 : case ThermostatCtrlType::LoadPriority: {
10289 10603 : if (state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) > std::abs(state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond)) &&
10290 3493 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) > 0.0) {
10291 3493 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
10292 3493 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10293 7234 : } else if (state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) <= std::abs(state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond)) &&
10294 3617 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) < 0.0) {
10295 3489 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10296 3489 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
10297 : } else {
10298 128 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10299 128 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10300 : }
10301 7110 : } break;
10302 0 : case ThermostatCtrlType::ZonePriority: {
10303 0 : if (state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond) > state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond) &&
10304 0 : state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond) > 0) {
10305 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
10306 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10307 0 : } else if (state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond) <= state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond) &&
10308 0 : state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond) > 0) {
10309 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10310 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
10311 : } else {
10312 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10313 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10314 : }
10315 0 : } break;
10316 0 : case ThermostatCtrlType::ScheduledPriority: {
10317 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).prioritySched->getCurrentVal() == 0) {
10318 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
10319 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10320 0 : } else if (state.dataHVACVarRefFlow->VRF(VRFCond).prioritySched->getCurrentVal() == 1) {
10321 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10322 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
10323 : } else {
10324 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10325 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10326 : }
10327 0 : } break;
10328 0 : case ThermostatCtrlType::MasterThermostatPriority: {
10329 0 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZonePtr).RemainingOutputRequired /
10330 0 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex).controlZoneMassFlowFrac;
10331 0 : if (state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex).fanOp == HVAC::FanOp::Continuous) {
10332 0 : SetCompFlowRate(state, state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex, VRFCond);
10333 :
10334 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
10335 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
10336 0 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex)
10337 0 : .CalcVRF_FluidTCtrl(state,
10338 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex,
10339 : FirstHVACIteration,
10340 : 0.0,
10341 : TempOutput,
10342 : OnOffAirFlowRatio,
10343 : SuppHeatCoilLoad);
10344 : } else {
10345 : // Algorithm Type: VRF model based on system curve
10346 0 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex)
10347 0 : .CalcVRF(state,
10348 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex,
10349 : FirstHVACIteration,
10350 : 0.0,
10351 : TempOutput,
10352 : OnOffAirFlowRatio,
10353 : SuppHeatCoilLoad);
10354 : }
10355 :
10356 0 : LoadToCoolingSP =
10357 0 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZonePtr).OutputRequiredToCoolingSP /
10358 0 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex).controlZoneMassFlowFrac;
10359 0 : LoadToHeatingSP =
10360 0 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZonePtr).OutputRequiredToHeatingSP /
10361 0 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex).controlZoneMassFlowFrac;
10362 0 : if (TempOutput < LoadToHeatingSP) {
10363 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10364 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
10365 0 : } else if (TempOutput > LoadToCoolingSP) {
10366 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
10367 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10368 : } else {
10369 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10370 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10371 : }
10372 0 : } else if (ZoneLoad > 0.0) {
10373 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
10374 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10375 0 : } else if (ZoneLoad < 0.0) {
10376 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10377 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
10378 : } else {
10379 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10380 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10381 : }
10382 0 : } break;
10383 0 : case ThermostatCtrlType::FirstOnPriority: {
10384 : // na
10385 0 : } break;
10386 0 : default:
10387 0 : break;
10388 : }
10389 :
10390 : // limit to one possible mode
10391 7115 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && state.dataHVACVarRefFlow->HeatingLoad(VRFCond))
10392 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10393 7115 : }
10394 :
10395 1 : void LimitTUCapacity(EnergyPlusData &state,
10396 : int const VRFCond, // Condenser Unit index
10397 : int const NumTUInList, // Number of terminal units in list
10398 : Real64 const StartingCapacity, // temporary variable holding condenser capacity [W]
10399 : const Array1D<Real64> &CapArray, // Array of coil capacities in either cooling or heating mode [W]
10400 : Real64 &MaxLimit, // Maximum terminal unit capacity for coils in same operating mode [W]
10401 : Real64 const AltCapacity, // temporary variable holding heat recovery capacity [W]
10402 : const Array1D<Real64> &AltArray, // Array of coil capacities of heat recovery [W]
10403 : Real64 &AltLimit // Maximum terminal unit capacity of heat recovery coils [W]
10404 : )
10405 : {
10406 :
10407 : // SUBROUTINE INFORMATION:
10408 : // AUTHOR Richard Raustad
10409 : // DATE WRITTEN July 2012 (Moved from InitVRF)
10410 : // MODIFIED na
10411 : // RE-ENGINEERED na
10412 :
10413 : // PURPOSE OF THIS SUBROUTINE:
10414 : // Calculate the maximum allowed terminal unit capacity. Total terminal unit capacity must not
10415 : // exceed the available condenser capacity. This variable, MaxCapacity (passed out to MaxCoolingCapacity
10416 : // or MaxHeatingCapacity), is used to limit the terminal units providing more capacity than allowed.
10417 : // Example: TU loads are 1-ton, 2-ton, 3-ton, and 4-ton connected to a condenser having only 9-tons available.
10418 : // This variable is will be set to 3-tons and the 4-ton terminal unit will be limited to 3-tons
10419 : // (see InitVRF where this variable is reset and CalcVRF where the call to the DX coils passes this argument).
10420 :
10421 : // METHODOLOGY EMPLOYED:
10422 : // The coils are simulated and summed. This value is compared to the available capacity. If the summed
10423 : // TU capacity is greater than the available capacity, limit the TU's with the highest capacity so that
10424 : // the TU capacity equals the available capacity. The report variable Variable Refrigerant Flow Heat Pump
10425 : // Maximum Terminal Unit Cool/Heating Capacity holds the value for maximum TU capacity. This value may not
10426 : // match the maximum individual coil capacity exactly since the available capacity uses a load weighted
10427 : // average WB temperature to calculate available capacity. When the TU's are limited, this weighting changes.
10428 : // The extra iterations required for these values to converge is considered excessive.
10429 : // If the global flag SimZoneEquipment could be set for 1 additional iteration, these variables would
10430 : // converge more closely (setting this global flag is not yet implemented).
10431 :
10432 : Real64 RemainingCapacity; // decrement capacity counter to find limiting TU capacity [W]
10433 :
10434 : // limit TU coil capacity to be equal to the condenser capacity (piping losses already accounted for)
10435 1 : LimitCoilCapacity(NumTUInList, StartingCapacity, CapArray, MaxLimit);
10436 :
10437 : // ** add in logic to limit coils operating opposite to mode when heat recovery is used
10438 : // ** this is a hard one since we are here because the system is overloaded. That means
10439 : // ** that we do not know at this point the actual operating capacity or compressor power.
10440 1 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed) {
10441 0 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
10442 0 : RemainingCapacity = StartingCapacity * (1 + 1 / state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCOP);
10443 0 : if (AltCapacity > RemainingCapacity) {
10444 0 : LimitCoilCapacity(NumTUInList, RemainingCapacity, AltArray, AltLimit);
10445 : }
10446 : }
10447 0 : if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
10448 0 : RemainingCapacity = StartingCapacity / (1 + 1 / state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCOP);
10449 0 : if (AltCapacity > RemainingCapacity) {
10450 0 : LimitCoilCapacity(NumTUInList, RemainingCapacity, AltArray, AltLimit);
10451 : }
10452 : }
10453 : }
10454 1 : }
10455 :
10456 1 : void LimitCoilCapacity(int const NumTUInList, // Number of terminal units in list
10457 : Real64 const TotalCapacity, // temporary variable holding condenser capacity [W]
10458 : const Array1D<Real64> &CapArray, // Array of coil capacities in either cooling or heating mode [W]
10459 : Real64 &MaxLimit // Maximum terminal unit capacity for coils in same operating mode [W]
10460 : )
10461 : {
10462 :
10463 : // SUBROUTINE INFORMATION:
10464 : // AUTHOR Richard Raustad
10465 : // DATE WRITTEN July 2012 (Moved from InitVRF)
10466 : // MODIFIED na
10467 : // RE-ENGINEERED na
10468 :
10469 : // PURPOSE OF THIS SUBROUTINE:
10470 : // Calculate the maximum allowed terminal unit capacity. Total terminal unit capacity must not
10471 : // exceed the available condenser capacity. This variable, MaxCapacity (passed out to MaxCoolingCapacity
10472 : // or MaxHeatingCapacity), is used to limit the terminal units providing more capacity than allowed.
10473 : // Example: TU loads are 1-ton, 2-ton, 3-ton, and 4-ton connected to a condenser having only 9-tons available.
10474 : // This variable is will be set to 3-tons and the 4-ton terminal unit will be limited to 3-tons
10475 : // (see InitVRF where this variable is reset and CalcVRF where the call to the DX coils passes this argument).
10476 :
10477 : // METHODOLOGY EMPLOYED:
10478 : // The coils are simulated and summed. This value is compared to the available capacity. If the summed
10479 : // TU capacity is greater than the available capacity, limit the TU's with the highest capacity so that
10480 : // the TU capacity equals the available capacity. The report variable Variable Refrigerant Flow Heat Pump
10481 : // Maximum Terminal Unit Cool/Heating Capacity holds the value for maximum TU capacity. This value may not
10482 : // match the maximum individual coil capacity exactly since the available capacity uses a load weighted
10483 : // average WB temperature to calculate available capacity. When the TU's are limited, this weighting changes.
10484 : // The extra iterations required for these values to converge is considered excessive.
10485 : // If the global flag SimZoneEquipment could be set for 1 additional iteration, these variables would
10486 : // converge more closely (setting this global flag is not yet implemented).
10487 :
10488 : int NumTU; // loop counter
10489 : int TempTUIndex; // temp variable used to find max terminal unit limit
10490 : int MinOutputIndex; // index to TU with lowest load
10491 : Real64 MinOutput; // used when finding TU "max" capacity limit
10492 : Real64 RemainingCapacity; // decrement capacity counter to find limiting TU capacity [W]
10493 1 : Array1D<Real64> Temp(NumTUInList, CapArray); // temporary array for processing terminal units
10494 1 : Array1D<Real64> Temp2(NumTUInList, Temp); // temporary array for processing terminal units
10495 :
10496 1 : RemainingCapacity = TotalCapacity;
10497 :
10498 : // sort TU capacity from lowest to highest
10499 2 : for (TempTUIndex = 1; TempTUIndex <= NumTUInList; ++TempTUIndex) {
10500 1 : MinOutput = Constant::MaxCap;
10501 2 : for (NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
10502 1 : if (Temp2(NumTU) < MinOutput) {
10503 1 : MinOutput = Temp2(NumTU);
10504 1 : Temp(TempTUIndex) = MinOutput;
10505 1 : MinOutputIndex = NumTU;
10506 : }
10507 : }
10508 1 : Temp2(MinOutputIndex) = Constant::MaxCap;
10509 : }
10510 :
10511 : // find limit of "terminal unit" capacity so that sum of all TU's does not exceed condenser capacity
10512 : // if the terminal unit capacity multiplied by number of remaining TU's does not exceed remaining available, subtract and cycle
10513 1 : for (TempTUIndex = 1; TempTUIndex <= NumTUInList; ++TempTUIndex) {
10514 1 : if ((Temp(TempTUIndex) * (NumTUInList - TempTUIndex + 1)) < RemainingCapacity) {
10515 0 : RemainingCapacity -= Temp(TempTUIndex);
10516 0 : continue;
10517 : } else {
10518 : // if it does exceed, limit is found
10519 1 : MaxLimit = RemainingCapacity / (NumTUInList - TempTUIndex + 1);
10520 1 : break;
10521 : }
10522 : }
10523 1 : }
10524 :
10525 865 : int GetVRFTUOutAirNode(EnergyPlusData &state, int const VRFTUNum)
10526 : {
10527 :
10528 : // FUNCTION INFORMATION:
10529 : // AUTHOR R. Raustad (copy of B Griffith routine)
10530 : // DATE WRITTEN Jan 2015
10531 : // MODIFIED na
10532 : // RE-ENGINEERED na
10533 :
10534 : // PURPOSE OF THIS FUNCTION:
10535 : // lookup function for VRF terminal unit OA inlet node
10536 :
10537 865 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10538 0 : GetVRFInput(state);
10539 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10540 : }
10541 :
10542 865 : if (VRFTUNum > 0 && VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU) {
10543 865 : return state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum;
10544 : } else {
10545 0 : return 0;
10546 : }
10547 : }
10548 :
10549 872 : int GetVRFTUZoneInletAirNode(EnergyPlusData &state, int const VRFTUNum)
10550 : {
10551 :
10552 : // FUNCTION INFORMATION:
10553 : // AUTHOR R. Raustad (copy of B Griffith routine)
10554 : // DATE WRITTEN Jan 2015
10555 : // MODIFIED na
10556 : // RE-ENGINEERED na
10557 :
10558 : // PURPOSE OF THIS FUNCTION:
10559 : // lookup function for VRF terminal unit zone inlet node
10560 :
10561 872 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10562 5 : GetVRFInput(state);
10563 5 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10564 : }
10565 :
10566 872 : if (VRFTUNum > 0 && VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU) {
10567 872 : return state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum;
10568 : } else {
10569 0 : return 0;
10570 : }
10571 : }
10572 :
10573 0 : int GetVRFTUOutAirNodeFromName(EnergyPlusData &state, std::string const &VRFTUName, bool &errorsFound)
10574 : {
10575 : int NodeNum; // return value of node number
10576 :
10577 0 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10578 0 : GetVRFInput(state);
10579 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10580 : }
10581 :
10582 : int WhichVRFTU =
10583 0 : Util::FindItemInList(VRFTUName, state.dataHVACVarRefFlow->VRFTU, &VRFTerminalUnitEquipment::Name, state.dataHVACVarRefFlow->NumVRFTU);
10584 0 : if (WhichVRFTU != 0) {
10585 0 : NodeNum = state.dataHVACVarRefFlow->VRFTU(WhichVRFTU).VRFTUOutletNodeNum;
10586 : } else {
10587 0 : ShowSevereError(state, format("GetVRFTUOutAirNodeFromName: Could not find VRF TU = \"{}\"", VRFTUName));
10588 0 : errorsFound = true;
10589 0 : NodeNum = 0;
10590 : }
10591 :
10592 0 : return NodeNum;
10593 : }
10594 :
10595 0 : int GetVRFTUInAirNodeFromName(EnergyPlusData &state, std::string const &VRFTUName, bool &errorsFound)
10596 : {
10597 : int NodeNum; // return value of node number
10598 :
10599 0 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10600 0 : GetVRFInput(state);
10601 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10602 : }
10603 :
10604 : int WhichVRFTU =
10605 0 : Util::FindItemInList(VRFTUName, state.dataHVACVarRefFlow->VRFTU, &VRFTerminalUnitEquipment::Name, state.dataHVACVarRefFlow->NumVRFTU);
10606 0 : if (WhichVRFTU != 0) {
10607 0 : NodeNum = state.dataHVACVarRefFlow->VRFTU(WhichVRFTU).VRFTUInletNodeNum;
10608 : } else {
10609 0 : ShowSevereError(state, format("GetVRFTUInAirNodeFromName: Could not find VRF TU = \"{}\"", VRFTUName));
10610 0 : errorsFound = true;
10611 0 : NodeNum = 0;
10612 : }
10613 :
10614 0 : return NodeNum;
10615 : }
10616 :
10617 865 : int GetVRFTUMixedAirNode(EnergyPlusData &state, int const VRFTUNum)
10618 : {
10619 :
10620 : // FUNCTION INFORMATION:
10621 : // AUTHOR R. Raustad (copy of B Griffith routine)
10622 : // DATE WRITTEN Jan 2015
10623 : // MODIFIED na
10624 : // RE-ENGINEERED na
10625 :
10626 : // PURPOSE OF THIS FUNCTION:
10627 : // lookup function for VRF terminal unit mixed air node
10628 :
10629 865 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10630 0 : GetVRFInput(state);
10631 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10632 : }
10633 :
10634 865 : if (VRFTUNum > 0 && VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU) {
10635 865 : return state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum;
10636 : } else {
10637 0 : return 0;
10638 : }
10639 : }
10640 :
10641 865 : int GetVRFTUReturnAirNode(EnergyPlusData &state, int const VRFTUNum)
10642 : {
10643 :
10644 : // FUNCTION INFORMATION:
10645 : // AUTHOR R. Raustad (copy of B Griffith routine)
10646 : // DATE WRITTEN Jan 2015
10647 : // MODIFIED na
10648 : // RE-ENGINEERED na
10649 :
10650 : // PURPOSE OF THIS FUNCTION:
10651 : // lookup function for VRF terminal unit return air node
10652 :
10653 865 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10654 0 : GetVRFInput(state);
10655 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10656 : }
10657 :
10658 865 : if (VRFTUNum > 0 && VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU) {
10659 865 : return state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum;
10660 : } else {
10661 0 : return 0;
10662 : }
10663 : }
10664 :
10665 1 : int getEqIndex(EnergyPlusData &state, std::string_view VRFTUName)
10666 : {
10667 1 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10668 0 : GetVRFInput(state);
10669 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10670 : }
10671 :
10672 1 : for (int VRFTUNum = 1; VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU; VRFTUNum++) {
10673 1 : if (Util::SameString(VRFTUName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name)) {
10674 1 : return VRFTUNum;
10675 : }
10676 : }
10677 0 : return 0;
10678 : }
10679 :
10680 14230 : void getVRFTUZoneLoad(
10681 : EnergyPlusData &state, int const VRFTUNum, Real64 &zoneLoad, Real64 &LoadToHeatingSP, Real64 &LoadToCoolingSP, bool const InitFlag)
10682 : {
10683 :
10684 14230 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).zoneSequenceCoolingNum > 0 &&
10685 14230 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).zoneSequenceHeatingNum > 0 && state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInAirLoop) {
10686 : // air loop equipment uses sequenced variables
10687 0 : LoadToCoolingSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum)
10688 0 : .SequencedOutputRequiredToCoolingSP(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).zoneSequenceCoolingNum) /
10689 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10690 0 : LoadToHeatingSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum)
10691 0 : .SequencedOutputRequiredToHeatingSP(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).zoneSequenceHeatingNum) /
10692 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10693 0 : if (LoadToHeatingSP > 0.0 && LoadToCoolingSP > 0.0 &&
10694 0 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleCool) {
10695 0 : zoneLoad = LoadToHeatingSP;
10696 0 : } else if (LoadToHeatingSP > 0.0 && LoadToCoolingSP > 0.0 &&
10697 0 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) == HVAC::SetptType::SingleCool) {
10698 0 : zoneLoad = 0.0;
10699 0 : } else if (LoadToHeatingSP < 0.0 && LoadToCoolingSP < 0.0 &&
10700 0 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleHeat) {
10701 0 : zoneLoad = LoadToCoolingSP;
10702 0 : } else if (LoadToHeatingSP < 0.0 && LoadToCoolingSP < 0.0 &&
10703 0 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) == HVAC::SetptType::SingleHeat) {
10704 0 : zoneLoad = 0.0;
10705 0 : } else if (LoadToHeatingSP <= 0.0 && LoadToCoolingSP >= 0.0) {
10706 0 : zoneLoad = 0.0;
10707 : }
10708 14230 : } else if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum > 0) {
10709 : // zone equipment uses Remaining* variables
10710 14223 : if (InitFlag) {
10711 : // this will need more investigation. Using Remaining* variable during the initial load calculation seems wrong.
10712 : // This may also have implications when VRF TUs are in the air loop or if SP control is used
10713 : // another question is whether initialization of the operating mode should look at TotalOutputRequired or RemainingOutputRequired
10714 7103 : zoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum).RemainingOutputRequired /
10715 7103 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10716 7103 : LoadToCoolingSP =
10717 7103 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum).OutputRequiredToCoolingSP /
10718 7103 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10719 7103 : LoadToHeatingSP =
10720 7103 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum).OutputRequiredToHeatingSP /
10721 7103 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10722 : } else {
10723 7120 : zoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum).RemainingOutputRequired /
10724 7120 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10725 7120 : LoadToCoolingSP =
10726 7120 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum).RemainingOutputReqToCoolSP /
10727 7120 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10728 7120 : LoadToHeatingSP =
10729 7120 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum).RemainingOutputReqToHeatSP /
10730 7120 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10731 : }
10732 7 : } else if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isSetPointControlled) {
10733 7 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coolSPActive) {
10734 4 : LoadToCoolingSP = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coolLoadToSP;
10735 4 : zoneLoad = LoadToCoolingSP;
10736 4 : LoadToHeatingSP = 0.0;
10737 : }
10738 7 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).heatSPActive) {
10739 3 : LoadToHeatingSP = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).heatLoadToSP;
10740 3 : zoneLoad = LoadToHeatingSP;
10741 3 : LoadToCoolingSP = 0.0;
10742 : }
10743 : }
10744 14230 : }
10745 :
10746 42 : bool getVRFTUNodeNumber(EnergyPlusData &state, int const nodeNumber)
10747 : {
10748 43 : for (int vrfTUIndex = 1; vrfTUIndex <= state.dataHVACVarRefFlow->NumVRFTU; ++vrfTUIndex) {
10749 11 : auto const &vrfTU = state.dataHVACVarRefFlow->VRFTU(vrfTUIndex);
10750 :
10751 11 : bool noVrfTUOutdoorAir = false;
10752 11 : if (vrfTU.CoolOutAirVolFlow == 0 && vrfTU.HeatOutAirVolFlow == 0 && vrfTU.NoCoolHeatOutAirVolFlow == 0) {
10753 11 : noVrfTUOutdoorAir = true;
10754 : }
10755 :
10756 11 : if (noVrfTUOutdoorAir &&
10757 11 : (nodeNumber == vrfTU.VRFTUInletNodeNum || nodeNumber == vrfTU.VRFTUOutletNodeNum || nodeNumber == vrfTU.fanInletNode ||
10758 8 : nodeNumber == vrfTU.fanOutletNode || nodeNumber == vrfTU.heatCoilAirOutNode || nodeNumber == vrfTU.coolCoilAirOutNode ||
10759 5 : nodeNumber == vrfTU.VRFTUOAMixerOANodeNum || nodeNumber == vrfTU.VRFTUOAMixerRelNodeNum || nodeNumber == vrfTU.VRFTUOAMixerRetNodeNum ||
10760 2 : nodeNumber == vrfTU.VRFTUOAMixerMixedNodeNum || nodeNumber == vrfTU.SuppHeatCoilAirInletNode ||
10761 1 : nodeNumber == vrfTU.SuppHeatCoilAirOutletNode)) {
10762 10 : return true;
10763 : }
10764 : }
10765 32 : return false;
10766 : }
10767 :
10768 2374 : void VRFCondenserEquipment::CalcVRFIUTeTc_FluidTCtrl(EnergyPlusData &state)
10769 : {
10770 : // SUBROUTINE INFORMATION:
10771 : // AUTHOR RP Zhang (LBNL), XF Pang (LBNL), Y Yura (Daikin Inc)
10772 : // DATE WRITTEN June 2015
10773 : // MODIFIED na
10774 : // RE-ENGINEERED na
10775 :
10776 : // PURPOSE OF THIS SUBROUTINE:
10777 : // This subroutine is part of the new VRF model based on physics, applicable for Fluid Temperature Control.
10778 : // This subroutine determines the VRF evaporating temperature at cooling mode and the condensing temperature
10779 : // at heating mode. This is the indoor unit side analysis.
10780 :
10781 : // METHODOLOGY EMPLOYED:
10782 : // There are two options to calculate the IU Te/Tc: (1) HighSensible method analyzes the conditions of each IU
10783 : // and then decide and Te/Tc that can satisfy all the zones (2) TeTcConstant method uses fixed values provided
10784 : // by the user.
10785 :
10786 : // Followings for FluidTCtrl Only
10787 2374 : Array1D<Real64> EvapTemp;
10788 2374 : Array1D<Real64> CondTemp;
10789 : Real64 IUMinEvapTemp;
10790 : Real64 IUMaxCondTemp;
10791 :
10792 2374 : int TUListNum = this->ZoneTUListPtr;
10793 2374 : EvapTemp.allocate(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList);
10794 2374 : CondTemp.allocate(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList);
10795 2374 : IUMinEvapTemp = 100.0;
10796 2374 : IUMaxCondTemp = 0.0;
10797 :
10798 2374 : if (this->AlgorithmIUCtrl == 1) {
10799 : // 1. HighSensible: analyze the conditions of each IU
10800 :
10801 15 : for (int i = 1; i <= state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList; i++) {
10802 10 : int VRFTUNum = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(i);
10803 : // analyze the conditions of each IU
10804 10 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRFIUVariableTeTc(state, EvapTemp(i), CondTemp(i));
10805 :
10806 : // select the Te/Tc that can satisfy all the zones
10807 10 : IUMinEvapTemp = min(IUMinEvapTemp, EvapTemp(i), this->IUEvapTempHigh);
10808 10 : IUMaxCondTemp = max(IUMaxCondTemp, CondTemp(i), this->IUCondTempLow);
10809 : }
10810 :
10811 5 : this->IUEvaporatingTemp = max(IUMinEvapTemp, this->IUEvapTempLow);
10812 5 : this->IUCondensingTemp = min(IUMaxCondTemp, this->IUCondTempHigh);
10813 :
10814 : } else {
10815 : // 2. TeTcConstant: use fixed values provided by the user
10816 2369 : this->IUEvaporatingTemp = this->EvapTempFixed;
10817 2369 : this->IUCondensingTemp = this->CondTempFixed;
10818 : }
10819 2374 : }
10820 :
10821 10 : void VRFTerminalUnitEquipment::CalcVRFIUVariableTeTc(EnergyPlusData &state,
10822 : Real64 &EvapTemp, // evaporating temperature
10823 : Real64 &CondTemp // condensing temperature
10824 : )
10825 : {
10826 : // SUBROUTINE INFORMATION:
10827 : // AUTHOR Xiufeng Pang, LBNL
10828 : // DATE WRITTEN Feb 2014
10829 : // MODIFIED Jul 2015, RP Zhang, LBNL, Modify the bounds of the Te/Tc
10830 : // MODIFIED Nov 2015, RP Zhang, LBNL, take into account OA in Te/Tc determination
10831 : // RE-ENGINEERED na
10832 :
10833 : // PURPOSE OF THIS SUBROUTINE:
10834 : // Calculate the VRF IU Te (cooling mode) and Tc (heating mode), given zonal loads.
10835 :
10836 : // METHODOLOGY EMPLOYED:
10837 : // A new physics based VRF model applicable for Fluid Temperature Control.
10838 :
10839 : using namespace DataZoneEnergyDemands;
10840 : using Psychrometrics::PsyHFnTdbW;
10841 : using SingleDuct::SimATMixer;
10842 :
10843 : int CoolCoilNum; // index to the VRF Cooling DX coil to be simulated
10844 : int HeatCoilNum; // index to the VRF Heating DX coil to be simulated
10845 : int IndexToTUInTUList; // index to TU in specific list for the VRF system
10846 : int TUListIndex; // index to TU list for this VRF system
10847 : int VRFNum; // index to VRF that the VRF Terminal Unit serves
10848 : int VRFInletNode; // VRF inlet node number
10849 : Real64 BFC; // Bypass factor at the cooling mode (-)
10850 : Real64 BFH; // Bypass factor at the heating mode (-)
10851 : Real64 C1Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
10852 : Real64 C2Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
10853 : Real64 C3Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
10854 : Real64 C1Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
10855 : Real64 C2Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
10856 : Real64 C3Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
10857 : Real64 CondTempMin; // Min condensing temperature (C)
10858 : Real64 CondTempMax; // Max condensing temperature, correspond to the maximum heating capacity (C)
10859 : Real64 DeltaT; // Difference between evaporating/condensing temperature and coil surface temperature (C)
10860 : Real64 EvapTempMax; // Max evaporating temperature (C)
10861 : Real64 EvapTempMin; // Min evaporating temperature, correspond to the maximum cooling capacity (C)
10862 : Real64 Garate; // Nominal air mass flow rate
10863 : Real64 H_coil_in; // Air enthalpy at the coil inlet (kJ/kg)
10864 : Real64 QZnReqSenCoolingLoad; // Zone required sensible cooling load (W)
10865 : Real64 QZnReqSenHeatingLoad; // Zone required sensible heating load (W)
10866 : Real64 RHsat; // Relative humidity of the air at saturated condition(-)
10867 : Real64 SH; // Super heating degrees (C)
10868 : Real64 SC; // Subcooling degrees (C)
10869 : Real64 T_coil_in; // Temperature of the air at the coil inlet, after absorbing the heat released by fan (C)
10870 : Real64 T_TU_in; // Air temperature at the indoor unit inlet (C)
10871 : Real64 Tout; // Air temperature at the indoor unit outlet (C)
10872 : Real64 Th2; // Air temperature at the coil surface (C)
10873 : Real64 W_coil_in; // coil inlet air humidity ratio [kg/kg]
10874 : Real64 W_TU_in; // Air humidity ratio at the indoor unit inlet[kg/kg]
10875 :
10876 : // Get the equipment/zone index corresponding to the VRFTU
10877 10 : CoolCoilNum = this->CoolCoilIndex;
10878 10 : HeatCoilNum = this->HeatCoilIndex;
10879 10 : VRFNum = this->VRFSysNum;
10880 10 : TUListIndex = state.dataHVACVarRefFlow->VRF(VRFNum).ZoneTUListPtr;
10881 10 : IndexToTUInTUList = this->IndexToTUInTUList;
10882 :
10883 : // Bounds of Te/Tc for VRF IU Control Algorithm: VariableTemp
10884 10 : EvapTempMin = state.dataHVACVarRefFlow->VRF(VRFNum).IUEvapTempLow;
10885 10 : EvapTempMax = state.dataHVACVarRefFlow->VRF(VRFNum).IUEvapTempHigh;
10886 10 : CondTempMin = state.dataHVACVarRefFlow->VRF(VRFNum).IUCondTempLow;
10887 10 : CondTempMax = state.dataHVACVarRefFlow->VRF(VRFNum).IUCondTempHigh;
10888 :
10889 : // Coefficients describing coil performance
10890 10 : SH = state.dataDXCoils->DXCoil(CoolCoilNum).SH;
10891 10 : SC = state.dataDXCoils->DXCoil(HeatCoilNum).SC;
10892 10 : C1Tevap = state.dataDXCoils->DXCoil(CoolCoilNum).C1Te;
10893 10 : C2Tevap = state.dataDXCoils->DXCoil(CoolCoilNum).C2Te;
10894 10 : C3Tevap = state.dataDXCoils->DXCoil(CoolCoilNum).C3Te;
10895 10 : C1Tcond = state.dataDXCoils->DXCoil(HeatCoilNum).C1Tc;
10896 10 : C2Tcond = state.dataDXCoils->DXCoil(HeatCoilNum).C2Tc;
10897 10 : C3Tcond = state.dataDXCoils->DXCoil(HeatCoilNum).C3Tc;
10898 :
10899 10 : VRFInletNode = this->VRFTUInletNodeNum;
10900 10 : T_TU_in = state.dataLoopNodes->Node(VRFInletNode).Temp;
10901 10 : W_TU_in = state.dataLoopNodes->Node(VRFInletNode).HumRat;
10902 10 : T_coil_in = this->coilInNodeT;
10903 10 : W_coil_in = this->coilInNodeW;
10904 :
10905 10 : Garate = state.dataHVACVarRefFlow->CompOnMassFlow;
10906 10 : H_coil_in = PsyHFnTdbW(T_coil_in, W_coil_in);
10907 10 : RHsat = 0.98;
10908 10 : BFC = 0.0592;
10909 10 : BFH = 0.136;
10910 10 : Real64 ZoneLoad = 0.0;
10911 10 : Real64 LoadToHeatingSP = 0.0;
10912 10 : Real64 LoadToCoolingSP = 0.0;
10913 :
10914 : // 1. COOLING Mode
10915 14 : if ((Garate > 0.0) && ((!state.dataHVACVarRefFlow->VRF(VRFNum).HeatRecoveryUsed && state.dataHVACVarRefFlow->CoolingLoad(VRFNum)) ||
10916 4 : (state.dataHVACVarRefFlow->VRF(VRFNum).HeatRecoveryUsed &&
10917 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList)))) {
10918 : // 1.1) Cooling coil is running
10919 4 : getVRFTUZoneLoad(state, IndexToTUInTUList, ZoneLoad, LoadToHeatingSP, LoadToCoolingSP, false);
10920 4 : QZnReqSenCoolingLoad = max(0.0, -1.0 * LoadToCoolingSP);
10921 4 : Tout = T_TU_in - QZnReqSenCoolingLoad * 1.2 / Garate / 1005;
10922 4 : Th2 = T_coil_in - (T_coil_in - Tout) / (1 - BFC);
10923 4 : DeltaT = C3Tevap * SH * SH + C2Tevap * SH + C1Tevap;
10924 4 : EvapTemp = max(min((Th2 - DeltaT), EvapTempMax), EvapTempMin);
10925 :
10926 : } else {
10927 : // 1.2) Cooling coil is not running
10928 6 : EvapTemp = T_coil_in;
10929 : }
10930 :
10931 : // 2. HEATING Mode
10932 14 : if ((Garate > 0.0) && ((!state.dataHVACVarRefFlow->VRF(VRFNum).HeatRecoveryUsed && state.dataHVACVarRefFlow->HeatingLoad(VRFNum)) ||
10933 4 : (state.dataHVACVarRefFlow->VRF(VRFNum).HeatRecoveryUsed &&
10934 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList)))) {
10935 : // 2.1) Heating coil is running
10936 4 : getVRFTUZoneLoad(state, IndexToTUInTUList, ZoneLoad, LoadToHeatingSP, LoadToCoolingSP, false);
10937 4 : QZnReqSenHeatingLoad = max(0.0, LoadToHeatingSP);
10938 4 : Tout = T_TU_in + QZnReqSenHeatingLoad / Garate / 1005;
10939 4 : Th2 = T_coil_in + (Tout - T_coil_in) / (1 - BFH);
10940 4 : DeltaT = C3Tcond * SC * SC + C2Tcond * SC + C1Tcond;
10941 4 : CondTemp = max(min((Th2 + DeltaT), CondTempMax), CondTempMin);
10942 : } else {
10943 : // 2.2) Heating coil is not running
10944 6 : CondTemp = T_coil_in;
10945 : }
10946 10 : }
10947 :
10948 2368 : void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state, const bool FirstHVACIteration)
10949 : {
10950 :
10951 : // SUBROUTINE INFORMATION:
10952 : // AUTHOR RP Zhang (LBNL), XF Pang (LBNL), Y Yura (Daikin Inc)
10953 : // DATE WRITTEN June 2015
10954 : // MODIFIED Feb 2016, RP Zhang, add the control logics for VRF-HR operations
10955 : // RE-ENGINEERED na
10956 :
10957 : // PURPOSE OF THIS SUBROUTINE:
10958 : // This subroutine is part of the new VRF model based on physics, applicable for Fluid Temperature Control.
10959 : // This is adapted from subroutine CalcVRFCondenser, which is part of the VRF model based on system curves.
10960 : // This subroutine models the interactions of VRF indoor units with the outdoor unit.
10961 : // The indoor terminal units are simulated first, and then the outdoor unit is simulated.
10962 :
10963 : // METHODOLOGY EMPLOYED:
10964 : // A new physics based VRF model applicable for Fluid Temperature Control.
10965 :
10966 : using Curve::CurveValue;
10967 : using General::SolveRoot;
10968 :
10969 : using PlantUtilities::SetComponentFlowRate;
10970 : using Psychrometrics::RhoH2O;
10971 :
10972 : static constexpr std::string_view RoutineName("CalcVRFCondenser_FluidTCtrl");
10973 :
10974 : int VRFCond; // index to VRF condenser
10975 : int TUListNum; // index to TU List
10976 : int NumTUInList; // number of terminal units is list
10977 : int NumTU; // index for loop on terminal units
10978 : int TUIndex; // Index to terminal unit
10979 : int CoolCoilIndex; // index to cooling coil in terminal unit
10980 : int HeatCoilIndex; // index to heating coil in terminal unit
10981 : int NumTUInCoolingMode; // number of terminal units actually cooling
10982 : int NumTUInHeatingMode; // number of terminal units actually heating
10983 :
10984 : Real64 TUParasiticPower; // total terminal unit parasitic power (W)
10985 : Real64 TUFanPower; // total terminal unit fan power (W)
10986 : Real64 InletAirWetBulbC; // coil inlet air wet-bulb temperature (C)
10987 : Real64 InletAirDryBulbC; // coil inlet air dry-bulb temperature (C)
10988 : Real64 CondInletTemp; // condenser inlet air temperature (C)
10989 : Real64 OutdoorDryBulb; // outdoor dry-bulb temperature (C)
10990 : Real64 OutdoorHumRat; // outdoor humidity ratio (kg/kg)
10991 : Real64 OutdoorPressure; // outdoor pressure (Pa)
10992 : Real64 OutdoorWetBulb; // outdoor wet-bulb temperature (C)
10993 : Real64 SumCoolInletWB; // sum of active TU's DX cooling coil inlet air wet-bulb temperature
10994 : Real64 SumHeatInletDB; // sum of active TU's DX heating coil inlet air dry-bulb temperature
10995 : Real64 SumHeatInletWB; // sum of active TU's DX heating coil inlet air wet-bulb temperature
10996 : Real64 TotalTUCoolingCapacity; // sum of TU's cooling capacity (W)
10997 : Real64 TotalTUHeatingCapacity; // sum of TU's heating capacity (W)
10998 : Real64 TotalCondCoolingCapacity; // total available condenser cooling capacity (W)
10999 : Real64 TotalCondHeatingCapacity; // total available condenser heating capacity (W)
11000 : Real64 CoolingPLR; // condenser cooling PLR
11001 : Real64 HeatingPLR; // condenser heating PLR
11002 : Real64 CyclingRatio; // cycling ratio of condenser's compressors
11003 : int Stage; // used for crankcase heater power calculation
11004 : Real64 UpperStageCompressorRatio; // used for crankcase heater power calculation
11005 : Real64 RhoAir; // Density of air [kg/m3]
11006 : Real64 PartLoadFraction; // Part load fraction from PLFFPLR curve
11007 : Real64 VRFRTF; // VRF runtime fraction when cycling below MINPLR
11008 : Real64 OutdoorCoilT; // Outdoor coil temperature (C)
11009 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
11010 : Real64 FractionalDefrostTime; // Fraction of time step system is in defrost
11011 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
11012 : Real64 InputPowerMultiplier; // Multiplier for power when system is in defrost
11013 : Real64 LoadDueToDefrost; // Additional load due to defrost
11014 : Real64 DefrostEIRTempModFac; // EIR modifier for defrost (function of entering drybulb, outside wetbulb)
11015 : Real64 HRInitialCapFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
11016 : Real64 HRCapTC; // Time constant used to recover from initial degradation in cooling heat recovery
11017 : Real64 HRInitialEIRFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
11018 : Real64 HREIRTC; // Time constant used to recover from initial degradation in cooling heat recovery
11019 : Real64 CurrentEndTime; // end time of current time step
11020 : Real64 SUMultiplier; // multiplier for simulating mode changes
11021 : Real64 CondPower; // condenser power [W]
11022 : Real64 CondCapacity; // condenser heat rejection [W]
11023 : Real64 TotPower; // total condenser power use [W]
11024 : bool HRHeatRequestFlag; // flag indicating VRF TU could operate in heating mode
11025 : bool HRCoolRequestFlag; // flag indicating VRF TU could operate in cooling mode
11026 :
11027 : // Followings for VRF FluidTCtrl Only
11028 : int Counter; // index for iterations [-]
11029 : int NumIteHIUIn; // index for HIU calculation iterations [-]
11030 : int NumOfCompSpdInput; // Number of compressor speed input by the user [-]
11031 : Real64 CompSpdActual; // Actual compressor running speed [rps]
11032 : Real64 C_cap_operation; // Compressor capacity modification algorithm_modified Cap [-]
11033 : Real64 CompEvaporatingCAPSpdMin; // evaporating capacity at the lowest compressor speed [W]
11034 : Real64 CompEvaporatingCAPSpdMax; // evaporating capacity at the highest compressor speed [W]
11035 : Real64 CompEvaporatingPWRSpdMin; // compressor power at the lowest compressor speed [W]
11036 : Real64 CompEvaporatingPWRSpdMax; // compressor power at the highest compressor speed [W]
11037 : Real64 CapMaxTe; // maximum Te during operation, for capacity calculations [C]
11038 : Real64 CapMinTe; // minimum Te during operation, for capacity calculations [C]
11039 : Real64 CapMinPe; // minimum Pe during operation, for capacity calculations [Pa]
11040 : Real64 CapMaxTc; // maximum Tc during operation, for capacity calculations [C]
11041 : Real64 CapMaxPc; // maximum Pc during operation, for capacity calculations [Pa]
11042 : Real64 CapMinTc; // minimum Tc during operation, for capacity calculations [C]
11043 : Real64 CapMinPc; // minimum Pc during operation, for capacity calculations [Pa]
11044 : Real64 h_IU_evap_in; // enthalpy of IU evaporator at inlet [kJ/kg]
11045 : Real64 h_IU_evap_in_new; // enthalpy of IU evaporator at inlet (new) [kJ/kg]
11046 : Real64 h_IU_evap_in_low; // enthalpy of IU evaporator at inlet (low) [kJ/kg]
11047 : Real64 h_IU_evap_in_up; // enthalpy of IU evaporator at inlet (up) [kJ/kg]
11048 : Real64 h_IU_evap_out; // enthalpy of IU evaporator at outlet [kJ/kg]
11049 : Real64 h_IU_evap_out_i; // enthalpy of IU evaporator at outlet (individual) [kJ/kg]
11050 : Real64 h_IU_cond_in; // enthalpy of IU condenser at inlet [kJ/kg]
11051 : Real64 h_IU_cond_in_low; // enthalpy of IU condenser at inlet (low) [kJ/kg]
11052 : Real64 h_IU_cond_in_up; // enthalpy of IU condenser at inlet (up) [kJ/kg]
11053 : Real64 h_IU_cond_out; // enthalpy of IU condenser at outlet [kJ/kg]
11054 : Real64 h_IU_cond_out_i; // enthalpy of IU condenser at outlet (individual) [kJ/kg]
11055 : Real64 h_IU_cond_out_ave; // average enthalpy of the refrigerant leaving IU condensers [kJ/kg]
11056 : Real64 h_IU_PLc_out; // enthalpy of refrigerant at the outlet of IU evaporator side main pipe, after piping loss (c) [kJ/kg]
11057 : Real64 h_comp_in; // enthalpy of refrigerant at compressor inlet, after piping loss (c) [kJ/kg]
11058 : Real64 h_comp_in_new; // enthalpy of refrigerant at compressor inlet (new) [kJ/kg]
11059 : Real64 h_comp_out; // enthalpy of refrigerant at compressor outlet [kJ/kg]
11060 : Real64 h_comp_out_new; // enthalpy of refrigerant at compressor outlet (new) [kJ/kg]
11061 : Real64 m_air; // OU coil air mass flow rate [kg/s]
11062 : Real64 m_ref_IU_cond; // mass flow rate of Refrigerant through IU condensers [kg/s]
11063 : Real64 m_ref_IU_cond_i; // mass flow rate of Refrigerant through an individual IU condenser [kg/s]
11064 : Real64 m_ref_IU_evap; // mass flow rate of Refrigerant through IU evaporators [kg/s]
11065 : Real64 m_ref_IU_evap_i; // mass flow rate of Refrigerant through an individual IU evaporator [kg/s]
11066 : Real64 m_ref_OU_evap; // mass flow rate of Refrigerant through OU evaporator [kg/s]
11067 : Real64 m_ref_OU_cond; // mass flow rate of Refrigerant through OU condenser [kg/s]
11068 : Real64 Ncomp; // compressor power [W]
11069 : Real64 Ncomp_new; // compressor power for temporary use in iterations [W]
11070 : Real64 P_comp_in; // pressure of refrigerant at IU condenser outlet [Pa]
11071 : Real64 Pcond; // VRF condensing pressure [Pa]
11072 : Real64 Pevap; // VRF evaporating pressure [Pa]
11073 : Real64 Pdischarge; // VRF compressor discharge pressure [Pa]
11074 : Real64 Psuction; // VRF compressor suction pressure [Pa]
11075 : Real64 Pipe_DeltP_c; // Piping Loss Algorithm Parameter: Pipe pressure drop (c) [Pa]
11076 : Real64 Pipe_DeltP_h; // Piping Loss Algorithm Parameter: Pipe pressure drop (h) [Pa]
11077 : Real64 Pipe_Q_c; // Piping Loss Algorithm Parameter: Heat loss (c) [W]
11078 : Real64 Pipe_Q_h; // Piping Loss Algorithm Parameter: Heat loss (h) [W]
11079 : Real64 Q_c_TU_PL; // Cooling load to be met at cooling mode, including the piping loss(W)
11080 : Real64 Q_h_TU_PL; // Heating load to be met at heating mode, including the piping loss (W)
11081 : Real64 Q_h_OU; // outdoor unit condenser heat release (cooling mode) [W]
11082 : Real64 Q_c_OU; // outdoor unit evaporator heat extract (heating mode) [W]
11083 : Real64 RefMaxPc; // maximum refrigerant condensing pressure [Pa]
11084 : Real64 RefMinTe; // Minimum refrigerant evaporating temperature [Pa]
11085 : Real64 RefMinPe; // Minimum refrigerant evaporating pressure [Pa]
11086 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
11087 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
11088 : Real64 RefTLow; // Low Temperature Value for Ps (max in tables) [C]
11089 : Real64 RefTHigh; // High Temperature Value for Ps (max in tables) [C]
11090 : Real64 RefTSat; // Saturated temperature of the refrigerant. Used to check whether the refrigerant is in the superheat area [C]
11091 : Real64 SC_IU_merged; // Piping Loss Algorithm Parameter: average subcooling degrees after the indoor units [C]
11092 : Real64 SH_IU_merged; // Piping Loss Algorithm Parameter: average super heating degrees after the indoor units [C]
11093 : Real64 SC_OU; // subcooling degrees at OU condenser [C]
11094 : Real64 SH_OU; // super heating degrees at OU evaporator [C]
11095 : Real64 SH_Comp; // Temperature difference between compressor inlet node and Tsuction [C]
11096 : Real64 T_comp_in; // temperature of refrigerant at compressor inlet, after piping loss (c) [C]
11097 : Real64 TU_HeatingLoad; // Heating load from terminal units, excluding heating loss [W]
11098 : Real64 TU_CoolingLoad; // Cooling load from terminal units, excluding heating loss [W]
11099 : Real64 Tdischarge; // VRF Compressor discharge refrigerant temperature [C]
11100 : Real64 Tsuction; // VRF compressor suction refrigerant temperature [C]
11101 : Real64 Tolerance; // Tolerance for condensing temperature calculation [C]
11102 : Real64 Tfs; // Temperature of the air at the coil surface [C]
11103 2368 : Array1D<Real64> CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W]
11104 2368 : Array1D<Real64> CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W]
11105 :
11106 : // variable initializations
11107 2368 : TUListNum = this->ZoneTUListPtr;
11108 2368 : NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
11109 2368 : VRFCond = state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(1)).VRFSysNum;
11110 2368 : TU_CoolingLoad = 0.0;
11111 2368 : TU_HeatingLoad = 0.0;
11112 2368 : TUParasiticPower = 0.0;
11113 2368 : TUFanPower = 0.0;
11114 2368 : CoolingPLR = 0.0;
11115 2368 : HeatingPLR = 0.0;
11116 2368 : CyclingRatio = 1.0;
11117 2368 : SumCoolInletWB = 0.0;
11118 2368 : SumHeatInletDB = 0.0;
11119 2368 : SumHeatInletWB = 0.0;
11120 2368 : TotalCondCoolingCapacity = 0.0;
11121 2368 : TotalCondHeatingCapacity = 0.0;
11122 2368 : TotalTUCoolingCapacity = 0.0;
11123 2368 : TotalTUHeatingCapacity = 0.0;
11124 2368 : NumTUInCoolingMode = 0;
11125 2368 : NumTUInHeatingMode = 0;
11126 2368 : Tolerance = 0.05;
11127 2368 : Counter = 1;
11128 2368 : NumIteHIUIn = 1;
11129 2368 : this->ElecCoolingPower = 0.0;
11130 2368 : this->ElecHeatingPower = 0.0;
11131 2368 : this->CrankCaseHeaterPower = 0.0;
11132 2368 : this->EvapCondPumpElecPower = 0.0; // for EvaporativelyCooled condenser
11133 2368 : this->EvapWaterConsumpRate = 0.0;
11134 2368 : this->DefrostPower = 0.0;
11135 2368 : this->OperatingCoolingCOP = 0.0;
11136 2368 : this->OperatingHeatingCOP = 0.0;
11137 2368 : this->OperatingCOP = 0.0;
11138 2368 : this->SCHE = 0.0;
11139 2368 : this->BasinHeaterPower = 0.0;
11140 2368 : this->CondensingTemp = 60.0; // OutDryBulbTemp;
11141 2368 : this->VRFHeatRec = 0.0;
11142 :
11143 : // Refrigerant data
11144 2368 : RefMinTe = -15;
11145 2368 : RefMaxPc = 4000000.0;
11146 2368 : RefMinPe = this->refrig->getSatPressure(state, RefMinTe, RoutineName);
11147 2368 : RefTLow = this->refrig->PsLowTempValue; // High Temperature Value for Ps (max in tables)
11148 2368 : RefTHigh = this->refrig->PsHighTempValue; // High Temperature Value for Ps (max in tables)
11149 2368 : RefPLow = this->refrig->PsLowPresValue; // Low Pressure Value for Ps (>0.0)
11150 2368 : RefPHigh = this->refrig->PsHighPresValue; // High Pressure Value for Ps (max in tables)
11151 :
11152 : // sum loads on TU coils
11153 4736 : for (NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
11154 2368 : TU_CoolingLoad += state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU);
11155 2368 : TU_HeatingLoad += state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU);
11156 2368 : TUParasiticPower +=
11157 2368 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU)).ParasiticCoolElecPower +
11158 2368 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU)).ParasiticHeatElecPower;
11159 2368 : TUFanPower += state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU)).FanPower;
11160 : }
11161 2368 : this->TUCoolingLoad = TU_CoolingLoad; // this is cooling coil load, not terminal unit load
11162 2368 : this->TUHeatingLoad = TU_HeatingLoad; // this is heating coil load, not terminal unit load
11163 :
11164 : // loop through TU's and calculate average inlet conditions for active coils
11165 4736 : for (NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
11166 2368 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
11167 2368 : CoolCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
11168 2368 : HeatCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex;
11169 :
11170 2368 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) > 0.0) {
11171 1171 : SumCoolInletWB += state.dataDXCoils->DXCoilCoolInletAirWBTemp(CoolCoilIndex) *
11172 1171 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) / TU_CoolingLoad;
11173 1171 : ++NumTUInCoolingMode;
11174 : }
11175 2368 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) > 0.0) {
11176 1158 : SumHeatInletDB += state.dataDXCoils->DXCoilHeatInletAirDBTemp(HeatCoilIndex) *
11177 1158 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) / TU_HeatingLoad;
11178 1158 : SumHeatInletWB += state.dataDXCoils->DXCoilHeatInletAirWBTemp(HeatCoilIndex) *
11179 1158 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) / TU_HeatingLoad;
11180 1158 : ++NumTUInHeatingMode;
11181 : }
11182 : }
11183 :
11184 : // set condenser entering air conditions (Outdoor air conditions)
11185 2368 : if (this->CondenserNodeNum != 0) {
11186 0 : OutdoorDryBulb = state.dataLoopNodes->Node(this->CondenserNodeNum).Temp;
11187 0 : if (this->CondenserType != DataHeatBalance::RefrigCondenserType::Water) {
11188 0 : OutdoorHumRat = state.dataLoopNodes->Node(this->CondenserNodeNum).HumRat;
11189 0 : OutdoorPressure = state.dataLoopNodes->Node(this->CondenserNodeNum).Press;
11190 0 : OutdoorWetBulb = state.dataLoopNodes->Node(this->CondenserNodeNum).OutAirWetBulb;
11191 : } else {
11192 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
11193 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11194 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
11195 : }
11196 : } else {
11197 2368 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
11198 2368 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
11199 2368 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11200 2368 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
11201 : }
11202 2368 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
11203 :
11204 2368 : CondInletTemp = OutdoorDryBulb; // this->CondenserType == AirCooled
11205 2368 : this->CondenserInletTemp = CondInletTemp;
11206 :
11207 : //*************
11208 : // VRF-HP MODES:
11209 : // 1. Cooling
11210 : // 2. Heating
11211 : // 3. No running
11212 : // VRF-HR MODES:
11213 : // 1. Cooling Only
11214 : // 2. Cooling Dominant w/o HR Loss
11215 : // 3. Cooling Dominant w/ HR Loss
11216 : // 4. Heating Dominant w/ HR Loss
11217 : // 5. Heating Dominant w/o HR Loss
11218 : // 6. Heating Only
11219 : // 7. No running
11220 :
11221 : // Flag for VRF-HR Operations
11222 2368 : if (TU_HeatingLoad > 0) {
11223 1158 : HRHeatRequestFlag = true;
11224 : } else {
11225 1210 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
11226 1210 : HRHeatRequestFlag = false;
11227 : }
11228 2368 : if (TU_CoolingLoad > 0) {
11229 1171 : HRCoolRequestFlag = true;
11230 : } else {
11231 1197 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
11232 1197 : HRCoolRequestFlag = false;
11233 : }
11234 :
11235 : // Initialization for Ncomp iterations
11236 2368 : NumOfCompSpdInput = this->CompressorSpeed.size();
11237 2368 : CompEvaporatingPWRSpd.dimension(NumOfCompSpdInput);
11238 2368 : CompEvaporatingCAPSpd.dimension(NumOfCompSpdInput);
11239 2368 : this->OperatingMode = 0; // report variable for heating or cooling mode
11240 :
11241 : // 1. VRF-HP Cooling Mode .OR. VRF-HR Mode_1
11242 3566 : if ((!this->HeatRecoveryUsed && state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) ||
11243 1198 : (this->HeatRecoveryUsed && !HRHeatRequestFlag && HRCoolRequestFlag)) {
11244 :
11245 1171 : this->OperatingMode = ModeCoolingOnly;
11246 1171 : this->VRFOperationSimPath = 10;
11247 :
11248 : // Initialization of VRF-FluidTCtrl Model
11249 1171 : Q_c_TU_PL = TU_CoolingLoad;
11250 :
11251 : // Evaporator (IU side) operational parameters
11252 1171 : Pevap = this->refrig->getSatPressure(state, this->IUEvaporatingTemp, RoutineName);
11253 1171 : Psuction = Pevap;
11254 1171 : this->EvaporatingTemp =
11255 1171 : this->IUEvaporatingTemp; // GetSatTemperatureRefrig(state, this->RefrigerantName, max( min( Pevap, RefPHigh ), RefPLow
11256 : // ), RefrigerantIndex, RoutineName );
11257 :
11258 : // Condenser (OU side) operation ranges
11259 1171 : CapMaxPc = min(Psuction + this->CompMaxDeltaP, RefMaxPc);
11260 1171 : CapMaxTc = this->refrig->getSatTemperature(state, max(min(CapMaxPc, RefPHigh), RefPLow), RoutineName);
11261 1171 : CapMinTc = OutdoorDryBulb + this->SC;
11262 1171 : CapMinPc = this->refrig->getSatPressure(state, CapMinTc, RoutineName);
11263 :
11264 : // Evaporator (IU side) operation ranges
11265 1171 : CapMinPe = max(CapMinPc - this->CompMaxDeltaP, RefMinPe);
11266 1171 : CapMinTe = this->refrig->getSatTemperature(state, max(min(CapMinPe, RefPHigh), RefPLow), RoutineName);
11267 :
11268 : // Evaporative capacity ranges
11269 1171 : CompEvaporatingCAPSpdMin = this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(1), CapMinTc, CapMinTe);
11270 1171 : CompEvaporatingPWRSpdMin = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(1), CapMinTc, CapMinTe);
11271 2342 : CompEvaporatingCAPSpdMax = this->CoffEvapCap * this->RatedEvapCapacity *
11272 1171 : CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), this->CondensingTemp, this->IUEvaporatingTemp);
11273 1171 : CompEvaporatingPWRSpdMax =
11274 1171 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(NumOfCompSpdInput), this->CondensingTemp, this->IUEvaporatingTemp);
11275 :
11276 : // Initialization for h_IU_evap_in iterations (Label12)
11277 1171 : h_IU_evap_in_low = this->refrig->getSatEnthalpy(state, OutdoorDryBulb - this->SC, 0.0, RoutineName); // Tc = Tamb
11278 1171 : h_IU_evap_in_up = this->refrig->getSatEnthalpy(state, CapMaxTc - this->SC, 0.0, RoutineName); // Tc = CapMaxTc
11279 1171 : h_IU_evap_in = this->refrig->getSatEnthalpy(state, OutdoorDryBulb + 10 - this->SC, 0.0, RoutineName); // Tc = Tamb+10
11280 :
11281 1171 : NumIteHIUIn = 1;
11282 : bool converged_12;
11283 : do {
11284 1555 : m_ref_IU_evap = 0;
11285 1555 : h_IU_evap_out = 0;
11286 1555 : h_IU_evap_out_i = 0;
11287 1555 : m_ref_IU_evap_i = 0;
11288 1555 : SH_IU_merged = 0;
11289 :
11290 : // Calculate total IU refrigerant flow rate and SH_IU_merged
11291 1555 : if (Q_c_TU_PL > CompEvaporatingCAPSpdMax) {
11292 : // Required load is beyond the max system capacity
11293 :
11294 236 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11295 472 : h_IU_evap_out = this->refrig->getSupHeatEnthalpy(
11296 236 : state, max(RefTSat, this->IUEvaporatingTemp + 3), max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11297 236 : SH_IU_merged = 3;
11298 236 : m_ref_IU_evap = TU_CoolingLoad / (h_IU_evap_out - h_IU_evap_in);
11299 :
11300 : } else {
11301 :
11302 2638 : for (NumTU = 1; NumTU <= NumTUInList; NumTU++) { // Calc total refrigerant flow rate
11303 1319 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) > 0) {
11304 1319 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
11305 1319 : CoolCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
11306 :
11307 1319 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11308 2638 : h_IU_evap_out_i = this->refrig->getSupHeatEnthalpy(
11309 : state,
11310 1319 : max(RefTSat, this->IUEvaporatingTemp + state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH),
11311 : max(min(Pevap, RefPHigh), RefPLow),
11312 : RoutineName);
11313 :
11314 1319 : if (h_IU_evap_out_i > h_IU_evap_in) {
11315 1319 : m_ref_IU_evap_i = (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) <= 0.0)
11316 1319 : ? 0.0
11317 1319 : : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) /
11318 1319 : (h_IU_evap_out_i - h_IU_evap_in)); // Ref Flow Rate in the IU( kg/s )
11319 1319 : m_ref_IU_evap = m_ref_IU_evap + m_ref_IU_evap_i;
11320 1319 : h_IU_evap_out = h_IU_evap_out + m_ref_IU_evap_i * h_IU_evap_out_i;
11321 1319 : SH_IU_merged = SH_IU_merged + m_ref_IU_evap_i * state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH;
11322 : }
11323 : }
11324 : }
11325 1319 : if (m_ref_IU_evap > 0) {
11326 1319 : h_IU_evap_out = h_IU_evap_out / m_ref_IU_evap;
11327 1319 : SH_IU_merged = SH_IU_merged / m_ref_IU_evap;
11328 : } else {
11329 0 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11330 0 : h_IU_evap_out = this->refrig->getSupHeatEnthalpy(
11331 0 : state, max(RefTSat, this->IUEvaporatingTemp + 3), max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11332 0 : SH_IU_merged = 3;
11333 0 : m_ref_IU_evap = TU_CoolingLoad / (h_IU_evap_out - h_IU_evap_in);
11334 : }
11335 : }
11336 :
11337 : // *Calculate piping loss
11338 1555 : this->VRFOU_PipeLossC(state,
11339 : m_ref_IU_evap,
11340 : max(min(Pevap, RefPHigh), RefPLow),
11341 : h_IU_evap_out,
11342 : SH_IU_merged,
11343 : OutdoorDryBulb,
11344 : Pipe_Q_c,
11345 : Pipe_DeltP_c,
11346 : h_comp_in);
11347 1555 : Tsuction = this->refrig->getSatTemperature(state, max(min(Pevap - Pipe_DeltP_c, RefPHigh), RefPLow), RoutineName);
11348 1555 : Psuction = Pevap - Pipe_DeltP_c; // This Psuction is used for rps > min; will be updated for rps = min
11349 :
11350 : // Perform iteration to calculate T_comp_in
11351 1555 : T_comp_in = this->refrig->getSupHeatTemp(
11352 : state, max(min(Pevap - Pipe_DeltP_c, RefPHigh), RefPLow), h_comp_in, Tsuction + 3, Tsuction + 30, RoutineName);
11353 1555 : SH_Comp = T_comp_in - Tsuction; // This is used for rps > min; will be updated for rps = min
11354 :
11355 1555 : Q_c_TU_PL = TU_CoolingLoad + Pipe_Q_c;
11356 1555 : Q_h_OU = Q_c_TU_PL + CompEvaporatingPWRSpdMin;
11357 :
11358 : // *Calculate capacity modification factor
11359 1555 : C_cap_operation = this->VRFOU_CapModFactor(
11360 : state, h_comp_in, h_IU_evap_in, max(min(Psuction, RefPHigh), RefPLow), Tsuction + SH_Comp, Tsuction + 8, CapMinTc - 5);
11361 :
11362 : // Iteration_Ncomp: Perform iterations to calculate Ncomp (Label10)
11363 1555 : Counter = 1;
11364 1555 : Ncomp = TU_CoolingLoad / this->CoolingCOP;
11365 1555 : Ncomp_new = Ncomp;
11366 : bool converged_10;
11367 : do {
11368 2834 : Q_h_OU = Q_c_TU_PL + Ncomp_new; // Ncomp_new may be updated during Iteration_Ncomp Label10
11369 :
11370 : // *VRF OU TeTc calculations
11371 2834 : m_air = this->OUAirFlowRate * RhoAir;
11372 2834 : SC_OU = this->SC;
11373 2834 : this->VRFOU_TeTc(
11374 2834 : state, HXOpMode::CondMode, Q_h_OU, SC_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->CondensingTemp);
11375 2834 : this->CondensingTemp = min(CapMaxTc, this->CondensingTemp);
11376 2834 : this->SC = SC_OU;
11377 :
11378 : // *VEF OU Compressor Simulation at cooling mode: Specify the compressor speed and power consumption
11379 2834 : this->VRFOU_CalcCompC(state,
11380 : TU_CoolingLoad,
11381 : Tsuction,
11382 : this->CondensingTemp,
11383 : Psuction,
11384 : T_comp_in,
11385 : h_comp_in,
11386 : h_IU_evap_in,
11387 : Pipe_Q_c,
11388 : CapMaxTc,
11389 : Q_h_OU,
11390 : CompSpdActual,
11391 : Ncomp,
11392 : CyclingRatio);
11393 :
11394 2834 : converged_10 = (std::abs(Ncomp - Ncomp_new) <= (Tolerance * Ncomp_new)) || (Counter >= 30);
11395 2834 : if (!converged_10) {
11396 1279 : Ncomp_new = Ncomp;
11397 : }
11398 2834 : } while (!converged_10);
11399 :
11400 : // Update h_IU_evap_in in iterations Label12
11401 1555 : h_IU_evap_in_new = this->refrig->getSatEnthalpy(state, this->CondensingTemp - this->SC, 0.0, RoutineName);
11402 1939 : converged_12 = !((std::abs(h_IU_evap_in - h_IU_evap_in_new) > Tolerance * h_IU_evap_in) && (h_IU_evap_in < h_IU_evap_in_up) &&
11403 384 : (h_IU_evap_in > h_IU_evap_in_low));
11404 1555 : h_IU_evap_in = h_IU_evap_in_new;
11405 1555 : NumIteHIUIn = NumIteHIUIn + 1;
11406 1555 : } while (!converged_12);
11407 1171 : if ((std::abs(h_IU_evap_in - h_IU_evap_in_new) > Tolerance * h_IU_evap_in)) {
11408 0 : h_IU_evap_in = 0.5 * (h_IU_evap_in_low + h_IU_evap_in_up);
11409 1171 : } else if (h_IU_evap_in > h_IU_evap_in_up) {
11410 0 : h_IU_evap_in = h_IU_evap_in_up;
11411 1171 : } else if (h_IU_evap_in < h_IU_evap_in_low) {
11412 0 : h_IU_evap_in = h_IU_evap_in_low;
11413 : } else {
11414 1171 : h_IU_evap_in = (h_IU_evap_in + h_IU_evap_in_new) / 2;
11415 : }
11416 :
11417 : // Key outputs of this subroutine
11418 1171 : Ncomp *= CyclingRatio;
11419 1171 : Q_h_OU *= CyclingRatio;
11420 1171 : this->CompActSpeed = max(CompSpdActual, 0.0);
11421 1171 : this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter; // 0.95 is the efficiency of the compressor inverter, can come from IDF //@minor
11422 1171 : this->OUFanPower = this->RatedOUFanPower * CyclingRatio; //@ * pow_3( CondFlowRatio )
11423 1171 : this->VRFCondCyclingRatio = CyclingRatio; // report variable for cycling rate
11424 :
11425 1171 : Tdischarge = this->CondensingTemp; // outdoor unit condensing temperature
11426 1171 : this->CoolingCapacity =
11427 2342 : this->CoffEvapCap * this->RatedEvapCapacity *
11428 2342 : CurveValue(
11429 1171 : state, this->OUCoolingCAPFT(NumOfCompSpdInput), Tdischarge, Tsuction); // Include the piping loss, at the highest compressor speed
11430 1171 : this->PipingCorrectionCooling = TU_CoolingLoad / (TU_CoolingLoad + Pipe_Q_c);
11431 1171 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond) = this->CoolingCapacity; // for report, maximum evaporating capacity of the system
11432 :
11433 1171 : this->HeatingCapacity = 0.0; // Include the piping loss
11434 1171 : this->PipingCorrectionHeating = 1.0; // 1 means no piping loss
11435 1171 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) = Constant::MaxCap;
11436 :
11437 1171 : this->OUCondHeatRate = Q_h_OU;
11438 1171 : this->OUEvapHeatRate = 0;
11439 1171 : this->IUCondHeatRate = 0;
11440 1171 : this->IUEvapHeatRate = TU_CoolingLoad;
11441 :
11442 : // 2. VRF-HP Heating Mode .OR. VRF-HR Mode_6
11443 1236 : } else if ((!this->HeatRecoveryUsed && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) ||
11444 39 : (this->HeatRecoveryUsed && !HRCoolRequestFlag && HRHeatRequestFlag)) {
11445 :
11446 1158 : this->OperatingMode = ModeHeatingOnly;
11447 1158 : this->VRFOperationSimPath = 60;
11448 :
11449 : // Initialization of VRF-FluidTCtrl Model
11450 1158 : Q_h_TU_PL = TU_HeatingLoad;
11451 1158 : Ncomp = TU_HeatingLoad / this->HeatingCOP;
11452 1158 : this->CondensingTemp = this->IUCondensingTemp;
11453 :
11454 : // Evaporative capacity ranges_Max
11455 1158 : CapMaxTe = OutdoorDryBulb - this->SH;
11456 2316 : CompEvaporatingCAPSpdMax = this->CoffEvapCap * this->RatedEvapCapacity *
11457 1158 : CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), this->IUCondensingTemp, CapMaxTe);
11458 1158 : CompEvaporatingPWRSpdMax =
11459 1158 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(NumOfCompSpdInput), this->IUCondensingTemp, CapMaxTe);
11460 :
11461 : // Initialization of h_comp_out iterations (Label23)
11462 1158 : Pcond = this->refrig->getSatPressure(state, 40.0, RoutineName);
11463 1158 : RefTSat = this->refrig->getSatTemperature(state, Pcond, RoutineName);
11464 1158 : h_IU_cond_in_up = this->refrig->getSupHeatEnthalpy(state, max(RefTSat, min(this->IUCondensingTemp + 50, RefTHigh)), Pcond, RoutineName);
11465 1158 : h_IU_cond_in_low = this->refrig->getSatEnthalpy(state, this->IUCondensingTemp, 1.0, RoutineName); // Quality=1
11466 1158 : h_IU_cond_in = h_IU_cond_in_low;
11467 :
11468 : bool converged_23;
11469 : do {
11470 2908 : m_ref_IU_cond = 0;
11471 2908 : h_IU_cond_out_ave = 0;
11472 2908 : SC_IU_merged = 0;
11473 :
11474 : // Calculate total refrigerant flow rate
11475 2908 : if (Q_h_TU_PL > CompEvaporatingCAPSpdMax + CompEvaporatingPWRSpdMax) {
11476 : // Required load is beyond the max system capacity
11477 :
11478 : h_IU_cond_out =
11479 0 : this->refrig->getSatEnthalpy(state,
11480 0 : this->refrig->getSatTemperature(state, max(min(Pcond, RefPHigh), RefPLow), RoutineName) - 5.0,
11481 : 0.0,
11482 : RoutineName); // Quality=0
11483 0 : h_IU_cond_out_ave = h_IU_cond_out;
11484 0 : SC_IU_merged = 5;
11485 0 : m_ref_IU_cond = TU_HeatingLoad / (h_IU_cond_in - h_IU_cond_out);
11486 :
11487 : } else {
11488 5816 : for (NumTU = 1; NumTU <= NumTUInList; NumTU++) {
11489 2908 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) > 0) {
11490 2908 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
11491 2908 : HeatCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex;
11492 : h_IU_cond_out_i =
11493 8724 : this->refrig->getSatEnthalpy(state,
11494 2908 : this->refrig->getSatTemperature(state, max(min(Pcond, RefPHigh), RefPLow), RoutineName) -
11495 2908 : state.dataDXCoils->DXCoil(HeatCoilIndex).ActualSC,
11496 : 0.0,
11497 : RoutineName); // Quality=0
11498 2908 : m_ref_IU_cond_i =
11499 2908 : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) <= 0.0)
11500 2908 : ? 0.0
11501 2908 : : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) / (h_IU_cond_in - h_IU_cond_out_i));
11502 2908 : m_ref_IU_cond = m_ref_IU_cond + m_ref_IU_cond_i;
11503 2908 : h_IU_cond_out_ave = h_IU_cond_out_ave + m_ref_IU_cond_i * h_IU_cond_out_i;
11504 2908 : SC_IU_merged = SC_IU_merged + m_ref_IU_cond_i * state.dataDXCoils->DXCoil(HeatCoilIndex).ActualSC;
11505 : }
11506 : }
11507 2908 : if (m_ref_IU_cond > 0) {
11508 2908 : h_IU_cond_out_ave = h_IU_cond_out_ave / m_ref_IU_cond; // h_merge
11509 2908 : SC_IU_merged = SC_IU_merged / m_ref_IU_cond;
11510 : } else {
11511 : h_IU_cond_out_ave =
11512 0 : this->refrig->getSatEnthalpy(state,
11513 0 : this->refrig->getSatTemperature(state, max(min(Pcond, RefPHigh), RefPLow), RoutineName) - 5.0,
11514 : 0.0,
11515 : RoutineName); // Quality=0
11516 0 : SC_IU_merged = 5;
11517 0 : m_ref_IU_cond = TU_HeatingLoad / (h_IU_cond_in - h_IU_cond_out_ave);
11518 : }
11519 : }
11520 :
11521 : // *Calculate piping loss
11522 2908 : this->VRFOU_PipeLossH(
11523 : state, m_ref_IU_cond, max(min(Pcond, RefPHigh), RefPLow), h_IU_cond_in, OutdoorDryBulb, Pipe_Q_h, Pipe_DeltP_h, h_comp_out);
11524 :
11525 2908 : Pdischarge = max(Pcond + Pipe_DeltP_h, Pcond); // affected by piping loss
11526 2908 : Tdischarge = this->refrig->getSatTemperature(state, max(min(Pdischarge, RefPHigh), RefPLow), RoutineName);
11527 :
11528 : // Evaporative capacity ranges_Min
11529 : // suction pressure lower bound need to be no less than both terms in the following
11530 2908 : CapMinPe = max(Pdischarge - this->CompMaxDeltaP, RefMinPe);
11531 2908 : CapMinTe = this->refrig->getSatTemperature(state, max(min(CapMinPe, RefPHigh), RefPLow), RoutineName);
11532 2908 : CompEvaporatingCAPSpdMin = this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(1), Tdischarge, CapMinTe);
11533 2908 : CompEvaporatingPWRSpdMin = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(1), Tdischarge, CapMinTe);
11534 :
11535 2908 : Q_h_TU_PL = TU_HeatingLoad + Pipe_Q_h;
11536 2908 : Q_c_OU = max(0.0, Q_h_TU_PL - CompEvaporatingPWRSpdMin);
11537 :
11538 : // *Calculate capacity modification factor
11539 2908 : RefTSat = this->refrig->getSatTemperature(state, max(min(CapMinPe, RefPHigh), RefPLow), RoutineName);
11540 2908 : h_comp_in =
11541 2908 : this->refrig->getSupHeatEnthalpy(state, max(RefTSat, CapMinTe + this->SH), max(min(CapMinPe, RefPHigh), RefPLow), RoutineName);
11542 2908 : C_cap_operation = this->VRFOU_CapModFactor(state,
11543 : h_comp_in,
11544 : h_IU_cond_out_ave,
11545 : max(min(CapMinPe, RefPHigh), RefPLow),
11546 2908 : CapMinTe + this->SH,
11547 : CapMinTe + 8,
11548 2908 : this->IUCondensingTemp - 5);
11549 :
11550 : Real64 CompEvaporatingCAPSpdMaxCurrentTsuc =
11551 5816 : this->CoffEvapCap * this->RatedEvapCapacity *
11552 2908 : CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), Tdischarge, this->EvaporatingTemp);
11553 : Real64 CompEvaporatingPWRSpdMaxCurrentTsuc =
11554 2908 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(NumOfCompSpdInput), Tdischarge, this->EvaporatingTemp);
11555 2908 : if (CompEvaporatingCAPSpdMin > CompEvaporatingCAPSpdMaxCurrentTsuc) {
11556 0 : if (this->CondenserCapErrIdx == 0) {
11557 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), this->Name));
11558 0 : ShowContinueErrorTimeStamp(state,
11559 0 : format(" Evaporative Capacity at max speed is smaller than evaporative capacity at min speed, "
11560 : "{:.3T} < {:.3T}",
11561 : CompEvaporatingCAPSpdMaxCurrentTsuc,
11562 : CompEvaporatingCAPSpdMin));
11563 : }
11564 0 : ShowRecurringSevereErrorAtEnd(
11565 : state,
11566 0 : format("\"{}\" - Evaporative Capacity at max speed is smaller than evaporative capacity at min speed ", this->Name),
11567 0 : this->CondenserCapErrIdx,
11568 0 : CompEvaporatingCAPSpdMaxCurrentTsuc - CompEvaporatingCAPSpdMin,
11569 0 : CompEvaporatingCAPSpdMaxCurrentTsuc - CompEvaporatingCAPSpdMin);
11570 : }
11571 2908 : if ((Q_c_OU * C_cap_operation) > CompEvaporatingCAPSpdMaxCurrentTsuc) {
11572 : // this branch resolves the issue of supplemental heating coil turning on when compressor speed is not at the highest
11573 0 : Q_c_OU = CompEvaporatingCAPSpdMaxCurrentTsuc;
11574 0 : CompSpdActual = this->CompressorSpeed(NumOfCompSpdInput);
11575 0 : Ncomp = CompEvaporatingPWRSpdMaxCurrentTsuc;
11576 0 : m_air = this->OUAirFlowRate * RhoAir;
11577 0 : SH_OU = this->SH;
11578 0 : this->VRFOU_TeTc(
11579 0 : state, HXOpMode::EvapMode, Q_c_OU, SH_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->EvaporatingTemp);
11580 1158 : break;
11581 : } else {
11582 : // CompEvaporatingCAPSpdMin < (Q_c_OU * C_cap_operation) <= CompEvaporatingCAPSpdMaxCurrentTsuc + CompEvaporatingPWRSpdMaxCurrentTsuc
11583 : // Required heating load is greater than or equal to the min heating capacity
11584 :
11585 : // Iteration_Ncomp: Perform iterations to calculate Ncomp (Label20)
11586 2908 : Counter = 1;
11587 : bool converged_20;
11588 : do {
11589 5269 : Ncomp_new = Ncomp;
11590 5269 : Q_c_OU = max(0.0, Q_h_TU_PL - Ncomp);
11591 :
11592 : // *VRF OU Te calculations
11593 5269 : m_air = this->OUAirFlowRate * RhoAir;
11594 5269 : SH_OU = this->SH;
11595 5269 : this->VRFOU_TeTc(
11596 5269 : state, HXOpMode::EvapMode, Q_c_OU, SH_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->EvaporatingTemp);
11597 5269 : this->SH = SH_OU;
11598 :
11599 : // *VRF OU Compressor Simulation at heating mode: Specify the compressor speed and power consumption
11600 5269 : this->VRFOU_CalcCompH(state,
11601 : TU_HeatingLoad,
11602 : this->EvaporatingTemp,
11603 : Tdischarge,
11604 : h_IU_cond_out_ave,
11605 : this->IUCondensingTemp,
11606 : CapMinTe,
11607 : Tfs,
11608 : Pipe_Q_h,
11609 : Q_c_OU,
11610 : CompSpdActual,
11611 : Ncomp_new,
11612 : CyclingRatio);
11613 :
11614 5269 : converged_20 = (std::abs(Ncomp_new - Ncomp) <= (Tolerance * Ncomp)) || (Counter >= 30);
11615 5269 : Counter = Counter + 1;
11616 5269 : if (!converged_20) {
11617 2361 : Ncomp = Ncomp_new;
11618 : }
11619 5269 : } while (!converged_20);
11620 :
11621 : // Update h_comp_out in iteration Label23
11622 2908 : P_comp_in = this->refrig->getSatPressure(state, this->EvaporatingTemp, RoutineName);
11623 2908 : RefTSat = this->refrig->getSatTemperature(state, max(min(P_comp_in, RefPHigh), RefPLow), RoutineName);
11624 5816 : h_comp_in_new = this->refrig->getSupHeatEnthalpy(
11625 2908 : state, max(RefTSat, this->SH + this->EvaporatingTemp), max(min(P_comp_in, RefPHigh), RefPLow), RoutineName);
11626 2908 : h_comp_out_new = Ncomp_new / m_ref_IU_cond + h_comp_in_new;
11627 :
11628 2908 : converged_23 = !((std::abs(h_comp_out - h_comp_out_new) > Tolerance * h_comp_out) && (h_IU_cond_in < h_IU_cond_in_up));
11629 2908 : if (!converged_23) {
11630 1750 : h_IU_cond_in = h_IU_cond_in + 0.1 * (h_IU_cond_in_up - h_IU_cond_in_low);
11631 : } else {
11632 1158 : if (h_IU_cond_in > h_IU_cond_in_up) {
11633 0 : h_IU_cond_in = 0.5 * (h_IU_cond_in_up + h_IU_cond_in_low);
11634 : }
11635 1158 : Ncomp = Ncomp_new;
11636 1158 : break;
11637 : }
11638 : }
11639 1750 : } while (!converged_23);
11640 :
11641 : // Key outputs of this subroutine
11642 1158 : Q_c_OU *= CyclingRatio;
11643 1158 : this->CompActSpeed = max(CompSpdActual, 0.0);
11644 1158 : this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter;
11645 1158 : this->OUFanPower = this->RatedOUFanPower * CyclingRatio;
11646 1158 : this->VRFCondCyclingRatio = CyclingRatio;
11647 :
11648 1158 : Tsuction = this->EvaporatingTemp; // Outdoor unit evaporating temperature
11649 1158 : this->HeatingCapacity =
11650 1158 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), Tdischarge, Tsuction) +
11651 3474 : this->RatedCompPower * CurveValue(state,
11652 1158 : this->OUCoolingPWRFT(NumOfCompSpdInput),
11653 : Tdischarge,
11654 : Tsuction); // Include the piping loss, at the highest compressor speed
11655 1158 : this->PipingCorrectionHeating = TU_HeatingLoad / (TU_HeatingLoad + Pipe_Q_h);
11656 1158 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) =
11657 1158 : this->HeatingCapacity; // for report, maximum condensing capacity the system can provide
11658 :
11659 1158 : this->CoolingCapacity = 0.0; // Include the piping loss
11660 1158 : this->PipingCorrectionCooling = 1.0;
11661 1158 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond) = Constant::MaxCap; // for report
11662 :
11663 1158 : this->OUCondHeatRate = 0;
11664 1158 : this->OUEvapHeatRate = Q_c_OU;
11665 1158 : this->IUCondHeatRate = TU_HeatingLoad;
11666 1158 : this->IUEvapHeatRate = 0;
11667 :
11668 : // 3. VRF-HR Mode_2-5, Simultaneous Heating and Cooling
11669 39 : } else if (this->HeatRecoveryUsed && HRCoolRequestFlag && HRHeatRequestFlag) {
11670 :
11671 0 : this->OperatingMode = ModeCoolingAndHeating;
11672 :
11673 : // Initialization of VRF-FluidTCtrl Model
11674 0 : Q_c_TU_PL = TU_CoolingLoad;
11675 0 : Q_h_TU_PL = TU_HeatingLoad;
11676 :
11677 : // Evaporator (IU side) operational parameters
11678 0 : Pevap = this->refrig->getSatPressure(state, this->IUEvaporatingTemp, RoutineName);
11679 0 : Psuction = Pevap;
11680 0 : this->EvaporatingTemp = this->IUEvaporatingTemp;
11681 :
11682 : // Condenser (OU side) operation ranges
11683 0 : CapMaxPc = min(Psuction + this->CompMaxDeltaP, RefMaxPc);
11684 0 : CapMaxTc = this->refrig->getSatTemperature(state, max(min(CapMaxPc, RefPHigh), RefPLow), RoutineName);
11685 0 : CapMinTc = OutdoorDryBulb + this->SC;
11686 0 : CapMinPc = this->refrig->getSatPressure(state, CapMinTc, RoutineName);
11687 :
11688 : // Evaporator (IU side) operation ranges
11689 0 : CapMinPe = max(CapMinPc - this->CompMaxDeltaP, RefMinPe);
11690 0 : CapMinTe = this->refrig->getSatTemperature(state, max(min(CapMinPe, RefPHigh), RefPLow), RoutineName);
11691 :
11692 : //===**h_comp_out Iteration Starts
11693 :
11694 : // Initialization of h_comp_out iterations (Label230)
11695 : {
11696 0 : Pcond = this->refrig->getSatPressure(state, this->IUCondensingTemp, RoutineName);
11697 0 : Real64 Pcond_temp = this->refrig->getSatPressure(state, 40.0, RoutineName);
11698 0 : RefTSat = this->refrig->getSatTemperature(state, Pcond_temp, RoutineName);
11699 : h_IU_cond_in_up =
11700 0 : this->refrig->getSupHeatEnthalpy(state, max(RefTSat, min(this->IUCondensingTemp + 50, RefTHigh)), Pcond_temp, RoutineName);
11701 0 : h_IU_cond_in_low = this->refrig->getSatEnthalpy(state, this->IUCondensingTemp, 1.0, RoutineName); // Quality=1
11702 0 : h_IU_cond_in = h_IU_cond_in_low;
11703 : }
11704 :
11705 : bool converged_230;
11706 : do {
11707 : // *PL-h: Calculate total refrigerant flow rate
11708 0 : m_ref_IU_cond = 0;
11709 0 : h_IU_cond_out_ave = 0;
11710 0 : SC_IU_merged = 0;
11711 0 : for (NumTU = 1; NumTU <= NumTUInList; NumTU++) {
11712 0 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) > 0) {
11713 0 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
11714 0 : HeatCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex;
11715 : h_IU_cond_out_i =
11716 0 : this->refrig->getSatEnthalpy(state,
11717 0 : this->refrig->getSatTemperature(state, max(min(Pcond, RefPHigh), RefPLow), RoutineName) -
11718 0 : state.dataDXCoils->DXCoil(HeatCoilIndex).ActualSC,
11719 : 0.0,
11720 : RoutineName); // Quality=0
11721 0 : m_ref_IU_cond_i =
11722 0 : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) <= 0.0)
11723 0 : ? 0.0
11724 0 : : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) / (h_IU_cond_in - h_IU_cond_out_i));
11725 0 : m_ref_IU_cond = m_ref_IU_cond + m_ref_IU_cond_i;
11726 0 : h_IU_cond_out_ave = h_IU_cond_out_ave + m_ref_IU_cond_i * h_IU_cond_out_i;
11727 0 : SC_IU_merged = SC_IU_merged + m_ref_IU_cond_i * state.dataDXCoils->DXCoil(HeatCoilIndex).ActualSC;
11728 : }
11729 : }
11730 0 : if (m_ref_IU_cond > 0) {
11731 0 : h_IU_cond_out_ave = h_IU_cond_out_ave / m_ref_IU_cond;
11732 0 : SC_IU_merged = SC_IU_merged / m_ref_IU_cond;
11733 : } else {
11734 : h_IU_cond_out_ave =
11735 0 : this->refrig->getSatEnthalpy(state,
11736 0 : this->refrig->getSatTemperature(state, max(min(Pcond, RefPHigh), RefPLow), RoutineName) - 5.0,
11737 : 0.0,
11738 : RoutineName); // Quality=0
11739 0 : SC_IU_merged = 5;
11740 0 : m_ref_IU_cond = TU_HeatingLoad / (h_IU_cond_in - h_IU_cond_out_ave);
11741 : }
11742 :
11743 : // *PL-h: Calculate piping loss
11744 0 : this->VRFOU_PipeLossH(
11745 : state, m_ref_IU_cond, max(min(Pcond, RefPHigh), RefPLow), h_IU_cond_in, OutdoorDryBulb, Pipe_Q_h, Pipe_DeltP_h, h_comp_out);
11746 0 : Pdischarge = max(Pcond + Pipe_DeltP_h, Pcond); // affected by piping loss
11747 0 : Tdischarge = this->refrig->getSatTemperature(state, max(min(Pdischarge, RefPHigh), RefPLow), RoutineName);
11748 0 : Q_h_TU_PL = TU_HeatingLoad + Pipe_Q_h;
11749 :
11750 : // *PL-c: Calculate total IU refrigerant flow rate and SH_IU_merged
11751 0 : h_IU_evap_in = h_IU_cond_out_ave;
11752 0 : m_ref_IU_evap = 0;
11753 0 : h_IU_evap_out = 0;
11754 0 : SH_IU_merged = 0;
11755 0 : for (NumTU = 1; NumTU <= NumTUInList; NumTU++) { // Calc total refrigerant flow rate
11756 0 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) > 0) {
11757 0 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
11758 0 : CoolCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
11759 :
11760 0 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11761 : h_IU_evap_out_i =
11762 0 : this->refrig->getSupHeatEnthalpy(state,
11763 0 : max(RefTSat, this->IUEvaporatingTemp + state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH),
11764 : max(min(Pevap, RefPHigh), RefPLow),
11765 : RoutineName);
11766 :
11767 0 : if (h_IU_evap_out_i > h_IU_evap_in) {
11768 0 : m_ref_IU_evap_i = (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) <= 0.0)
11769 0 : ? 0.0
11770 0 : : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) /
11771 0 : (h_IU_evap_out_i - h_IU_evap_in)); // Ref Flow Rate in the IU( kg/s )
11772 0 : m_ref_IU_evap = m_ref_IU_evap + m_ref_IU_evap_i;
11773 0 : h_IU_evap_out = h_IU_evap_out + m_ref_IU_evap_i * h_IU_evap_out_i;
11774 0 : SH_IU_merged = SH_IU_merged + m_ref_IU_evap_i * state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH;
11775 : }
11776 : }
11777 : }
11778 0 : if (m_ref_IU_evap > 0) {
11779 0 : h_IU_evap_out = h_IU_evap_out / m_ref_IU_evap;
11780 0 : SH_IU_merged = SH_IU_merged / m_ref_IU_evap;
11781 : } else {
11782 0 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11783 0 : h_IU_evap_out = this->refrig->getSupHeatEnthalpy(
11784 0 : state, max(RefTSat, this->IUEvaporatingTemp + 3), max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11785 0 : SH_IU_merged = 3;
11786 0 : m_ref_IU_evap = TU_CoolingLoad / (h_IU_evap_out - h_IU_evap_in);
11787 : }
11788 :
11789 : // *PL-c: Calculate piping loss
11790 0 : this->VRFOU_PipeLossC(state,
11791 : m_ref_IU_evap,
11792 : max(min(Pevap, RefPHigh), RefPLow),
11793 : h_IU_evap_out,
11794 : SH_IU_merged,
11795 : OutdoorDryBulb,
11796 : Pipe_Q_c,
11797 : Pipe_DeltP_c,
11798 : h_IU_PLc_out);
11799 0 : Psuction = min(Pevap - Pipe_DeltP_c, Pevap); // This Psuction is used for rps > min; will be updated for rps = min
11800 0 : Tsuction = this->refrig->getSatTemperature(state, max(min(Psuction, RefPHigh), RefPLow), RoutineName);
11801 0 : h_comp_in = h_IU_PLc_out;
11802 0 : Q_c_TU_PL = TU_CoolingLoad + Pipe_Q_c;
11803 :
11804 : //**OU operations: Determine VRF-HR OU system operational mode
11805 : // Determine the operational mode of the VRF-HR system, given the terminal unit side load conditions.
11806 : // A number of OU side operational parameters are also calculated here, including:
11807 : // (1) OU evaporator load Q_c_OU, (2) OU condenser load Q_h_OU,
11808 : // (3) m_ref_OU_evap, (4) m_ref_OU_cond
11809 : // Note that Te and Te' may be updated here, and thus IU evaporator side piping loss recalculations.
11810 : // Then a number of operational parameters need to be updated, including:
11811 : // (1) IU evaporating temperature Te (2) OU evaporating temperature Te' etc (3) m_ref_IU_evap
11812 : // (4) Pipe_Q_c (5) h_IU_PLc_out (6) h_comp_in
11813 : //*VRF OU Compressor Simulation at HR mode: Specify the compressor speed and power consumption
11814 : {
11815 0 : Real64 Pipe_Q_c_new = Pipe_Q_c;
11816 0 : Real64 Tsuction_new = Tsuction;
11817 0 : Real64 Te_new = this->IUEvaporatingTemp;
11818 : Real64 N_fan_OU;
11819 :
11820 0 : this->VRFHR_OU_HR_Mode(state,
11821 : h_IU_evap_in,
11822 : h_comp_out,
11823 : Q_c_TU_PL,
11824 : Q_h_TU_PL,
11825 : Tdischarge,
11826 : Tsuction_new,
11827 : Te_new,
11828 : h_comp_in,
11829 : h_IU_PLc_out,
11830 : Pipe_Q_c_new,
11831 : Q_c_OU,
11832 : Q_h_OU,
11833 : m_ref_IU_evap,
11834 : m_ref_OU_evap,
11835 : m_ref_OU_cond,
11836 : N_fan_OU,
11837 : CompSpdActual,
11838 : Ncomp);
11839 :
11840 : // parameter update
11841 0 : Tsuction = Tsuction_new;
11842 0 : Pipe_Q_c = Pipe_Q_c_new;
11843 0 : this->OUFanPower = N_fan_OU;
11844 0 : this->IUEvaporatingTemp = Te_new;
11845 : }
11846 :
11847 : //* Update h_comp_out in iteration (Label230)
11848 0 : h_comp_out_new = Ncomp / (m_ref_IU_evap + m_ref_OU_evap) + h_comp_in;
11849 :
11850 0 : converged_230 = !((std::abs(h_comp_out - h_comp_out_new) > Tolerance * h_comp_out) && (h_IU_cond_in < h_IU_cond_in_up));
11851 0 : h_IU_cond_in = h_IU_cond_in + 0.1 * (h_IU_cond_in_up - h_IU_cond_in_low);
11852 0 : } while (!converged_230);
11853 0 : if (h_IU_cond_in > h_IU_cond_in_up) {
11854 0 : h_IU_cond_in = 0.5 * (h_IU_cond_in_up + h_IU_cond_in_low);
11855 : }
11856 :
11857 : //===**h_comp_out Iteration Ends (Label230)
11858 :
11859 : // Key outputs of this subroutine
11860 0 : this->CompActSpeed = max(CompSpdActual, 0.0);
11861 0 : this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter;
11862 0 : this->VRFCondCyclingRatio = 1.0;
11863 :
11864 0 : this->HeatingCapacity =
11865 0 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), Tdischarge, Tsuction) +
11866 0 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(NumOfCompSpdInput), Tdischarge, Tsuction); // Include the piping loss
11867 0 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) =
11868 0 : this->HeatingCapacity; // for report, maximum heating capacity of the system, at the highest compressor speed
11869 0 : this->PipingCorrectionHeating = TU_HeatingLoad / Q_h_TU_PL;
11870 :
11871 0 : this->CoolingCapacity =
11872 0 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), Tdischarge, Tsuction);
11873 0 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond) =
11874 0 : this->CoolingCapacity; // for report, maximum evaporating capacity of the system, at the highest compressor speed
11875 0 : this->PipingCorrectionCooling = TU_CoolingLoad / Q_c_TU_PL;
11876 :
11877 0 : this->CondensingTemp = Tdischarge; // OU condensing temperature
11878 0 : this->EvaporatingTemp = Tsuction; // OU evaporating temperature
11879 :
11880 0 : this->OUCondHeatRate = Q_h_OU;
11881 0 : this->OUEvapHeatRate = Q_c_OU;
11882 0 : this->IUCondHeatRate = TU_HeatingLoad;
11883 0 : this->IUEvapHeatRate = TU_CoolingLoad;
11884 :
11885 : // 4. Stop running
11886 0 : } else {
11887 :
11888 39 : this->OperatingMode = 0;
11889 39 : this->VRFOperationSimPath = 0;
11890 :
11891 39 : this->Ncomp = 0.0;
11892 39 : this->CompActSpeed = 0.0;
11893 39 : this->OUFanPower = 0.0;
11894 39 : this->VRFCondCyclingRatio = 0.0;
11895 :
11896 39 : this->HeatingCapacity = 0.0; // Include the piping loss
11897 39 : this->PipingCorrectionHeating = 1.0; // 1 means no piping loss
11898 39 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) = Constant::MaxCap; // yujie: default value is MaxCap = 1e+20, not 0
11899 :
11900 39 : this->CoolingCapacity = 0.0; // Include the piping loss
11901 39 : this->PipingCorrectionCooling = 1.0;
11902 39 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond) = Constant::MaxCap; // for report
11903 :
11904 39 : this->CondensingTemp = state.dataEnvrn->OutDryBulbTemp;
11905 39 : this->EvaporatingTemp = state.dataEnvrn->OutDryBulbTemp;
11906 :
11907 39 : this->OUCondHeatRate = 0.0;
11908 39 : this->OUEvapHeatRate = 0.0;
11909 39 : this->IUCondHeatRate = 0.0;
11910 39 : this->IUEvapHeatRate = 0.0;
11911 : }
11912 :
11913 : // calculate capacities and energy use
11914 3539 : if (((!this->HeatRecoveryUsed && state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) || (this->HeatRecoveryUsed && HRCoolRequestFlag)) &&
11915 1171 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).CoolingCoilPresent(NumTUInList)) {
11916 1171 : InletAirWetBulbC = SumCoolInletWB;
11917 :
11918 : // From the VRF_FluidTCtrl model
11919 1171 : TotalCondCoolingCapacity = this->CoolingCapacity;
11920 1171 : TotalTUCoolingCapacity = TotalCondCoolingCapacity * this->PipingCorrectionCooling;
11921 :
11922 1171 : if (TotalCondCoolingCapacity > 0.0) {
11923 1171 : CoolingPLR = min(1.0, (this->TUCoolingLoad / this->PipingCorrectionCooling) / TotalCondCoolingCapacity);
11924 : } else {
11925 0 : CoolingPLR = 0.0;
11926 : }
11927 : }
11928 3526 : if (((!this->HeatRecoveryUsed && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) || (this->HeatRecoveryUsed && HRHeatRequestFlag)) &&
11929 1158 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HeatingCoilPresent(NumTUInList)) {
11930 1158 : InletAirDryBulbC = SumHeatInletDB;
11931 1158 : InletAirWetBulbC = SumHeatInletWB;
11932 :
11933 : // Initializing defrost adjustment factors
11934 1158 : LoadDueToDefrost = 0.0;
11935 1158 : HeatingCapacityMultiplier = 1.0;
11936 1158 : FractionalDefrostTime = 0.0;
11937 1158 : InputPowerMultiplier = 1.0;
11938 :
11939 : // Check outdoor temperature to determine of defrost is active
11940 1158 : if (OutdoorDryBulb <= this->MaxOATDefrost && this->CondenserType != DataHeatBalance::RefrigCondenserType::Water) {
11941 :
11942 : // Calculating adjustment factors for defrost
11943 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
11944 0 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
11945 0 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
11946 :
11947 : // Calculate defrost adjustment factors depending on defrost control type
11948 0 : if (this->DefrostControl == StandardRatings::HPdefrostControl::Timed) {
11949 0 : FractionalDefrostTime = this->DefrostFraction;
11950 0 : if (FractionalDefrostTime > 0.0) {
11951 0 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
11952 0 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
11953 : }
11954 : } else { // else defrost control is on-demand
11955 0 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
11956 0 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
11957 0 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
11958 : }
11959 :
11960 0 : if (FractionalDefrostTime > 0.0) {
11961 : // Calculate defrost adjustment factors depending on defrost control strategy
11962 0 : if (this->DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle &&
11963 0 : this->DefrostControl == StandardRatings::HPdefrostControl::OnDemand) {
11964 0 : LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (this->HeatingCapacity / 1.01667);
11965 0 : DefrostEIRTempModFac = CurveValue(state, this->DefrostEIRPtr, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
11966 :
11967 : // Warn user if curve output goes negative
11968 0 : if (DefrostEIRTempModFac < 0.0) {
11969 0 : if (!state.dataGlobal->WarmupFlag) {
11970 0 : if (this->DefrostHeatErrorIndex == 0) {
11971 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), this->Name));
11972 0 : ShowContinueError(
11973 : state,
11974 0 : format(" Defrost Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).",
11975 : DefrostEIRTempModFac));
11976 0 : ShowContinueError(state,
11977 0 : format(" Negative value occurs using an outdoor air dry-bulb temperature of {:.1T} C and an "
11978 : "average indoor air wet-bulb temperature of {:.1T} C.",
11979 : OutdoorDryBulb,
11980 : InletAirWetBulbC));
11981 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
11982 : }
11983 0 : ShowRecurringWarningErrorAtEnd(state,
11984 0 : format("{} \"{}\": Defrost Energy Input Ratio Modifier curve (function of temperature) "
11985 : "output is negative warning continues...",
11986 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
11987 0 : this->Name),
11988 0 : this->DefrostHeatErrorIndex,
11989 : DefrostEIRTempModFac,
11990 : DefrostEIRTempModFac);
11991 0 : DefrostEIRTempModFac = 0.0;
11992 : }
11993 : }
11994 :
11995 0 : this->DefrostPower = DefrostEIRTempModFac * (this->HeatingCapacity / 1.01667) * FractionalDefrostTime;
11996 :
11997 : } else { // Defrost strategy is resistive
11998 0 : this->DefrostPower = this->DefrostCapacity * FractionalDefrostTime;
11999 : }
12000 : } else { // Defrost is not active because FractionalDefrostTime = 0.0
12001 0 : this->DefrostPower = 0.0;
12002 : }
12003 : }
12004 :
12005 : // From the VRF_FluidTCtrl model
12006 1158 : TotalCondHeatingCapacity = this->HeatingCapacity;
12007 1158 : TotalTUHeatingCapacity = TotalCondHeatingCapacity * this->PipingCorrectionHeating;
12008 :
12009 1158 : if (TotalCondHeatingCapacity > 0.0) {
12010 1158 : HeatingPLR = min(1.0, (this->TUHeatingLoad / this->PipingCorrectionHeating) / TotalCondHeatingCapacity);
12011 1158 : HeatingPLR += (LoadDueToDefrost * HeatingPLR) / TotalCondHeatingCapacity;
12012 : } else {
12013 0 : HeatingPLR = 0.0;
12014 : }
12015 : }
12016 :
12017 2368 : this->VRFCondPLR = max(CoolingPLR, HeatingPLR);
12018 :
12019 : // For VRF-HR Operations
12020 2368 : HRInitialCapFrac = 1.0;
12021 2368 : HRInitialEIRFrac = 1.0;
12022 2368 : HRCapTC = 0.0;
12023 2368 : HREIRTC = 0.0;
12024 2368 : if (!state.dataGlobal->DoingSizing && !state.dataGlobal->WarmupFlag) {
12025 577 : if (HRHeatRequestFlag && HRCoolRequestFlag) { // Simultaneous Heating and Cooling operations for HR system
12026 : // determine operating mode change: (1) ModeChange (2) HRCoolingActive (3) HRHeatingActive
12027 0 : if (!this->HRCoolingActive && !this->HRHeatingActive) {
12028 0 : this->ModeChange = true;
12029 : }
12030 0 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
12031 0 : if (this->HRHeatingActive && !this->HRCoolingActive) {
12032 0 : this->HRModeChange = true;
12033 : }
12034 0 : this->HRCoolingActive = true;
12035 0 : this->HRHeatingActive = false;
12036 :
12037 0 : HRInitialCapFrac = this->HRInitialCoolCapFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
12038 0 : HRCapTC = this->HRCoolCapTC; // Time constant used to recover from initial degradation in cooling heat recovery
12039 :
12040 0 : HRInitialEIRFrac = this->HRInitialCoolEIRFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
12041 0 : HREIRTC = this->HRCoolEIRTC; // Time constant used to recover from initial degradation in cooling heat recovery
12042 :
12043 0 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
12044 0 : if (!this->HRHeatingActive && this->HRCoolingActive) {
12045 0 : this->HRModeChange = true;
12046 : }
12047 0 : this->HRCoolingActive = false;
12048 0 : this->HRHeatingActive = true;
12049 :
12050 0 : HRInitialCapFrac = this->HRInitialHeatCapFrac; // Fractional heating degradation at the start of heat recovery from cooling mode
12051 0 : HRCapTC = this->HRHeatCapTC; // Time constant used to recover from initial degradation in heating heat recovery
12052 :
12053 0 : HRInitialEIRFrac = this->HRInitialHeatEIRFrac; // Fractional heating degradation at the start of heat recovery from heating mode
12054 0 : HREIRTC = this->HRHeatEIRTC; // Time constant used to recover from initial degradation in heating heat recovery
12055 :
12056 : } else {
12057 : // zone thermostats satisfied, condenser is off. Set values anyway
12058 : // HRCAPFTConst = 1.0;
12059 0 : HRInitialCapFrac = 1.0;
12060 0 : HRCapTC = 1.0;
12061 : // HREIRFTConst = 1.0;
12062 0 : HRInitialEIRFrac = 1.0;
12063 0 : HREIRTC = 1.0;
12064 0 : if (this->HRHeatingActive || this->HRCoolingActive) {
12065 0 : this->HRModeChange = true;
12066 : }
12067 0 : this->HRCoolingActive = false;
12068 0 : this->HRHeatingActive = false;
12069 : }
12070 :
12071 : } else { // IF(HRHeatRequestFlag .AND. HRCoolRequestFlag)THEN -- Heat recovery turned off
12072 577 : HRInitialCapFrac = 1.0;
12073 577 : HRCapTC = 0.0;
12074 577 : HRInitialEIRFrac = 1.0;
12075 577 : HREIRTC = 0.0;
12076 577 : this->HRModeChange = false;
12077 577 : this->HRCoolingActive = false;
12078 577 : this->HRHeatingActive = false;
12079 : }
12080 :
12081 : // Calculate the capacity modification factor (SUMultiplier) for the HR mode transition period
12082 : {
12083 577 : CurrentEndTime = double((state.dataGlobal->DayOfSim - 1) * 24) + state.dataGlobal->CurrentTime - state.dataGlobal->TimeStepZone +
12084 577 : state.dataHVACGlobal->SysTimeElapsed;
12085 :
12086 577 : if (this->ModeChange || this->HRModeChange) {
12087 0 : if (this->HRCoolingActive && this->HRTimer == 0.0) {
12088 0 : this->HRTimer = state.dataHVACVarRefFlow->CurrentEndTimeLast;
12089 0 : } else if (this->HRHeatingActive && this->HRTimer == 0.0) {
12090 0 : this->HRTimer = state.dataHVACVarRefFlow->CurrentEndTimeLast;
12091 0 : } else if (!this->HRCoolingActive && !this->HRHeatingActive) {
12092 0 : this->HRTimer = 0.0;
12093 : }
12094 : }
12095 :
12096 577 : this->HRTime = max(0.0, CurrentEndTime - this->HRTimer);
12097 577 : if (this->HRTime < (HRCapTC * 5.0)) {
12098 0 : if (HRCapTC > 0.0) {
12099 0 : SUMultiplier = min(1.0, 1.0 - std::exp(-this->HRTime / HRCapTC));
12100 : } else {
12101 0 : SUMultiplier = 1.0;
12102 : }
12103 : } else {
12104 577 : SUMultiplier = 1.0;
12105 577 : this->ModeChange = false;
12106 577 : this->HRModeChange = false;
12107 : }
12108 577 : this->SUMultiplier = SUMultiplier;
12109 :
12110 577 : state.dataHVACVarRefFlow->CurrentEndTimeLast = CurrentEndTime;
12111 : }
12112 :
12113 : // Modify HR capacity for the transition period
12114 : {
12115 577 : if (this->HeatRecoveryUsed && this->HRCoolingActive) {
12116 0 : TotalCondCoolingCapacity =
12117 0 : HRInitialCapFrac * TotalCondCoolingCapacity + (1.0 - HRInitialCapFrac) * TotalCondCoolingCapacity * SUMultiplier;
12118 0 : TotalTUCoolingCapacity = TotalCondCoolingCapacity * this->PipingCorrectionCooling;
12119 0 : if (TotalCondCoolingCapacity > 0.0) {
12120 0 : CoolingPLR = min(1.0, (this->TUCoolingLoad / this->PipingCorrectionCooling) / TotalCondCoolingCapacity);
12121 : } else {
12122 0 : CoolingPLR = 0.0;
12123 : }
12124 0 : this->VRFHeatRec = this->TUHeatingLoad;
12125 577 : } else if (this->HeatRecoveryUsed && this->HRHeatingActive) {
12126 0 : TotalCondHeatingCapacity =
12127 0 : HRInitialCapFrac * TotalCondHeatingCapacity + (1.0 - HRInitialCapFrac) * TotalCondHeatingCapacity * SUMultiplier;
12128 0 : TotalTUHeatingCapacity = TotalCondHeatingCapacity * this->PipingCorrectionHeating;
12129 0 : if (TotalCondHeatingCapacity > 0.0) {
12130 0 : HeatingPLR = min(1.0, (this->TUHeatingLoad / this->PipingCorrectionHeating) / TotalCondHeatingCapacity);
12131 : } else {
12132 0 : HeatingPLR = 0.0;
12133 : }
12134 0 : this->VRFHeatRec = this->TUCoolingLoad;
12135 : }
12136 :
12137 577 : this->VRFCondPLR = max(CoolingPLR, HeatingPLR);
12138 : }
12139 : }
12140 :
12141 2368 : this->TotalCoolingCapacity = TotalCondCoolingCapacity * CoolingPLR;
12142 2368 : this->TotalHeatingCapacity = TotalCondHeatingCapacity * HeatingPLR;
12143 :
12144 2368 : if (this->MinPLR > 0.0) {
12145 0 : bool const plrTooLow = this->VRFCondPLR < this->MinPLR;
12146 0 : bool const plrGreaterThanZero = this->VRFCondPLR > 0.0;
12147 0 : if (plrTooLow && plrGreaterThanZero) {
12148 0 : this->VRFCondPLR = this->MinPLR;
12149 : }
12150 : }
12151 :
12152 2368 : VRFRTF = 0.0;
12153 : // VRF Cooling and Heating Electric Power (output variables)
12154 2368 : if (this->OperatingMode == ModeCoolingOnly) {
12155 1171 : PartLoadFraction = 1.0;
12156 1171 : VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));
12157 :
12158 1171 : this->ElecCoolingPower = state.dataHVACVarRefFlow->VRF(VRFCond).Ncomp + this->OUFanPower;
12159 1171 : this->ElecHeatingPower = 0;
12160 :
12161 1197 : } else if (this->OperatingMode == ModeHeatingOnly) {
12162 1158 : PartLoadFraction = 1.0;
12163 1158 : VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));
12164 :
12165 1158 : this->ElecCoolingPower = 0;
12166 1158 : this->ElecHeatingPower = this->Ncomp + this->OUFanPower;
12167 :
12168 39 : } else if (this->OperatingMode == ModeCoolingAndHeating) {
12169 0 : PartLoadFraction = 1.0;
12170 0 : VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));
12171 :
12172 0 : this->ElecCoolingPower = (this->Ncomp + this->OUFanPower) * this->IUEvapHeatRate / (this->IUCondHeatRate + this->IUEvapHeatRate);
12173 0 : this->ElecHeatingPower = (this->Ncomp + this->OUFanPower) * this->IUCondHeatRate / (this->IUCondHeatRate + this->IUEvapHeatRate);
12174 :
12175 : } else {
12176 39 : this->ElecCoolingPower = 0;
12177 39 : this->ElecHeatingPower = 0;
12178 : }
12179 2368 : this->VRFCondRTF = VRFRTF;
12180 2368 : this->DefrostPower *= VRFRTF;
12181 :
12182 : // Calculate CrankCaseHeaterPower: VRF Heat Pump Crankcase Heater Electric Power [W]
12183 2368 : if (this->MaxOATCCHeater > OutdoorDryBulb) {
12184 : // calculate crankcase heater power
12185 0 : this->CrankCaseHeaterPower = this->CCHeaterPower * (1.0 - VRFRTF);
12186 0 : if (this->NumCompressors > 1) {
12187 0 : UpperStageCompressorRatio = (1.0 - this->CompressorSizeRatio) / (this->NumCompressors - 1);
12188 0 : for (Stage = 1; Stage <= this->NumCompressors - 2; ++Stage) {
12189 0 : if (this->VRFCondPLR < (this->CompressorSizeRatio + Stage * UpperStageCompressorRatio)) {
12190 0 : this->CrankCaseHeaterPower += this->CCHeaterPower;
12191 : }
12192 : }
12193 : }
12194 : } else {
12195 2368 : this->CrankCaseHeaterPower = 0.0;
12196 : }
12197 :
12198 : // Calculate QCondenser: VRF Heat Pump Condenser Heat Transfer Rate [W]
12199 2368 : CondCapacity = max(this->TotalCoolingCapacity, this->TotalHeatingCapacity) * VRFRTF;
12200 2368 : CondPower = max(this->ElecCoolingPower, this->ElecHeatingPower);
12201 2368 : if (this->ElecHeatingPower > 0.0) {
12202 1158 : this->QCondenser = CondCapacity + CondPower - this->TUHeatingLoad / this->PipingCorrectionHeating;
12203 1210 : } else if (this->ElecCoolingPower > 0.0) {
12204 1171 : this->QCondenser = -CondCapacity + CondPower + this->TUCoolingLoad / this->PipingCorrectionCooling;
12205 : } else {
12206 39 : this->QCondenser = 0.0;
12207 : }
12208 : // if ( this->CondenserType == HVAC::EvapCooled )
12209 :
12210 : // Calculate OperatingHeatingCOP & OperatingCoolingCOP: VRF Heat Pump Operating COP []
12211 2368 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && CoolingPLR > 0.0) {
12212 1171 : if (this->ElecCoolingPower != 0.0) {
12213 : // this calc should use delivered capacity, not condenser capacity, use VRF(VRFCond).TUCoolingLoad
12214 1171 : this->OperatingCoolingCOP = (this->TotalCoolingCapacity) /
12215 1171 : (this->ElecCoolingPower + this->CrankCaseHeaterPower + this->EvapCondPumpElecPower + this->DefrostPower);
12216 : } else {
12217 0 : this->OperatingCoolingCOP = 0.0;
12218 : }
12219 : }
12220 2368 : if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && HeatingPLR > 0.0) {
12221 : // this calc should use delivered capacity, not condenser capacity, use VRF(VRFCond).TUHeatingLoad
12222 1158 : if (this->ElecHeatingPower != 0.0) {
12223 1158 : this->OperatingHeatingCOP = (this->TotalHeatingCapacity) /
12224 1158 : (this->ElecHeatingPower + this->CrankCaseHeaterPower + this->EvapCondPumpElecPower + this->DefrostPower);
12225 : } else {
12226 0 : this->OperatingHeatingCOP = 0.0;
12227 : }
12228 : }
12229 :
12230 2368 : TotPower = TUParasiticPower + TUFanPower + this->ElecHeatingPower + this->ElecCoolingPower + this->CrankCaseHeaterPower +
12231 2368 : this->EvapCondPumpElecPower + this->DefrostPower;
12232 2368 : if (TotPower > 0.0) {
12233 2368 : this->OperatingCOP = (this->TUCoolingLoad + this->TUHeatingLoad) / TotPower;
12234 2368 : this->SCHE = this->OperatingCOP * 3.412141633; // see StandardRatings::ConvFromSIToIP
12235 : }
12236 :
12237 : // limit the TU capacity when the condenser is maxed out on capacity
12238 : // I think this next line will make the max cap report variable match the coil objects, will probably change the answer though
12239 : // IF(CoolingLoad(VRFCond) .AND. NumTUInCoolingMode .GT. 0 .AND. MaxCoolingCapacity(VRFCond) == MaxCap)THEN
12240 2368 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && NumTUInCoolingMode > 0) {
12241 :
12242 : // IF TU capacity is greater than condenser capacity find maximum allowed TU capacity (i.e., conserve energy)
12243 1171 : if (TU_CoolingLoad > TotalTUCoolingCapacity) {
12244 0 : LimitTUCapacity(state,
12245 : VRFCond,
12246 : NumTUInList,
12247 : TotalTUCoolingCapacity,
12248 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad,
12249 0 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond),
12250 : TotalTUHeatingCapacity,
12251 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad,
12252 0 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
12253 : }
12254 1197 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && NumTUInHeatingMode > 0) {
12255 : // IF TU capacity is greater than condenser capacity
12256 1158 : if (TU_HeatingLoad > TotalTUHeatingCapacity) {
12257 0 : LimitTUCapacity(state,
12258 : VRFCond,
12259 : NumTUInList,
12260 : TotalTUHeatingCapacity,
12261 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad,
12262 0 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond),
12263 : TotalTUCoolingCapacity,
12264 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad,
12265 0 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond));
12266 : }
12267 : } else {
12268 : }
12269 :
12270 : // Calculate the IU Te/Tc for the next time step
12271 2368 : this->CalcVRFIUTeTc_FluidTCtrl(state);
12272 : // update coil and IU evaporating temperature, also keep coil RTF updated with the condenser side cycling ratio, for the FluidTCtrl model
12273 4736 : for (int VRFTUNum = 1; VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU; ++VRFTUNum) {
12274 2368 : auto const &thisTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
12275 2368 : auto &coolingCoil = state.dataDXCoils->DXCoil(thisTU.CoolCoilIndex);
12276 2368 : if (this->adjustedTe && (!FirstHVACIteration)) {
12277 65 : coolingCoil.EvaporatingTemp = this->EvaporatingTemp;
12278 65 : this->IUEvaporatingTemp = this->EvaporatingTemp;
12279 : }
12280 :
12281 : int PLF;
12282 2368 : if (coolingCoil.PLFFPLR(1) > 0 && this->VRFCondCyclingRatio < 1.0) {
12283 0 : PLF = Curve::CurveValue(state, coolingCoil.PLFFPLR(1), this->VRFCondCyclingRatio); // Calculate part-load factor
12284 : } else {
12285 2368 : PLF = 1.0;
12286 : }
12287 2368 : if (coolingCoil.TotalCoolingEnergyRate > 0.0) {
12288 1171 : coolingCoil.CoolingCoilRuntimeFraction = this->VRFCondCyclingRatio / PLF;
12289 : }
12290 : }
12291 2368 : }
12292 :
12293 2378 : void VRFTerminalUnitEquipment::ControlVRF_FluidTCtrl(EnergyPlusData &state,
12294 : int const VRFTUNum, // Index to VRF terminal unit
12295 : Real64 const QZnReq, // Index to zone number
12296 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
12297 : Real64 &PartLoadRatio, // unit part load ratio
12298 : Real64 &OnOffAirFlowRatio, // ratio of compressor ON airflow to AVERAGE airflow over timestep
12299 : Real64 &SuppHeatCoilLoad // supplemental heating coil load (W)
12300 : )
12301 : {
12302 :
12303 : // SUBROUTINE INFORMATION:
12304 : // AUTHOR Rongpeng Zhang
12305 : // DATE WRITTEN Nov 2015
12306 : // MODIFIED na
12307 : // RE-ENGINEERED na
12308 :
12309 : // PURPOSE OF THIS SUBROUTINE:
12310 : // Determine the coil load and part load ratio, given the zone load
12311 : // Determine the air mass flow rate corresponding to the coil load of the heat pump for this time step
12312 :
12313 : // METHODOLOGY EMPLOYED:
12314 : // Use RegulaFalsi technique to iterate on part-load ratio until convergence is achieved.
12315 :
12316 : using General::SolveRoot;
12317 :
12318 2378 : int constexpr MaxIte(500); // maximum number of iterations
12319 2378 : Real64 constexpr MinPLF(0.0); // minimum part load factor allowed
12320 2378 : Real64 constexpr ErrorTol(0.001); // tolerance for RegulaFalsi iterations
12321 :
12322 : Real64 FullOutput; // unit full output when compressor is operating [W]
12323 : Real64 TempOutput; // unit output when iteration limit exceeded [W]
12324 : Real64 NoCompOutput; // output when no active compressor [W]
12325 : Real64 TempMinPLR; // min PLR used in Regula Falsi call
12326 : Real64 TempMaxPLR; // max PLR used in Regula Falsi call
12327 : int VRFCond; // index to VRF condenser
12328 : int IndexToTUInTUList; // index to TU in specific list for the VRF system
12329 : int TUListIndex; // index to TU list for this VRF system
12330 : bool VRFCoolingMode;
12331 : bool VRFHeatingMode;
12332 : bool HRCoolingMode;
12333 : bool HRHeatingMode;
12334 :
12335 2378 : PartLoadRatio = 0.0;
12336 2378 : state.dataHVACVarRefFlow->LoopDXCoolCoilRTF = 0.0;
12337 2378 : state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = 0.0;
12338 2378 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatPartLoadRatio = 0.0;
12339 2378 : VRFCond = this->VRFSysNum;
12340 2378 : IndexToTUInTUList = this->IndexToTUInTUList;
12341 2378 : auto &thisVRFCond = state.dataHVACVarRefFlow->VRF(VRFCond);
12342 2378 : TUListIndex = thisVRFCond.ZoneTUListPtr;
12343 2378 : VRFCoolingMode = state.dataHVACVarRefFlow->CoolingLoad(VRFCond);
12344 2378 : VRFHeatingMode = state.dataHVACVarRefFlow->HeatingLoad(VRFCond);
12345 2378 : HRCoolingMode = state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList);
12346 2378 : HRHeatingMode = state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList);
12347 2378 : auto &thisVRFTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
12348 :
12349 : // The RETURNS here will jump back to SimVRF where the CalcVRF routine will simulate with latest PLR
12350 :
12351 : // do nothing else if TU is scheduled off
12352 2419 : if (this->availSched->getCurrentVal() == 0.0) return;
12353 :
12354 : // Block the following statement: QZnReq==0 doesn't mean QCoilReq==0 due to possible OA mixer operation. zrp_201511
12355 : // do nothing if TU has no load (TU will be modeled using PLR=0)
12356 : // if ( QZnReq == 0.0 ) return;
12357 :
12358 : // Set EMS value for PLR and return
12359 2378 : if (this->EMSOverridePartLoadFrac) {
12360 0 : PartLoadRatio = this->EMSValueForPartLoadFrac;
12361 0 : return;
12362 : }
12363 :
12364 : // Get result when DX coil is off
12365 2378 : PartLoadRatio = 0.0;
12366 2378 : bool DXCoolingCoilOprCtrl = true;
12367 :
12368 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
12369 2378 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, 0.0, NoCompOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
12370 :
12371 2378 : if (VRFCoolingMode && HRHeatingMode) {
12372 : // IF the system is in cooling mode, but the terminal unit requests heating (heat recovery)
12373 0 : if (NoCompOutput >= QZnReq) return;
12374 2378 : } else if (VRFHeatingMode && HRCoolingMode) {
12375 : // IF the system is in heating mode, but the terminal unit requests cooling (heat recovery)
12376 0 : if (NoCompOutput <= QZnReq) return;
12377 2378 : } else if (VRFCoolingMode || HRCoolingMode) {
12378 : // IF the system is in cooling mode and/or the terminal unit requests cooling
12379 1180 : if (NoCompOutput <= QZnReq && ((QZnReq <= 0.0) || (QZnReq >= HVAC::SmallLoad && !HRCoolingMode))) {
12380 4 : DXCoolingCoilOprCtrl = false;
12381 4 : if (!this->SuppHeatingCoilPresent) {
12382 0 : return;
12383 : }
12384 : }
12385 1198 : } else if (VRFHeatingMode || HRHeatingMode) {
12386 : // IF the system is in heating mode and/or the terminal unit requests heating
12387 1158 : if (NoCompOutput >= QZnReq) return;
12388 : }
12389 :
12390 : // Otherwise the coil needs to turn on. Get full load result
12391 2378 : PartLoadRatio = 1.0;
12392 2378 : if (!DXCoolingCoilOprCtrl) PartLoadRatio = 0.0;
12393 2378 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, PartLoadRatio, FullOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
12394 2378 : if (this->CoolingCoilPresent) {
12395 2378 : auto const &thisAirInNode = state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(this->CoolCoilIndex).AirInNode);
12396 2378 : this->coilInNodeT = thisAirInNode.Temp;
12397 2378 : this->coilInNodeW = thisAirInNode.HumRat;
12398 : } else {
12399 0 : auto const &thisAirInNode = state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(this->HeatCoilIndex).AirInNode);
12400 0 : this->coilInNodeT = thisAirInNode.Temp;
12401 0 : this->coilInNodeW = thisAirInNode.HumRat;
12402 : }
12403 :
12404 : // set supplemental heating coil calculation if the condition requires
12405 2378 : if (this->SuppHeatingCoilPresent) {
12406 6 : auto const &thisSuppHeatCoilAirInletNode = state.dataLoopNodes->Node(this->SuppHeatCoilAirInletNode);
12407 6 : if (((QZnReq > HVAC::SmallLoad && QZnReq > FullOutput) || (((QZnReq - NoCompOutput) > HVAC::SmallLoad) && QZnReq <= 0.0)) ||
12408 2 : (this->isSetPointControlled && this->suppTempSetPoint > thisSuppHeatCoilAirInletNode.Temp)) {
12409 4 : Real64 ZoneLoad = 0.0;
12410 4 : Real64 LoadToHeatingSP = 0.0;
12411 4 : Real64 LoadToCoolingSP = 0.0;
12412 4 : if (this->isSetPointControlled) {
12413 0 : Real64 mDot = thisSuppHeatCoilAirInletNode.MassFlowRate;
12414 0 : Real64 Tin = thisSuppHeatCoilAirInletNode.Temp;
12415 0 : Real64 Win = thisSuppHeatCoilAirInletNode.HumRat;
12416 0 : Real64 CpAirIn = Psychrometrics::PsyCpAirFnW(Win);
12417 0 : SuppHeatCoilLoad = mDot * CpAirIn * (this->suppTempSetPoint - Tin);
12418 0 : this->SuppHeatingCoilLoad = SuppHeatCoilLoad;
12419 0 : if (this->DesignSuppHeatingCapacity > 0.0) {
12420 0 : this->SuppHeatPartLoadRatio = min(1.0, SuppHeatCoilLoad / this->DesignSuppHeatingCapacity);
12421 : }
12422 : } else {
12423 4 : getVRFTUZoneLoad(state, VRFTUNum, ZoneLoad, LoadToHeatingSP, LoadToCoolingSP, false);
12424 4 : if (((FullOutput < (LoadToHeatingSP - HVAC::SmallLoad) || ((QZnReq - NoCompOutput) > HVAC::SmallLoad && QZnReq <= 0.0))) &&
12425 4 : !FirstHVACIteration) {
12426 2 : if ((QZnReq - NoCompOutput) > HVAC::SmallLoad && QZnReq <= 0.0) {
12427 0 : if (LoadToHeatingSP < 0.0 && QZnReq == 0.0) {
12428 0 : SuppHeatCoilLoad = max(0.0, LoadToHeatingSP - FullOutput);
12429 : } else {
12430 0 : SuppHeatCoilLoad = max(0.0, QZnReq - FullOutput);
12431 : }
12432 : } else {
12433 2 : if (QZnReq > 0.0 && (NoCompOutput - QZnReq) >= HVAC::SmallLoad) {
12434 0 : SuppHeatCoilLoad = 0.0;
12435 : } else {
12436 2 : SuppHeatCoilLoad = max(0.0, LoadToHeatingSP - FullOutput);
12437 : }
12438 : }
12439 2 : this->SuppHeatingCoilLoad = SuppHeatCoilLoad;
12440 2 : if (this->DesignSuppHeatingCapacity > 0.0) {
12441 2 : this->SuppHeatPartLoadRatio = min(1.0, SuppHeatCoilLoad / this->DesignSuppHeatingCapacity);
12442 : }
12443 : } else {
12444 2 : SuppHeatCoilLoad = 0.0;
12445 2 : this->SuppHeatPartLoadRatio = 0.0;
12446 : }
12447 : }
12448 4 : } else {
12449 2 : SuppHeatCoilLoad = 0.0;
12450 2 : this->SuppHeatPartLoadRatio = 0.0;
12451 : }
12452 : } else {
12453 2372 : SuppHeatCoilLoad = 0.0;
12454 2372 : this->SuppHeatPartLoadRatio = 0.0;
12455 : }
12456 :
12457 2378 : if ((VRFCoolingMode && !thisVRFCond.HeatRecoveryUsed) || (thisVRFCond.HeatRecoveryUsed && HRCoolingMode)) {
12458 : // Since we are cooling, we expect FullOutput < NoCompOutput
12459 : // If the QZnReq <= FullOutput the unit needs to run full out
12460 1180 : if (QZnReq <= FullOutput) {
12461 : // if no coil present in terminal unit, no need to reset PLR?
12462 1 : if (thisVRFTU.CoolingCoilPresent) {
12463 1 : PartLoadRatio = 1.0;
12464 : // the zone set point could be exceeded if set point control is used so protect against that
12465 1 : if (this->isSetPointControlled) {
12466 0 : if (state.dataLoopNodes->Node(this->coolCoilAirOutNode).Temp > this->coilTempSetPoint) return;
12467 : } else {
12468 1 : if (QZnReq >= 0.0 && FullOutput >= 0.0) PartLoadRatio = 0.0;
12469 1 : return;
12470 : }
12471 : } else {
12472 0 : PartLoadRatio = 0.0;
12473 0 : return;
12474 : }
12475 : } else {
12476 1179 : if (QZnReq == 0.0 && (FullOutput < 0.0 && NoCompOutput < FullOutput)) {
12477 0 : PartLoadRatio = 0.0;
12478 0 : return;
12479 : }
12480 : }
12481 1198 : } else if ((VRFHeatingMode && !thisVRFCond.HeatRecoveryUsed) || (thisVRFCond.HeatRecoveryUsed && HRHeatingMode)) {
12482 : // Since we are heating, we expect FullOutput > NoCompOutput
12483 : // If the QZnReq >= FullOutput the unit needs to run full out
12484 1158 : if (QZnReq >= FullOutput) {
12485 : // if no coil present in terminal unit, no need reset PLR?
12486 0 : if (this->HeatingCoilPresent) {
12487 0 : PartLoadRatio = 1.0;
12488 : // the zone set point could be exceeded if set point control is used so protect against that
12489 0 : if (this->isSetPointControlled) {
12490 0 : if (state.dataLoopNodes->Node(this->heatCoilAirOutNode).Temp < this->coilTempSetPoint) return;
12491 : } else {
12492 0 : return;
12493 : }
12494 : } else {
12495 0 : PartLoadRatio = 0.0;
12496 0 : return;
12497 : }
12498 : }
12499 : } else {
12500 : // VRF terminal unit is off
12501 : // shouldn't actually get here
12502 40 : PartLoadRatio = 0.0;
12503 40 : return;
12504 : }
12505 :
12506 : // The coil will not operate at PLR=0 or PLR=1, calculate the operating part-load ratio
12507 :
12508 2337 : if ((VRFHeatingMode || HRHeatingMode) || ((VRFCoolingMode && DXCoolingCoilOprCtrl) || HRCoolingMode)) {
12509 : int SolFla; // Flag of RegulaFalsi solver
12510 18771 : auto f = [&state, VRFTUNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio](Real64 const PartLoadRatio) {
12511 16438 : Real64 QZnReqTemp = QZnReq; // denominator representing zone load (W)
12512 : Real64 ActualOutput; // delivered capacity of VRF terminal unit
12513 16438 : Real64 SuppHeatCoilLoad = 0.0; // supplemental heating coil load (W)
12514 16438 : bool setPointControlled = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isSetPointControlled;
12515 16438 : Real64 nonConstOnOffAirFlowRatio = OnOffAirFlowRatio;
12516 :
12517 16438 : if (state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
12518 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
12519 16438 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
12520 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, ActualOutput, nonConstOnOffAirFlowRatio, SuppHeatCoilLoad);
12521 : } else {
12522 : // Algorithm Type: VRF model based on system curve
12523 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
12524 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, ActualOutput, nonConstOnOffAirFlowRatio, SuppHeatCoilLoad);
12525 : }
12526 :
12527 16438 : if (setPointControlled) {
12528 0 : Real64 outletNodeT = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum).Temp;
12529 0 : return (outletNodeT - state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coilTempSetPoint);
12530 : } else {
12531 16438 : if (std::abs(QZnReq) < 100.0) QZnReqTemp = sign(100.0, QZnReq);
12532 16438 : return (ActualOutput - QZnReq) / QZnReqTemp;
12533 : }
12534 2333 : };
12535 2333 : SolveRoot(state, ErrorTol, MaxIte, SolFla, PartLoadRatio, f, 0.0, 1.0);
12536 2333 : if (SolFla == -1) {
12537 : // Very low loads may not converge quickly. Tighten PLR boundary and try again.
12538 8 : TempMaxPLR = -0.1;
12539 8 : bool ContinueIter = true;
12540 42 : while (ContinueIter && TempMaxPLR < 1.0) {
12541 34 : TempMaxPLR += 0.1;
12542 :
12543 34 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, TempMaxPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
12544 :
12545 34 : if (VRFHeatingMode && TempOutput > QZnReq) ContinueIter = false;
12546 34 : if (VRFCoolingMode && TempOutput < QZnReq) ContinueIter = false;
12547 : }
12548 8 : TempMinPLR = TempMaxPLR;
12549 8 : ContinueIter = true;
12550 49 : while (ContinueIter && TempMinPLR > 0.0) {
12551 41 : TempMaxPLR = TempMinPLR;
12552 41 : TempMinPLR -= 0.01;
12553 :
12554 41 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, TempMaxPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
12555 :
12556 41 : if (VRFHeatingMode && TempOutput < QZnReq) ContinueIter = false;
12557 41 : if (VRFCoolingMode && TempOutput > QZnReq) ContinueIter = false;
12558 : }
12559 :
12560 8 : SolveRoot(state, ErrorTol, MaxIte, SolFla, PartLoadRatio, f, TempMinPLR, TempMaxPLR);
12561 8 : if (SolFla == -1) {
12562 0 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
12563 0 : if (this->IterLimitExceeded == 0) {
12564 0 : ShowWarningMessage(state, format("{} \"{}\"", tuTypeNames[(int)this->type], this->Name));
12565 0 : ShowContinueError(
12566 0 : state, format(" Iteration limit exceeded calculating terminal unit part-load ratio, maximum iterations = {}", MaxIte));
12567 0 : ShowContinueErrorTimeStamp(state, format(" Part-load ratio returned = {:.3R}", PartLoadRatio));
12568 :
12569 0 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, TempMinPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
12570 :
12571 0 : ShowContinueError(state, format(" Load requested = {:.5T}, Load delivered = {:.5T}", QZnReq, TempOutput));
12572 0 : ShowRecurringWarningErrorAtEnd(state,
12573 0 : format("{} \"{}\" -- Terminal unit Iteration limit exceeded error continues...",
12574 0 : tuTypeNames[(int)this->type],
12575 0 : this->Name),
12576 0 : this->IterLimitExceeded);
12577 : } else {
12578 0 : ShowRecurringWarningErrorAtEnd(state,
12579 0 : format("{} \"{}\" -- Terminal unit Iteration limit exceeded error continues...",
12580 0 : tuTypeNames[(int)this->type],
12581 0 : this->Name),
12582 0 : this->IterLimitExceeded);
12583 : }
12584 : }
12585 8 : } else if (SolFla == -2) {
12586 8 : PartLoadRatio = max(MinPLF, std::abs(QZnReq - NoCompOutput) / std::abs(FullOutput - NoCompOutput));
12587 : }
12588 2325 : } else if (SolFla == -2) {
12589 0 : if (FullOutput - NoCompOutput == 0.0) {
12590 0 : PartLoadRatio = 0.0;
12591 : } else {
12592 0 : PartLoadRatio = min(1.0, max(MinPLF, std::abs(QZnReq - NoCompOutput) / std::abs(FullOutput - NoCompOutput)));
12593 : }
12594 : }
12595 : }
12596 : }
12597 :
12598 23653 : void VRFTerminalUnitEquipment::CalcVRF_FluidTCtrl(EnergyPlusData &state,
12599 : int const VRFTUNum, // Index to VRF terminal unit
12600 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
12601 : Real64 const PartLoadRatio, // compressor part load fraction
12602 : Real64 &LoadMet, // load met by unit (W)
12603 : Real64 &OnOffAirFlowRatio, // ratio of ON air flow to average air flow
12604 : Real64 &SuppHeatCoilLoad, // supplemental heating coil load (W)
12605 : ObjexxFCL::Optional<Real64> LatOutputProvided // delivered latent capacity (W)
12606 : )
12607 : {
12608 :
12609 : // SUBROUTINE INFORMATION:
12610 : // AUTHOR RP Zhang (LBNL), XF Pang (LBNL), Y Yura (Daikin Inc)
12611 : // DATE WRITTEN June 2015
12612 : // MODIFIED na
12613 : // RE-ENGINEERED na
12614 :
12615 : // PURPOSE OF THIS SUBROUTINE:
12616 : // This subroutine is part of the new VRF model based on physics, applicable for Fluid Temperature Control.
12617 : // This is adapted from subroutine CalcVRF, which is part of the VRF model based on system curves.
12618 : // This subroutine simulates the components making up the VRF indoor terminal unit.
12619 :
12620 : // METHODOLOGY EMPLOYED:
12621 : // A new physics based VRF model applicable for Fluid Temperature Control.
12622 : using DXCoils::SimDXCoil;
12623 : using SingleDuct::SimATMixer;
12624 : using SteamCoils::SimulateSteamCoilComponents;
12625 : using WaterCoils::SimulateWaterCoilComponents;
12626 :
12627 : int VRFTUOutletNodeNum; // TU air outlet node
12628 : int VRFTUInletNodeNum; // TU air inlet node
12629 : Real64 AirMassFlow; // total supply air mass flow [m3/s]
12630 : HVAC::FanOp fanOp; // fan operating mode, HVAC::FanOp::Cycling or HVAC::FanOp::Continuous
12631 : int VRFCond; // index to VRF condenser
12632 : Real64 SpecHumOut; // specific humidity ratio at outlet node
12633 : Real64 SpecHumIn; // specific humidity ratio at inlet node
12634 : int TUListIndex; // index to TU list for this VRF system
12635 : int IndexToTUInTUList; // index to TU in specific list for the VRF system
12636 : Real64 EvapTemp; // evaporating temperature
12637 : Real64 CondTemp; // condensing temperature
12638 : int ZoneNode; // Zone node of VRFTU is serving
12639 :
12640 23653 : VRFCond = this->VRFSysNum;
12641 23653 : TUListIndex = state.dataHVACVarRefFlow->VRF(VRFCond).ZoneTUListPtr;
12642 23653 : IndexToTUInTUList = this->IndexToTUInTUList;
12643 23653 : VRFTUOutletNodeNum = this->VRFTUOutletNodeNum;
12644 23653 : VRFTUInletNodeNum = this->VRFTUInletNodeNum;
12645 23653 : fanOp = this->fanOp;
12646 23653 : EvapTemp = state.dataHVACVarRefFlow->VRF(VRFCond).IUEvaporatingTemp;
12647 23653 : CondTemp = state.dataHVACVarRefFlow->VRF(VRFCond).IUCondensingTemp;
12648 23653 : ZoneNode = this->ZoneAirNode;
12649 :
12650 : // Set inlet air mass flow rate based on PLR and compressor on/off air flow rates
12651 23653 : if (PartLoadRatio == 0) {
12652 : // only provide required OA when coil is off
12653 4773 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->OACompOnMassFlow;
12654 4773 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->OACompOffMassFlow;
12655 : } else {
12656 : // identify the air flow rate corresponding to the coil load
12657 18880 : if (this->HeatingCoilPresent && state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) < Constant::MaxCap) {
12658 : // Only fix heating only mode for now
12659 4300 : state.dataHVACVarRefFlow->CompOnMassFlow = CalVRFTUAirFlowRate_FluidTCtrl(
12660 4300 : state, VRFTUNum, PartLoadRatio, FirstHVACIteration, state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
12661 : } else {
12662 14580 : state.dataHVACVarRefFlow->CompOnMassFlow = CalVRFTUAirFlowRate_FluidTCtrl(state, VRFTUNum, PartLoadRatio, FirstHVACIteration, _);
12663 : }
12664 : }
12665 23653 : SetAverageAirFlow(state, VRFTUNum, PartLoadRatio, OnOffAirFlowRatio);
12666 23653 : AirMassFlow = state.dataLoopNodes->Node(VRFTUInletNodeNum).MassFlowRate;
12667 :
12668 23653 : if (this->ATMixerExists) {
12669 : // There is an air terminal mixer
12670 18 : state.dataHVACVarRefFlow->ATMixOutNode2 = this->ATMixerOutNode;
12671 18 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
12672 : // set the primary air inlet mass flow rate
12673 10 : state.dataLoopNodes->Node(this->ATMixerPriNode).MassFlowRate =
12674 10 : min(state.dataLoopNodes->Node(this->ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(VRFTUInletNodeNum).MassFlowRate);
12675 : // now calculate the the mixer outlet air conditions (and the secondary air inlet flow rate). The mixer outlet flow rate has already
12676 : // been set above (it is the "inlet" node flow rate)
12677 10 : SimATMixer(state, this->ATMixerName, FirstHVACIteration, this->ATMixerIndex);
12678 : // inlet side ATMixer can change the VRF TU inlet condition and therefore the operating air flow rate
12679 10 : if (this->fanOp == HVAC::FanOp::Cycling && PartLoadRatio > 0) {
12680 8 : if (this->HeatingCoilPresent && state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) < Constant::MaxCap) {
12681 : // Only fix heating only mode for now
12682 0 : state.dataHVACVarRefFlow->CompOnMassFlow = CalVRFTUAirFlowRate_FluidTCtrl(
12683 0 : state, VRFTUNum, PartLoadRatio, FirstHVACIteration, state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
12684 : } else {
12685 8 : state.dataHVACVarRefFlow->CompOnMassFlow = CalVRFTUAirFlowRate_FluidTCtrl(state, VRFTUNum, PartLoadRatio, FirstHVACIteration, _);
12686 : }
12687 8 : if (std::abs(state.dataHVACVarRefFlow->CompOnMassFlow - AirMassFlow) > HVAC::SmallMassFlow) {
12688 8 : SetAverageAirFlow(state, VRFTUNum, PartLoadRatio, OnOffAirFlowRatio);
12689 8 : AirMassFlow = state.dataLoopNodes->Node(VRFTUInletNodeNum).MassFlowRate;
12690 : // set the primary air inlet mass flow rate
12691 8 : state.dataLoopNodes->Node(this->ATMixerPriNode).MassFlowRate =
12692 8 : min(state.dataLoopNodes->Node(this->ATMixerPriNode).MassFlowRateMaxAvail,
12693 8 : state.dataLoopNodes->Node(VRFTUInletNodeNum).MassFlowRate);
12694 8 : SimATMixer(state, this->ATMixerName, FirstHVACIteration, this->ATMixerIndex);
12695 : }
12696 : }
12697 : }
12698 : } else {
12699 23635 : state.dataHVACVarRefFlow->ATMixOutNode2 = 0;
12700 : // simulate OA Mixer
12701 23635 : if (this->OAMixerUsed) MixedAir::SimOAMixer(state, this->OAMixerName, this->OAMixerIndex);
12702 : }
12703 : // if blow through, simulate fan then coils
12704 23653 : if (this->fanPlace == HVAC::FanPlace::BlowThru) {
12705 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::SystemModel) {
12706 0 : if (OnOffAirFlowRatio > 0.0) {
12707 0 : state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex)->simulate(state, FirstHVACIteration, _, _);
12708 : } else {
12709 0 : state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex)->simulate(state, FirstHVACIteration, _, _, PartLoadRatio);
12710 : }
12711 : } else {
12712 0 : state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex)
12713 0 : ->simulate(state, FirstHVACIteration, state.dataHVACVarRefFlow->FanSpeedRatio);
12714 : }
12715 : }
12716 23653 : if (this->CoolingCoilPresent) {
12717 : // above condition for heat pump mode, below condition for heat recovery mode
12718 34647 : if ((!state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed && state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) ||
12719 10994 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
12720 9 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList))) {
12721 25334 : SimDXCoil(state,
12722 : "",
12723 : HVAC::CompressorOp::On,
12724 : FirstHVACIteration,
12725 12667 : this->CoolCoilIndex,
12726 : fanOp,
12727 : PartLoadRatio,
12728 : _,
12729 : _,
12730 12667 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond),
12731 12667 : state.dataHVACVarRefFlow->VRF(this->VRFSysNum).VRFCondCyclingRatio);
12732 : } else { // cooling coil is off
12733 10986 : SimDXCoil(state, "", HVAC::CompressorOp::Off, FirstHVACIteration, this->CoolCoilIndex, fanOp, 0.0, _);
12734 : }
12735 23653 : state.dataHVACVarRefFlow->LoopDXCoolCoilRTF = state.dataAirLoop->LoopDXCoilRTF;
12736 : } else {
12737 0 : state.dataHVACVarRefFlow->LoopDXCoolCoilRTF = 0.0;
12738 : }
12739 :
12740 23653 : if (this->HeatingCoilPresent) {
12741 : // above condition for heat pump mode, below condition for heat recovery mode
12742 36440 : if ((!state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) ||
12743 12787 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
12744 9 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList))) {
12745 32598 : SimDXCoil(state,
12746 : "",
12747 : HVAC::CompressorOp::On,
12748 : FirstHVACIteration,
12749 10866 : this->HeatCoilIndex,
12750 : fanOp,
12751 : PartLoadRatio,
12752 : _,
12753 : _,
12754 10866 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
12755 : } else {
12756 12787 : SimDXCoil(state, "", HVAC::CompressorOp::Off, FirstHVACIteration, this->HeatCoilIndex, fanOp, 0.0, _);
12757 : }
12758 23653 : state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = state.dataAirLoop->LoopDXCoilRTF;
12759 : } else {
12760 0 : state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = 0.0;
12761 : }
12762 :
12763 23653 : Real64 OnOffFanPartLoadFraction = 1.0;
12764 23653 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Cycling) {
12765 23648 : OnOffFanPartLoadFraction = state.dataHVACGlobal->OnOffFanPartLoadFraction;
12766 : }
12767 : // if draw through, simulate coils then fan
12768 23653 : if (this->fanPlace == HVAC::FanPlace::DrawThru) {
12769 23653 : auto *fan = state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex);
12770 23653 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::SystemModel) {
12771 23653 : if (OnOffAirFlowRatio > 0.0) {
12772 18891 : fan->simulate(state, FirstHVACIteration, _, _, _, fan->inletAirMassFlowRate, OnOffFanPartLoadFraction, 0, 0, _);
12773 : } else {
12774 4762 : fan->simulate(state, FirstHVACIteration, _, _, PartLoadRatio);
12775 : }
12776 : } else {
12777 0 : fan->simulate(state, FirstHVACIteration, state.dataHVACVarRefFlow->FanSpeedRatio);
12778 : }
12779 : }
12780 :
12781 : // track fan power per terminal unit for calculating COP
12782 23653 : this->FanPower = state.dataFans->fans(this->FanIndex)->totalPower;
12783 :
12784 : // run supplemental heating coil
12785 23653 : if (this->SuppHeatingCoilPresent) {
12786 32 : Real64 SuppPLR = this->SuppHeatPartLoadRatio;
12787 32 : this->CalcVRFSuppHeatingCoil(state, VRFTUNum, FirstHVACIteration, SuppPLR, SuppHeatCoilLoad);
12788 32 : if ((state.dataLoopNodes->Node(this->SuppHeatCoilAirOutletNode).Temp > this->MaxSATFromSuppHeatCoil) && SuppPLR > 0.0) {
12789 : // adjust the heating load to maximum allowed
12790 0 : Real64 MaxHeatCoilLoad = this->HeatingCoilCapacityLimit(state, this->SuppHeatCoilAirInletNode, this->MaxSATFromSuppHeatCoil);
12791 0 : this->CalcVRFSuppHeatingCoil(state, VRFTUNum, FirstHVACIteration, SuppPLR, MaxHeatCoilLoad);
12792 0 : SuppHeatCoilLoad = MaxHeatCoilLoad;
12793 : }
12794 : }
12795 :
12796 23653 : Real64 LatentLoadMet = 0.0;
12797 23653 : Real64 TempOut = 0.0;
12798 23653 : Real64 TempIn = 0.0;
12799 23653 : if (this->ATMixerExists) {
12800 18 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
12801 : // Air terminal supply side mixer, calculate supply side mixer output
12802 8 : SimATMixer(state, this->ATMixerName, FirstHVACIteration, this->ATMixerIndex);
12803 8 : TempOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->ATMixOutNode2).Temp;
12804 8 : SpecHumOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->ATMixOutNode2).HumRat;
12805 8 : AirMassFlow = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->ATMixOutNode2).MassFlowRate;
12806 : } else {
12807 : // Air terminal inlet side mixer
12808 10 : TempOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).Temp;
12809 10 : SpecHumOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).HumRat;
12810 : }
12811 18 : TempIn = state.dataLoopNodes->Node(ZoneNode).Temp;
12812 18 : SpecHumIn = state.dataLoopNodes->Node(ZoneNode).HumRat;
12813 : } else {
12814 23635 : TempOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).Temp;
12815 23635 : SpecHumOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).HumRat;
12816 23635 : if (ZoneNode > 0) {
12817 23635 : TempIn = state.dataLoopNodes->Node(ZoneNode).Temp;
12818 23635 : SpecHumIn = state.dataLoopNodes->Node(ZoneNode).HumRat;
12819 : } else {
12820 0 : TempIn = state.dataLoopNodes->Node(VRFTUInletNodeNum).Temp;
12821 0 : SpecHumIn = state.dataLoopNodes->Node(VRFTUInletNodeNum).HumRat;
12822 : }
12823 : }
12824 : // calculate sensible load met using delta enthalpy
12825 23653 : Real64 TotalOutput = AirMassFlow * (Psychrometrics::PsyHFnTdbW(TempOut, SpecHumOut) -
12826 23653 : Psychrometrics::PsyHFnTdbW(TempIn, SpecHumIn)); // total addition/removal rate, {W};
12827 23653 : LoadMet = AirMassFlow * PsyDeltaHSenFnTdb2W2Tdb1W1(TempOut, SpecHumOut, TempIn, SpecHumIn); // sensible {W}
12828 23653 : LatentLoadMet = TotalOutput - LoadMet;
12829 23653 : if (present(LatOutputProvided)) {
12830 2378 : LatOutputProvided = LatentLoadMet;
12831 : }
12832 23653 : }
12833 :
12834 18888 : Real64 VRFTerminalUnitEquipment::CalVRFTUAirFlowRate_FluidTCtrl(EnergyPlusData &state,
12835 : int const VRFTUNum, // Index to VRF terminal unit
12836 : Real64 PartLoadRatio, // part load ratio of the coil
12837 : [[maybe_unused]] bool FirstHVACIteration, // FirstHVACIteration flag
12838 : ObjexxFCL::Optional<Real64 const> MaxHeatCap // maximum allowed heating capacity
12839 : )
12840 : {
12841 : // SUBROUTINE INFORMATION:
12842 : // AUTHOR Rongpeng Zhang, LBNL
12843 : // DATE WRITTEN Nov 2015
12844 : // MODIFIED na
12845 : // RE-ENGINEERED na
12846 :
12847 : // PURPOSE OF THIS FUNCTION:
12848 : // This function determines the TU airflow rate corresponding to the coil load.
12849 : // This is used to address the coupling between OA mixer simulation and VRF-FluidTCtrl coil simulation.
12850 :
12851 : // METHODOLOGY EMPLOYED:
12852 : // VRF-FluidTCtrl TU airflow rate is determined by the control logic of VRF-FluidTCtrl coil to match the
12853 : // coil load. This is affected by the coil inlet conditions. However, the airflow rate will affect the
12854 : // OA mixer simulation, which leads to different coil inlet conditions. So, there is a coupling issue here.
12855 :
12856 : using General::SolveRoot;
12857 :
12858 : Real64 AirMassFlowRate; // air mass flow rate of the coil (kg/s)
12859 :
12860 18888 : int constexpr Mode(1); // Performance mode for MultiMode DX coil. Always 1 for other coil types
12861 18888 : int constexpr MaxIte(500); // maximum number of iterations
12862 : int DXCoilNum; // index to DX Coil
12863 : int IndexToTUInTUList; // index to TU in specific list for the VRF system
12864 : int SolFla; // Flag of RegulaFalsi solver
12865 : int TUListIndex; // index to TU list for this VRF system
12866 : int VRFCond; // index to VRF condenser
12867 18888 : Real64 constexpr ErrorTol(0.01); // tolerance for RegulaFalsi iterations
12868 : Real64 FanSpdRatio; // ratio of required and rated air flow rate
12869 : Real64 FanSpdRatioMin; // min fan speed ratio
12870 : Real64 FanSpdRatioMax; // min fan speed ratio
12871 : Real64 QCoilReq; // required coil load (W)
12872 : Real64 QCoilAct; // actual coil load (W)
12873 : Real64 TeTc; // evaporating temperature or condensing temperature for VRF indoor unit(C)
12874 :
12875 18888 : VRFCond = this->VRFSysNum;
12876 18888 : TUListIndex = state.dataHVACVarRefFlow->VRF(VRFCond).ZoneTUListPtr;
12877 18888 : IndexToTUInTUList = this->IndexToTUInTUList;
12878 :
12879 27481 : if ((!state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed && state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) ||
12880 8593 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
12881 6 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList))) {
12882 : // VRF terminal unit is on cooling mode
12883 10301 : DXCoilNum = this->CoolCoilIndex;
12884 10301 : QCoilReq = -PartLoadRatio * state.dataDXCoils->DXCoil(DXCoilNum).RatedTotCap(Mode);
12885 10301 : TeTc = state.dataHVACVarRefFlow->VRF(VRFCond).IUEvaporatingTemp;
12886 :
12887 : // For HR operations, Te is lower than the outdoor air temperature because of outdoor evaporator operations
12888 : // The difference is usually 2-3C according to the engineering experience. 2 is used here for a slightly bigger fan flow rate.
12889 10301 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed) TeTc = min(TeTc, state.dataEnvrn->OutDryBulbTemp - 2);
12890 :
12891 8627 : } else if ((!state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) ||
12892 40 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
12893 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList))) {
12894 : // VRF terminal unit is on heating mode
12895 8547 : DXCoilNum = this->HeatCoilIndex;
12896 8547 : Real64 RatedCapacity = state.dataDXCoils->DXCoil(DXCoilNum).RatedTotCap(Mode);
12897 8547 : if (present(MaxHeatCap)) {
12898 4300 : RatedCapacity = min(MaxHeatCap, RatedCapacity);
12899 : }
12900 8547 : QCoilReq = PartLoadRatio * RatedCapacity;
12901 8547 : TeTc = state.dataHVACVarRefFlow->VRF(VRFCond).IUCondensingTemp;
12902 :
12903 : } else {
12904 : // VRF terminal unit is off
12905 40 : QCoilAct = 0.0;
12906 40 : AirMassFlowRate = max(state.dataHVACVarRefFlow->OACompOnMassFlow, 0.0);
12907 40 : return AirMassFlowRate;
12908 : }
12909 :
12910 : // minimum airflow rate
12911 18848 : if (state.dataDXCoils->DXCoil(DXCoilNum).RatedAirMassFlowRate(Mode) > 0.0) {
12912 18848 : FanSpdRatioMin = min(state.dataHVACVarRefFlow->OACompOnMassFlow / state.dataDXCoils->DXCoil(DXCoilNum).RatedAirMassFlowRate(Mode), 1.0);
12913 : } else {
12914 : // VRF terminal unit is off
12915 0 : QCoilAct = 0.0;
12916 0 : AirMassFlowRate = max(state.dataHVACVarRefFlow->OACompOnMassFlow, 0.0);
12917 0 : return AirMassFlowRate;
12918 : }
12919 :
12920 18848 : FanSpdRatioMax = 1.0;
12921 :
12922 71534 : auto f = [&state, VRFTUNum, DXCoilNum, QCoilReq, TeTc, PartLoadRatio](Real64 const FanSpdRatio) {
12923 : using DXCoils::ControlVRFIUCoil;
12924 : using Psychrometrics::PsyHFnTdbW;
12925 : using SingleDuct::SimATMixer;
12926 :
12927 71534 : int constexpr Mode(1); // Performance mode for MultiMode DX coil. Always 1 for other coil types
12928 : int VRFCond; // index to VRF condenser
12929 : int VRFInletNode; // VRF inlet node number
12930 : Real64 FanSpdRatioBase; // baseline FanSpdRatio for VRFTUAirFlowResidual
12931 : Real64 FanSpdRatioAct; // calculated FanSpdRatio for VRFTUAirFlowResidual
12932 : Real64 QCoilAct; // actual coil load [W]
12933 : Real64 temp; // for temporary use
12934 : Real64 Tin; // coil inlet air temperature [C]
12935 : Real64 Win; // coil inlet air humidity ratio [kg/kg]
12936 : Real64 Hin; // coil inlet air enthalpy
12937 : Real64 Wout; // coil outlet air humidity ratio
12938 : Real64 Tout; // coil outlet air temperature
12939 : Real64 Hout; // coil outlet air enthalpy
12940 : Real64 SHact; // coil actual SH
12941 : Real64 SCact; // coil actual SC
12942 :
12943 71534 : VRFCond = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum;
12944 71534 : VRFInletNode = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum;
12945 :
12946 71534 : if (std::abs(FanSpdRatio) < 0.01)
12947 18 : FanSpdRatioBase = sign(0.01, FanSpdRatio);
12948 : else
12949 71516 : FanSpdRatioBase = FanSpdRatio;
12950 :
12951 : // Set inlet air mass flow rate based on PLR and compressor on/off air flow rates
12952 71534 : state.dataHVACVarRefFlow->CompOnMassFlow = FanSpdRatio * state.dataDXCoils->DXCoil(DXCoilNum).RatedAirMassFlowRate(Mode);
12953 71534 : SetAverageAirFlow(state, VRFTUNum, PartLoadRatio, temp);
12954 71534 : Tin = state.dataLoopNodes->Node(VRFInletNode).Temp;
12955 71534 : Win = state.dataLoopNodes->Node(VRFInletNode).HumRat;
12956 :
12957 : // Simulation the OAMixer if there is any
12958 71534 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
12959 71450 : MixedAir::SimOAMixer(
12960 71450 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
12961 71450 : int OAMixNode = state.dataMixedAir->OAMixer(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex).MixNode;
12962 71450 : Tin = state.dataLoopNodes->Node(OAMixNode).Temp;
12963 71450 : Win = state.dataLoopNodes->Node(OAMixNode).HumRat;
12964 : }
12965 : // Simulate the blow-through fan if there is any
12966 71534 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanPlace == HVAC::FanPlace::BlowThru) {
12967 0 : auto *fan = state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex);
12968 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::SystemModel) {
12969 0 : if (temp > 0) {
12970 0 : fan->simulate(state, false, _, _);
12971 : } else {
12972 0 : fan->simulate(state, false, _, _, PartLoadRatio);
12973 : }
12974 : } else {
12975 0 : fan->simulate(state, false, state.dataHVACVarRefFlow->FanSpeedRatio);
12976 : }
12977 0 : Tin = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOutletNode).Temp;
12978 0 : Win = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOutletNode).HumRat;
12979 : }
12980 :
12981 : // Call the coil control logic to determine the air flow rate to match the given coil load
12982 71534 : ControlVRFIUCoil(
12983 71534 : state, DXCoilNum, QCoilReq, Tin, Win, TeTc, state.dataHVACVarRefFlow->OACompOnMassFlow, FanSpdRatioAct, Wout, Tout, Hout, SHact, SCact);
12984 :
12985 71534 : Hin = PsyHFnTdbW(Tin, Win);
12986 71534 : QCoilAct = FanSpdRatioAct * state.dataDXCoils->DXCoil(DXCoilNum).RatedAirMassFlowRate(Mode) *
12987 71534 : (Hout - Hin); // positive for heating, negative for cooling
12988 :
12989 71534 : return (FanSpdRatioAct - FanSpdRatio);
12990 18848 : };
12991 :
12992 18848 : SolveRoot(state, ErrorTol, MaxIte, SolFla, FanSpdRatio, f, FanSpdRatioMin, FanSpdRatioMax);
12993 18848 : if (SolFla < 0) FanSpdRatio = FanSpdRatioMax; // over capacity
12994 :
12995 18848 : AirMassFlowRate = FanSpdRatio * state.dataDXCoils->DXCoil(DXCoilNum).RatedAirMassFlowRate(Mode);
12996 :
12997 18848 : return AirMassFlowRate;
12998 : }
12999 :
13000 26134 : Real64 CompResidual_FluidTCtrl(EnergyPlusData &state,
13001 : Real64 T_dis,
13002 : Real64 CondHeat,
13003 : int CAPFT,
13004 : Real64 const T_suc // Compressor suction temperature Te' [C]
13005 : )
13006 : {
13007 : // FUNCTION INFORMATION:
13008 : // AUTHOR Xiufeng Pang (XP)
13009 : // DATE WRITTEN Mar 2013
13010 : // MODIFIED Jul 2015, RP Zhang, LBNL
13011 : // RE-ENGINEERED
13012 : //
13013 : // PURPOSE OF THIS FUNCTION:
13014 : // Calculates residual function ((VRV terminal unit cooling output - Zone sensible cooling load)
13015 : //
13016 : using Curve::CurveValue;
13017 :
13018 : Real64 CAPSpd; // Evaporative capacity of the compressor at a given spd[W]
13019 : Real64 CompResidual;
13020 :
13021 26134 : CAPSpd = CurveValue(state, CAPFT, T_dis, T_suc);
13022 26134 : CompResidual = (CondHeat - CAPSpd) / CAPSpd;
13023 :
13024 26134 : return CompResidual;
13025 : }
13026 :
13027 15376 : void VRFCondenserEquipment::VRFOU_TeTc(EnergyPlusData &state,
13028 : HXOpMode const OperationMode, // Mode 0 for running as condenser, 1 for evaporator
13029 : Real64 const Q_coil, // // OU coil heat release at cooling mode or heat extract at heating mode [W]
13030 : Real64 const SHSC, // SC for OU condenser or SH for OU evaporator [C]
13031 : Real64 const m_air, // OU coil air mass flow rate [kg/s]
13032 : Real64 const T_coil_in, // Temperature of air at OU coil inlet [C]
13033 : Real64 const W_coil_in, // Humidity ratio of air at OU coil inlet [kg/kg]
13034 : Real64 const OutdoorPressure, // Outdoor air pressure [Pa]
13035 : Real64 &T_coil_surf, // Air temperature at coil surface [C]
13036 : Real64 &TeTc // VRF Tc at cooling mode, or Te at heating mode [C]
13037 : )
13038 : {
13039 :
13040 : // SUBROUTINE INFORMATION:
13041 : // AUTHOR Rongpeng Zhang, LBNL
13042 : // DATE WRITTEN Jan 2016
13043 : // MODIFIED na
13044 : //
13045 : // RE-ENGINEERED na
13046 : //
13047 : // PURPOSE OF THIS SUBROUTINE:
13048 : // Calculate the VRF OU refrigerant side temperature, i.e., condensing temperature
13049 : // at cooling mode, or evaporating temperature at heating mode, given the coil heat
13050 : // release/extract amount and air side parameters.
13051 : //
13052 : // METHODOLOGY EMPLOYED:
13053 : // This is part of the physics based VRF model applicable for Fluid Temperature Control.
13054 : //
13055 :
13056 : Real64 BF; // VRF OU bypass [-]
13057 : Real64 deltaT; // Difference between Te/Tc and air temperature at coil surface [C]
13058 : Real64 h_coil_in; // Enthalpy of air at OU coil inlet [C]
13059 : Real64 h_coil_out; // Enthalpy of air at OU coil outlet [C]
13060 : Real64 T_coil_out; // Air temperature at coil outlet [C]
13061 : Real64 T_coil_surf_sat; // Saturated air temperature at coil surface [C]
13062 : Real64 W_coil_surf_sat; // Humidity ratio of saturated air at coil surface [kg/kg]
13063 :
13064 15376 : if (OperationMode == HXOpMode::CondMode) {
13065 : // IU Cooling: OperationMode 0
13066 :
13067 10106 : if (m_air <= 0) {
13068 0 : TeTc = this->CondensingTemp;
13069 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit airflow rate ({:.3T} ) for \"{}\":", m_air, this->Name));
13070 0 : ShowContinueError(state, " This cannot be used to calculate outdoor unit refrigerant temperature.");
13071 0 : ShowContinueError(state, format(" Default condensing temperature is used: {:.3T}", TeTc));
13072 : }
13073 :
13074 10106 : BF = this->RateBFOUCond; // 0.219;
13075 10106 : T_coil_out = T_coil_in + Q_coil / 1005.0 / m_air;
13076 10106 : T_coil_surf = T_coil_in + (T_coil_out - T_coil_in) / (1 - BF);
13077 :
13078 10106 : deltaT = this->C3Tc * pow_2(SHSC) + this->C2Tc * SHSC + this->C1Tc;
13079 :
13080 10106 : TeTc = T_coil_surf + deltaT;
13081 :
13082 5270 : } else if (OperationMode == HXOpMode::EvapMode) {
13083 : // IU Heating: OperationMode 1
13084 :
13085 5270 : if (m_air <= 0) {
13086 0 : TeTc = this->EvaporatingTemp;
13087 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit airflow rate ({:.3T} ) for \"{}\":", m_air, this->Name));
13088 0 : ShowContinueError(state, " This cannot be used to calculate outdoor unit refrigerant temperature.");
13089 0 : ShowContinueError(state, format(" Default condensing temperature is used: {:.3T}", TeTc));
13090 : }
13091 :
13092 5270 : BF = this->RateBFOUEvap; // 0.45581;
13093 5270 : h_coil_in = PsyHFnTdbW(T_coil_in, W_coil_in);
13094 5270 : h_coil_out = h_coil_in - Q_coil / m_air / (1 - BF);
13095 5270 : h_coil_out = max(0.01, h_coil_out);
13096 :
13097 5270 : T_coil_surf_sat = PsyTsatFnHPb(state, h_coil_out, OutdoorPressure, "VRFOU_TeTc");
13098 5270 : W_coil_surf_sat = PsyWFnTdbH(state, T_coil_surf_sat, h_coil_out, "VRFOU_TeTc");
13099 :
13100 5270 : if (W_coil_surf_sat < W_coil_in)
13101 : // There is dehumidification
13102 5269 : T_coil_surf = T_coil_surf_sat;
13103 : else
13104 : // No dehumidification
13105 1 : T_coil_surf = PsyTdbFnHW(h_coil_out, W_coil_in);
13106 :
13107 5270 : deltaT = this->C3Te * pow_2(SHSC) + this->C2Te * SHSC + this->C1Te;
13108 :
13109 5270 : TeTc = T_coil_surf - deltaT;
13110 : }
13111 15376 : }
13112 :
13113 2 : Real64 VRFCondenserEquipment::VRFOU_Cap(EnergyPlusData &state,
13114 : HXOpMode const OperationMode, // Mode 0 for running as condenser, 1 for evaporator
13115 : Real64 const TeTc, // VRF Tc at cooling mode, or Te at heating mode [C]
13116 : Real64 const SHSC, // SC for OU condenser or SH for OU evaporator [C]
13117 : Real64 const m_air, // OU coil air mass flow rate [kg/s]
13118 : Real64 const T_coil_in, // Temperature of air at OU coil inlet [C]
13119 : Real64 const W_coil_in // Humidity ratio of air at OU coil inlet [kg/kg]
13120 : )
13121 : {
13122 :
13123 : // SUBROUTINE INFORMATION:
13124 : // AUTHOR Rongpeng Zhang, LBNL
13125 : // DATE WRITTEN Jan 2016
13126 : // MODIFIED na
13127 : //
13128 : // RE-ENGINEERED na
13129 : //
13130 : // PURPOSE OF THIS SUBROUTINE:
13131 : // Calculate the VRF OU load, given refrigerant side temperature, i.e., condensing temperature
13132 : // and SC for condenser, or evaporating temperature and SH for evaporator.
13133 : //
13134 : // METHODOLOGY EMPLOYED:
13135 : // This is part of the physics based VRF model applicable for Fluid Temperature Control.
13136 :
13137 : Real64 BF; // VRF OU bypass [-]
13138 : Real64 deltaT; // Difference between Te/Tc and air temperature at coil surface [C]
13139 : Real64 h_coil_in; // Enthalpy of air at OU coil inlet [C]
13140 : Real64 h_coil_out; // Enthalpy of air at OU coil outlet [C]
13141 : Real64 Q_coil; // OU coil heat release at cooling mode or heat extract at heating mode [W]
13142 : Real64 T_coil_out; // Air temperature at coil outlet [C]
13143 : Real64 T_coil_surf; // Air temperature at coil surface [C]
13144 : Real64 W_coil_surf_sat; // Humidity ratio of saturated air at coil surface [kg/kg]
13145 :
13146 2 : Q_coil = 0.0;
13147 :
13148 2 : if (OperationMode == HXOpMode::CondMode) {
13149 : // IU Cooling: OperationMode 0
13150 1 : if (m_air <= 0) {
13151 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit airflow rate ({:.3T} ) for \"{}\":", m_air, this->Name));
13152 0 : ShowContinueError(state, " This cannot be used to calculate outdoor unit capacity.");
13153 : }
13154 :
13155 1 : BF = this->RateBFOUCond; // 0.219;
13156 1 : deltaT = this->C3Tc * pow_2(SHSC) + this->C2Tc * SHSC + this->C1Tc;
13157 1 : T_coil_surf = TeTc - deltaT;
13158 1 : T_coil_out = T_coil_in + (T_coil_surf - T_coil_in) * (1 - BF);
13159 1 : Q_coil = (T_coil_out - T_coil_in) * 1005.0 * m_air;
13160 :
13161 1 : } else if (OperationMode == HXOpMode::EvapMode) {
13162 : // IU Heating: OperationMode 1
13163 1 : if (m_air <= 0) {
13164 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit airflow rate ({:.3T} ) for \"{}\":", m_air, this->Name));
13165 0 : ShowContinueError(state, " This cannot be used to calculate outdoor unit capacity.");
13166 : }
13167 :
13168 1 : BF = this->RateBFOUEvap; // 0.45581;
13169 1 : deltaT = this->C3Te * pow_2(SHSC) + this->C2Te * SHSC + this->C1Te;
13170 1 : T_coil_surf = TeTc + deltaT;
13171 :
13172 : // saturated humidity ratio corresponding to T_coil_surf
13173 1 : W_coil_surf_sat = PsyWFnTdpPb(state, T_coil_surf, state.dataEnvrn->OutBaroPress);
13174 :
13175 1 : if (W_coil_surf_sat < W_coil_in) {
13176 : // There is dehumidification, W_coil_out = W_coil_surf_sat
13177 0 : h_coil_out = PsyHFnTdbW(T_coil_surf, W_coil_surf_sat);
13178 : } else {
13179 : // No dehumidification, W_coil_out = W_coil_in
13180 1 : h_coil_out = PsyHFnTdbW(T_coil_surf, W_coil_in);
13181 : }
13182 1 : h_coil_out = max(0.01, h_coil_out);
13183 1 : h_coil_in = PsyHFnTdbW(T_coil_in, W_coil_in);
13184 1 : Q_coil = (h_coil_in - h_coil_out) * m_air * (1 - BF); // bypass airflow should not be included here
13185 :
13186 : } else {
13187 : // Should not come here
13188 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit operational mode for \"{}\":", this->Name));
13189 0 : ShowContinueError(state, " The operational mode is not correctly set in the function VRFOU_Cap.");
13190 : }
13191 :
13192 2 : return Q_coil;
13193 : }
13194 :
13195 3 : Real64 VRFCondenserEquipment::VRFOU_FlowRate(EnergyPlusData &state,
13196 : HXOpMode const OperationMode, // Mode 0 for running as condenser, 1 for evaporator
13197 : Real64 const TeTc, // VRF Tc at cooling mode, or Te at heating mode [C]
13198 : Real64 const SHSC, // SC for OU condenser or SH for OU evaporator [C]
13199 : Real64 const Q_coil, // absolute value of OU coil heat release or heat extract [W]
13200 : Real64 const T_coil_in, // Temperature of air at OU coil inlet [C]
13201 : Real64 const W_coil_in // Humidity ratio of air at OU coil inlet [kg/kg]
13202 : ) const
13203 : {
13204 :
13205 : // SUBROUTINE INFORMATION:
13206 : // AUTHOR Rongpeng Zhang, LBNL
13207 : // DATE WRITTEN Mar 2016
13208 : // MODIFIED na
13209 : //
13210 : // RE-ENGINEERED na
13211 : //
13212 : // PURPOSE OF THIS SUBROUTINE:
13213 : // Calculate the outdoor unit fan flow rate, given VRF OU load and refrigerant side temperature, i.e.,
13214 : // condensing temperature and SC for condenser, or evaporating temperature and SH for evaporator.
13215 : //
13216 : // METHODOLOGY EMPLOYED:
13217 : // This is part of the physics based VRF model applicable for Fluid Temperature Control.
13218 :
13219 : Real64 BF; // VRF OU bypass [-]
13220 : Real64 deltaT; // Difference between Te/Tc and air temperature at coil surface [C]
13221 : Real64 h_coil_in; // Enthalpy of air at OU coil inlet [C]
13222 : Real64 h_coil_out; // Enthalpy of air at OU coil outlet [C]
13223 : Real64 m_air; // OU coil air mass flow rate [kg/s]
13224 : Real64 T_coil_out; // Air temperature at coil outlet [C]
13225 : Real64 T_coil_surf; // Air temperature at coil surface [C]
13226 : Real64 W_coil_surf_sat; // Humidity ratio of saturated air at coil surface [kg/kg]
13227 :
13228 3 : m_air = 0.0;
13229 :
13230 3 : if (OperationMode == HXOpMode::CondMode) {
13231 : // IU Cooling: OperationMode 0
13232 :
13233 1 : BF = this->RateBFOUCond; // 0.219;
13234 1 : deltaT = this->C3Tc * pow_2(SHSC) + this->C2Tc * SHSC + this->C1Tc;
13235 1 : T_coil_surf = TeTc - deltaT;
13236 1 : T_coil_out = T_coil_in + (T_coil_surf - T_coil_in) * (1 - BF);
13237 1 : m_air = Q_coil / (T_coil_out - T_coil_in) / 1005.0;
13238 :
13239 2 : } else if (OperationMode == HXOpMode::EvapMode) {
13240 : // IU Heating: OperationMode 1
13241 :
13242 2 : BF = this->RateBFOUEvap; // 0.45581;
13243 2 : deltaT = this->C3Te * pow_2(SHSC) + this->C2Te * SHSC + this->C1Te;
13244 2 : T_coil_surf = TeTc + deltaT;
13245 :
13246 : // saturated humidity ratio corresponding to T_coil_surf
13247 2 : W_coil_surf_sat = PsyWFnTdpPb(state, T_coil_surf, state.dataEnvrn->OutBaroPress);
13248 :
13249 2 : if (W_coil_surf_sat < W_coil_in) {
13250 : // There is dehumidification, W_coil_out = W_coil_surf_sat
13251 0 : h_coil_out = PsyHFnTdbW(T_coil_surf, W_coil_surf_sat);
13252 : } else {
13253 : // No dehumidification, W_coil_out = W_coil_in
13254 2 : h_coil_out = PsyHFnTdbW(T_coil_surf, W_coil_in);
13255 : }
13256 2 : h_coil_out = max(0.01, h_coil_out);
13257 2 : h_coil_in = PsyHFnTdbW(T_coil_in, W_coil_in);
13258 2 : m_air = Q_coil / (h_coil_in - h_coil_out) / (1 - BF);
13259 :
13260 : } else {
13261 : // Should not come here
13262 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit operational mode for \"{}\":", this->Name));
13263 0 : ShowContinueError(state, " The operational mode is not correctly set in the function VRFOU_Cap.");
13264 : }
13265 :
13266 3 : return m_air;
13267 : }
13268 :
13269 2 : Real64 VRFCondenserEquipment::VRFOU_SCSH(EnergyPlusData &state,
13270 : HXOpMode const OperationMode, // Mode 0 for running as condenser, 1 for evaporator
13271 : Real64 const Q_coil, // // OU coil heat release at cooling mode or heat extract at heating mode [W]
13272 : Real64 const TeTc, // VRF Tc at cooling mode, or Te at heating mode [C]
13273 : Real64 const m_air, // OU coil air mass flow rate [kg/s]
13274 : Real64 const T_coil_in, // Temperature of air at OU coil inlet [C]
13275 : Real64 const W_coil_in, // Humidity ratio of air at OU coil inlet [kg/kg]
13276 : Real64 const OutdoorPressure // Outdoor air pressure [Pa]
13277 : ) const
13278 : {
13279 :
13280 : // SUBROUTINE INFORMATION:
13281 : // AUTHOR Rongpeng Zhang, LBNL
13282 : // DATE WRITTEN Jan 2016
13283 : // MODIFIED na
13284 : //
13285 : // RE-ENGINEERED na
13286 : //
13287 : // PURPOSE OF THIS SUBROUTINE:
13288 : // Calculate the SC for OU condenser, or SH for OU evaporator, given
13289 : // VRF OU load and refrigerant side temperature, i.e., condensing temperature
13290 : // for condenser, or evaporating temperature for evaporator.
13291 : //
13292 : // METHODOLOGY EMPLOYED:
13293 : // This is part of the physics based VRF model applicable for Fluid Temperature Control.
13294 :
13295 : Real64 BF; // VRF OU bypass [-]
13296 : Real64 deltaT; // Difference between Te/Tc and air temperature at coil surface [C]
13297 : Real64 h_coil_in; // Enthalpy of air at OU coil inlet [C]
13298 : Real64 h_coil_out; // Enthalpy of air at OU coil outlet [C]
13299 : Real64 SHSC; // SC for OU condenser, or SH for OU evaporator
13300 : Real64 T_coil_out; // Air temperature at coil outlet [C]
13301 : Real64 T_coil_surf; // Air temperature at coil surface [C]
13302 : Real64 T_coil_surf_sat; // Saturated air temperature at coil surface [C]
13303 : Real64 W_coil_surf_sat; // Humidity ratio of saturated air at coil surface [kg/kg]
13304 :
13305 2 : SHSC = 0.0;
13306 :
13307 2 : if (OperationMode == HXOpMode::CondMode) {
13308 : // Cooling: OperationMode 0
13309 1 : if (m_air <= 0) {
13310 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit airflow rate ({:.3T} ) for \"{}\":", m_air, this->Name));
13311 0 : ShowContinueError(state, " This cannot be used to calculate outdoor unit subcooling.");
13312 : }
13313 :
13314 1 : BF = this->RateBFOUCond; // 0.219;
13315 1 : T_coil_out = T_coil_in + Q_coil / 1005.0 / m_air;
13316 1 : T_coil_surf = T_coil_in + (T_coil_out - T_coil_in) / (1 - BF);
13317 1 : deltaT = TeTc - T_coil_surf;
13318 :
13319 : // SC_OU
13320 1 : if (this->C3Tc == 0)
13321 0 : SHSC = -(this->C1Tc - deltaT) / this->C2Tc;
13322 : else
13323 1 : SHSC = (-this->C2Tc + std::pow((pow_2(this->C2Tc) - 4 * (this->C1Tc - deltaT) * this->C3Tc), 0.5)) / (2 * this->C3Tc);
13324 :
13325 1 : } else if (OperationMode == HXOpMode::EvapMode) {
13326 : // Heating: OperationMode 1
13327 1 : if (m_air <= 0) {
13328 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit airflow rate ({:.3T} ) for \"{}\":", m_air, this->Name));
13329 0 : ShowContinueError(state, " This cannot be used to calculate outdoor unit super heating.");
13330 : }
13331 :
13332 1 : BF = this->RateBFOUEvap; // 0.45581;
13333 1 : h_coil_in = PsyHFnTdbW(T_coil_in, W_coil_in);
13334 1 : h_coil_out = h_coil_in - Q_coil / m_air / (1 - BF);
13335 1 : h_coil_out = max(0.01, h_coil_out);
13336 :
13337 1 : T_coil_surf_sat = PsyTsatFnHPb(state, h_coil_out, OutdoorPressure, "VRFOU_TeTc");
13338 1 : W_coil_surf_sat = PsyWFnTdbH(state, T_coil_surf_sat, h_coil_out, "VRFOU_TeTc");
13339 :
13340 1 : if (W_coil_surf_sat < W_coil_in)
13341 : // There is dehumidification
13342 0 : T_coil_surf = T_coil_surf_sat;
13343 : else
13344 : // No dehumidification
13345 1 : T_coil_surf = PsyTdbFnHW(h_coil_out, W_coil_in);
13346 :
13347 1 : deltaT = T_coil_surf - TeTc;
13348 :
13349 : // SH_OU
13350 1 : if (this->C3Te == 0)
13351 0 : SHSC = -(this->C1Te - deltaT) / this->C2Te;
13352 : else
13353 1 : SHSC = (-this->C2Te + std::pow((pow_2(this->C2Te) - 4 * (this->C1Te - deltaT) * this->C3Te), 0.5)) / (2 * this->C3Te);
13354 :
13355 : } else {
13356 : // Should not come here
13357 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit operational mode for \"{}\":", this->Name));
13358 0 : ShowContinueError(state, " The operational mode is not correctly set in the function VRFOU_Cap.");
13359 : }
13360 :
13361 2 : return SHSC;
13362 : }
13363 :
13364 21832 : Real64 VRFCondenserEquipment::VRFOU_CapModFactor(
13365 : EnergyPlusData &state,
13366 : Real64 const h_comp_in_real, // Enthalpy of refrigerant at the compressor inlet at real conditions [kJ/kg]
13367 : Real64 const h_evap_in_real, // Enthalpy of refrigerant at the evaporator inlet at real conditions [kJ/kg]
13368 : Real64 const P_evap_real, // Evaporative pressure at real conditions [Pa]
13369 : Real64 const T_comp_in_real, // Temperature of the refrigerant at the compressor inlet at real conditions [C]
13370 : Real64 const T_comp_in_rate, // Temperature of the refrigerant at the compressor inlet at rated conditions [C]
13371 : Real64 const T_cond_out_rate // Temperature of the refrigerant at the condenser outlet at rated conditions [C]
13372 : )
13373 : {
13374 :
13375 : // SUBROUTINE INFORMATION:
13376 : // AUTHOR Rongpeng Zhang
13377 : // DATE WRITTEN Nov 2015
13378 : // MODIFIED na
13379 : // RE-ENGINEERED na
13380 :
13381 : // PURPOSE OF THIS SUBROUTINE:
13382 : // Calculate capacity modification factor for the compressors at Outdoor Unit.
13383 : // This factor is used to modify the system evaporative capacity, by describing
13384 : // the difference between rated conditions and real conditions.
13385 :
13386 : // METHODOLOGY EMPLOYED:
13387 : // This is part of the VRF-FluidTCtrl Model.
13388 :
13389 : Real64 C_cap_density; // Compressor capacity modification algorithm_modified flow rate [-]
13390 : Real64 C_cap_enthalpy; // Compressor capacity modification algorithm_modified enthalpy difference [-]
13391 : Real64 C_cap_operation; // Compressor capacity modification algorithm_modified Cap [-]
13392 : Real64 RefTSat; // Saturated temperature of the refrigerant. Used to check whether the refrigerant is in the superheat area [C].
13393 : Real64 h_evap_out_rate; // enthalpy of refrigerant at the evaporator outlet at rated conditions [kJ/kg]
13394 : Real64 h_evap_in_rate; // enthalpy of refrigerant at the evaporator inlet at rated conditions [kJ/kg]
13395 : Real64 density_rate; // density of refrigerant at rated conditions [kg/m3]
13396 : Real64 density_real; // density of refrigerant at rated conditions [kg/m3]
13397 :
13398 : static constexpr std::string_view RoutineName("VRFOU_CapModFactor");
13399 :
13400 : // Saturated temperature at real evaporating pressure
13401 21832 : RefTSat = this->refrig->getSatTemperature(state, P_evap_real, RoutineName);
13402 :
13403 : // Enthalpy at rated conditions
13404 21832 : h_evap_out_rate = this->refrig->getSupHeatEnthalpy(state, max(RefTSat, T_comp_in_rate), P_evap_real, RoutineName);
13405 21832 : h_evap_in_rate = this->refrig->getSatEnthalpy(state, T_cond_out_rate, 0.0, RoutineName);
13406 :
13407 : // Density calculations
13408 21832 : density_rate = this->refrig->getSupHeatDensity(state, T_comp_in_rate, P_evap_real, RoutineName);
13409 21832 : density_real = this->refrig->getSupHeatDensity(state, T_comp_in_real, P_evap_real, RoutineName);
13410 :
13411 : // Modification factor calculations
13412 21832 : if (density_real > 0)
13413 21832 : C_cap_density = density_rate / density_real;
13414 : else
13415 0 : C_cap_density = 1.0;
13416 :
13417 21832 : if ((h_comp_in_real - h_evap_in_real) > 0)
13418 21832 : C_cap_enthalpy = std::abs(h_evap_out_rate - h_evap_in_rate) / std::abs(h_comp_in_real - h_evap_in_real);
13419 : else
13420 0 : C_cap_enthalpy = 1.0;
13421 :
13422 21832 : C_cap_operation = C_cap_density * C_cap_enthalpy;
13423 :
13424 21832 : return C_cap_operation;
13425 : }
13426 :
13427 0 : void VRFCondenserEquipment::VRFOU_TeModification(
13428 : EnergyPlusData &state,
13429 : Real64 const Te_up, // Upper bound of Te during iteration, i.e., Te before reduction [C]
13430 : Real64 const Te_low, // Lower bound of Te during iteration, i.e., the given suction temperature Te' [C]
13431 : Real64 const Pipe_h_IU_in, // Piping Loss Algorithm Parameter: enthalpy of IU at inlet [kJ/kg]
13432 : Real64 const OutdoorDryBulb, // outdoor dry-bulb temperature [C]
13433 : Real64 &Te_update, // Updated Te that can generate the required Tsuction [C]
13434 : Real64 &Pe_update, // Piping Loss Algorithm Parameter: evaporating pressure assumed for iterations [Pa]
13435 : Real64 &Pipe_m_ref, // Piping Loss Algorithm Parameter: Refrigerant mass flow rate [kg/s]
13436 : Real64 &Pipe_h_IU_out, // Piping Loss Algorithm Parameter: enthalpy of IU at outlet [kJ/kg]
13437 : Real64 &Pipe_SH_merged // Piping Loss Algorithm Parameter: Average SH after the indoor units [C]
13438 : )
13439 : {
13440 :
13441 : // SUBROUTINE INFORMATION:
13442 : // AUTHOR Rongpeng Zhang
13443 : // DATE WRITTEN Jan 2016
13444 : // MODIFIED na
13445 : // RE-ENGINEERED na
13446 :
13447 : // PURPOSE OF THIS SUBROUTINE:
13448 : // This is part of the low load modification algorithm for the VRF-FluidTCtrl model. It aims
13449 : // to find a new Te (Te_update) that can generate a new compressor suction temperature (Tsuction) equaling
13450 : // to the given compressor suction temperature (Te_low). This requires the re-calculate of piping loss.
13451 :
13452 : // METHODOLOGY EMPLOYED:
13453 : // This is part of the VRF-FluidTCtrl Model.
13454 :
13455 : int CoolCoilIndex; // index to cooling coil in terminal unit
13456 : int NumTUInList; // number of terminal units is list
13457 : int NumTeIte; // counter for Te calculation iterations [-]
13458 : int TUListNum; // index to TU List
13459 : int TUIndex; // Index to terminal unit
13460 : Real64 MaxNumTeIte; // Piping Loss Algorithm Parameter: max number of iterations for Te [-]
13461 : Real64 Pipe_h_comp_in; // Piping Loss Algorithm Parameter: Enthalpy after piping loss (compressor inlet) [kJ/kg]
13462 : Real64 Pipe_DeltP; // Piping Loss Algorithm Parameter: Pipe pressure drop [Pa]
13463 : Real64 Pipe_Q; // Piping Loss Algorithm Parameter: Heat loss [W]
13464 : Real64 Pipe_m_ref_i; // Piping Loss Algorithm Parameter: Refrigerant mass flow rate for a individual IU[kg/s]
13465 : Real64 Pipe_h_IU_out_i; // Piping Loss Algorithm Parameter: enthalpy of IU at outlet (individual) [kJ/kg]
13466 : Real64 RefTSat; // Saturated temperature of the refrigerant [C]
13467 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
13468 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
13469 : Real64 SH_IU_update; // Modified SH for VRF IU [C]
13470 : Real64 Te_ItePreci; // Precision of iterations for Te [C]he superheat area [C]
13471 : Real64 Tfs; // Temperature of the air at the coil surface [C]]
13472 : Real64 Tsuction; // VRF compressor suction refrigerant temperature [Pa]
13473 :
13474 : static constexpr std::string_view RoutineName("VRFOU_TeModification");
13475 :
13476 : // variable initializations
13477 0 : TUListNum = this->ZoneTUListPtr;
13478 0 : RefPLow = this->refrig->PsLowPresValue;
13479 0 : RefPHigh = this->refrig->PsHighPresValue;
13480 0 : NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
13481 :
13482 : // Initialization of Te iterations (Label11)
13483 0 : NumTeIte = 1;
13484 0 : Te_ItePreci = 0.1;
13485 0 : MaxNumTeIte = (Te_up - Te_low) / Te_ItePreci + 1; // upper bound and lower bound of Te iterations
13486 0 : Te_update = Te_up - Te_ItePreci;
13487 :
13488 : bool converged_11;
13489 : // The following is triggered in VariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf
13490 : do {
13491 0 : Pipe_m_ref = 0; // Total Ref Flow Rate( kg/s )
13492 0 : Pipe_h_IU_out = 0;
13493 0 : Pipe_h_IU_out_i = 0;
13494 0 : Pipe_m_ref_i = 0;
13495 0 : Pipe_SH_merged = 0;
13496 0 : Pe_update = this->refrig->getSatPressure(state, Te_update, RoutineName);
13497 :
13498 : // Re-calculate total refrigerant flow rate, with updated SH
13499 0 : for (int NumTU = 1; NumTU <= NumTUInList; NumTU++) {
13500 0 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) > 0) {
13501 0 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
13502 0 : CoolCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
13503 :
13504 : // The IU coil surface temperature should be the same.
13505 0 : Tfs = Te_up + (this->C3Te * pow_2(state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH) +
13506 0 : this->C2Te * state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH + this->C1Te);
13507 :
13508 : // SH_IU_update is the updated SH for a specific IU
13509 0 : if (this->C3Te == 0)
13510 0 : SH_IU_update = -(this->C1Te - Tfs + Te_update) / this->C2Te;
13511 : else
13512 0 : SH_IU_update =
13513 0 : (-this->C2Te + std::pow((pow_2(this->C2Te) - 4 * (this->C1Te - Tfs + Te_update) * this->C3Te), 0.5)) / (2 * this->C3Te);
13514 :
13515 0 : RefTSat = this->refrig->getSatTemperature(state, Pe_update, RoutineName);
13516 0 : Pipe_h_IU_out_i = this->refrig->getSupHeatEnthalpy(state,
13517 0 : max(RefTSat, Te_update + SH_IU_update),
13518 : Pe_update,
13519 : RoutineName); // hB_i for the IU
13520 :
13521 0 : if (Pipe_h_IU_out_i > Pipe_h_IU_in) {
13522 0 : Pipe_m_ref_i =
13523 0 : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) <= 0.0)
13524 0 : ? 0.0
13525 0 : : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) / (Pipe_h_IU_out_i - Pipe_h_IU_in));
13526 0 : Pipe_m_ref = Pipe_m_ref + Pipe_m_ref_i;
13527 0 : Pipe_SH_merged = Pipe_SH_merged + Pipe_m_ref_i * SH_IU_update;
13528 0 : Pipe_h_IU_out = Pipe_h_IU_out + Pipe_m_ref_i * Pipe_h_IU_out_i;
13529 : }
13530 : }
13531 : }
13532 0 : if (Pipe_m_ref > 0) {
13533 0 : Pipe_h_IU_out = Pipe_h_IU_out / Pipe_m_ref;
13534 0 : Pipe_SH_merged = Pipe_SH_merged / Pipe_m_ref;
13535 : } else {
13536 0 : Pipe_SH_merged = this->SH;
13537 0 : RefTSat = this->refrig->getSatTemperature(state, Pe_update, RoutineName);
13538 0 : Pipe_h_IU_out = this->refrig->getSupHeatEnthalpy(state, max(RefTSat, Te_update + Pipe_SH_merged), Pe_update, RoutineName);
13539 : }
13540 :
13541 : // Re-calculate piping loss
13542 0 : this->VRFOU_PipeLossC(state, Pipe_m_ref, Pe_update, Pipe_h_IU_out, Pipe_SH_merged, OutdoorDryBulb, Pipe_Q, Pipe_DeltP, Pipe_h_comp_in);
13543 :
13544 0 : Tsuction = this->refrig->getSatTemperature(state, max(min(Pe_update - Pipe_DeltP, RefPHigh), RefPLow), RoutineName);
13545 0 : converged_11 = !((std::abs(Tsuction - Te_low) > 0.5) && (Te_update < Te_up) && (Te_update > Te_low) && (NumTeIte < MaxNumTeIte));
13546 0 : Te_update = Te_update - 0.1;
13547 0 : NumTeIte = NumTeIte + 1;
13548 0 : } while (!converged_11);
13549 :
13550 0 : if (std::abs(Tsuction - Te_low) > 0.5) {
13551 0 : NumTeIte = 999;
13552 0 : Tsuction = Te_low;
13553 0 : Pipe_SH_merged = 3.0;
13554 0 : Te_update = Te_low + 1;
13555 : }
13556 0 : }
13557 :
13558 4 : void VRFCondenserEquipment::VRFOU_CompSpd(
13559 : EnergyPlusData &state,
13560 : Real64 const Q_req, // Required capacity [W]
13561 : HXOpMode const Q_type, // Required capacity type: 0 for condenser, 1 for evaporator
13562 : Real64 const T_suction, // Compressor suction temperature Te' [C]
13563 : Real64 const T_discharge, // Compressor discharge temperature Tc' [C]
13564 : Real64 const h_IU_evap_in, // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg]
13565 : Real64 const h_comp_in, // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg]
13566 : Real64 &CompSpdActual // Actual compressor running speed [rps]
13567 : )
13568 : {
13569 :
13570 : // SUBROUTINE INFORMATION:
13571 : // AUTHOR Rongpeng Zhang, LBNL
13572 : // DATE WRITTEN Feb 2016
13573 : // MODIFIED na
13574 : // RE-ENGINEERED na
13575 :
13576 : // PURPOSE OF THIS SUBROUTINE:
13577 : // This subroutine specifies the compressor speed at given operational conditions to meet the evaporator or condenser capacity provided.
13578 :
13579 : // METHODOLOGY EMPLOYED:
13580 : // This is part of the VRF-FluidTCtrl Model.
13581 :
13582 : using Curve::CurveValue;
13583 :
13584 : // Locals
13585 : // SUBROUTINE ARGUMENT DEFINITIONS:
13586 :
13587 : // SUBROUTINE PARAMETER DEFINITIONS:
13588 : int CounterCompSpdTemp; // Index for the compressor speed level[-]
13589 : int CompSpdLB; // index for Compressor speed low bound [-]
13590 : int CompSpdUB; // index for Compressor speed up bound [-]
13591 : int NumOfCompSpdInput; // Number of compressor speed input by the user [-]
13592 : Real64 C_cap_operation; // Compressor capacity modification algorithm_modified Cap [-]
13593 : Real64 P_suction; // Compressor suction pressure Pe' [Pa]
13594 : Real64 Q_evap_req; // Required evaporative capacity [W]
13595 : Real64 Q_cond_req; // Required evaporative capacity [W]
13596 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
13597 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
13598 : Real64 SH_Comp; // Temperature between compressor inlet temperature and evaporative temperature Te' [C]
13599 : Real64 T_comp_in; // Refrigerant temperature at compressor inlet (after piping loss) [C]
13600 4 : Array1D<Real64> CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W]
13601 4 : Array1D<Real64> CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W]
13602 :
13603 : static constexpr std::string_view RoutineName("VRFOU_CompSpd");
13604 :
13605 : // variable initializations: component index
13606 4 : RefPLow = this->refrig->PsLowPresValue;
13607 4 : RefPHigh = this->refrig->PsHighPresValue;
13608 :
13609 : // variable initializations: compressor
13610 4 : NumOfCompSpdInput = this->CompressorSpeed.size();
13611 4 : CompEvaporatingPWRSpd.dimension(NumOfCompSpdInput);
13612 4 : CompEvaporatingCAPSpd.dimension(NumOfCompSpdInput);
13613 :
13614 : // variable initializations: system operational parameters
13615 4 : P_suction = this->refrig->getSatPressure(state, T_suction, RoutineName);
13616 4 : T_comp_in = this->refrig->getSupHeatTemp(state, max(min(P_suction, RefPHigh), RefPLow), h_comp_in, T_suction + 3, T_suction + 30, RoutineName);
13617 4 : SH_Comp = T_comp_in - T_suction;
13618 :
13619 : // Calculate capacity modification factor
13620 4 : C_cap_operation = this->VRFOU_CapModFactor(
13621 : state, h_comp_in, h_IU_evap_in, max(min(P_suction, RefPHigh), RefPLow), T_suction + SH_Comp, T_suction + 8, T_discharge - 5);
13622 :
13623 4 : if (Q_type == HXOpMode::EvapMode) {
13624 : // Capacity to meet is for evaporator
13625 :
13626 2 : Q_evap_req = Q_req;
13627 :
13628 2 : for (CounterCompSpdTemp = 1; CounterCompSpdTemp <= NumOfCompSpdInput; CounterCompSpdTemp++) {
13629 : // Iteration to find the VRF speed that can meet the required load, Iteration DoName1
13630 :
13631 4 : CompEvaporatingPWRSpd(CounterCompSpdTemp) =
13632 2 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
13633 4 : CompEvaporatingCAPSpd(CounterCompSpdTemp) =
13634 2 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction);
13635 :
13636 2 : if (Q_evap_req * C_cap_operation <= CompEvaporatingCAPSpd(CounterCompSpdTemp)) {
13637 : // Compressor speed stage CounterCompSpdTemp need not to be increased, finish Iteration DoName1
13638 :
13639 2 : if (CounterCompSpdTemp > 1) {
13640 :
13641 0 : CompSpdLB = CounterCompSpdTemp - 1;
13642 0 : CompSpdUB = CounterCompSpdTemp;
13643 :
13644 0 : CompSpdActual = this->CompressorSpeed(CompSpdLB) + (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB)) /
13645 0 : (CompEvaporatingCAPSpd(CompSpdUB) - CompEvaporatingCAPSpd(CompSpdLB)) *
13646 0 : (Q_evap_req * C_cap_operation - CompEvaporatingCAPSpd(CompSpdLB));
13647 :
13648 : } else {
13649 2 : CompSpdActual = this->CompressorSpeed(1) * (Q_evap_req * C_cap_operation) / CompEvaporatingCAPSpd(1);
13650 : }
13651 :
13652 2 : break; // EXIT DoName1
13653 : }
13654 : } // End: Iteration DoName1
13655 :
13656 2 : if (CounterCompSpdTemp > NumOfCompSpdInput) {
13657 0 : CompSpdActual = this->CompressorSpeed(NumOfCompSpdInput);
13658 : }
13659 :
13660 : } else {
13661 : // Capacity to meet is for condenser
13662 :
13663 : // derivation process
13664 : // let
13665 : // k be the speed level
13666 : // C be the short form for C_cap_operation
13667 : // PWR(.) be the short form of CompEvaporatingPWRSpd(.)
13668 : // CAP(.) be the short form of CompEvaporatingCAPSpd(.)
13669 : // spd(.) be the short form of this->CompressorSpeed(.)
13670 : // deltaPWR be PWR(k) - PWR(k - 1)
13671 : // deltaCAP be CAP(k) - CAP(k - 1)
13672 : //
13673 : // compressor heat = deltaPWR * r + PWR(k - 1)
13674 : // so
13675 : // Q_cond_req = Q_req = Q_evap_req + deltaPWR * r + PWR(k - 1) <---- eq 1
13676 : //
13677 : // we also know this from the CompSpdActual calculation equation that
13678 : // CompSpdActual = Spd(k - 1) + deltaSpd / deltaCAP * (Q_evap_req * C - CAP(k - 1))
13679 : // so we call the following r
13680 : // r = (Q_evap_req * C - CAP(k - 1)) / deltaCAP
13681 : // so
13682 : // CompSpdActual = Spd(k - 1) + deltaSpd * r
13683 : //
13684 : // arranging terms in eq 1
13685 : // Q_cond_req - deltaPWR * r - PWR(k - 1) = Q_evap_req
13686 : // (Q_cond_req - deltaPWR * r - PWR(k - 1)) * C - CAP(k - 1) = Q_evap_req * C - CAP(k - 1)
13687 : // ((Q_cond_req - deltaPWR * r - PWR(k - 1)) * C - CAP(k - 1)) / deltaCAP = (Q_evap_req * C - CAP(k - 1)) / deltaCAP
13688 : // ((Q_cond_req - deltaPWR * r - PWR(k - 1)) * C - CAP(k - 1)) / deltaCAP = r
13689 : // (Q_cond_req - deltaPWR * r - PWR(k - 1)) * C - CAP(k - 1) = deltaCAP * r
13690 : // (Q_cond_req - PWR(k - 1)) * C - CAP(k - 1) = deltaCAP * r + deltaPWR * r * C
13691 : // so
13692 : // r = ((Q_cond_req - PWR(k - 1)) * C - CAP(k - 1)) / (deltaCAP + deltaPWR * C)
13693 : // = ((Q_cond_req - PWR(k - 1)) - CAP(k - 1)/C) / (deltaCAP/C + deltaPWR)
13694 : //
13695 : // in the special case where k = 1, then k - 1, PWR(k - 1) and CAP(k - 1) will all be 0
13696 : // r = ((Q_cond_req) * C) / (CAP(1) - PWR(1) * C)
13697 : // = (Q_cond_req) / (CAP(1)/C - PWR(1))
13698 :
13699 2 : Q_cond_req = Q_req;
13700 :
13701 2 : CounterCompSpdTemp = 1;
13702 2 : CompEvaporatingPWRSpd(1) = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(1), T_discharge, T_suction);
13703 2 : CompEvaporatingCAPSpd(1) = this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(1), T_discharge, T_suction);
13704 2 : Real64 r = (Q_cond_req * C_cap_operation) / (CompEvaporatingCAPSpd(1) + CompEvaporatingPWRSpd(1) * C_cap_operation);
13705 2 : if (r < 1.0) {
13706 2 : CompSpdActual = this->CompressorSpeed(1) * r;
13707 2 : Q_evap_req = Q_cond_req - CompEvaporatingPWRSpd(1) * r;
13708 : } else {
13709 0 : for (CounterCompSpdTemp = 2; CounterCompSpdTemp <= NumOfCompSpdInput; CounterCompSpdTemp++) {
13710 0 : CompEvaporatingPWRSpd(CounterCompSpdTemp) =
13711 0 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
13712 0 : CompEvaporatingCAPSpd(CounterCompSpdTemp) =
13713 0 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction);
13714 0 : CompSpdLB = CounterCompSpdTemp - 1;
13715 0 : CompSpdUB = CounterCompSpdTemp;
13716 0 : Real64 deltaCAP = CompEvaporatingCAPSpd(CompSpdUB) - CompEvaporatingCAPSpd(CompSpdLB);
13717 0 : Real64 deltaPWR = CompEvaporatingPWRSpd(CompSpdUB) - CompEvaporatingPWRSpd(CompSpdLB);
13718 0 : Real64 r = ((Q_cond_req - CompEvaporatingPWRSpd(CompSpdLB)) * C_cap_operation - CompEvaporatingCAPSpd(CompSpdLB)) /
13719 0 : (deltaCAP + deltaPWR * C_cap_operation);
13720 0 : if (r < 1.0) {
13721 0 : CompSpdActual = this->CompressorSpeed(CompSpdLB) + (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB)) * r;
13722 0 : Q_evap_req = Q_cond_req - deltaPWR * r - CompEvaporatingPWRSpd(CompSpdLB);
13723 0 : break;
13724 : }
13725 : }
13726 : } // End: Iteration DoName1
13727 :
13728 2 : if (CounterCompSpdTemp > NumOfCompSpdInput) {
13729 0 : CompSpdActual = this->CompressorSpeed(NumOfCompSpdInput);
13730 : }
13731 : }
13732 4 : }
13733 :
13734 2 : void VRFCondenserEquipment::VRFOU_CompCap(
13735 : EnergyPlusData &state,
13736 : Real64 const CompSpdActual, // Given compressor speed
13737 : Real64 const T_suction, // Compressor suction temperature Te' [C]
13738 : Real64 const T_discharge, // Compressor discharge temperature Tc' [C]
13739 : Real64 const h_IU_evap_in, // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg]
13740 : Real64 const h_comp_in, // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg]
13741 : Real64 &Q_c_tot, // Compressor evaporative capacity [W]
13742 : Real64 &Ncomp // Compressor power [W]
13743 : )
13744 : {
13745 :
13746 : // SUBROUTINE INFORMATION:
13747 : // AUTHOR Rongpeng Zhang, LBNL
13748 : // DATE WRITTEN Feb 2016
13749 : // MODIFIED na
13750 : // RE-ENGINEERED na
13751 :
13752 : // PURPOSE OF THIS SUBROUTINE:
13753 : // This subroutine specifies the compressor performance (power and capacity) at given compressor speed and operational conditions.
13754 :
13755 : // METHODOLOGY EMPLOYED:
13756 : // This is part of the VRF-FluidTCtrl Model.
13757 :
13758 : using Curve::CurveValue;
13759 : int CounterCompSpdTemp; // Index for the compressor speed level[-]
13760 : int CompSpdLB; // index for Compressor speed low bound [-]
13761 : int CompSpdUB; // index for Compressor speed up bound [-]
13762 : int NumOfCompSpdInput; // Number of compressor speed input by the user [-]
13763 : Real64 C_cap_operation; // Compressor capacity modification algorithm_modified Cap [-]
13764 : Real64 P_suction; // Compressor suction pressure Pe' [Pa]
13765 : Real64 Q_evap_sys; // evaporative capacity [W]
13766 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
13767 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
13768 : Real64 SH_Comp; // Temperature between compressor inlet temperature and evaporative temperature Te' [C]
13769 : Real64 T_comp_in; // Refrigerant temperature at compressor inlet (after piping loss) [C]
13770 2 : Array1D<Real64> CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W]
13771 2 : Array1D<Real64> CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W]
13772 :
13773 : static constexpr std::string_view RoutineName("VRFOU_CompCap");
13774 :
13775 : // variable initializations: component index
13776 2 : RefPLow = this->refrig->PsLowPresValue;
13777 2 : RefPHigh = this->refrig->PsHighPresValue;
13778 :
13779 : // variable initializations: compressor
13780 2 : NumOfCompSpdInput = this->CompressorSpeed.size();
13781 2 : CompEvaporatingPWRSpd.dimension(NumOfCompSpdInput);
13782 2 : CompEvaporatingCAPSpd.dimension(NumOfCompSpdInput);
13783 :
13784 2 : for (CounterCompSpdTemp = 1; CounterCompSpdTemp <= NumOfCompSpdInput; CounterCompSpdTemp++) {
13785 :
13786 4 : CompEvaporatingPWRSpd(CounterCompSpdTemp) =
13787 2 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
13788 4 : CompEvaporatingCAPSpd(CounterCompSpdTemp) =
13789 2 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction);
13790 :
13791 2 : if (CompSpdActual <= this->CompressorSpeed(CounterCompSpdTemp)) {
13792 : // Compressor speed stage CounterCompSpdTemp need not to be increased, finish Iteration DoName1
13793 :
13794 2 : if (CounterCompSpdTemp > 1) {
13795 :
13796 0 : CompSpdLB = CounterCompSpdTemp - 1;
13797 0 : CompSpdUB = CounterCompSpdTemp;
13798 :
13799 0 : Q_evap_sys = CompEvaporatingCAPSpd(CompSpdLB) + (CompEvaporatingCAPSpd(CompSpdUB) - CompEvaporatingCAPSpd(CompSpdLB)) *
13800 0 : (CompSpdActual - this->CompressorSpeed(CompSpdLB)) /
13801 0 : (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB));
13802 0 : Ncomp = CompEvaporatingPWRSpd(CompSpdLB) + (CompEvaporatingPWRSpd(CompSpdUB) - CompEvaporatingPWRSpd(CompSpdLB)) *
13803 0 : (CompSpdActual - this->CompressorSpeed(CompSpdLB)) /
13804 0 : (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB));
13805 :
13806 : } else {
13807 2 : Q_evap_sys = CompEvaporatingCAPSpd(1) * CompSpdActual / this->CompressorSpeed(1);
13808 2 : Ncomp = CompEvaporatingPWRSpd(1) * CompSpdActual / this->CompressorSpeed(1);
13809 : }
13810 :
13811 2 : break;
13812 : }
13813 : }
13814 :
13815 2 : if (CounterCompSpdTemp > NumOfCompSpdInput) {
13816 0 : Q_evap_sys = CompEvaporatingCAPSpd(NumOfCompSpdInput);
13817 0 : Ncomp = CompEvaporatingPWRSpd(NumOfCompSpdInput);
13818 : }
13819 :
13820 : // variable initializations: system operational parameters
13821 2 : P_suction = this->refrig->getSatPressure(state, T_suction, RoutineName);
13822 2 : T_comp_in = this->refrig->getSupHeatTemp(state, max(min(P_suction, RefPHigh), RefPLow), h_comp_in, T_suction + 3, T_suction + 30, RoutineName);
13823 2 : SH_Comp = T_comp_in - T_suction;
13824 :
13825 : // Calculate capacity modification factor
13826 2 : C_cap_operation = this->VRFOU_CapModFactor(
13827 : state, h_comp_in, h_IU_evap_in, max(min(P_suction, RefPHigh), RefPLow), T_suction + SH_Comp, T_suction + 8, T_discharge - 5);
13828 2 : C_cap_operation = min(1.5, max(0.5, C_cap_operation));
13829 2 : Q_c_tot = Q_evap_sys / C_cap_operation;
13830 2 : }
13831 :
13832 2835 : void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state,
13833 : Real64 TU_load, // Indoor unit cooling load [W]
13834 : Real64 T_suction, // Compressor suction temperature Te' [C]
13835 : Real64 T_discharge, // Compressor discharge temperature Tc' [C]
13836 : Real64 P_suction, // Compressor suction pressure Pe' [Pa]
13837 : Real64 Pipe_T_comp_in, // Refrigerant temperature at compressor inlet (after piping loss) [C]
13838 : Real64 Pipe_h_comp_in, // Enthalpy after piping loss (compressor inlet) [kJ/kg]
13839 : Real64 Pipe_h_IU_in, // Enthalpy of IU at inlet [kJ/kg]
13840 : Real64 Pipe_Q, // Piping Loss Algorithm Parameter: Heat loss [W]
13841 : Real64 MaxOutdoorUnitTc, // The maximum temperature that Tc can be at heating mode [C]
13842 : Real64 &OUCondHeatRelease, // Condenser heat release (cooling mode) [W]
13843 : Real64 &CompSpdActual, // Actual compressor running speed [rps]
13844 : Real64 &Ncomp, // Compressor power [W]
13845 : Real64 &CyclingRatio // Cycling Ratio [W]
13846 : )
13847 : {
13848 :
13849 : // SUBROUTINE INFORMATION:
13850 : // AUTHOR Xiufeng Pang
13851 : // DATE WRITTEN Feb 2014
13852 : // MODIFIED Rongpeng Zhang, Jan 2016
13853 : // MODIFIED Yujie Xu, Sep 2023
13854 : // RE-ENGINEERED na
13855 :
13856 : // PURPOSE OF THIS SUBROUTINE:
13857 : // This subroutine simulates the compressor performance at given operational conditions (cooling mode). More specifically, it specifies
13858 : // the compressor speed to provide sufficient evaporative capacity, and calculate the power of the compressor running at the specified
13859 : // speed. Note that it may be needed to manipulate the operational conditions to further adjust system capacity at low load conditions.
13860 : // The low load modification logics are different for cooling mode and heating mode.
13861 :
13862 : // METHODOLOGY EMPLOYED:
13863 : // This is part of the VRF-FluidTCtrl Model.
13864 :
13865 : using Curve::CurveValue;
13866 :
13867 : using General::SolveRoot;
13868 :
13869 : int CounterCompSpdTemp; // Index for the compressor speed level[-]
13870 : int CompSpdLB; // index for Compressor speed low bound [-]
13871 : int CompSpdUB; // index for Compressor speed up bound [-]
13872 : int CoolCoilIndex; // index to cooling coil in terminal unit
13873 2835 : int MaxIter(500); // max iteration number allowed [-]
13874 : int NumOfCompSpdInput; // Number of compressor speed input by the user [-]
13875 : int NumIteCcap; // counter for Ccap calculation iterations [-]
13876 : int NumIteTe; // counter for Te calculation iterations [-]
13877 : int NumTUInList; // number of terminal units is list
13878 : int SolFla; // Slove flag for SolveRoot [-]
13879 : int TUListNum; // index to TU List
13880 : int TUIndex; // Index to terminal unit
13881 : Real64 Cap_Eva0; // Evaporating capacity calculated based on physics model, used in the iterations [W]
13882 : Real64 Cap_Eva1; // Evaporating capacity calculated by curves, used in the iterations [W]
13883 : Real64 CapDiff; // Evaporating capacity difference used in the iterations [W]
13884 : Real64 C_cap_operation; // Compressor capacity modification algorithm_modified Cap [-]
13885 : Real64 C_cap_operation0; // Compressor capacity modification algorithm_modified Cap, for temporary use [-]
13886 : Real64 SmallLoadTe; // Updated suction temperature at small load conditions (Te') [C]
13887 : Real64 Modifi_SH; // Temperature between compressor inlet temperature and evaporative temperature Te' [C]
13888 : Real64 MaxNumIteTe; // Piping Loss Algorithm Parameter: max number of iterations for Te [-]
13889 : Real64 MinOutdoorUnitTe; // The minimum temperature that Te can be at cooling mode (only used for calculating Min capacity)
13890 : Real64 MinOutdoorUnitPe; // The minimum pressure that Pe can be at cooling mode (only used for calculating Min capacity)
13891 : Real64 MinRefriPe; // Minimum refrigerant evaporating pressure [Pa]
13892 : Real64 Modifi_SHin; // Compressor power modification algorithm_modified SH for IDU [C]
13893 : Real64 P_discharge; // VRF compressor discharge pressure [Pa]
13894 : Real64 Pipe_m_ref; // Piping Loss Algorithm Parameter: Refrigerant mass flow rate [kg/s]
13895 : Real64 Pipe_DeltP; // Piping Loss Algorithm Parameter: Pipe pressure drop [Pa]
13896 : Real64 Pipe_Q0; // Compressor capacity modification algorithm_modified Pipe_Q, for temporary use [W]
13897 : Real64 Pipe_m_ref_i; // Piping Loss Algorithm Parameter: Refrigerant mass flow rate for a individual IU[kg/s]
13898 : Real64 Pipe_h_IU_out; // Piping Loss Algorithm Parameter: enthalpy of IU at outlet [kJ/kg]
13899 : Real64 Pipe_h_IU_out_i; // Piping Loss Algorithm Parameter: enthalpy of IU at outlet (individual) [kJ/kg]
13900 : Real64 Pipe_Pe_assumed; // Piping Loss Algorithm Parameter: evaporating pressure assumed for iterations[Pa]
13901 : Real64 Pipe_SH_merged; // Piping Loss Algorithm Parameter: average super heating degrees after the indoor units [C]
13902 : Real64 Pipe_Te_assumed; // Piping Loss Algorithm Parameter: evaporating temperature assumed for iterations[C]
13903 : Real64 Q_evap_req; // Required evaporative capacity [W]
13904 : Real64 RefTSat; // Saturated temperature of the refrigerant [C]
13905 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
13906 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
13907 : Real64 T_discharge_new; // Condensing temperature, for temporary use in iterations [C]
13908 : Real64 Tfs; // Temperature of the air at the coil surface [C]]
13909 2835 : Real64 constexpr Tolerance(0.05); // Tolerance for condensing temperature calculation [C]
13910 2835 : Real64 constexpr TeTol(0.5); // Tolerance for the difference between Te and SmallLoadTe
13911 2835 : Array1D<Real64> CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W]
13912 2835 : Array1D<Real64> CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W]
13913 :
13914 : static constexpr std::string_view RoutineName("VRFOU_CalcCompC");
13915 :
13916 : // variable initializations
13917 2835 : NumOfCompSpdInput = this->CompressorSpeed.size();
13918 2835 : CompEvaporatingPWRSpd.dimension(NumOfCompSpdInput);
13919 2835 : CompEvaporatingCAPSpd.dimension(NumOfCompSpdInput);
13920 2835 : Q_evap_req = TU_load + Pipe_Q;
13921 :
13922 2835 : TUListNum = this->ZoneTUListPtr;
13923 2835 : RefPLow = this->refrig->PsLowPresValue;
13924 2835 : RefPHigh = this->refrig->PsHighPresValue;
13925 2835 : NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
13926 :
13927 2835 : Modifi_SH = Pipe_T_comp_in - T_suction;
13928 :
13929 : // set condenser entering air conditions (Outdoor air conditions)
13930 2835 : Real64 OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13931 2835 : Real64 OutdoorHumRat = state.dataEnvrn->OutHumRat;
13932 2835 : Real64 OutdoorPressure = state.dataEnvrn->OutBaroPress;
13933 2835 : Real64 RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
13934 :
13935 : // Calculate capacity modification factor
13936 2835 : C_cap_operation = this->VRFOU_CapModFactor(
13937 : state, Pipe_h_comp_in, Pipe_h_IU_in, max(min(P_suction, RefPHigh), RefPLow), T_suction + Modifi_SH, T_suction + 8, T_discharge - 5);
13938 :
13939 2835 : this->adjustedTe = false;
13940 6941 : for (CounterCompSpdTemp = 1; CounterCompSpdTemp <= NumOfCompSpdInput; CounterCompSpdTemp++) {
13941 : // Iteration to find the VRF speed that can meet the required load, Iteration DoName1
13942 :
13943 13882 : CompEvaporatingPWRSpd(CounterCompSpdTemp) =
13944 6941 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
13945 13882 : CompEvaporatingCAPSpd(CounterCompSpdTemp) =
13946 6941 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction);
13947 :
13948 6941 : if (Q_evap_req * C_cap_operation <= CompEvaporatingCAPSpd(CounterCompSpdTemp)) {
13949 : // Compressor speed stage CounterCompSpdTemp need not to be increased, finish Iteration DoName1
13950 :
13951 2835 : if (CounterCompSpdTemp > 1) { // Since: if( CounterCompSpdTemp <= 1 )
13952 : // Compressor speed > min
13953 :
13954 2582 : CompSpdLB = CounterCompSpdTemp - 1;
13955 2582 : CompSpdUB = CounterCompSpdTemp;
13956 :
13957 2582 : CompSpdActual = this->CompressorSpeed(CompSpdLB) + (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB)) /
13958 2582 : (CompEvaporatingCAPSpd(CompSpdUB) - CompEvaporatingCAPSpd(CompSpdLB)) *
13959 2582 : (Q_evap_req * C_cap_operation - CompEvaporatingCAPSpd(CompSpdLB));
13960 :
13961 2582 : Ncomp = CompEvaporatingPWRSpd(CompSpdLB) + (CompEvaporatingPWRSpd(CompSpdUB) - CompEvaporatingPWRSpd(CompSpdLB)) /
13962 2582 : (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB)) *
13963 2582 : (CompSpdActual - this->CompressorSpeed(CompSpdLB));
13964 2582 : break; // EXIT DoName1
13965 :
13966 : } else {
13967 : // Compressor runs at the min speed
13968 : // Low Load Modification Algorithm for cooling (IU side modification)
13969 :
13970 : // Initialization of NumIteCcap iterations (Label13)
13971 253 : Pipe_Q0 = Pipe_Q;
13972 253 : C_cap_operation0 = C_cap_operation;
13973 253 : T_discharge_new = T_discharge;
13974 253 : NumIteCcap = 1;
13975 :
13976 : // Update the C_cap_operation
13977 : bool converged_13;
13978 : do {
13979 7271 : Q_evap_req = TU_load + Pipe_Q0; // Pipe_Q0 is updated during the iteration
13980 7271 : Pipe_h_IU_in = this->refrig->getSatEnthalpy(state, T_discharge_new - this->SC, 0.0, RoutineName);
13981 7271 : CompSpdActual = this->CompressorSpeed(1);
13982 7271 : Real64 CondHeat = Q_evap_req * C_cap_operation0 / this->RatedEvapCapacity; // 150130 To be confirmed
13983 7271 : int CAPFT = this->OUCoolingCAPFT(CounterCompSpdTemp);
13984 :
13985 7271 : P_discharge = this->refrig->getSatPressure(state, T_discharge, RoutineName);
13986 7271 : MinRefriPe = this->refrig->getSatPressure(state, -15, RoutineName);
13987 7271 : MinOutdoorUnitPe = max(P_discharge - this->CompMaxDeltaP, MinRefriPe);
13988 7271 : MinOutdoorUnitTe = this->refrig->getSatTemperature(state, max(min(MinOutdoorUnitPe, RefPHigh), RefPLow), RoutineName);
13989 : // Te can't be smaller than user input lower bound
13990 7271 : MinOutdoorUnitTe = max(this->IUEvapTempLow, MinOutdoorUnitTe);
13991 :
13992 22011 : auto f = [&state, T_discharge_new, CondHeat, CAPFT](Real64 const T_suc) {
13993 22011 : return CompResidual_FluidTCtrl(state, T_discharge_new, CondHeat, CAPFT, T_suc);
13994 7271 : };
13995 :
13996 7271 : General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, SmallLoadTe, f, MinOutdoorUnitTe,
13997 : T_suction); // SmallLoadTe is the updated Te'
13998 7271 : if (SolFla == -1) {
13999 : // show error not converging
14000 0 : ShowWarningMessage(state, format("{}: low load Te adjustment failed for {}", RoutineName, this->Name));
14001 0 : ShowContinueErrorTimeStamp(state, "");
14002 0 : ShowContinueError(state, format(" Iteration limit [{}] exceeded in calculating OU evaporating temperature", MaxIter));
14003 7271 : } else if (SolFla == -2) {
14004 7269 : this->LowLoadTeError++;
14005 7269 : if (LowLoadTeError < 5) {
14006 24 : ShowWarningMessage(state,
14007 24 : format("{}: no Te solution was found for {} f({})={} and f({})={} are the same sign",
14008 : RoutineName,
14009 12 : this->Name,
14010 : MinOutdoorUnitTe,
14011 12 : f(MinOutdoorUnitTe),
14012 : T_suction,
14013 12 : f(T_suction)));
14014 36 : ShowContinueErrorTimeStamp(state, "");
14015 : }
14016 50883 : ShowRecurringWarningErrorAtEnd(state,
14017 : "Low load calculation Te solution not found as end points have the same sign",
14018 7269 : this->LowLoadTeErrorIndex,
14019 : SolFla,
14020 : SolFla);
14021 7269 : if (f(T_suction) < 0) {
14022 : // demand < capacity at both endpoints of the Te range, assuming f(x) is roughly monotonic than this is the low load case
14023 : // TeTol is added to prevent the final updated Te to go out of bounds
14024 7182 : SmallLoadTe = MinOutdoorUnitTe + TeTol; // MinOutdoorUnitTe; //SmallLoadTe( Te'_new ) is constant during iterations
14025 : } else {
14026 : // demand > capacity at both endpoints of the Te range, take the end point x where f(x) is closer to zero
14027 87 : if (f(MinOutdoorUnitTe) > f(T_suction)) { // f(T_suction > 0, not equal as SolFla will not be -2
14028 87 : SmallLoadTe = T_suction;
14029 : } else {
14030 0 : SmallLoadTe = MinOutdoorUnitTe;
14031 : }
14032 : }
14033 : }
14034 :
14035 : // Get an updated Te corresponding to the updated Te'
14036 : // VRFOU_TeModification( VRFCond, this->EvaporatingTemp, SmallLoadTe, Pipe_h_IU_in, OutdoorDryBulb, Pipe_Te_assumed,
14037 : // Pipe_Pe_assumed, Pipe_m_ref, Pipe_SH_merged );
14038 : {
14039 : // Initialization of Iteration_Te (Label11)
14040 : // i.e., find a new Te (Pipe_Te_assumed) that can generate a new T_suction equaling to SmallLoadTe.
14041 : // This requires the re-calculate of piping loss.
14042 7271 : NumIteTe = 1;
14043 7271 : MaxNumIteTe = (this->EvaporatingTemp - SmallLoadTe) / 0.1 + 1; // upper bound and lower bound of Te iterations
14044 7271 : Pipe_Te_assumed = this->EvaporatingTemp - 0.1;
14045 7271 : this->adjustedTe = true;
14046 :
14047 : bool converged_11_2;
14048 : do {
14049 7481 : Pipe_m_ref = 0; // Total Ref Flow Rate( kg/s )
14050 :
14051 : // Re-calculate Piping loss due to the Te and SH updates
14052 7481 : Pipe_h_IU_out = 0;
14053 7481 : Pipe_h_IU_out_i = 0;
14054 7481 : Pipe_m_ref_i = 0;
14055 7481 : Pipe_SH_merged = 0;
14056 7481 : Pipe_Pe_assumed = this->refrig->getSatPressure(state, Pipe_Te_assumed, RoutineName);
14057 :
14058 : // Re-calculate total refrigerant flow rate, with updated SH
14059 14962 : for (int NumTU = 1; NumTU <= NumTUInList; NumTU++) {
14060 7481 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) > 0) {
14061 7451 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
14062 7451 : CoolCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
14063 :
14064 7451 : Tfs = this->EvaporatingTemp + (this->C3Te * pow_2(state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH) +
14065 7451 : this->C2Te * state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH + this->C1Te);
14066 :
14067 : // Modifi_SH is the updated SH for a specific IU
14068 7451 : if (this->C3Te == 0)
14069 0 : Modifi_SHin = -(this->C1Te - Tfs + Pipe_Te_assumed) / this->C2Te; // 150130 Modifi_SH>Modifi_SHin
14070 : else
14071 7451 : Modifi_SHin = (-this->C2Te +
14072 7451 : std::pow((pow_2(this->C2Te) - 4 * (this->C1Te - Tfs + Pipe_Te_assumed) * this->C3Te), 0.5)) /
14073 7451 : (2 * this->C3Te);
14074 :
14075 7451 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pipe_Pe_assumed, RefPHigh), RefPLow), RoutineName);
14076 7451 : Pipe_h_IU_out_i = this->refrig->getSupHeatEnthalpy(state,
14077 : max(RefTSat, Pipe_Te_assumed + Modifi_SHin),
14078 : max(min(Pipe_Pe_assumed, RefPHigh), RefPLow),
14079 : RoutineName);
14080 :
14081 7451 : if (Pipe_h_IU_out_i > Pipe_h_IU_in) {
14082 7451 : Real64 min_speed_capacity = this->CoffEvapCap * this->RatedEvapCapacity *
14083 7451 : CurveValue(state, this->OUCoolingCAPFT(1), T_discharge, T_suction);
14084 7451 : Pipe_m_ref_i = (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) <= 0.0)
14085 7451 : ? 0.0
14086 : // refrigerant flow rate do not get smaller when the compressor needs to cycle.
14087 7451 : : max(min_speed_capacity,
14088 7451 : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU)) /
14089 7451 : (Pipe_h_IU_out_i - Pipe_h_IU_in));
14090 7451 : Pipe_m_ref = Pipe_m_ref + Pipe_m_ref_i;
14091 7451 : Pipe_SH_merged = Pipe_SH_merged + Pipe_m_ref_i * Modifi_SHin;
14092 7451 : Pipe_h_IU_out = Pipe_h_IU_out + Pipe_m_ref_i * Pipe_h_IU_out_i;
14093 : }
14094 : }
14095 : }
14096 7481 : if (Pipe_m_ref > 0) {
14097 7451 : Pipe_h_IU_out = Pipe_h_IU_out / Pipe_m_ref;
14098 7451 : Pipe_SH_merged = Pipe_SH_merged / Pipe_m_ref;
14099 : } else {
14100 30 : Pipe_SH_merged = this->SH;
14101 30 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pipe_Pe_assumed, RefPHigh), RefPLow), RoutineName);
14102 30 : Pipe_h_IU_out = this->refrig->getSupHeatEnthalpy(
14103 : state, max(RefTSat, Pipe_Te_assumed + Pipe_SH_merged), max(min(Pipe_Pe_assumed, RefPHigh), RefPLow), RoutineName);
14104 : }
14105 :
14106 : // Re-calculate piping loss
14107 7481 : this->VRFOU_PipeLossC(state,
14108 : Pipe_m_ref,
14109 : max(min(Pipe_Pe_assumed, RefPHigh), RefPLow),
14110 : Pipe_h_IU_out,
14111 : Pipe_SH_merged,
14112 : OutdoorDryBulb,
14113 : Pipe_Q,
14114 : Pipe_DeltP,
14115 : Pipe_h_comp_in);
14116 :
14117 7481 : T_suction =
14118 7481 : this->refrig->getSatTemperature(state, max(min(Pipe_Pe_assumed - Pipe_DeltP, RefPHigh), RefPLow), RoutineName);
14119 :
14120 14962 : converged_11_2 = !((std::abs(T_suction - SmallLoadTe) > TeTol) && (Pipe_Te_assumed < this->EvaporatingTemp) &&
14121 7481 : (Pipe_Te_assumed > SmallLoadTe) && (NumIteTe < MaxNumIteTe));
14122 7481 : Pipe_Te_assumed = Pipe_Te_assumed - 0.1;
14123 7481 : NumIteTe = NumIteTe + 1;
14124 7481 : } while (!converged_11_2);
14125 :
14126 7271 : if (std::abs(T_suction - SmallLoadTe) > TeTol) {
14127 7271 : NumIteTe = 999;
14128 7271 : T_suction = SmallLoadTe;
14129 7271 : Pipe_SH_merged = 3.0;
14130 7271 : Pipe_Te_assumed = SmallLoadTe + 1;
14131 : }
14132 : // Iteration_Te End
14133 : }
14134 :
14135 : // Perform iteration to calculate Pipe_T_comp_in( Te'+SH' )
14136 7271 : Pipe_T_comp_in = this->refrig->getSupHeatTemp(
14137 : state, max(min(Pipe_Pe_assumed - Pipe_DeltP, RefPHigh), RefPLow), Pipe_h_comp_in, T_suction + 3, T_suction + 30, RoutineName);
14138 :
14139 7271 : Modifi_SH = Pipe_T_comp_in - T_suction;
14140 7271 : P_suction = Pipe_Pe_assumed - Pipe_DeltP;
14141 7271 : OUCondHeatRelease = TU_load + Pipe_Q + Ncomp; // Pipe_Q is changed when T_suction is changed -> Tc is also changed
14142 :
14143 : // *VRF OU Tc calculations
14144 7271 : this->VRFOU_TeTc(state,
14145 : HXOpMode::CondMode,
14146 : OUCondHeatRelease,
14147 : this->SC,
14148 7271 : this->OUAirFlowRate * RhoAir,
14149 : OutdoorDryBulb,
14150 : OutdoorHumRat,
14151 : OutdoorPressure,
14152 : Tfs,
14153 : T_discharge);
14154 7271 : T_discharge = min(MaxOutdoorUnitTc, T_discharge);
14155 :
14156 : // *Calculate capacity modification factor
14157 7271 : C_cap_operation = this->VRFOU_CapModFactor(state,
14158 : Pipe_h_comp_in,
14159 : Pipe_h_IU_in,
14160 : max(min(P_suction, RefPHigh), RefPLow),
14161 : T_suction + Modifi_SH,
14162 : T_suction + 8,
14163 : T_discharge - 5);
14164 :
14165 7271 : Cap_Eva0 = (TU_load + Pipe_Q) * C_cap_operation; // New Pipe_Q & C_cap_operation
14166 14542 : Cap_Eva1 = this->CoffEvapCap * this->RatedEvapCapacity *
14167 7271 : CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction); // New Tc
14168 7271 : CapDiff = std::abs(Cap_Eva1 - Cap_Eva0);
14169 7271 : converged_13 = !((CapDiff > (Tolerance * Cap_Eva0)) && (NumIteCcap < 30));
14170 7271 : NumIteCcap = NumIteCcap + 1;
14171 7271 : Pipe_Q0 = Pipe_Q;
14172 7271 : C_cap_operation0 = C_cap_operation;
14173 7271 : T_discharge_new = T_discharge;
14174 7271 : } while (!converged_13);
14175 :
14176 : // when it gets here, either NumIteCcap = 30 or CapDiff > (Tolerance * Cap_Eva0)
14177 253 : if (CapDiff > (Tolerance * Cap_Eva0) && (Cap_Eva1 - Cap_Eva0) >= 0.0) {
14178 239 : NumIteCcap = 999;
14179 239 : CyclingRatio = Cap_Eva0 / Cap_Eva1;
14180 : } else {
14181 14 : CyclingRatio = 1.0;
14182 : }
14183 :
14184 253 : Ncomp = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
14185 253 : OUCondHeatRelease = Ncomp + Cap_Eva1;
14186 :
14187 253 : this->CondensingTemp = T_discharge; // OU Tc' is updated due to OUCondHeatRelease updates, which is caused by IU Te' updates
14188 : // during low load conditions
14189 253 : this->EvaporatingTemp = T_suction;
14190 253 : this->IUEvaporatingTemp = T_suction;
14191 :
14192 253 : break; // EXIT DoName1
14193 :
14194 : } // End: if( CounterCompSpdTemp <= 1 ) Low load modification
14195 :
14196 : } // End: if( Q_evap_req <= CompEvaporatingCAPSpd( CounterCompSpdTemp ) )
14197 :
14198 : } // End: Iteration DoName1
14199 :
14200 2835 : if (CounterCompSpdTemp > NumOfCompSpdInput) {
14201 : // Required load is beyond the maximum system capacity
14202 0 : CompEvaporatingCAPSpd(NumOfCompSpdInput) =
14203 0 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), T_discharge, T_suction);
14204 0 : OUCondHeatRelease = Ncomp + CompEvaporatingCAPSpd(NumOfCompSpdInput);
14205 0 : CompSpdActual = this->CompressorSpeed(NumOfCompSpdInput);
14206 0 : Ncomp = CompEvaporatingPWRSpd(NumOfCompSpdInput);
14207 : }
14208 2835 : }
14209 :
14210 5271 : void VRFCondenserEquipment::VRFOU_CalcCompH(
14211 : EnergyPlusData &state,
14212 : Real64 TU_load, // Indoor unit heating load [W]
14213 : Real64 T_suction, // Compressor suction temperature Te' [C]
14214 : Real64 T_discharge, // Compressor discharge temperature Tc' [C]
14215 : Real64 Pipe_h_out_ave, // Average Enthalpy of the refrigerant leaving IUs [kJ/kg]
14216 : Real64 IUMaxCondTemp, // VRV IU condensing temperature, max among all indoor units [C]
14217 : Real64 MinOutdoorUnitTe, // The minimum temperature that OU Te can be at cooling mode (only used for calculating Min capacity)
14218 : Real64 Tfs, // Temperature of the air at the OU evaporator coil surface [C]]
14219 : Real64 Pipe_Q, // Piping Loss Algorithm Parameter: Heat loss [W]
14220 : Real64 &OUEvapHeatExtract, // Condenser heat release (cooling mode) [W]
14221 : Real64 &CompSpdActual, // Actual compressor running speed [rps]
14222 : Real64 &Ncomp, // Compressor power [W]
14223 : Real64 &CyclingRatio // Compressor cycling ratio
14224 : )
14225 : {
14226 :
14227 : // SUBROUTINE INFORMATION:
14228 : // AUTHOR Xiufeng Pang
14229 : // DATE WRITTEN Feb 2014
14230 : // MODIFIED Rongpeng Zhang, Jan 2016
14231 : // RE-ENGINEERED na
14232 :
14233 : // PURPOSE OF THIS SUBROUTINE:
14234 : // This subroutine simulates the compressor performance at given proportional conditions (heating mode). More specifically, it specifies
14235 : // the compressor speed to provide sufficient evaporative capacity, and calculate the power of the compressor running at the specified
14236 : // speed. Note that it may be needed to manipulate the operational conditions to further adjust system capacity at low load conditions.
14237 : // The low load modification logics are different for cooling mode and heating mode.
14238 :
14239 : // METHODOLOGY EMPLOYED:
14240 : // This is part of the VRF-FluidTCtrl Model.
14241 :
14242 : using Curve::CurveValue;
14243 : using General::SolveRoot;
14244 :
14245 : int CounterCompSpdTemp; // Index for the compressor speed level[-]
14246 : int CompSpdLB; // index for Compressor speed low bound [-]
14247 : int CompSpdUB; // index for Compressor speed up bound [-]
14248 5271 : int MaxIter(500); // max iteration number allowed [-]
14249 : int NumOfCompSpdInput; // Number of compressor speed input by the user [-]
14250 : int NumIteCcap; // counter for Ccap calculation iterations [-]
14251 : int NumTUInList; // number of terminal units is list
14252 : int SolFla; // Solve flag for SolveRoot [-]
14253 : int TUListNum; // index to TU List
14254 : Real64 Cap_Eva0; // Evaporating capacity calculated based on physics model, used in the iterations [W]
14255 : Real64 Cap_Eva1; // Evaporating capacity calculated by curves, used in the iterations [W]
14256 : Real64 CapDiff; // Evaporating capacity difference used in the iterations [W]
14257 : Real64 C_cap_operation; // Compressor capacity modification algorithm_modified Cap [-]
14258 : Real64 SmallLoadTe; // Updated suction temperature at small load conditions (Te') [C]
14259 : Real64 Modifi_SH; // Temperature between compressor inlet temperature and evaporative temperature Te' [C]
14260 : Real64 MinOutdoorUnitPe; // The minimum pressure that Pe can be at cooling mode (only used for calculating Min capacity)
14261 : Real64 Modifi_Pe; // Compressor power modification algorithm_modified Pe [Pa]
14262 : Real64 Pipe_h_comp_in; // Piping Loss Algorithm Parameter: Enthalpy after piping loss (compressor inlet) [kJ/kg]
14263 : Real64 Q_evap_req; // Required evaporative capacity [W]
14264 : Real64 RefTSat; // Saturated temperature of the refrigerant [C]
14265 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
14266 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
14267 5271 : Real64 constexpr Tolerance(0.05); // Tolerance for condensing temperature calculation [C}
14268 5271 : Array1D<Real64> CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W]
14269 5271 : Array1D<Real64> CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W]
14270 :
14271 : static constexpr std::string_view RoutineName("VRFOU_CalcCompH");
14272 :
14273 : // variable initializations
14274 5271 : NumOfCompSpdInput = this->CompressorSpeed.size();
14275 5271 : CompEvaporatingPWRSpd.dimension(NumOfCompSpdInput);
14276 5271 : CompEvaporatingCAPSpd.dimension(NumOfCompSpdInput);
14277 5271 : Q_evap_req = TU_load + Pipe_Q - Ncomp;
14278 :
14279 5271 : TUListNum = this->ZoneTUListPtr;
14280 5271 : RefPLow = this->refrig->PsLowPresValue;
14281 5271 : RefPHigh = this->refrig->PsHighPresValue;
14282 5271 : NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
14283 :
14284 : // Calculate capacity modification factor
14285 5271 : MinOutdoorUnitPe = this->refrig->getSatPressure(state, T_suction, RoutineName);
14286 5271 : RefTSat = this->refrig->getSatTemperature(state, max(min(MinOutdoorUnitPe, RefPHigh), RefPLow), RoutineName);
14287 : Pipe_h_comp_in =
14288 5271 : this->refrig->getSupHeatEnthalpy(state, max(RefTSat, T_suction + this->SH), max(min(MinOutdoorUnitPe, RefPHigh), RefPLow), RoutineName);
14289 5271 : C_cap_operation = this->VRFOU_CapModFactor(
14290 5271 : state, Pipe_h_comp_in, Pipe_h_out_ave, max(min(MinOutdoorUnitPe, RefPHigh), RefPLow), T_suction + this->SH, T_suction + 8, IUMaxCondTemp - 5);
14291 :
14292 : // Perform iterations to find the compressor speed that can meet the required heating load, Iteration DoName2
14293 10413 : for (CounterCompSpdTemp = 1; CounterCompSpdTemp <= NumOfCompSpdInput; CounterCompSpdTemp++) {
14294 :
14295 20826 : CompEvaporatingPWRSpd(CounterCompSpdTemp) =
14296 10413 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
14297 20826 : CompEvaporatingCAPSpd(CounterCompSpdTemp) =
14298 10413 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction);
14299 :
14300 10413 : if ((Q_evap_req * C_cap_operation) <= CompEvaporatingCAPSpd(CounterCompSpdTemp)) {
14301 : // Compressor Capacity is greater than the required, finish Iteration DoName2
14302 :
14303 5271 : if (CounterCompSpdTemp > 1) {
14304 : // Compressor runs at higher speed than min speed
14305 5142 : CompSpdLB = CounterCompSpdTemp - 1;
14306 5142 : CompSpdUB = CounterCompSpdTemp;
14307 :
14308 5142 : CompSpdActual = this->CompressorSpeed(CompSpdLB) + (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB)) /
14309 5142 : (CompEvaporatingCAPSpd(CompSpdUB) - CompEvaporatingCAPSpd(CompSpdLB)) *
14310 5142 : (Q_evap_req * C_cap_operation - CompEvaporatingCAPSpd(CompSpdLB));
14311 5142 : Modifi_SH = this->SH;
14312 5142 : Ncomp = CompEvaporatingPWRSpd(CompSpdLB) + (CompEvaporatingPWRSpd(CompSpdUB) - CompEvaporatingPWRSpd(CompSpdLB)) /
14313 5142 : (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB)) *
14314 5142 : (CompSpdActual - this->CompressorSpeed(CompSpdLB));
14315 :
14316 5142 : break; // EXIT DoName2
14317 :
14318 : } else {
14319 : // Compressor runs at the min speed
14320 : // Low Load Modifications
14321 :
14322 129 : NumIteCcap = 1;
14323 : bool converged_19;
14324 : // triggered in VariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf
14325 : do {
14326 1985 : Q_evap_req = max(0.0, TU_load + Pipe_Q - Ncomp);
14327 :
14328 : // Update Te'( SmallLoadTe ) to meet the required evaporator capacity
14329 1985 : CompSpdActual = this->CompressorSpeed(1);
14330 1985 : Real64 CondHeat = Q_evap_req * C_cap_operation / this->RatedEvapCapacity;
14331 1985 : int CAPFT = this->OUCoolingCAPFT(CounterCompSpdTemp);
14332 :
14333 4122 : auto f = [&state, T_discharge, CondHeat, CAPFT](Real64 const T_suc) {
14334 4122 : return CompResidual_FluidTCtrl(state, T_discharge, CondHeat, CAPFT, T_suc);
14335 1985 : };
14336 1985 : General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, SmallLoadTe, f, MinOutdoorUnitTe, T_suction);
14337 1985 : if (SolFla < 0) SmallLoadTe = MinOutdoorUnitTe;
14338 :
14339 1985 : T_suction = SmallLoadTe;
14340 :
14341 : // Update SH and Pe to calculate Modification Factor, which is used to update rps to for N_comp calculations
14342 1985 : if (this->C3Te == 0)
14343 0 : Modifi_SH = -(this->C1Te - Tfs + T_suction) / this->C2Te;
14344 : else {
14345 1985 : if ((pow_2(this->C2Te) - 4 * (this->C1Te - Tfs + T_suction) * this->C3Te) < 0.0)
14346 0 : Modifi_SH = this->C2Te / (-2 * (this->C1Te - Tfs + T_suction));
14347 : else
14348 1985 : Modifi_SH = (-this->C2Te + std::pow((pow_2(this->C2Te) - 4 * (this->C1Te - Tfs + T_suction) * this->C3Te), 0.5)) /
14349 1985 : (2 * this->C3Te);
14350 : }
14351 :
14352 1985 : Modifi_Pe = this->refrig->getSatPressure(state, T_suction, RoutineName);
14353 :
14354 : // Calculate capacity modification factor
14355 1985 : RefTSat = this->refrig->getSatTemperature(state, max(min(Modifi_Pe, RefPHigh), RefPLow), RoutineName);
14356 1985 : Pipe_h_comp_in = this->refrig->getSupHeatEnthalpy(
14357 : state, max(RefTSat, T_suction + Modifi_SH), max(min(Modifi_Pe, RefPHigh), RefPLow), RoutineName);
14358 1985 : C_cap_operation = this->VRFOU_CapModFactor(state,
14359 : Pipe_h_comp_in,
14360 : Pipe_h_out_ave,
14361 : max(min(Modifi_Pe, RefPHigh), RefPLow),
14362 : T_suction + Modifi_SH,
14363 : T_suction + 8,
14364 : IUMaxCondTemp - 5);
14365 :
14366 1985 : Cap_Eva0 = Q_evap_req * C_cap_operation;
14367 3970 : Cap_Eva1 = this->CoffEvapCap * this->RatedEvapCapacity *
14368 1985 : CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction);
14369 1985 : CapDiff = std::abs(Cap_Eva1 - Cap_Eva0);
14370 1985 : converged_19 = (CapDiff <= (Tolerance * Cap_Eva0)) || (NumIteCcap >= 30);
14371 1985 : NumIteCcap = NumIteCcap + 1;
14372 1985 : } while (!converged_19);
14373 129 : if (CapDiff > (Tolerance * Cap_Eva0) && (Cap_Eva1 - Cap_Eva0) >= 0.0) {
14374 64 : NumIteCcap = 999;
14375 64 : CyclingRatio = Cap_Eva0 / Cap_Eva1;
14376 : } else {
14377 65 : CyclingRatio = 1.0;
14378 : }
14379 :
14380 129 : Ncomp = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction) * CyclingRatio;
14381 : // Cap_Eva1 is the updated compressor min speed capacity
14382 129 : OUEvapHeatExtract = Cap_Eva1;
14383 129 : this->EvaporatingTemp = T_suction;
14384 129 : this->CondensingTemp = T_discharge;
14385 129 : this->IUCondensingTemp = T_discharge;
14386 129 : break; // EXIT DoName2
14387 :
14388 : } // End: if( CounterCompSpdTemp <= 1 ) Low load modification
14389 :
14390 : } // End: if( Q_evap_req <= CompEvaporatingCAPSpd( CounterCompSpdTemp ) )
14391 :
14392 : } // End: Iteration DoName2
14393 :
14394 5271 : if (CounterCompSpdTemp > NumOfCompSpdInput) {
14395 : // Required heating load is beyond the maximum system capacity
14396 0 : CompEvaporatingCAPSpd(NumOfCompSpdInput) =
14397 0 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), T_discharge, T_suction);
14398 0 : OUEvapHeatExtract = CompEvaporatingCAPSpd(NumOfCompSpdInput);
14399 0 : CompSpdActual = this->CompressorSpeed(NumOfCompSpdInput);
14400 0 : Ncomp = CompEvaporatingPWRSpd(NumOfCompSpdInput);
14401 : }
14402 5271 : }
14403 :
14404 1 : void VRFCondenserEquipment::VRFHR_OU_HR_Mode(EnergyPlusData &state,
14405 : Real64 const h_IU_evap_in, // enthalpy of IU evaporator at inlet [kJ/kg]
14406 : Real64 const h_comp_out, // enthalpy of refrigerant at compressor outlet [kJ/kg]
14407 : Real64 const Q_c_TU_PL, // IU evaporator load, including piping loss [W]
14408 : Real64 const Q_h_TU_PL, // IU condenser load, including piping loss [W]
14409 : Real64 const Tdischarge, // VRF Compressor discharge refrigerant temperature [C]
14410 : Real64 &Tsuction, // VRF compressor suction refrigerant temperature [C]
14411 : Real64 &Te_update, // updated evaporating temperature, only updated when Tsuction is updated [C]
14412 : Real64 &h_comp_in, // enthalpy of refrigerant at compressor inlet [kJ/kg]
14413 : Real64 &h_IU_PLc_out, // enthalpy of refrigerant at the outlet of IU evaporator side main pipe [kJ/kg]
14414 : Real64 &Pipe_Q_c, // IU evaporator side piping loss [W]
14415 : Real64 &Q_c_OU, // OU evaporator load [W]
14416 : Real64 &Q_h_OU, // OU condenser load [W]
14417 : Real64 &m_ref_IU_evap, // mass flow rate of Refrigerant through IU evaporators [kg/s]
14418 : Real64 &m_ref_OU_evap, // mass flow rate of Refrigerant through OU evaporator [kg/s]
14419 : Real64 &m_ref_OU_cond, // mass flow rate of Refrigerant through OU condenser [kg/s]
14420 : Real64 &N_fan_OU, // outdoor unit fan power [W]
14421 : Real64 &CompSpdActual, // Actual compressor running speed [rps]
14422 : Real64 &Ncomp // compressor power [W]
14423 : )
14424 : {
14425 :
14426 : // SUBROUTINE INFORMATION:
14427 : // AUTHOR Rongpeng Zhang, LBNL
14428 : // DATE WRITTEN Jan 2016
14429 : // MODIFIED na
14430 : //
14431 : // RE-ENGINEERED na
14432 : //
14433 : // PURPOSE OF THIS SUBROUTINE:
14434 : // Determine the operational mode of the VRF-HR system, given the terminal unit side load conditions.
14435 : // Compressor and OU hex performance are analyzed for each mode.
14436 : // A number of OU side operational parameters are also calculated here, including:
14437 : // (1) OU evaporator load Q_c_OU (2) OU condenser load Q_h_OU (3) OU fan energy consumption
14438 : // (4) OU compressor speed and energy consumption
14439 : // Note that Te and Te' may be updated here, and thus IU evaporator side piping loss recalculations.
14440 : // Then a number of operational parameters need to be updated, including:
14441 : // (1) IU evaporating temperature Te (2) OU evaporating temperature Te' etc.
14442 : //
14443 : // METHODOLOGY EMPLOYED:
14444 : // This is part of the physics based VRF model applicable for Fluid Temperature Control.
14445 :
14446 : using General::SolveRoot;
14447 :
14448 1 : Real64 constexpr ErrorTol(0.1); // tolerance for RegulaFalsi iterations
14449 1 : int constexpr MaxIte(100); // maximum number of iterations
14450 1 : int HRMode(0); // HR operational mode [W]
14451 1 : int HRMode_sub(0); // HR operational mode (sub) [W]
14452 : int SolFla; // Flag of RegulaFalsi solver
14453 : Real64 C_OU_HexRatio; // capacity ratio between the OU condenser and OU evaporator [-]
14454 : Real64 m_air_rated; // OU coil air mass flow rate [kg/s]
14455 : Real64 m_air_evap; // OU evaporator air mass flow rate [kg/s]
14456 : Real64 m_air_cond; // OU condenser air mass flow rate [kg/s]
14457 : Real64 m_air_evap_rated; // Rated OU evaporator air mass flow rate [kg/s]
14458 1 : Real64 N_fan_OU_evap(0); // OU evaporator air mass flow rate [kg/s]
14459 1 : Real64 N_fan_OU_cond(0); // OU condenser air mass flow rate [kg/s]
14460 : Real64 RhoAir; // outdoor air density [kg/m3]
14461 : Real64 Q_c_tot; // Total evaporator capacity [W]
14462 : Real64 Q_h_tot; // Total condenser capacity [W]
14463 : Real64 Pipe_Q_c_new; // IU evaporator side piping loss (new), updated because of Te update [W]
14464 : Real64 rps1_evap; // compressor speed satisfying IU cooling load
14465 : Real64 rps2_cond; // compressor speed satisfying IU heating load
14466 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
14467 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
14468 : Real64 Tfs; // temperature of the air at coil surface [C]
14469 1 : Real64 Tolerance(0.05); // Tolerance for condensing temperature calculation [C}
14470 : Real64 Tsuction_new; // VRF compressor suction refrigerant temperature (new) [C]
14471 :
14472 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14473 : static constexpr std::string_view RoutineName("VRFHR_OU_Mode");
14474 :
14475 : // Initialization: operational parameters
14476 1 : RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
14477 1 : m_air_rated = this->OUAirFlowRate * RhoAir;
14478 1 : C_OU_HexRatio = this->HROUHexRatio;
14479 :
14480 : // Initializations: component index
14481 1 : RefPLow = this->refrig->PsLowPresValue;
14482 1 : RefPHigh = this->refrig->PsHighPresValue;
14483 :
14484 : // **Q_OU: HR mode determination
14485 : // HRMode-1. Cooling Only
14486 : // HRMode-2. Cooling Dominant w/o HR Loss
14487 : // HRMode-3. Cooling Dominant w/ HR Loss
14488 : // HRMode-4. Heating Dominant w/ HR Loss
14489 : // HRMode-5. Heating Dominant w/o HR Loss
14490 : // HRMode-6. Heating Only
14491 : // HRMode-7. OU Hex not running
14492 : {
14493 :
14494 : bool FlagMode5; // true if compressor speed satisfying IU cooling load < that satisfying IU heating load
14495 : bool FlagToLower; // true if To-5 is lower than the Tsuction determined by IU part
14496 : Real64 temp_Tsuction;
14497 :
14498 : // Determine FlagToLower
14499 1 : if (state.dataEnvrn->OutDryBulbTemp - this->DiffOUTeTo < Tsuction) {
14500 0 : temp_Tsuction = state.dataEnvrn->OutDryBulbTemp - this->DiffOUTeTo;
14501 0 : FlagToLower = true;
14502 : } else {
14503 1 : temp_Tsuction = Tsuction;
14504 1 : FlagToLower = false;
14505 : }
14506 :
14507 : // Calculate compressor speed satisfying IU loads: rps1_evap & rps2_cond
14508 1 : this->VRFOU_CompSpd(state, Q_c_TU_PL, HXOpMode::EvapMode, temp_Tsuction, Tdischarge, h_IU_evap_in, h_IU_PLc_out, rps1_evap);
14509 1 : this->VRFOU_CompSpd(state, Q_h_TU_PL, HXOpMode::CondMode, temp_Tsuction, Tdischarge, h_IU_evap_in, h_IU_PLc_out, rps2_cond);
14510 :
14511 : // Determine FlagMode5
14512 1 : if (rps1_evap <= rps2_cond) {
14513 1 : FlagMode5 = true;
14514 : } else {
14515 0 : FlagMode5 = false;
14516 : }
14517 :
14518 : // Determine HR Mode
14519 1 : if (FlagMode5) {
14520 1 : HRMode = 5;
14521 1 : if (FlagToLower)
14522 0 : HRMode_sub = 1;
14523 : else
14524 1 : HRMode_sub = 2;
14525 : } else {
14526 :
14527 0 : if (FlagToLower)
14528 0 : HRMode = 3; // Mode 3&4 share the same logics below
14529 : else
14530 0 : HRMode = 2;
14531 : }
14532 :
14533 1 : this->VRFOperationSimPath = HRMode * 10 + HRMode_sub;
14534 : }
14535 :
14536 : // **Simulate outdoor unit and compressor performance, including
14537 : // (1) compressor spd/power (2) OU hex capacity (3) OU fan flow rate and power
14538 : // Tsuction/Te may also need updates
14539 1 : if (HRMode == 5 && HRMode_sub == 2) {
14540 :
14541 1 : CompSpdActual = rps2_cond; // constant in this mode
14542 : // Tsuction = Te'_iu < OutDryBulbTemp - 5; constant in this mode
14543 :
14544 : // compressor: Ncomp & Q_c_tot
14545 1 : this->VRFOU_CompCap(state, CompSpdActual, Tsuction, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot, Ncomp);
14546 :
14547 : // OU hex capacity
14548 1 : Q_c_OU = Q_c_tot - Q_c_TU_PL;
14549 1 : Q_h_OU = 0;
14550 :
14551 : // OU fan flow rate and power
14552 : m_air_evap =
14553 1 : this->VRFOU_FlowRate(state, HXOpMode::EvapMode, Tsuction, this->SH, Q_c_OU, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
14554 1 : m_air_evap_rated = m_air_rated;
14555 1 : N_fan_OU_evap = this->RatedOUFanPower * m_air_evap / m_air_evap_rated;
14556 1 : N_fan_OU_cond = 0;
14557 :
14558 0 : } else if (HRMode == 5 && HRMode_sub == 1) {
14559 :
14560 : // local parameters
14561 : int Counter_Iter_Ncomp;
14562 0 : bool Flag_Iter_Ncomp(true); // Flag to perform iterations
14563 : Real64 Ncomp_ini;
14564 : Real64 Ncomp_new;
14565 : Real64 Q_c_tot_temp;
14566 : Real64 Q_c_OU_temp;
14567 :
14568 : //===**Ncomp Iterations
14569 :
14570 : // initialization: Ncomp_ini, CompSpdActual
14571 0 : Counter_Iter_Ncomp = 1;
14572 0 : CompSpdActual = rps2_cond;
14573 0 : Tsuction_new = state.dataEnvrn->OutDryBulbTemp - this->DiffOUTeTo;
14574 0 : Pipe_Q_c_new = Pipe_Q_c;
14575 :
14576 0 : this->VRFOU_CompCap(state, CompSpdActual, Tsuction_new, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot, Ncomp_ini);
14577 :
14578 0 : while (Flag_Iter_Ncomp) {
14579 :
14580 0 : Q_c_tot_temp = Q_h_TU_PL - Ncomp_ini; // Q_h_OU = 0
14581 0 : Q_c_OU_temp = Q_c_tot_temp - Q_c_TU_PL;
14582 :
14583 : // Tsuction_new updated based on OU evaporator air-side calculations (Tsuction_new < To)
14584 0 : m_air_evap_rated = m_air_rated;
14585 0 : this->VRFOU_TeTc(state,
14586 : HXOpMode::EvapMode,
14587 : Q_c_OU_temp,
14588 : this->SH,
14589 : m_air_evap_rated,
14590 0 : state.dataEnvrn->OutDryBulbTemp,
14591 0 : state.dataEnvrn->OutHumRat,
14592 0 : state.dataEnvrn->OutBaroPress,
14593 : Tfs,
14594 : Tsuction_new);
14595 0 : Tsuction_new = min(Tsuction_new, Tsuction); // should be lower than Tsuction_IU
14596 :
14597 : // Calculate updated rps corresponding to updated Tsuction_new and Q_c_tot_temp
14598 0 : this->VRFOU_CompSpd(state, Q_c_tot_temp, HXOpMode::EvapMode, Tsuction_new, Tdischarge, h_IU_evap_in, h_comp_in, CompSpdActual);
14599 :
14600 : // Calculate Ncomp_new, using updated CompSpdActual and Tsuction_new
14601 0 : this->VRFOU_CompCap(state, CompSpdActual, Tsuction_new, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot_temp, Ncomp_new);
14602 :
14603 0 : if ((std::abs(Ncomp_new - Ncomp_ini) > (Tolerance * Ncomp_ini)) && (Counter_Iter_Ncomp < 30)) {
14604 0 : Ncomp_ini = 0.5 * Ncomp_ini + 0.5 * Ncomp_new;
14605 0 : Counter_Iter_Ncomp = Counter_Iter_Ncomp + 1;
14606 0 : continue;
14607 : }
14608 :
14609 0 : Flag_Iter_Ncomp = false;
14610 : }
14611 :
14612 : // Ncomp Iterations Update
14613 0 : Ncomp = Ncomp_new;
14614 0 : Q_c_tot = Q_c_tot_temp;
14615 :
14616 0 : if (Tsuction_new < Tsuction) {
14617 : // Need to update the Tsuction, and thus update Te_update & Pipe_Q_c_new.
14618 : // Iteration continues.
14619 :
14620 : // temporary parameters
14621 : Real64 Pe_update;
14622 : Real64 Pipe_SH_merged;
14623 : Real64 Pipe_DeltP;
14624 : Real64 Pipe_h_IU_out;
14625 :
14626 : // Get an updated Te (Te_update) corresponding to the updated Te' (Tsuction_new). PL_c is re-performed.
14627 0 : this->VRFOU_TeModification(state,
14628 : this->EvaporatingTemp,
14629 : Tsuction_new,
14630 : h_IU_evap_in,
14631 0 : state.dataEnvrn->OutDryBulbTemp,
14632 : Te_update,
14633 : Pe_update,
14634 : m_ref_IU_evap,
14635 : Pipe_h_IU_out,
14636 : Pipe_SH_merged);
14637 :
14638 : // Re-calculate piping loss, update Pipe_Q_c_new
14639 0 : this->VRFOU_PipeLossC(state,
14640 : m_ref_IU_evap,
14641 : Pe_update,
14642 : Pipe_h_IU_out,
14643 : Pipe_SH_merged,
14644 0 : state.dataEnvrn->OutDryBulbTemp,
14645 : Pipe_Q_c_new,
14646 : Pipe_DeltP,
14647 : h_IU_PLc_out);
14648 :
14649 0 : Tsuction = Tsuction_new;
14650 0 : Pipe_Q_c = Pipe_Q_c_new;
14651 : }
14652 :
14653 : // No need to update the Tsuction.
14654 :
14655 : //===**Ncomp Iteration Ends (Label200)
14656 :
14657 : // OU hex capacity
14658 0 : Q_c_OU = Q_c_tot - Q_c_TU_PL;
14659 0 : Q_h_OU = 0;
14660 :
14661 : // OU fan power
14662 0 : N_fan_OU_evap = this->RatedOUFanPower;
14663 0 : N_fan_OU_cond = 0;
14664 :
14665 0 : } else if (HRMode == 3) { // Mode3 & Mode4 share the same algorithm
14666 :
14667 : // local parameters
14668 : Real64 Ncomp_new;
14669 : Real64 Q_c_tot_temp;
14670 : Real64 Q_c_OU_temp;
14671 0 : Real64 Tsuction_LB = state.dataEnvrn->OutDryBulbTemp - this->DiffOUTeTo;
14672 0 : Real64 Tsuction_HB = Tsuction;
14673 :
14674 : // compressor speed is fixed in this mode
14675 0 : CompSpdActual = rps1_evap; // constant in this mode
14676 0 : m_air_evap_rated = m_air_rated * (1 - C_OU_HexRatio);
14677 0 : m_air_evap = m_air_evap_rated; // may be updated
14678 :
14679 : // perform iterations to calculate Te at the given compressor speed and operational conditions
14680 : {
14681 :
14682 0 : auto f = [&state, this, CompSpdActual, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_TU_PL, m_air_evap_rated](Real64 const Te) {
14683 0 : int VRFCond = state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->TerminalUnitList(this->ZoneTUListPtr).ZoneTUPtr(1))
14684 0 : .VRFSysNum; // VRFCond;
14685 :
14686 : Real64 Ncomp_temp; // compressor power [W]
14687 : Real64 Q_c_tot_temp; // total evaporator load, including piping loss [W]
14688 : Real64 Q_c_OU_temp; // OU evaporator load, including piping loss [W]
14689 : Real64 Te_new; // newly calculated OU evaporating temperature
14690 : Real64 Tfs; // OU evaporator coil surface temperature [C]
14691 :
14692 0 : state.dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompCap(
14693 : state, CompSpdActual, Te, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot_temp, Ncomp_temp);
14694 0 : Q_c_OU_temp = Q_c_tot_temp - Q_c_TU_PL;
14695 :
14696 : // Tsuction_new calculated based on OU evaporator air-side calculations (Tsuction_new < To)
14697 0 : state.dataHVACVarRefFlow->VRF(VRFCond).VRFOU_TeTc(state,
14698 : HXOpMode::EvapMode,
14699 : Q_c_OU_temp,
14700 0 : state.dataHVACVarRefFlow->VRF(VRFCond).SH,
14701 : m_air_evap_rated,
14702 0 : state.dataEnvrn->OutDryBulbTemp,
14703 0 : state.dataEnvrn->OutHumRat,
14704 0 : state.dataEnvrn->OutBaroPress,
14705 : Tfs,
14706 : Te_new);
14707 :
14708 0 : return Te_new - Te;
14709 0 : };
14710 :
14711 0 : General::SolveRoot(state, ErrorTol, MaxIte, SolFla, Tsuction_new, f, Tsuction_LB, Tsuction_HB);
14712 0 : if (SolFla < 0) Tsuction_new = Tsuction_LB;
14713 :
14714 : // Update Q_c_tot_temp using updated Tsuction_new
14715 0 : this->VRFOU_CompCap(state, CompSpdActual, Tsuction_new, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot_temp, Ncomp_new);
14716 0 : Q_c_OU_temp = Q_c_tot_temp - Q_c_TU_PL;
14717 :
14718 : // Iterations_Te Update
14719 0 : Ncomp = Ncomp_new;
14720 0 : Tsuction = Tsuction_new;
14721 0 : Q_c_tot = Q_c_tot_temp;
14722 0 : Q_c_OU = Q_c_OU_temp;
14723 : }
14724 :
14725 0 : if (Tsuction >= Tsuction_HB) {
14726 : // modify m_air_evap to adjust OU evaporator capacity;
14727 : // update Ncomp, Q_c_OU, m_air_evap
14728 :
14729 0 : Tsuction = Tsuction_HB;
14730 :
14731 : // Q_c_tot
14732 0 : this->VRFOU_CompCap(state, CompSpdActual, Tsuction_new, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot, Ncomp);
14733 0 : Q_c_OU = Q_c_tot - Q_c_TU_PL;
14734 :
14735 : // OU evaporator fan flow rate and power
14736 0 : m_air_evap = this->VRFOU_FlowRate(
14737 0 : state, HXOpMode::EvapMode, Tsuction, this->SH, Q_c_OU_temp, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
14738 :
14739 : } else {
14740 : // Need to update Te_update & Pipe_Q_c_new, corresponding to Tsuction update.
14741 :
14742 : // temporary parameters
14743 : Real64 Pe_update;
14744 : Real64 Pipe_SH_merged;
14745 : Real64 Pipe_DeltP;
14746 : Real64 Pipe_h_IU_out;
14747 :
14748 : // Get an updated Te (Te_update) corresponding to the updated Te' (Tsuction_new). PL_c is re-performed.
14749 0 : this->VRFOU_TeModification(state,
14750 : this->EvaporatingTemp,
14751 : Tsuction_new,
14752 : h_IU_evap_in,
14753 0 : state.dataEnvrn->OutDryBulbTemp,
14754 : Te_update,
14755 : Pe_update,
14756 : m_ref_IU_evap,
14757 : Pipe_h_IU_out,
14758 : Pipe_SH_merged);
14759 :
14760 : // Re-calculate piping loss, update Pipe_Q_c_new
14761 0 : this->VRFOU_PipeLossC(state,
14762 : m_ref_IU_evap,
14763 : Pe_update,
14764 : Pipe_h_IU_out,
14765 : Pipe_SH_merged,
14766 0 : state.dataEnvrn->OutDryBulbTemp,
14767 : Pipe_Q_c_new,
14768 : Pipe_DeltP,
14769 : h_IU_PLc_out);
14770 0 : Pipe_Q_c = Pipe_Q_c_new;
14771 : }
14772 :
14773 : // Q_h_ou
14774 0 : Q_h_tot = Q_c_tot + Ncomp;
14775 0 : Q_h_OU = Q_h_tot - Q_h_TU_PL;
14776 :
14777 : // OU condenser fan flow rate and power
14778 0 : m_air_cond = this->VRFOU_FlowRate(
14779 0 : state, HXOpMode::CondMode, Tdischarge, this->SC, Q_h_OU, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
14780 :
14781 : // OU fan power
14782 0 : N_fan_OU_evap = this->RatedOUFanPower * m_air_evap / m_air_rated;
14783 0 : N_fan_OU_cond = this->RatedOUFanPower * m_air_cond / m_air_rated;
14784 :
14785 0 : } else if (HRMode == 2) {
14786 :
14787 0 : CompSpdActual = rps1_evap; // constant in this mode
14788 : // Tsuction = Te'_iu < OutDryBulbTemp - 5; constant in this mode
14789 :
14790 : // compressor: Ncomp & Q_c_tot
14791 0 : this->VRFOU_CompCap(state, CompSpdActual, Tsuction, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot, Ncomp);
14792 :
14793 : // OU hex capacity
14794 0 : Q_h_tot = Q_c_tot + Ncomp;
14795 0 : Q_h_OU = Q_h_tot - Q_h_TU_PL;
14796 0 : Q_c_OU = 0;
14797 :
14798 : // OU fan flow rate and power
14799 0 : m_air_cond = this->VRFOU_FlowRate(
14800 0 : state, HXOpMode::CondMode, Tdischarge, this->SC, Q_h_OU, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
14801 0 : N_fan_OU_cond = this->RatedOUFanPower * m_air_cond / m_air_rated;
14802 0 : N_fan_OU_evap = 0;
14803 :
14804 : } else {
14805 0 : Ncomp = 0;
14806 0 : CompSpdActual = 0;
14807 0 : Q_c_OU = 0;
14808 0 : Q_h_OU = 0;
14809 0 : N_fan_OU_evap = 0;
14810 0 : N_fan_OU_cond = 0;
14811 : }
14812 :
14813 : // OU fan power
14814 1 : N_fan_OU = N_fan_OU_evap + N_fan_OU_cond;
14815 :
14816 : // Calculate the m_ref_OU_evap & m_ref_OU_cond, with updated Tsuction
14817 : {
14818 : Real64 h_OU_evap_in; // enthalpy of OU evaporator at inlet [kJ/kg]
14819 : Real64 h_OU_evap_out; // enthalpy of OU evaporator at outlet [kJ/kg]
14820 : Real64 h_OU_cond_in; // enthalpy of OU condenser at inlet [kJ/kg]
14821 : Real64 h_OU_cond_out; // enthalpy of OU condenser at outlet [kJ/kg]
14822 :
14823 1 : Real64 Psuction = this->refrig->getSatPressure(state, Tsuction, RoutineName);
14824 :
14825 : // enthalpy of OU evaporator/condenser inlets and outlets
14826 1 : h_OU_evap_in = h_IU_evap_in;
14827 1 : h_OU_cond_in = h_comp_out;
14828 1 : h_OU_evap_out = this->refrig->getSupHeatEnthalpy(state, Tsuction + this->SH, max(min(Psuction, RefPHigh), RefPLow), RoutineName);
14829 1 : h_OU_cond_out = this->refrig->getSatEnthalpy(state, Tdischarge - this->SC, 0.0, RoutineName);
14830 :
14831 1 : if ((Q_c_OU == 0) || (h_OU_evap_out - h_OU_evap_in) <= 0) {
14832 0 : m_ref_OU_evap = 0;
14833 : } else {
14834 1 : m_ref_OU_evap = Q_c_OU / (h_OU_evap_out - h_OU_evap_in);
14835 : }
14836 :
14837 1 : if ((Q_h_OU == 0) || (h_OU_cond_in - h_OU_cond_out <= 0)) {
14838 1 : m_ref_OU_cond = 0;
14839 : } else {
14840 0 : m_ref_OU_cond = Q_h_OU / (h_OU_cond_in - h_OU_cond_out);
14841 : }
14842 :
14843 : // Calculate the parameters of refrigerant at compressor inlet, which is
14844 : // a combination of refrigerant from IU evaporators and OU evaporator
14845 1 : if ((m_ref_OU_evap + m_ref_IU_evap) > 0) {
14846 1 : h_comp_in = (m_ref_OU_evap * h_OU_evap_out + m_ref_IU_evap * h_IU_PLc_out) / (m_ref_OU_evap + m_ref_IU_evap);
14847 : }
14848 : }
14849 1 : }
14850 :
14851 9036 : void VRFCondenserEquipment::VRFOU_PipeLossC(
14852 : EnergyPlusData &state,
14853 : Real64 const Pipe_m_ref, // Refrigerant mass flow rate [kg/s]
14854 : Real64 const Pevap, // VRF evaporating pressure [Pa]
14855 : Real64 const Pipe_h_IU_out, // Enthalpy of IU at outlet [kJ/kg]
14856 : Real64 const Pipe_SH_merged, // Average super heating degrees after the indoor units [C]
14857 : Real64 const OutdoorDryBulb, // outdoor dry-bulb temperature (C)
14858 : Real64 &Pipe_Q, // unit part load ratio
14859 : Real64 &Pipe_DeltP, // ratio of compressor ON airflow to AVERAGE airflow over timestep
14860 : Real64 &Pipe_h_comp_in // Piping Loss Algorithm Parameter: Enthalpy after piping loss (compressor inlet) [kJ/kg]
14861 : )
14862 : {
14863 :
14864 : // SUBROUTINE INFORMATION:
14865 : // AUTHOR Rongpeng Zhang
14866 : // DATE WRITTEN Nov 2015
14867 : // MODIFIED na
14868 : // RE-ENGINEERED na
14869 :
14870 : // PURPOSE OF THIS SUBROUTINE:
14871 : // Determine the piping loss of the refrigerant, including both the heat loss and pressure drop.
14872 : // This happens at VRF cooling mode, within the Main Pipe connecting Outdoor Unit to Indoor Units.
14873 :
14874 : // METHODOLOGY EMPLOYED:
14875 : // Use a physics based piping loss model.
14876 :
14877 : using General::SolveRoot;
14878 :
14879 : int TUListNum; // index to TU List
14880 : int NumTUInList; // number of terminal units is list
14881 : int NumIUActivated; // number of the used indoor units [-]
14882 :
14883 : Real64 Pipe_v_ref; // Piping Loss Algorithm Parameter: Refrigerant velocity [m/s]
14884 : Real64 Pipe_T_room; // Piping Loss Algorithm Parameter: Average Room Temperature [C]
14885 : Real64 Pipe_Num_Re; // Piping Loss Algorithm Parameter: refrigerant Re Number [-]
14886 : Real64 Pipe_Num_Pr; // Piping Loss Algorithm Parameter: refrigerant Pr Number [-]
14887 : Real64 Pipe_Num_Nu; // Piping Loss Algorithm Parameter: refrigerant Nu Number [-]
14888 : Real64 Pipe_Num_St; // Piping Loss Algorithm Parameter: refrigerant St Number [-]
14889 : Real64 Pipe_Coe_k1; // Piping Loss Algorithm Parameter: coefficients [-]
14890 : Real64 Pipe_Coe_k2; // Piping Loss Algorithm Parameter: coefficients [-]
14891 : Real64 Pipe_Coe_k3; // Piping Loss Algorithm Parameter: coefficients [-]
14892 : Real64 Pipe_cp_ref; // Piping Loss Algorithm_[kJ/kg/K]
14893 : Real64 Pipe_conductivity_ref; // Piping Loss Algorithm: refrigerant conductivity [W/m/K]
14894 : Real64 Pipe_viscosity_ref; // Piping Loss Algorithm Parameter: refrigerant viscosity [MuPa*s]
14895 : Real64 Ref_Coe_v1; // Piping Loss Algorithm Parameter: coefficient to calculate Pipe_viscosity_ref [-]
14896 : Real64 Ref_Coe_v2; // Piping Loss Algorithm Parameter: coefficient to calculate Pipe_viscosity_ref [-]
14897 : Real64 Ref_Coe_v3; // Piping Loss Algorithm Parameter: coefficient to calculate Pipe_viscosity_ref [-]
14898 : Real64 RefPipInsH; // Heat transfer coefficient for calculating piping loss [W/m2K]
14899 :
14900 : static constexpr std::string_view RoutineName("VRFOU_PipeLossC");
14901 :
14902 9036 : TUListNum = this->ZoneTUListPtr;
14903 9036 : NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
14904 9036 : Pipe_conductivity_ref = this->RefPipInsCon;
14905 :
14906 9036 : RefPipInsH = 9.3;
14907 9036 : Pipe_cp_ref = 1.6;
14908 :
14909 : // Refrigerant data
14910 9036 : Real64 RefPLow = this->refrig->PsLowPresValue; // Low Pressure Value for Ps (>0.0)
14911 9036 : Real64 RefPHigh = this->refrig->PsHighPresValue; // High Pressure Value for Ps (max in tables)
14912 :
14913 : // Calculate Pipe_T_room
14914 9036 : Pipe_T_room = 0;
14915 9036 : NumIUActivated = 0;
14916 18072 : for (int NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
14917 9036 : int TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
14918 9036 : int CoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
14919 :
14920 9036 : if (state.dataDXCoils->DXCoil(CoilIndex).TotalCoolingEnergyRate > 0.0) {
14921 9006 : Pipe_T_room = Pipe_T_room + state.dataDXCoils->DXCoil(CoilIndex).InletAirTemp;
14922 9006 : NumIUActivated = NumIUActivated + 1;
14923 : }
14924 : }
14925 9036 : if (NumIUActivated > 0)
14926 9006 : Pipe_T_room = Pipe_T_room / NumIUActivated;
14927 : else
14928 30 : Pipe_T_room = 24;
14929 :
14930 9036 : if (Pipe_m_ref > 0) {
14931 9006 : if (this->RefPipDiaSuc <= 0) this->RefPipDiaSuc = 0.025;
14932 :
14933 9006 : Ref_Coe_v1 = Pevap / 1000000 / 4.926;
14934 9006 : Ref_Coe_v2 = Pipe_h_IU_out / 383.5510343;
14935 9006 : Ref_Coe_v3 = (this->EvaporatingTemp + Pipe_SH_merged + 273.15) / 344.39;
14936 :
14937 9006 : Pipe_viscosity_ref = 4.302 * Ref_Coe_v1 + 0.81622 * pow_2(Ref_Coe_v1) - 120.98 * Ref_Coe_v2 + 139.17 * pow_2(Ref_Coe_v2) +
14938 9006 : 118.76 * Ref_Coe_v3 + 81.04 * pow_2(Ref_Coe_v3) + 5.7858 * Ref_Coe_v1 * Ref_Coe_v2 - 8.3817 * Ref_Coe_v1 * Ref_Coe_v3 -
14939 9006 : 218.48 * Ref_Coe_v2 * Ref_Coe_v3 + 21.58;
14940 9006 : if (Pipe_viscosity_ref <= 0) Pipe_viscosity_ref = 16.26; // default superheated vapor viscosity data (MuPa*s) at T=353.15 K, P=2MPa
14941 :
14942 9006 : Pipe_v_ref = Pipe_m_ref / (Constant::Pi * pow_2(this->RefPipDiaSuc) * 0.25) /
14943 9006 : this->refrig->getSupHeatDensity(state, this->EvaporatingTemp + Pipe_SH_merged, max(min(Pevap, RefPHigh), RefPLow), RoutineName);
14944 9006 : Pipe_Num_Re = Pipe_m_ref / (Constant::Pi * pow_2(this->RefPipDiaSuc) * 0.25) * this->RefPipDiaSuc / Pipe_viscosity_ref * 1000000;
14945 9006 : Pipe_Num_Pr = Pipe_viscosity_ref * Pipe_cp_ref * 0.001 / Pipe_conductivity_ref;
14946 9006 : Pipe_Num_Nu = 0.023 * std::pow(Pipe_Num_Re, 0.8) * std::pow(Pipe_Num_Pr, 0.3);
14947 9006 : Pipe_Num_St = Pipe_Num_Nu / Pipe_Num_Re / Pipe_Num_Pr;
14948 :
14949 18012 : Pipe_DeltP = max(
14950 : 0.0,
14951 18012 : 8 * Pipe_Num_St * std::pow(Pipe_Num_Pr, 0.6667) * this->RefPipEquLen / this->RefPipDiaSuc *
14952 9006 : this->refrig->getSupHeatDensity(state, this->EvaporatingTemp + Pipe_SH_merged, max(min(Pevap, RefPHigh), RefPLow), RoutineName) *
14953 9006 : pow_2(Pipe_v_ref) / 2 -
14954 18012 : this->RefPipHei *
14955 9006 : this->refrig->getSupHeatDensity(state, this->EvaporatingTemp + Pipe_SH_merged, max(min(Pevap, RefPHigh), RefPLow), RoutineName) *
14956 : 9.80665);
14957 :
14958 9006 : Pipe_Coe_k1 = Pipe_Num_Nu * Pipe_viscosity_ref;
14959 9006 : Pipe_Coe_k3 = RefPipInsH * (this->RefPipDiaSuc + 2 * this->RefPipInsThi);
14960 9006 : if (this->RefPipInsThi >= 0.0) {
14961 9006 : Pipe_Coe_k2 = 2 * this->RefPipInsCon / std::log1p(2 * this->RefPipInsThi / this->RefPipDiaSuc);
14962 : } else {
14963 0 : Pipe_Coe_k2 = 9999.9;
14964 : }
14965 :
14966 18012 : Pipe_Q = max(0.0,
14967 9006 : (Constant::Pi * this->RefPipLen) * (OutdoorDryBulb / 2 + Pipe_T_room / 2 - this->EvaporatingTemp - Pipe_SH_merged) /
14968 9006 : (1 / Pipe_Coe_k1 + 1 / Pipe_Coe_k2 + 1 / Pipe_Coe_k3));
14969 :
14970 9006 : Pipe_h_comp_in = Pipe_h_IU_out + Pipe_Q / Pipe_m_ref;
14971 : // when Pipe_m_ref is close to 0, there will still be Pipe_Q, Pipe_Q / Pipe_m_ref will blow up
14972 : // At low flow rate (stationary flow)
14973 : // Pipe_h_comp_in = Pipe_h_IU_out + Cp * deltaT
14974 : // where deltaT is the refrigerant temperature change over time t,
14975 : // deltaT = Pipe_Q * t / (refrigerant_mass_in_pipe * Cp)
14976 : // so Pipe_h_comp_in = Pipe_h_IU_out + Cp * Pipe_Q / refrigerant_mass_in_pipe
14977 : // assume 0.001 is the cutoff Re for stationary flow
14978 9006 : if (Pipe_Num_Re < 0.001) { // low flow rate calculation
14979 108 : Pipe_h_comp_in =
14980 108 : Pipe_h_IU_out + Pipe_Q * state.dataHVACGlobal->TimeStepSysSec /
14981 108 : ((Constant::Pi * std::pow(this->RefPipDiaSuc / 2, 2) * this->RefPipLen *
14982 216 : this->refrig->getSupHeatDensity(
14983 108 : state, this->EvaporatingTemp + Pipe_SH_merged, max(min(Pevap, RefPHigh), RefPLow), RoutineName)));
14984 : }
14985 :
14986 : } else {
14987 30 : Pipe_DeltP = 0;
14988 30 : Pipe_Q = 0;
14989 30 : Pipe_h_comp_in = Pipe_h_IU_out;
14990 : }
14991 9036 : }
14992 :
14993 2908 : void VRFCondenserEquipment::VRFOU_PipeLossH(
14994 : EnergyPlusData &state,
14995 : Real64 const Pipe_m_ref, // Refrigerant mass flow rate [kg/s]
14996 : Real64 const Pcond, // VRF condensing pressure [Pa]
14997 : Real64 const Pipe_h_IU_in, // Enthalpy of IU at outlet [kJ/kg]
14998 : Real64 const OutdoorDryBulb, // outdoor dry-bulb temperature (C)
14999 : Real64 &Pipe_Q, // unit part load ratio
15000 : Real64 &Pipe_DeltP, // ratio of compressor ON airflow to AVERAGE airflow over timestep
15001 : Real64 &Pipe_h_comp_out // Piping Loss Algorithm Parameter: Enthalpy before piping loss (compressor outlet) [kJ/kg]
15002 : ) const
15003 : {
15004 :
15005 : // SUBROUTINE INFORMATION:
15006 : // AUTHOR Rongpeng Zhang
15007 : // DATE WRITTEN Nov 2015
15008 : // MODIFIED na
15009 : // RE-ENGINEERED na
15010 :
15011 : // PURPOSE OF THIS SUBROUTINE:
15012 : // Determine the piping loss of the refrigerant, including both the heat loss and pressure drop.
15013 : // This happens at VRF cooling mode, within the Main Pipe connecting Outdoor Unit to Indoor Units.
15014 :
15015 : // METHODOLOGY EMPLOYED:
15016 : // Use a physics based piping loss model.
15017 :
15018 : using General::SolveRoot;
15019 :
15020 : int TUListNum; // index to TU List
15021 : int NumTUInList; // number of terminal units is list
15022 : int NumIUActivated; // number of the used indoor units [-]
15023 :
15024 : Real64 Pipe_v_ref; // Piping Loss Algorithm Parameter: Refrigerant velocity [m/s]
15025 : Real64 Pipe_T_room; // Piping Loss Algorithm Parameter: Average Room Temperature [C]
15026 : Real64 Pipe_T_IU_in; // Piping Loss Algorithm Parameter: Average Refrigerant Temperature [C]
15027 : Real64 Pipe_Num_Re; // Piping Loss Algorithm Parameter: refrigerant Re Number [-]
15028 : Real64 Pipe_Num_Pr; // Piping Loss Algorithm Parameter: refrigerant Pr Number [-]
15029 : Real64 Pipe_Num_Nu; // Piping Loss Algorithm Parameter: refrigerant Nu Number [-]
15030 : Real64 Pipe_Num_St; // Piping Loss Algorithm Parameter: refrigerant St Number [-]
15031 : Real64 Pipe_Coe_k1; // Piping Loss Algorithm Parameter: coefficients [-]
15032 : Real64 Pipe_Coe_k2; // Piping Loss Algorithm Parameter: coefficients [-]
15033 : Real64 Pipe_Coe_k3; // Piping Loss Algorithm Parameter: coefficients [-]
15034 : Real64 Pipe_cp_ref; // Piping Loss Algorithm_[kJ/kg/K]
15035 : Real64 Pipe_conductivity_ref; // Piping Loss Algorithm: refrigerant conductivity [W/m/K]
15036 : Real64 Pipe_viscosity_ref; // Piping Loss Algorithm Parameter: refrigerant viscosity [MuPa*s]
15037 : Real64 Ref_Coe_v1; // Piping Loss Algorithm Parameter: coefficient to calculate Pipe_viscosity_ref [-]
15038 : Real64 Ref_Coe_v2; // Piping Loss Algorithm Parameter: coefficient to calculate Pipe_viscosity_ref [-]
15039 : Real64 Ref_Coe_v3; // Piping Loss Algorithm Parameter: coefficient to calculate Pipe_viscosity_ref [-]
15040 : Real64 RefPipInsH; // Heat transfer coefficient for calculating piping loss [W/m2K]
15041 :
15042 : static constexpr std::string_view RoutineName("VRFOU_PipeLossH");
15043 :
15044 2908 : TUListNum = this->ZoneTUListPtr;
15045 2908 : NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
15046 2908 : Pipe_conductivity_ref = this->RefPipInsCon;
15047 :
15048 2908 : RefPipInsH = 9.3;
15049 2908 : Pipe_cp_ref = 1.6;
15050 :
15051 : // Refrigerant data
15052 2908 : Real64 RefTHigh = this->refrig->PsHighTempValue; // High Temperature Value for Ps (max in tables)
15053 2908 : Real64 RefPLow = this->refrig->PsLowPresValue; // Low Pressure Value for Ps (>0.0)
15054 2908 : Real64 RefPHigh = this->refrig->PsHighPresValue; // High Pressure Value for Ps (max in tables)
15055 2908 : Real64 RefTSat = this->refrig->getSatTemperature(state, max(min(Pcond, RefPHigh), RefPLow), RoutineName);
15056 :
15057 : // Perform iteration to calculate Pipe_T_IU_in, given P and h
15058 2908 : Pipe_T_IU_in = this->refrig->getSupHeatTemp(state,
15059 : max(min(Pcond, RefPHigh), RefPLow),
15060 : Pipe_h_IU_in,
15061 2908 : max(this->IUCondensingTemp, RefTSat),
15062 2908 : min(this->IUCondensingTemp + 50, RefTHigh),
15063 : RoutineName);
15064 2908 : Pipe_T_IU_in = min(RefTHigh, Pipe_T_IU_in);
15065 :
15066 : // Calculate average room temperature
15067 2908 : Pipe_T_room = 0;
15068 2908 : NumIUActivated = 0;
15069 5816 : for (int NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
15070 2908 : int TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
15071 2908 : int CoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex;
15072 :
15073 2908 : if (state.dataDXCoils->DXCoil(CoilIndex).TotalHeatingEnergyRate > 0.0) {
15074 2908 : Pipe_T_room = Pipe_T_room + state.dataDXCoils->DXCoil(CoilIndex).InletAirTemp;
15075 2908 : NumIUActivated = NumIUActivated + 1;
15076 : }
15077 : }
15078 2908 : if (NumIUActivated > 0)
15079 2908 : Pipe_T_room = Pipe_T_room / NumIUActivated;
15080 : else
15081 0 : Pipe_T_room = 18;
15082 :
15083 : // Calculate piping loss
15084 2908 : if (Pipe_m_ref > 0) {
15085 2908 : Ref_Coe_v1 = Pcond / 1000000 / 4.926;
15086 2908 : Ref_Coe_v2 = Pipe_h_IU_in / 383.5510343;
15087 2908 : Ref_Coe_v3 = (Pipe_T_IU_in + 273.15) / 344.39;
15088 2908 : Pipe_viscosity_ref = 4.302 * Ref_Coe_v1 + 0.81622 * pow_2(Ref_Coe_v1) - 120.98 * Ref_Coe_v2 + 139.17 * pow_2(Ref_Coe_v2) +
15089 2908 : 118.76 * Ref_Coe_v3 + 81.04 * pow_2(Ref_Coe_v3) + 5.7858 * Ref_Coe_v1 * Ref_Coe_v2 - 8.3817 * Ref_Coe_v1 * Ref_Coe_v3 -
15090 2908 : 218.48 * Ref_Coe_v2 * Ref_Coe_v3 + 21.58;
15091 2908 : if (Pipe_viscosity_ref <= 0) Pipe_viscosity_ref = 16.26; // default superheated vapor viscosity data (MuPa*s) at T=353.15 K, P=2MPa
15092 :
15093 2908 : Pipe_v_ref = Pipe_m_ref / (Constant::Pi * pow_2(this->RefPipDiaDis) * 0.25) /
15094 2908 : this->refrig->getSupHeatDensity(state, Pipe_T_IU_in, max(min(Pcond, RefPHigh), RefPLow), RoutineName);
15095 2908 : Pipe_Num_Re = Pipe_m_ref / (Constant::Pi * pow_2(this->RefPipDiaDis) * 0.25) * this->RefPipDiaDis / Pipe_viscosity_ref * 1000000;
15096 2908 : Pipe_Num_Pr = Pipe_viscosity_ref * Pipe_cp_ref * 0.001 / Pipe_conductivity_ref;
15097 2908 : Pipe_Num_Nu = 0.023 * std::pow(Pipe_Num_Re, 0.8) * std::pow(Pipe_Num_Pr, 0.4);
15098 2908 : Pipe_Num_St = Pipe_Num_Nu / Pipe_Num_Re / Pipe_Num_Pr;
15099 :
15100 2908 : Pipe_Coe_k1 = Pipe_Num_Nu * Pipe_viscosity_ref;
15101 2908 : Pipe_Coe_k2 = this->RefPipInsCon * (this->RefPipDiaDis + this->RefPipInsThi) / this->RefPipInsThi;
15102 2908 : Pipe_Coe_k3 = RefPipInsH * (this->RefPipDiaDis + 2 * this->RefPipInsThi);
15103 :
15104 5816 : Pipe_Q = max(0.0,
15105 2908 : (Constant::Pi * this->RefPipLen) * (Pipe_T_IU_in - OutdoorDryBulb / 2 - Pipe_T_room / 2) /
15106 2908 : (1 / Pipe_Coe_k1 + 1 / Pipe_Coe_k2 + 1 / Pipe_Coe_k3)); // [W]
15107 5816 : Pipe_DeltP = max(
15108 : 0.0,
15109 5816 : 8 * Pipe_Num_St * std::pow(Pipe_Num_Pr, 0.6667) * this->RefPipEquLen / this->RefPipDiaDis *
15110 2908 : this->refrig->getSupHeatDensity(state, Pipe_T_IU_in, max(min(Pcond, RefPHigh), RefPLow), RoutineName) * pow_2(Pipe_v_ref) / 2 -
15111 2908 : this->RefPipHei * this->refrig->getSupHeatDensity(state, Pipe_T_IU_in, max(min(Pcond, RefPHigh), RefPLow), RoutineName) * 9.80665);
15112 :
15113 2908 : Pipe_h_comp_out = Pipe_h_IU_in + Pipe_Q / Pipe_m_ref;
15114 :
15115 : } else {
15116 0 : Pipe_DeltP = 0;
15117 0 : Pipe_Q = 0;
15118 0 : Pipe_h_comp_out = Pipe_h_IU_in;
15119 : }
15120 2908 : }
15121 0 : void VRFCondenserEquipment::oneTimeInit([[maybe_unused]] EnergyPlusData &state)
15122 : {
15123 0 : }
15124 1 : void VRFCondenserEquipment::oneTimeInit_new([[maybe_unused]] EnergyPlusData &state)
15125 : {
15126 1 : }
15127 :
15128 40 : void VRFTerminalUnitEquipment::CalcVRFSuppHeatingCoil(EnergyPlusData &state,
15129 : int const VRFTUNum, // index of vrf terminal unit
15130 : bool const FirstHVACIteration, // True when first HVAC iteration
15131 : Real64 const PartLoadRatio, // coil operating part-load ratio
15132 : Real64 &SuppCoilLoad // supp heating coil load max (W)
15133 : )
15134 : {
15135 :
15136 : // PURPOSE OF THIS SUBROUTINE:
15137 : // Manages VRF terminal unit supplemental heaters simulation.
15138 :
15139 : // Locals
15140 : // subroutine parameter definitions:
15141 40 : int constexpr MaxIte(500); // Maximum number of iterations for solver
15142 40 : Real64 constexpr Acc(1.e-3); // Accuracy of solver result
15143 :
15144 : // local variable declaration:
15145 : Real64 SuppHeatCoilLoad; // load passed to supplemental heating coil (W)
15146 : Real64 QActual; // actual coil output (W)
15147 : Real64 PartLoadFrac; // temporary PLR variable
15148 :
15149 40 : QActual = 0.0;
15150 40 : PartLoadFrac = 0.0;
15151 40 : SuppHeatCoilLoad = 0.0;
15152 :
15153 : // simulate gas, electric, hot water, and steam heating coils
15154 40 : if (state.dataEnvrn->OutDryBulbTemp <= this->MaxOATSuppHeatingCoil) {
15155 40 : SuppHeatCoilLoad = SuppCoilLoad;
15156 : } else {
15157 0 : SuppHeatCoilLoad = 0.0;
15158 : }
15159 :
15160 40 : switch (this->SuppHeatCoilType_Num) {
15161 36 : case HVAC::Coil_HeatingGasOrOtherFuel:
15162 : case HVAC::Coil_HeatingElectric: {
15163 144 : HeatingCoils::SimulateHeatingCoilComponents(
15164 108 : state, this->SuppHeatCoilName, FirstHVACIteration, SuppHeatCoilLoad, this->SuppHeatCoilIndex, QActual, true, this->fanOp, PartLoadRatio);
15165 36 : SuppHeatCoilLoad = QActual;
15166 36 : } break;
15167 2 : case HVAC::Coil_HeatingWater: {
15168 2 : if (SuppHeatCoilLoad > HVAC::SmallLoad) {
15169 : // see if HW coil has enough capacity to meet the load
15170 2 : Real64 mdot = this->SuppHeatCoilFluidMaxFlow;
15171 2 : state.dataLoopNodes->Node(this->SuppHeatCoilFluidInletNode).MassFlowRate = mdot;
15172 : // simulate hot water coil to find the full flow operating capacity
15173 6 : WaterCoils::SimulateWaterCoilComponents(
15174 4 : state, this->SuppHeatCoilName, FirstHVACIteration, this->SuppHeatCoilIndex, QActual, this->fanOp, PartLoadRatio);
15175 2 : if (QActual > SuppHeatCoilLoad) {
15176 : int SolFla; // Flag of solver, num iterations if >0, else error index
15177 20 : auto f = [&state, VRFTUNum, FirstHVACIteration, SuppHeatCoilLoad](Real64 const PartLoadFrac) {
15178 20 : Real64 QActual = 0.0; // actual heating load delivered [W]
15179 20 : Real64 mdot = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow * PartLoadFrac;
15180 20 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode).MassFlowRate = mdot;
15181 60 : WaterCoils::SimulateWaterCoilComponents(state,
15182 20 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
15183 : FirstHVACIteration,
15184 20 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex,
15185 : QActual,
15186 20 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp,
15187 : PartLoadFrac);
15188 20 : if (std::abs(SuppHeatCoilLoad) == 0.0) {
15189 0 : return (QActual - SuppHeatCoilLoad) / 100.0;
15190 : } else {
15191 20 : return (QActual - SuppHeatCoilLoad) / SuppHeatCoilLoad;
15192 : }
15193 2 : };
15194 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
15195 2 : this->SuppHeatPartLoadRatio = PartLoadFrac;
15196 : } else {
15197 0 : this->SuppHeatPartLoadRatio = 1.0;
15198 0 : SuppHeatCoilLoad = QActual;
15199 : }
15200 : } else {
15201 0 : this->SuppHeatPartLoadRatio = 0.0;
15202 0 : Real64 mdot = 0.0;
15203 0 : SuppHeatCoilLoad = 0.0;
15204 0 : PlantUtilities::SetComponentFlowRate(
15205 0 : state, mdot, this->SuppHeatCoilFluidInletNode, this->SuppHeatCoilFluidOutletNode, this->SuppHeatCoilPlantLoc);
15206 : }
15207 : // simulate water heating coil
15208 4 : WaterCoils::SimulateWaterCoilComponents(
15209 4 : state, this->SuppHeatCoilName, FirstHVACIteration, this->SuppHeatCoilIndex, SuppHeatCoilLoad, this->fanOp, this->SuppHeatPartLoadRatio);
15210 2 : } break;
15211 2 : case HVAC::Coil_HeatingSteam: {
15212 : // simulate steam heating coil
15213 2 : Real64 mdot = this->SuppHeatCoilFluidMaxFlow * PartLoadRatio;
15214 2 : state.dataLoopNodes->Node(this->SuppHeatCoilFluidInletNode).MassFlowRate = mdot;
15215 6 : SteamCoils::SimulateSteamCoilComponents(
15216 4 : state, this->SuppHeatCoilName, FirstHVACIteration, this->SuppHeatCoilIndex, SuppHeatCoilLoad, QActual, this->fanOp, PartLoadRatio);
15217 2 : SuppHeatCoilLoad = QActual;
15218 2 : } break;
15219 0 : default:
15220 0 : break;
15221 : }
15222 :
15223 40 : SuppCoilLoad = SuppHeatCoilLoad;
15224 40 : }
15225 :
15226 0 : Real64 VRFTerminalUnitEquipment::HotWaterHeatingCoilResidual(EnergyPlusData &state,
15227 : Real64 const PartLoadFrac, // water heating coil part-load ratio
15228 : std::vector<Real64> const &Par // par(1) = index to current VRF terminal unit
15229 : )
15230 : {
15231 :
15232 : // PURPOSE OF THIS FUNCTION:
15233 : // Calculates supplemental hot water heating coils load fraction residual [(QActual - Load)/Load]
15234 : // hot water Coil output depends on the part load ratio which is being varied to drive the load
15235 : // fraction residual to zero.
15236 :
15237 : // METHODOLOGY EMPLOYED:
15238 : // runs Coil:Heating:Water component object to get the actual heating load delivered [W] at a
15239 : // given part load ratio and calculates the residual as defined above
15240 :
15241 : // Return value
15242 : Real64 Residuum; // Residual to be minimized to zero
15243 :
15244 : // local variables declaration:
15245 0 : int VRFTUNum = int(Par[1]); // index to current terminal unit simulated
15246 0 : bool FirstHVACIteration = Par[2]; // 0 flag if it first HVAC iteration, or else 1
15247 0 : Real64 SuppHeatCoilLoad = Par[3]; // supplemental heating coil load to be met [W]
15248 0 : Real64 QActual = 0.0; // actual heating load delivered [W]
15249 :
15250 : // Real64 mdot = min(state.dataLoopNodes->Node(VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode).MassFlowRateMaxAvail,
15251 : // VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow * PartLoadFrac);
15252 :
15253 0 : Real64 mdot = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow * PartLoadFrac;
15254 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode).MassFlowRate = mdot;
15255 0 : WaterCoils::SimulateWaterCoilComponents(state,
15256 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
15257 : FirstHVACIteration,
15258 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex,
15259 : QActual,
15260 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp,
15261 : PartLoadFrac);
15262 :
15263 0 : if (std::abs(SuppHeatCoilLoad) == 0.0) {
15264 0 : Residuum = (QActual - SuppHeatCoilLoad) / 100.0;
15265 : } else {
15266 0 : Residuum = (QActual - SuppHeatCoilLoad) / SuppHeatCoilLoad;
15267 : }
15268 :
15269 0 : return Residuum;
15270 : }
15271 :
15272 1 : Real64 VRFTerminalUnitEquipment::HeatingCoilCapacityLimit(
15273 : EnergyPlusData &state,
15274 : Real64 const HeatCoilAirInletNode, // supplemental heating coil air inlet node
15275 : Real64 const HeatCoilMaxSATAllowed // supplemental heating coil maximum supply air temperature allowed [C]
15276 : )
15277 : {
15278 : // PURPOSE OF THIS FUNCTION:
15279 : // Calculates supplemental heating coils maximum heating capacity allowed based on the maximum
15280 : // supply air temperature limit specified.
15281 :
15282 : // METHODOLOGY EMPLOYED:
15283 : // ( m_dot_air * Cp_air_avg * DeltaT_air_across_heating_coil) [W]
15284 :
15285 : // Return value
15286 : Real64 HeatCoilCapacityAllowed; // heating coil maximum capacity that can be delivered at current time [W]
15287 :
15288 1 : Real64 MDotAir = state.dataLoopNodes->Node(HeatCoilAirInletNode).MassFlowRate;
15289 1 : Real64 CpAirIn = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(HeatCoilAirInletNode).HumRat);
15290 1 : Real64 HCDeltaT = max(0.0, HeatCoilMaxSATAllowed - state.dataLoopNodes->Node(HeatCoilAirInletNode).Temp);
15291 1 : HeatCoilCapacityAllowed = MDotAir * CpAirIn * HCDeltaT;
15292 :
15293 1 : return HeatCoilCapacityAllowed;
15294 : }
15295 :
15296 : } // namespace EnergyPlus::HVACVariableRefrigerantFlow
|