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) {
260 3517 : CoolingActive = true;
261 : }
262 7087 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalHeatingRate > 0.0) {
263 3523 : HeatingActive = true;
264 : }
265 :
266 : // make sure all TU in a list are able to get simulated, otherwise condenser is never simulated **
267 : // either fatal on GetInput, or keep track of unused TU's and set their respective flag to TRUE **
268 : // after all VRF terminal units have been simulated, call the VRF condenser model
269 7087 : if (all(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).IsSimulated)) {
270 :
271 7087 : if (state.dataHVACVarRefFlow->VRF(VRFCondenser).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
272 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
273 2368 : state.dataHVACVarRefFlow->VRF(VRFCondenser).CalcVRFCondenser_FluidTCtrl(state, FirstHVACIteration);
274 : } else {
275 : // Algorithm Type: VRF model based on system curve
276 4719 : CalcVRFCondenser(state, VRFCondenser);
277 : }
278 :
279 7087 : ReportVRFCondenser(state, VRFCondenser);
280 :
281 7087 : if (state.dataHVACVarRefFlow->VRF(VRFCondenser).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
282 5 : UpdateVRFCondenser(state, VRFCondenser);
283 : }
284 : }
285 7087 : }
286 :
287 2 : PlantComponent *VRFCondenserEquipment::factory(EnergyPlusData &state, std::string const &objectName)
288 : {
289 : // Process the input data if it hasn't been done already
290 2 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
291 1 : GetVRFInput(state);
292 1 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
293 : }
294 : // Now look for this object in the list
295 2 : for (auto &obj : state.dataHVACVarRefFlow->VRF) {
296 2 : if (obj.Name == objectName) {
297 2 : return &obj;
298 : }
299 4 : }
300 : // If we didn't find it, fatal
301 : ShowFatalError(state, format("LocalVRFCondenserFactory: Error getting inputs for object named: {}", objectName)); // LCOV_EXCL_LINE
302 : // Shut up the compiler
303 : return nullptr; // LCOV_EXCL_LINE
304 : }
305 :
306 1 : void VRFCondenserEquipment::onInitLoopEquip(EnergyPlusData &state, [[maybe_unused]] const PlantLocation &calledFromLocation)
307 : {
308 1 : this->SizeVRFCondenser(state);
309 1 : }
310 :
311 0 : void VRFCondenserEquipment::getDesignCapacities([[maybe_unused]] EnergyPlusData &state,
312 : [[maybe_unused]] const PlantLocation &calledFromLocation,
313 : Real64 &MaxLoad,
314 : Real64 &MinLoad,
315 : Real64 &OptLoad)
316 : {
317 0 : MinLoad = 0.0;
318 0 : MaxLoad = max(this->CoolingCapacity, this->HeatingCapacity); // greater of cooling and heating capacity
319 0 : OptLoad = max(this->CoolingCapacity,
320 : this->HeatingCapacity); // connects to single loop, need to switch between cooling/heating capacity?
321 0 : }
322 :
323 0 : void VRFCondenserEquipment::simulate(EnergyPlusData &state,
324 : const PlantLocation &calledFromLocation,
325 : bool FirstHVACIteration,
326 : [[maybe_unused]] Real64 &CurLoad,
327 : [[maybe_unused]] bool RunFlag)
328 : {
329 0 : if (calledFromLocation.loopNum == this->SourcePlantLoc.loopNum) { // condenser loop
330 0 : PlantUtilities::UpdateChillerComponentCondenserSide(state,
331 : this->SourcePlantLoc.loopNum,
332 : this->SourcePlantLoc.loopSideNum,
333 : PlantEquipmentType::HeatPumpVRF,
334 : this->CondenserNodeNum,
335 : this->CondenserOutletNodeNum,
336 : this->QCondenser,
337 : this->CondenserInletTemp,
338 : this->CondenserSideOutletTemp,
339 : this->WaterCondenserMassFlow,
340 : FirstHVACIteration);
341 : } else {
342 0 : ShowFatalError(state, format("SimVRFCondenserPlant:: Invalid loop connection {}", cVRFTypes(VRF_HeatPump)));
343 : }
344 0 : }
345 :
346 4735 : void CalcVRFCondenser(EnergyPlusData &state, int const VRFCond)
347 : {
348 :
349 : // SUBROUTINE INFORMATION:
350 : // AUTHOR R. Raustad, FSEC
351 : // DATE WRITTEN September 2010
352 :
353 : // PURPOSE OF THIS SUBROUTINE:
354 : // Model the interactions of VRF terminal units with a single variable-speed condenser.
355 : // The terminal units are simulated first, and then the condenser is simulated.
356 : // If terminal units require more capacity than can be delivered by condenser, a limit is set.
357 :
358 : using Curve::CurveValue;
359 : using PlantUtilities::SetComponentFlowRate;
360 : using Psychrometrics::RhoH2O;
361 :
362 : static constexpr std::string_view RoutineName("VRFCondenser");
363 :
364 : int NumTU; // loop counter
365 :
366 : Real64 TotCoolCapTempModFac; // cooling CAPFT curve output
367 : Real64 TotHeatCapTempModFac; // heating CAPFT curve output
368 : Real64 TotCoolEIRTempModFac; // cooling EIRFT curve output
369 : Real64 TotHeatEIRTempModFac; // heating EIRFT curve output
370 : Real64 InletAirWetBulbC; // coil inlet air wet-bulb temperature (C)
371 : Real64 InletAirDryBulbC; // coil inlet air dry-bulb temperature (C)
372 4735 : Real64 CondInletTemp(0.0); // condenser inlet air temperature (C)
373 : Real64 CondInletHumRat; // condenser inlet air humidity ratio (kg/kg)
374 : Real64 OutdoorDryBulb; // outdoor dry-bulb temperature (C)
375 : Real64 OutdoorHumRat; // outdoor humidity ratio (kg/kg)
376 : Real64 OutdoorPressure; // outdoor pressure (Pa)
377 : Real64 OutdoorWetBulb; // outdoor wet-bulb temperature (C)
378 : Real64 CoolOABoundary; // output of cooling boundary curve (outdoor temperature, C)
379 : Real64 HeatOABoundary; // output of heating boundary curve (outdoor temperature, C)
380 : Real64 EIRFPLRModFac; // EIRFPLR curve output
381 : Real64 UpperStageCompressorRatio; // used for crankcase heater power calculation
382 : Real64 RhoAir; // Density of air [kg/m3]
383 : Real64 RhoWater; // Density of water [kg/m3]
384 : Real64 CpCond; // Specific Heat of water [J/kg-k]
385 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
386 : Real64 CondWaterMassFlow; // Condenser water mass flow rate [kg/s]
387 : Real64 PartLoadFraction; // Part load fraction from PLFFPLR curve
388 : Real64 VRFRTF; // VRF runtime fraction when cycling below MINPLR
389 : Real64 OutdoorCoilT; // Outdoor coil temperature (C)
390 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
391 : Real64 FractionalDefrostTime; // Fraction of time step system is in defrost
392 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
393 : Real64 InputPowerMultiplier; // Multiplier for power when system is in defrost
394 : Real64 LoadDueToDefrost; // Additional load due to defrost
395 : Real64 DefrostEIRTempModFac; // EIR modifier for defrost (function of entering drybulb, outside wetbulb)
396 : Real64 HRCAPFTConst; // stead-state capacity fraction
397 : Real64 HRInitialCapFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
398 : Real64 HRCapTC; // Time constant used to recover from initial degradation in cooling heat recovery
399 : Real64 HREIRFTConst; // stead-state EIR fraction
400 : Real64 HRInitialEIRFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
401 : Real64 HREIRTC; // Time constant used to recover from initial degradation in cooling heat recovery
402 : Real64 CurrentEndTime; // end time of current time step
403 : Real64 SUMultiplier; // multiplier for simulating mode changes
404 : Real64 CondPower; // condenser power [W]
405 : Real64 CondCapacity; // condenser heat rejection [W]
406 : Real64 CondOutletTemp; // Outlet temperature from VRF condenser [C]
407 : Real64 TotPower; // total condenser power use [W]
408 : bool HRHeatRequestFlag; // flag indicating VRF TU could operate in heating mode
409 : bool HRCoolRequestFlag; // flag indicating VRF TU could operate in cooling mode
410 :
411 4735 : auto &vrf = state.dataHVACVarRefFlow->VRF(VRFCond);
412 :
413 : // variable initializations
414 4735 : int TUListNum = vrf.ZoneTUListPtr;
415 4735 : int NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
416 4735 : int NumTUInCoolingMode = 0; // number of terminal units actually cooling
417 4735 : int NumTUInHeatingMode = 0; // number of terminal units actually heating
418 4735 : Real64 TUCoolingLoad = 0.0; // sum of TU's cooling coil load (W)
419 4735 : Real64 TUHeatingLoad = 0.0; // sum of TU's heating coil load (W)
420 4735 : Real64 TUParasiticPower = 0.0; // total terminal unit parasitic power (W)
421 4735 : Real64 TUFanPower = 0.0; // total terminal unit fan power (W)
422 4735 : Real64 CoolingPLR = 0.0; // condenser cooling PLR
423 4735 : Real64 HeatingPLR = 0.0; // condenser heating PLR
424 4735 : Real64 CyclingRatio = 1.0; // cycling ratio of condenser's compressors
425 4735 : Real64 SumCoolInletWB = 0.0; // sum of active TU's DX cooling coil inlet air wet-bulb temperature
426 4735 : Real64 SumHeatInletDB = 0.0; // sum of active TU's DX heating coil inlet air dry-bulb temperature
427 4735 : Real64 SumHeatInletWB = 0.0; // sum of active TU's DX heating coil inlet air wet-bulb temperature
428 4735 : Real64 TotalCondCoolingCapacity = 0.0; // total available condenser cooling capacity (W)
429 4735 : Real64 TotalCondHeatingCapacity = 0.0; // total available condenser heating capacity (W)
430 4735 : Real64 TotalTUCoolingCapacity = 0.0; // sum of TU's cooling capacity including piping losses (W)
431 4735 : Real64 TotalTUHeatingCapacity = 0.0; // sum of TU's heating capacity including piping losses (W)
432 :
433 4735 : vrf.ElecCoolingPower = 0.0;
434 4735 : vrf.ElecHeatingPower = 0.0;
435 4735 : vrf.CrankCaseHeaterPower = 0.0;
436 4735 : vrf.EvapCondPumpElecPower = 0.0;
437 4735 : vrf.EvapWaterConsumpRate = 0.0;
438 4735 : vrf.DefrostPower = 0.0;
439 4735 : vrf.OperatingCoolingCOP = 0.0;
440 4735 : vrf.OperatingHeatingCOP = 0.0;
441 4735 : vrf.OperatingCOP = 0.0;
442 4735 : vrf.SCHE = 0.0;
443 4735 : vrf.BasinHeaterPower = 0.0;
444 4735 : vrf.VRFHeatRec = 0.0;
445 :
446 : // set condenser entering air conditions
447 4735 : if (vrf.CondenserNodeNum != 0) {
448 4719 : OutdoorDryBulb = state.dataLoopNodes->Node(vrf.CondenserNodeNum).Temp;
449 4719 : if (vrf.CondenserType != DataHeatBalance::RefrigCondenserType::Water) {
450 4714 : OutdoorHumRat = state.dataLoopNodes->Node(vrf.CondenserNodeNum).HumRat;
451 4714 : OutdoorPressure = state.dataLoopNodes->Node(vrf.CondenserNodeNum).Press;
452 4714 : OutdoorWetBulb = state.dataLoopNodes->Node(vrf.CondenserNodeNum).OutAirWetBulb;
453 : } else {
454 5 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
455 5 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
456 5 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
457 : }
458 : } else {
459 16 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
460 16 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
461 16 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
462 16 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
463 : }
464 :
465 4735 : if (vrf.CondenserType == DataHeatBalance::RefrigCondenserType::Air) {
466 4730 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
467 5 : } else if (vrf.CondenserType == DataHeatBalance::RefrigCondenserType::Evap) {
468 0 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
469 0 : CondAirMassFlow = RhoAir * vrf.EvapCondAirVolFlowRate;
470 : // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
471 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - vrf.EvapCondEffectiveness);
472 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
473 5 : } else if (vrf.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
474 5 : CondInletTemp = OutdoorDryBulb; // node inlet temp from above
475 5 : OutdoorWetBulb = CondInletTemp; // for watercooled
476 5 : CondWaterMassFlow = vrf.WaterCondenserDesignMassFlow;
477 : } else {
478 0 : assert(false);
479 : }
480 4735 : vrf.CondenserInletTemp = CondInletTemp;
481 :
482 : // sum loads on TU coils
483 9534 : for (NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
484 4799 : TUCoolingLoad += state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU);
485 4799 : TUHeatingLoad += state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU);
486 : }
487 :
488 4735 : vrf.TUCoolingLoad = TUCoolingLoad;
489 4735 : vrf.TUHeatingLoad = TUHeatingLoad;
490 :
491 : // no need to do anything else if the terminal units are off
492 4735 : if (TUCoolingLoad == 0.0 && TUHeatingLoad == 0.0) {
493 90 : vrf.SUMultiplier = 0.0;
494 90 : vrf.VRFCondPLR = 0.0;
495 90 : vrf.VRFCondRTF = 0.0;
496 90 : vrf.VRFCondCyclingRatio = 0.0;
497 90 : vrf.QCondenser = 0.0;
498 90 : vrf.TotalCoolingCapacity = 0.0;
499 90 : vrf.TotalHeatingCapacity = 0.0;
500 90 : vrf.OperatingMode = 0.0;
501 90 : vrf.HRHeatingActive = false;
502 90 : vrf.HRCoolingActive = false;
503 90 : state.dataHVACVarRefFlow->CurrentEndTimeLast = double((state.dataGlobal->DayOfSim - 1) * 24) + state.dataGlobal->CurrentTime -
504 90 : state.dataGlobal->TimeStepZone + state.dataHVACGlobal->SysTimeElapsed;
505 90 : if (vrf.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
506 3 : state.dataHVACVarRefFlow->CondenserWaterMassFlowRate = 0.0;
507 6 : SetComponentFlowRate(
508 3 : state, state.dataHVACVarRefFlow->CondenserWaterMassFlowRate, vrf.CondenserNodeNum, vrf.CondenserOutletNodeNum, vrf.SourcePlantLoc);
509 3 : vrf.WaterCondenserMassFlow = state.dataHVACVarRefFlow->CondenserWaterMassFlowRate;
510 3 : vrf.CondenserSideOutletTemp = CondInletTemp;
511 : }
512 90 : return;
513 : }
514 :
515 : // switch modes if summed coil capacity shows opposite operating mode
516 : // if total TU heating exceeds total TU cooling * ( 1 + 1/COP) then system is in heating mode
517 4645 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && TUHeatingLoad > (TUCoolingLoad * (1.0 + 1.0 / vrf.CoolingCOP))) {
518 1 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
519 1 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
520 1 : vrf.ModeChange = true;
521 1 : if (!state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
522 1 : state.dataHVACVarRefFlow->LastModeHeating(VRFCond) = true;
523 : // reset heat recovery startup timer
524 1 : vrf.HRTimer = 0.0;
525 1 : vrf.HRHeatingActive = false;
526 1 : vrf.HRCoolingActive = false;
527 : }
528 4644 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && (TUCoolingLoad * (1.0 + 1.0 / vrf.CoolingCOP)) > TUHeatingLoad) {
529 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
530 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
531 0 : vrf.ModeChange = true;
532 0 : if (!state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
533 0 : state.dataHVACVarRefFlow->LastModeCooling(VRFCond) = true;
534 : // reset heat recovery startup timer
535 0 : vrf.HRTimer = 0.0;
536 0 : vrf.HRHeatingActive = false;
537 0 : vrf.HRCoolingActive = false;
538 : }
539 4650 : } else if (TUCoolingLoad > 0.0 && TUHeatingLoad > 0.0 &&
540 6 : ((state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) ||
541 6 : (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && state.dataHVACVarRefFlow->LastModeCooling(VRFCond)))) {
542 0 : vrf.ModeChange = true;
543 : // reset heat recovery startup timer
544 0 : vrf.HRTimer = 0.0;
545 0 : vrf.HRHeatingActive = false;
546 0 : vrf.HRCoolingActive = false;
547 : }
548 :
549 : // loop through TU's and calculate average inlet conditions for active coils
550 9342 : for (NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
551 4697 : int TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
552 4697 : int CoolCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
553 4697 : int HeatCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex;
554 4697 : TUParasiticPower +=
555 4697 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ParasiticCoolElecPower + state.dataHVACVarRefFlow->VRFTU(TUIndex).ParasiticHeatElecPower;
556 4697 : TUFanPower += state.dataHVACVarRefFlow->VRFTU(TUIndex).FanPower;
557 :
558 4697 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) > 0.0) {
559 2335 : SumCoolInletWB += state.dataDXCoils->DXCoilCoolInletAirWBTemp(CoolCoilIndex) *
560 2335 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) / TUCoolingLoad;
561 2335 : ++NumTUInCoolingMode;
562 : }
563 4697 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) > 0.0) {
564 2362 : SumHeatInletDB += state.dataDXCoils->DXCoilHeatInletAirDBTemp(HeatCoilIndex) *
565 2362 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) / TUHeatingLoad;
566 2362 : SumHeatInletWB += state.dataDXCoils->DXCoilHeatInletAirWBTemp(HeatCoilIndex) *
567 2362 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) / TUHeatingLoad;
568 2362 : ++NumTUInHeatingMode;
569 : }
570 : }
571 :
572 4645 : bool CoolingCoilAvailableFlag = any(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).CoolingCoilAvailable);
573 4645 : bool HeatingCoilAvailableFlag = any(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HeatingCoilAvailable);
574 :
575 : // calculate capacities and energy use
576 4645 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && CoolingCoilAvailableFlag) {
577 2309 : InletAirWetBulbC = SumCoolInletWB;
578 2309 : TotCoolCapTempModFac = CurveValue(state, vrf.CoolCapFT, InletAirWetBulbC, CondInletTemp);
579 2309 : TotCoolEIRTempModFac = CurveValue(state, vrf.CoolEIRFT, InletAirWetBulbC, CondInletTemp);
580 :
581 : // recalculate cooling Cap and EIR curve output if using boundary curve along with dual Cap and EIR curves.
582 2309 : if (vrf.CoolBoundaryCurvePtr > 0) {
583 2306 : CoolOABoundary = CurveValue(state, vrf.CoolBoundaryCurvePtr, InletAirWetBulbC);
584 2306 : if (OutdoorDryBulb > CoolOABoundary) {
585 2303 : if (vrf.CoolCapFTHi > 0) {
586 2303 : TotCoolCapTempModFac = CurveValue(state, vrf.CoolCapFTHi, InletAirWetBulbC, CondInletTemp);
587 : }
588 : }
589 : }
590 2309 : if (vrf.EIRCoolBoundaryCurvePtr > 0) {
591 2306 : CoolOABoundary = CurveValue(state, vrf.EIRCoolBoundaryCurvePtr, InletAirWetBulbC);
592 2306 : if (OutdoorDryBulb > CoolOABoundary) {
593 2303 : if (vrf.CoolEIRFTHi > 0) {
594 2303 : TotCoolEIRTempModFac = CurveValue(state, vrf.CoolEIRFTHi, InletAirWetBulbC, CondInletTemp);
595 : }
596 : }
597 : }
598 :
599 : // Warn user if curve output goes negative
600 2309 : if (TotCoolCapTempModFac < 0.0) {
601 0 : if (!state.dataGlobal->WarmupFlag && NumTUInCoolingMode > 0) {
602 0 : if (vrf.CoolCapFTErrorIndex == 0) {
603 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
604 0 : ShowContinueError(
605 : state,
606 0 : format(" Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCoolCapTempModFac));
607 0 : ShowContinueError(state,
608 0 : format(" Negative value occurs using an outdoor air temperature of {:.1T} C and an average indoor air "
609 : "wet-bulb temperature of {:.1T} C.",
610 : CondInletTemp,
611 : InletAirWetBulbC));
612 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
613 : }
614 0 : ShowRecurringWarningErrorAtEnd(
615 : state,
616 0 : format("{} \"{}\": Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
617 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
618 0 : vrf.Name),
619 0 : vrf.CoolCapFTErrorIndex,
620 : TotCoolCapTempModFac,
621 : TotCoolCapTempModFac);
622 0 : TotCoolCapTempModFac = 0.0;
623 : }
624 : }
625 :
626 : // Warn user if curve output goes negative
627 2309 : if (TotCoolEIRTempModFac < 0.0) {
628 0 : if (!state.dataGlobal->WarmupFlag && NumTUInCoolingMode > 0) {
629 0 : if (vrf.EIRFTempCoolErrorIndex == 0) {
630 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
631 0 : ShowContinueError(state,
632 0 : format(" Cooling Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).",
633 : TotCoolEIRTempModFac));
634 0 : ShowContinueError(state,
635 0 : format(" Negative value occurs using an outdoor air temperature of {:.1T} C and an average indoor air "
636 : "wet-bulb temperature of {:.1T} C.",
637 : CondInletTemp,
638 : InletAirWetBulbC));
639 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
640 : }
641 0 : ShowRecurringWarningErrorAtEnd(
642 : state,
643 0 : format("{} \"{}\": Cooling Energy Input Ratio Modifier curve (function of temperature) output is negative warning continues...",
644 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
645 0 : vrf.Name),
646 0 : vrf.EIRFTempCoolErrorIndex,
647 : TotCoolEIRTempModFac,
648 : TotCoolEIRTempModFac);
649 0 : TotCoolEIRTempModFac = 0.0;
650 : }
651 : }
652 :
653 2309 : TotalCondCoolingCapacity = vrf.CoolingCapacity * state.dataHVACVarRefFlow->CoolCombinationRatio(VRFCond) * TotCoolCapTempModFac;
654 2309 : TotalTUCoolingCapacity = TotalCondCoolingCapacity * vrf.PipingCorrectionCooling;
655 :
656 2309 : if (TotalCondCoolingCapacity > 0.0) {
657 2309 : CoolingPLR = (TUCoolingLoad / vrf.PipingCorrectionCooling) / TotalCondCoolingCapacity;
658 : } else {
659 0 : CoolingPLR = 0.0;
660 : }
661 :
662 : // Warn user if curve output goes negative
663 2309 : if (TotCoolCapTempModFac < 0.0) {
664 0 : if (!state.dataGlobal->WarmupFlag && NumTUInCoolingMode > 0) {
665 0 : if (vrf.CoolCapFTErrorIndex == 0) {
666 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
667 0 : ShowContinueError(
668 : state,
669 0 : format(" Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCoolCapTempModFac));
670 0 : ShowContinueError(state,
671 0 : format(" Negative value occurs using an outdoor air temperature of {:.1T} C and an average indoor air "
672 : "wet-bulb temperature of {:.1T} C.",
673 : CondInletTemp,
674 : InletAirWetBulbC));
675 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
676 : }
677 0 : ShowRecurringWarningErrorAtEnd(
678 : state,
679 0 : format("{} \"{}\": Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
680 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
681 0 : vrf.Name),
682 0 : vrf.CoolCapFTErrorIndex,
683 : TotCoolCapTempModFac,
684 : TotCoolCapTempModFac);
685 0 : TotCoolCapTempModFac = 0.0;
686 : }
687 : }
688 : // Warn user if curve output goes negative
689 2309 : if (TotCoolEIRTempModFac < 0.0) {
690 0 : if (!state.dataGlobal->WarmupFlag && NumTUInCoolingMode > 0) {
691 0 : if (vrf.EIRFTempCoolErrorIndex == 0) {
692 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
693 0 : ShowContinueError(state,
694 0 : format(" Cooling Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).",
695 : TotCoolEIRTempModFac));
696 0 : ShowContinueError(state,
697 0 : format(" Negative value occurs using an outdoor air temperature of {:.1T} C and an average indoor air "
698 : "wet-bulb temperature of {:.1T} C.",
699 : CondInletTemp,
700 : InletAirWetBulbC));
701 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
702 : }
703 0 : ShowRecurringWarningErrorAtEnd(
704 : state,
705 0 : format("{} \"{}\": Cooling Energy Input Ratio Modifier curve (function of temperature) output is negative warning continues...",
706 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
707 0 : vrf.Name),
708 0 : vrf.EIRFTempCoolErrorIndex,
709 : TotCoolEIRTempModFac,
710 : TotCoolEIRTempModFac);
711 0 : TotCoolEIRTempModFac = 0.0;
712 : }
713 : }
714 :
715 2336 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && HeatingCoilAvailableFlag) {
716 2336 : InletAirDryBulbC = SumHeatInletDB;
717 2336 : InletAirWetBulbC = SumHeatInletWB;
718 2336 : switch (vrf.HeatingPerformanceOATType) {
719 0 : case HVAC::OATType::DryBulb: {
720 0 : TotHeatCapTempModFac = CurveValue(state, vrf.HeatCapFT, InletAirDryBulbC, CondInletTemp);
721 0 : TotHeatEIRTempModFac = CurveValue(state, vrf.HeatEIRFT, InletAirDryBulbC, CondInletTemp);
722 0 : } break;
723 2326 : case HVAC::OATType::WetBulb: {
724 2326 : TotHeatCapTempModFac = CurveValue(state, vrf.HeatCapFT, InletAirDryBulbC, OutdoorWetBulb);
725 2326 : TotHeatEIRTempModFac = CurveValue(state, vrf.HeatEIRFT, InletAirDryBulbC, OutdoorWetBulb);
726 2326 : } break;
727 10 : default: {
728 10 : TotHeatCapTempModFac = 1.0;
729 10 : TotHeatEIRTempModFac = 1.0;
730 10 : } break;
731 : }
732 : // recalculate heating Cap and EIR curve output if using boundary curve along with dual Cap and EIR curves.
733 2336 : if (vrf.HeatBoundaryCurvePtr > 0) {
734 2326 : HeatOABoundary = CurveValue(state, vrf.HeatBoundaryCurvePtr, InletAirDryBulbC);
735 2326 : switch (vrf.HeatingPerformanceOATType) {
736 0 : case HVAC::OATType::DryBulb: {
737 0 : if (OutdoorDryBulb > HeatOABoundary) {
738 0 : if (vrf.HeatCapFTHi > 0) {
739 0 : TotHeatCapTempModFac = CurveValue(state, vrf.HeatCapFTHi, InletAirDryBulbC, CondInletTemp);
740 : }
741 : }
742 0 : } break;
743 2326 : case HVAC::OATType::WetBulb: {
744 2326 : if (OutdoorWetBulb > HeatOABoundary) {
745 2323 : if (vrf.HeatCapFTHi > 0) {
746 2323 : TotHeatCapTempModFac = CurveValue(state, vrf.HeatCapFTHi, InletAirDryBulbC, OutdoorWetBulb);
747 : }
748 : }
749 2326 : } break;
750 0 : default: {
751 0 : TotHeatCapTempModFac = 1.0;
752 0 : } break;
753 : }
754 : }
755 2336 : if (vrf.EIRHeatBoundaryCurvePtr > 0) {
756 2326 : HeatOABoundary = CurveValue(state, vrf.EIRHeatBoundaryCurvePtr, InletAirDryBulbC);
757 2326 : switch (vrf.HeatingPerformanceOATType) {
758 0 : case HVAC::OATType::DryBulb: {
759 0 : if (OutdoorDryBulb > HeatOABoundary) {
760 0 : if (vrf.HeatEIRFTHi > 0) {
761 0 : TotHeatEIRTempModFac = CurveValue(state, vrf.HeatEIRFTHi, InletAirDryBulbC, CondInletTemp);
762 : }
763 : }
764 0 : } break;
765 2326 : case HVAC::OATType::WetBulb: {
766 2326 : if (OutdoorWetBulb > HeatOABoundary) {
767 2323 : if (vrf.HeatEIRFTHi > 0) {
768 2323 : TotHeatEIRTempModFac = CurveValue(state, vrf.HeatEIRFTHi, InletAirDryBulbC, OutdoorWetBulb);
769 : }
770 : }
771 2326 : } break;
772 0 : default: {
773 0 : TotHeatEIRTempModFac = 1.0;
774 0 : } break;
775 : }
776 : }
777 :
778 : // Warn user if curve output goes negative
779 2336 : if (TotHeatCapTempModFac < 0.0) {
780 0 : if (!state.dataGlobal->WarmupFlag && NumTUInHeatingMode > 0) {
781 0 : if (vrf.HeatCapFTErrorIndex == 0) {
782 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
783 0 : ShowContinueError(
784 : state,
785 0 : format(" Heating Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotHeatCapTempModFac));
786 :
787 0 : switch (vrf.HeatingPerformanceOATType) {
788 0 : case HVAC::OATType::DryBulb: {
789 0 : ShowContinueError(state,
790 0 : format(" Negative value occurs using an outdoor air temperature of {:.1T} C and an average indoor air "
791 : "dry-bulb temperature of {:.1T} C.",
792 : CondInletTemp,
793 : InletAirDryBulbC));
794 0 : } break;
795 0 : case HVAC::OATType::WetBulb: {
796 0 : ShowContinueError(state,
797 0 : format(" Negative value occurs using an outdoor air wet-bulb temperature of {:.1T} C and an average "
798 : "indoor air wet-bulb temperature of {:.1T} C.",
799 : OutdoorWetBulb,
800 : InletAirWetBulbC));
801 0 : } break;
802 0 : default:
803 : // should never get here
804 0 : break;
805 : }
806 :
807 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
808 : }
809 0 : ShowRecurringWarningErrorAtEnd(
810 : state,
811 0 : format("{} \"{}\": Heating Capacity Ratio Modifier curve (function of temperature) output is negative warning continues...",
812 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
813 0 : vrf.Name),
814 0 : vrf.HeatCapFTErrorIndex,
815 : TotHeatCapTempModFac,
816 : TotHeatCapTempModFac);
817 0 : TotHeatCapTempModFac = 0.0;
818 : }
819 : }
820 : // Warn user if curve output goes negative
821 2336 : if (TotHeatEIRTempModFac < 0.0) {
822 0 : if (!state.dataGlobal->WarmupFlag && NumTUInHeatingMode > 0) {
823 0 : if (vrf.EIRFTempHeatErrorIndex == 0) {
824 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
825 0 : ShowContinueError(state,
826 0 : format(" Heating Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).",
827 : TotHeatEIRTempModFac));
828 0 : switch (vrf.HeatingPerformanceOATType) {
829 0 : case HVAC::OATType::DryBulb: {
830 0 : ShowContinueError(state,
831 0 : format(" Negative value occurs using an outdoor air dry-bulb temperature of {:.1T} C and an "
832 : "average indoor air dry-bulb temperature of {:.1T} C.",
833 : CondInletTemp,
834 : InletAirDryBulbC));
835 0 : } break;
836 0 : case HVAC::OATType::WetBulb: {
837 0 : ShowContinueError(state,
838 0 : format(" Negative value occurs using an outdoor air wet-bulb temperature of {:.1T} C and an "
839 : "average indoor air wet-bulb temperature of {:.1T} C.",
840 : OutdoorWetBulb,
841 : InletAirWetBulbC));
842 0 : } break;
843 0 : default:
844 0 : break;
845 : }
846 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
847 : }
848 0 : ShowRecurringWarningErrorAtEnd(
849 : state,
850 0 : format("{} \"{}\": Heating Energy Input Ratio Modifier curve (function of temperature) output is negative warning continues...",
851 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
852 0 : vrf.Name),
853 0 : vrf.EIRFTempHeatErrorIndex,
854 : TotHeatEIRTempModFac,
855 : TotHeatEIRTempModFac);
856 0 : TotHeatEIRTempModFac = 0.0;
857 : }
858 : }
859 :
860 : // Initializing defrost adjustment factors
861 2336 : LoadDueToDefrost = 0.0;
862 2336 : HeatingCapacityMultiplier = 1.0;
863 2336 : FractionalDefrostTime = 0.0;
864 2336 : InputPowerMultiplier = 1.0;
865 :
866 : // Check outdoor temperature to determine of defrost is active
867 2336 : if (OutdoorDryBulb <= vrf.MaxOATDefrost && vrf.CondenserType != DataHeatBalance::RefrigCondenserType::Water) {
868 :
869 : // Calculating adjustment factors for defrost
870 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
871 3 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
872 3 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
873 :
874 : // Calculate defrost adjustment factors depending on defrost control type
875 3 : if (vrf.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
876 3 : FractionalDefrostTime = vrf.DefrostFraction;
877 3 : if (FractionalDefrostTime > 0.0) {
878 2 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
879 2 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
880 : }
881 : } else { // else defrost control is on-demand
882 0 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
883 0 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
884 0 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
885 : }
886 :
887 3 : if (FractionalDefrostTime > 0.0) {
888 : // Calculate defrost adjustment factors depending on defrost control strategy
889 2 : if (vrf.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
890 1 : LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (vrf.HeatingCapacity / 1.01667);
891 1 : DefrostEIRTempModFac = CurveValue(state, vrf.DefrostEIRPtr, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
892 :
893 : // Warn user if curve output goes negative
894 1 : if (DefrostEIRTempModFac < 0.0) {
895 0 : if (!state.dataGlobal->WarmupFlag) {
896 0 : if (vrf.DefrostHeatErrorIndex == 0) {
897 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), vrf.Name));
898 0 : ShowContinueError(
899 : state,
900 0 : format(" Defrost Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).",
901 : DefrostEIRTempModFac));
902 0 : ShowContinueError(state,
903 0 : format(" Negative value occurs using an outdoor air dry-bulb temperature of {:.1T} C and an "
904 : "average indoor air wet-bulb temperature of {:.1T} C.",
905 : OutdoorDryBulb,
906 : InletAirWetBulbC));
907 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
908 : }
909 0 : ShowRecurringWarningErrorAtEnd(state,
910 0 : format("{} \"{}\": Defrost Energy Input Ratio Modifier curve (function of temperature) "
911 : "output is negative warning continues...",
912 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
913 0 : vrf.Name),
914 0 : vrf.DefrostHeatErrorIndex,
915 : DefrostEIRTempModFac,
916 : DefrostEIRTempModFac);
917 0 : DefrostEIRTempModFac = 0.0;
918 : }
919 : }
920 :
921 1 : vrf.DefrostPower = DefrostEIRTempModFac * (vrf.HeatingCapacity / 1.01667) * FractionalDefrostTime;
922 :
923 : } else { // Defrost strategy is resistive
924 1 : vrf.DefrostPower = vrf.DefrostCapacity * FractionalDefrostTime;
925 : }
926 : }
927 : }
928 :
929 2336 : TotalCondHeatingCapacity =
930 2336 : vrf.HeatingCapacity * state.dataHVACVarRefFlow->HeatCombinationRatio(VRFCond) * TotHeatCapTempModFac * HeatingCapacityMultiplier;
931 2336 : TotalTUHeatingCapacity = TotalCondHeatingCapacity * vrf.PipingCorrectionHeating;
932 2336 : if (TotalCondHeatingCapacity > 0.0) {
933 2336 : HeatingPLR = (TUHeatingLoad / vrf.PipingCorrectionHeating) / TotalCondHeatingCapacity;
934 2336 : HeatingPLR += (LoadDueToDefrost * HeatingPLR) / TotalCondHeatingCapacity;
935 : } else {
936 0 : HeatingPLR = 0.0;
937 : }
938 : }
939 :
940 4645 : vrf.VRFCondPLR = max(CoolingPLR, HeatingPLR);
941 4645 : Real64 tmpVRFCondPLR = 0.0;
942 4645 : if (CoolingPLR > 0.0 || HeatingPLR > 0.0) {
943 4645 : tmpVRFCondPLR = max(vrf.MinPLR, vrf.VRFCondPLR);
944 : }
945 :
946 4645 : HRHeatRequestFlag = any(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HRHeatRequest);
947 4645 : HRCoolRequestFlag = any(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HRCoolRequest);
948 4645 : HREIRFTConst = 1.0;
949 4645 : Real64 HREIRAdjustment = 1.0;
950 :
951 4645 : if (!state.dataGlobal->DoingSizing && !state.dataGlobal->WarmupFlag) {
952 1175 : if (HRHeatRequestFlag && HRCoolRequestFlag) {
953 : // determine operating mode change
954 7 : if (!vrf.HRCoolingActive && !vrf.HRHeatingActive) {
955 3 : vrf.ModeChange = true;
956 3 : vrf.HRTimer = 0.0;
957 : }
958 7 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
959 0 : if (vrf.HRHeatingActive && !vrf.HRCoolingActive) {
960 0 : vrf.HRModeChange = true;
961 : }
962 0 : vrf.HRCoolingActive = true;
963 0 : vrf.HRHeatingActive = false;
964 0 : int HRCAPFT = vrf.HRCAPFTCool; // Index to cool capacity as a function of temperature\PLR curve for heat recovery
965 0 : if (HRCAPFT > 0) {
966 : // VRF(VRFCond)%HRCAPFTCoolConst = 0.9d0 ! initialized to 0.9
967 0 : if (state.dataCurveManager->curves(vrf.HRCAPFTCool)->numDims == 2) { // Curve type for HRCAPFTCool
968 0 : vrf.HRCAPFTCoolConst = CurveValue(state, HRCAPFT, InletAirWetBulbC, CondInletTemp);
969 : } else {
970 0 : vrf.HRCAPFTCoolConst = CurveValue(state, HRCAPFT, tmpVRFCondPLR);
971 : }
972 : }
973 0 : HRCAPFTConst = vrf.HRCAPFTCoolConst;
974 0 : HRInitialCapFrac = vrf.HRInitialCoolCapFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
975 0 : HRCapTC = vrf.HRCoolCapTC; // Time constant used to recover from initial degradation in cooling heat recovery
976 :
977 0 : int HREIRFT = vrf.HREIRFTCool; // Index to cool EIR as a function of temperature curve for heat recovery
978 0 : if (HREIRFT > 0) {
979 : // VRF(VRFCond)%HREIRFTCoolConst = 1.1d0 ! initialized to 1.1
980 0 : if (state.dataCurveManager->curves(vrf.HREIRFTCool)->numDims == 2) { // Curve type for HREIRFTCool
981 0 : vrf.HREIRFTCoolConst = CurveValue(state, HREIRFT, InletAirWetBulbC, CondInletTemp);
982 : } else {
983 0 : vrf.HREIRFTCoolConst = CurveValue(state, HREIRFT, tmpVRFCondPLR);
984 : }
985 : }
986 0 : HREIRFTConst = vrf.HREIRFTCoolConst;
987 0 : HRInitialEIRFrac = vrf.HRInitialCoolEIRFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
988 0 : HREIRTC = vrf.HRCoolEIRTC; // Time constant used to recover from initial degradation in cooling heat recovery
989 7 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
990 7 : if (!vrf.HRHeatingActive && vrf.HRCoolingActive) {
991 0 : vrf.HRModeChange = true;
992 : }
993 7 : vrf.HRCoolingActive = false;
994 7 : vrf.HRHeatingActive = true;
995 7 : int HRCAPFT = vrf.HRCAPFTHeat; // Index to heat capacity as a function of temperature\PLR curve for heat recovery
996 7 : if (HRCAPFT > 0) {
997 : // VRF(VRFCond)%HRCAPFTHeatConst = 1.1d0 ! initialized to 1.1
998 1 : if (state.dataCurveManager->curves(vrf.HRCAPFTHeat)->numDims == 2) { // Curve type for HRCAPFTCool
999 0 : switch (vrf.HeatingPerformanceOATType) {
1000 0 : case HVAC::OATType::DryBulb: {
1001 0 : vrf.HRCAPFTHeatConst = CurveValue(state, HRCAPFT, InletAirDryBulbC, CondInletTemp);
1002 0 : } break;
1003 0 : case HVAC::OATType::WetBulb: {
1004 0 : vrf.HRCAPFTHeatConst = CurveValue(state, HRCAPFT, InletAirDryBulbC, OutdoorWetBulb);
1005 0 : } break;
1006 0 : default: {
1007 0 : vrf.HRCAPFTHeatConst = 1.0;
1008 0 : } break;
1009 : }
1010 : } else {
1011 1 : vrf.HRCAPFTHeatConst = CurveValue(state, HRCAPFT, tmpVRFCondPLR);
1012 : }
1013 : }
1014 7 : HRCAPFTConst = vrf.HRCAPFTHeatConst;
1015 7 : HRInitialCapFrac = vrf.HRInitialHeatCapFrac; // Fractional heating degradation at the start of heat recovery from cooling mode
1016 7 : HRCapTC = vrf.HRHeatCapTC; // Time constant used to recover from initial degradation in heating heat recovery
1017 :
1018 7 : int HREIRFT = vrf.HREIRFTHeat; // Index to cool EIR as a function of temperature curve for heat recovery
1019 7 : if (HREIRFT > 0) {
1020 : // VRF(VRFCond)%HREIRFTCoolConst = 1.1d0 ! initialized to 1.1
1021 1 : if (state.dataCurveManager->curves(vrf.HREIRFTHeat)->numDims == 2) { // Curve type for HREIRFTHeat
1022 0 : switch (vrf.HeatingPerformanceOATType) {
1023 0 : case HVAC::OATType::DryBulb: {
1024 0 : vrf.HREIRFTHeatConst = CurveValue(state, HREIRFT, InletAirDryBulbC, CondInletTemp);
1025 0 : } break;
1026 0 : case HVAC::OATType::WetBulb: {
1027 0 : vrf.HREIRFTHeatConst = CurveValue(state, HREIRFT, InletAirDryBulbC, OutdoorWetBulb);
1028 0 : } break;
1029 0 : default: {
1030 0 : vrf.HREIRFTHeatConst = 1.0;
1031 0 : } break;
1032 : }
1033 : } else {
1034 1 : vrf.HREIRFTHeatConst = CurveValue(state, HREIRFT, tmpVRFCondPLR);
1035 : }
1036 : }
1037 7 : HREIRFTConst = vrf.HREIRFTHeatConst;
1038 7 : HRInitialEIRFrac = vrf.HRInitialHeatEIRFrac; // Fractional heating degradation at the start of heat recovery from heating mode
1039 7 : HREIRTC = vrf.HRHeatEIRTC; // Time constant used to recover from initial degradation in heating heat recovery
1040 : } else {
1041 : // zone thermostats satisfied, condenser is off. Set values anyway
1042 0 : HRCAPFTConst = 1.0;
1043 0 : HRInitialCapFrac = 1.0;
1044 0 : HRCapTC = 1.0;
1045 0 : HREIRFTConst = 1.0;
1046 0 : HRInitialEIRFrac = 1.0;
1047 0 : HREIRTC = 1.0;
1048 0 : if (vrf.HRHeatingActive || vrf.HRCoolingActive) {
1049 0 : vrf.HRModeChange = true;
1050 : }
1051 0 : vrf.HRCoolingActive = false;
1052 0 : vrf.HRHeatingActive = false;
1053 : }
1054 :
1055 7 : } else { // IF(HRHeatRequestFlag .AND. HRCoolRequestFlag)THEN -- Heat recovery turned off
1056 1168 : HRCAPFTConst = 1.0;
1057 1168 : HRInitialCapFrac = 1.0;
1058 1168 : HRCapTC = 0.0;
1059 1168 : HREIRFTConst = 1.0;
1060 1168 : HRInitialEIRFrac = 1.0;
1061 1168 : HREIRTC = 0.0;
1062 1168 : vrf.HRModeChange = false;
1063 1168 : vrf.HRCoolingActive = false;
1064 1168 : vrf.HRHeatingActive = false;
1065 1168 : vrf.HRTimer = 0.0;
1066 : }
1067 :
1068 : // Calculate the capacity modification factor (SUMultiplier) for the HR mode transition period
1069 1175 : CurrentEndTime = double((state.dataGlobal->DayOfSim - 1) * 24) + state.dataGlobal->CurrentTime - state.dataGlobal->TimeStepZone +
1070 1175 : state.dataHVACGlobal->SysTimeElapsed;
1071 :
1072 1175 : if (vrf.ModeChange || vrf.HRModeChange) {
1073 7 : if (vrf.HRCoolingActive && vrf.HRTimer == 0.0) {
1074 0 : vrf.HRTimer = state.dataHVACVarRefFlow->CurrentEndTimeLast;
1075 7 : } else if (vrf.HRHeatingActive && vrf.HRTimer == 0.0) {
1076 3 : vrf.HRTimer = state.dataHVACVarRefFlow->CurrentEndTimeLast;
1077 4 : } else if (!vrf.HRCoolingActive && !vrf.HRHeatingActive) {
1078 0 : vrf.HRTimer = 0.0;
1079 : }
1080 : }
1081 :
1082 1175 : vrf.HRTime = max(0.0, CurrentEndTime - vrf.HRTimer);
1083 1175 : if (vrf.HRTime < (HRCapTC * 5.0)) {
1084 6 : if (HRCapTC > 0.0) {
1085 6 : SUMultiplier = min(1.0, 1.0 - std::exp(-vrf.HRTime / HRCapTC));
1086 : } else {
1087 0 : SUMultiplier = 1.0;
1088 : }
1089 : } else {
1090 1169 : SUMultiplier = 1.0;
1091 1169 : vrf.ModeChange = false;
1092 1169 : vrf.HRModeChange = false;
1093 : }
1094 1175 : vrf.SUMultiplier = SUMultiplier;
1095 :
1096 1175 : state.dataHVACVarRefFlow->CurrentEndTimeLast = CurrentEndTime;
1097 :
1098 1175 : if (vrf.HeatRecoveryUsed && vrf.HRCoolingActive) {
1099 0 : TotalCondCoolingCapacity *= HRCAPFTConst;
1100 0 : TotalCondCoolingCapacity =
1101 0 : HRInitialCapFrac * TotalCondCoolingCapacity + (1.0 - HRInitialCapFrac) * TotalCondCoolingCapacity * SUMultiplier;
1102 0 : TotalTUCoolingCapacity = TotalCondCoolingCapacity * vrf.PipingCorrectionCooling;
1103 0 : if (TotalCondCoolingCapacity > 0.0) {
1104 0 : CoolingPLR = min(1.0, (TUCoolingLoad / vrf.PipingCorrectionCooling) / TotalCondCoolingCapacity);
1105 : } else {
1106 0 : CoolingPLR = 0.0;
1107 : }
1108 0 : HREIRAdjustment = HRInitialEIRFrac + (HREIRFTConst - HRInitialEIRFrac) * SUMultiplier;
1109 0 : vrf.VRFHeatRec = TUHeatingLoad;
1110 1175 : } else if (vrf.HeatRecoveryUsed && vrf.HRHeatingActive) {
1111 7 : TotalCondHeatingCapacity *= HRCAPFTConst;
1112 7 : TotalCondHeatingCapacity =
1113 7 : HRInitialCapFrac * TotalCondHeatingCapacity + (1.0 - HRInitialCapFrac) * TotalCondHeatingCapacity * SUMultiplier;
1114 7 : TotalTUHeatingCapacity = TotalCondHeatingCapacity * vrf.PipingCorrectionHeating;
1115 7 : if (TotalCondHeatingCapacity > 0.0) {
1116 7 : HeatingPLR = min(1.0, (TUHeatingLoad / vrf.PipingCorrectionHeating) / TotalCondHeatingCapacity);
1117 : } else {
1118 0 : HeatingPLR = 0.0;
1119 : }
1120 7 : HREIRAdjustment = HRInitialEIRFrac + (HREIRFTConst - HRInitialEIRFrac) * SUMultiplier;
1121 7 : vrf.VRFHeatRec = TUCoolingLoad;
1122 : }
1123 1175 : vrf.VRFCondPLR = max(CoolingPLR, HeatingPLR);
1124 : }
1125 :
1126 4645 : if (vrf.MinPLR > 0.0) {
1127 4632 : CyclingRatio = min(1.0, vrf.VRFCondPLR / vrf.MinPLR);
1128 4632 : if (vrf.VRFCondPLR < vrf.MinPLR && vrf.VRFCondPLR > 0.0) {
1129 304 : vrf.VRFCondPLR = vrf.MinPLR;
1130 304 : if (CoolingPLR > 0.0) {
1131 259 : CoolingPLR = vrf.MinPLR; // also adjust local PLR variables
1132 : }
1133 304 : if (HeatingPLR > 0.0) {
1134 45 : HeatingPLR = vrf.MinPLR; // also adjust local PLR variables
1135 : }
1136 : }
1137 : }
1138 4645 : vrf.VRFCondCyclingRatio = CyclingRatio; // report variable for cycling rate
1139 4645 : vrf.TotalCoolingCapacity = TotalCondCoolingCapacity * CoolingPLR * CyclingRatio;
1140 4645 : vrf.TotalHeatingCapacity = TotalCondHeatingCapacity * HeatingPLR * CyclingRatio;
1141 :
1142 4645 : vrf.OperatingMode = 0; // report variable for heating or cooling mode
1143 4645 : EIRFPLRModFac = 1.0;
1144 4645 : VRFRTF = 0.0;
1145 : // cooling and heating is optional (only one may exist), if so then performance curve for missing coil are not required
1146 4645 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && CoolingPLR > 0.0) {
1147 2309 : vrf.OperatingMode = ModeCoolingOnly;
1148 2309 : if (CoolingPLR > 1.0) {
1149 1 : if (vrf.CoolEIRFPLR2 > 0) {
1150 1 : EIRFPLRModFac = CurveValue(state, vrf.CoolEIRFPLR2, max(vrf.MinPLR, CoolingPLR));
1151 : }
1152 : } else {
1153 2308 : if (vrf.CoolEIRFPLR1 > 0) {
1154 2308 : EIRFPLRModFac = CurveValue(state, vrf.CoolEIRFPLR1, max(vrf.MinPLR, CoolingPLR));
1155 : }
1156 : }
1157 :
1158 2309 : if (EIRFPLRModFac < 0.0) {
1159 1 : if (vrf.CoolEIRFPLRErrorIndex == 0) {
1160 3 : ShowSevereMessage(state, fmt::format("{} \"{}\":", std::string(cVRFTypes(VRF_HeatPump)), vrf.Name));
1161 1 : ShowContinueError(state, format(" Cooling EIR Modifier curve (function of PLR) output is negative ({:.3T}).", EIRFPLRModFac));
1162 1 : ShowContinueError(state, format(" Negative value occurs using a cooling Part Load Ratio (PLR) of {:.2T}.", CoolingPLR));
1163 3 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
1164 : }
1165 6 : ShowRecurringWarningErrorAtEnd(
1166 : state,
1167 1 : fmt::format("{} \"{}\": Cooling EIR Modifier curve (function of PLR) output is negative warning continues...",
1168 1 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
1169 1 : vrf.Name),
1170 1 : vrf.CoolEIRFPLRErrorIndex,
1171 : EIRFPLRModFac,
1172 : EIRFPLRModFac);
1173 1 : EIRFPLRModFac = 0.0;
1174 : }
1175 :
1176 : // find part load fraction to calculate RTF
1177 2309 : if (vrf.CoolPLFFPLR > 0) {
1178 2306 : PartLoadFraction = max(0.7, CurveValue(state, vrf.CoolPLFFPLR, CyclingRatio));
1179 : } else {
1180 3 : PartLoadFraction = 1.0;
1181 : }
1182 2309 : VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));
1183 :
1184 2309 : vrf.ElecCoolingPower = (vrf.RatedCoolingPower * TotCoolCapTempModFac) * TotCoolEIRTempModFac * EIRFPLRModFac * HREIRAdjustment * VRFRTF;
1185 : }
1186 4645 : if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && HeatingPLR > 0.0) {
1187 2336 : vrf.OperatingMode = ModeHeatingOnly;
1188 2336 : if (HeatingPLR > 1.0) {
1189 0 : if (vrf.HeatEIRFPLR2 > 0) {
1190 0 : EIRFPLRModFac = CurveValue(state, vrf.HeatEIRFPLR2, max(vrf.MinPLR, HeatingPLR));
1191 : }
1192 : } else {
1193 2336 : if (vrf.HeatEIRFPLR1 > 0) {
1194 2336 : EIRFPLRModFac = CurveValue(state, vrf.HeatEIRFPLR1, max(vrf.MinPLR, HeatingPLR));
1195 : }
1196 : }
1197 :
1198 2336 : if (EIRFPLRModFac < 0.0) {
1199 1 : if (vrf.HeatEIRFPLRErrorIndex == 0) {
1200 3 : ShowSevereMessage(state, fmt::format("{} \"{}\":", std::string(cVRFTypes(VRF_HeatPump)), vrf.Name));
1201 1 : ShowContinueError(state, format(" Heating EIR Modifier curve (function of PLR) output is negative ({:.3T}).", EIRFPLRModFac));
1202 1 : ShowContinueError(state, format(" Negative value occurs using a heating Part Load Ratio (PLR) of {:.2T}.", HeatingPLR));
1203 3 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
1204 : }
1205 6 : ShowRecurringWarningErrorAtEnd(
1206 : state,
1207 1 : fmt::format("{} \"{}\": Heating EIR Modifier curve (function of PLR) output is negative warning continues...",
1208 1 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
1209 1 : vrf.Name),
1210 1 : vrf.HeatEIRFPLRErrorIndex,
1211 : EIRFPLRModFac,
1212 : EIRFPLRModFac);
1213 1 : EIRFPLRModFac = 0.0;
1214 : }
1215 :
1216 : // find part load fraction to calculate RTF
1217 2336 : if (vrf.HeatPLFFPLR > 0) {
1218 2326 : PartLoadFraction = max(0.7, CurveValue(state, vrf.HeatPLFFPLR, CyclingRatio));
1219 : } else {
1220 10 : PartLoadFraction = 1.0;
1221 : }
1222 2336 : VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));
1223 :
1224 2336 : vrf.ElecHeatingPower =
1225 2336 : (vrf.RatedHeatingPower * TotHeatCapTempModFac) * TotHeatEIRTempModFac * EIRFPLRModFac * HREIRAdjustment * VRFRTF * InputPowerMultiplier;
1226 : }
1227 : // adjust defrost power based on RTF
1228 4645 : vrf.DefrostPower *= VRFRTF;
1229 4645 : vrf.VRFCondRTF = VRFRTF;
1230 :
1231 : // calculate crankcase heater power
1232 4645 : if (vrf.MaxOATCCHeater > OutdoorDryBulb) {
1233 : // calculate crankcase heater power
1234 3 : vrf.CrankCaseHeaterPower = vrf.CCHeaterPower * (1.0 - VRFRTF);
1235 3 : if (vrf.NumCompressors > 1) {
1236 3 : UpperStageCompressorRatio = (1.0 - vrf.CompressorSizeRatio) / (vrf.NumCompressors - 1);
1237 6 : for (int Stage = 1; Stage <= vrf.NumCompressors - 2; ++Stage) {
1238 3 : if (vrf.VRFCondPLR < (vrf.CompressorSizeRatio + Stage * UpperStageCompressorRatio)) {
1239 3 : vrf.CrankCaseHeaterPower += vrf.CCHeaterPower;
1240 : }
1241 : }
1242 : }
1243 : } else {
1244 4642 : vrf.CrankCaseHeaterPower = 0.0;
1245 : }
1246 :
1247 4645 : CondCapacity = max(vrf.TotalCoolingCapacity, vrf.TotalHeatingCapacity);
1248 4645 : CondPower = max(vrf.ElecCoolingPower, vrf.ElecHeatingPower);
1249 4645 : if (vrf.ElecCoolingPower > 0.0) {
1250 2308 : vrf.QCondenser = CondCapacity + CondPower - vrf.TUHeatingLoad / vrf.PipingCorrectionHeating;
1251 2337 : } else if (vrf.ElecHeatingPower > 0.0) {
1252 2335 : vrf.QCondenser = -CondCapacity + CondPower + vrf.TUCoolingLoad / vrf.PipingCorrectionCooling;
1253 : } else {
1254 2 : vrf.QCondenser = 0.0;
1255 : }
1256 :
1257 4645 : if (vrf.CondenserType == DataHeatBalance::RefrigCondenserType::Evap) {
1258 : // Calculate basin heater power
1259 0 : CalcBasinHeaterPower(state, vrf.BasinHeaterPowerFTempDiff, vrf.basinHeaterSched, vrf.BasinHeaterSetPointTemp, vrf.BasinHeaterPower);
1260 0 : vrf.BasinHeaterPower *= (1.0 - VRFRTF);
1261 :
1262 : // calculate evaporative condenser pump power and water consumption
1263 0 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && CoolingPLR > 0.0) {
1264 : //******************
1265 : // WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
1266 : // H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
1267 : // /RhoWater [kgWater/m3]
1268 : //******************
1269 0 : RhoWater = RhoH2O(OutdoorDryBulb);
1270 0 : vrf.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater * vrf.VRFCondPLR;
1271 0 : vrf.EvapCondPumpElecPower = vrf.EvapCondPumpPower * VRFRTF;
1272 : }
1273 4645 : } else if (vrf.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
1274 :
1275 2 : if (CondCapacity > 0.0) {
1276 2 : state.dataHVACVarRefFlow->CondenserWaterMassFlowRate = CondWaterMassFlow;
1277 : } else {
1278 0 : state.dataHVACVarRefFlow->CondenserWaterMassFlowRate = 0.0;
1279 : }
1280 4 : SetComponentFlowRate(
1281 2 : state, state.dataHVACVarRefFlow->CondenserWaterMassFlowRate, vrf.CondenserNodeNum, vrf.CondenserOutletNodeNum, vrf.SourcePlantLoc);
1282 :
1283 : // should be the same as above just entering this function
1284 : // VRF( VRFCond ).CondenserInletTemp = state.dataLoopNodes->Node(VRF(VRFCond).CondenserNodeNum).Temp;
1285 2 : vrf.WaterCondenserMassFlow = state.dataLoopNodes->Node(vrf.CondenserNodeNum).MassFlowRate;
1286 :
1287 2 : CpCond = state.dataPlnt->PlantLoop(vrf.SourcePlantLoc.loopNum).glycol->getSpecificHeat(state, vrf.CondenserInletTemp, RoutineName);
1288 2 : if (CondWaterMassFlow > 0.0) {
1289 2 : CondOutletTemp = vrf.QCondenser / (CondWaterMassFlow * CpCond) + CondInletTemp;
1290 : } else {
1291 0 : CondOutletTemp = CondInletTemp;
1292 : }
1293 2 : vrf.CondenserSideOutletTemp = CondOutletTemp;
1294 : }
1295 :
1296 : // calculate operating COP
1297 4645 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && CoolingPLR > 0.0) {
1298 2309 : if (vrf.ElecCoolingPower != 0.0) {
1299 : // this calc should use delivered capacity, not condenser capacity, use VRF(VRFCond)%TUCoolingLoad
1300 2308 : vrf.OperatingCoolingCOP =
1301 2308 : (vrf.TotalCoolingCapacity) / (vrf.ElecCoolingPower + vrf.CrankCaseHeaterPower + vrf.EvapCondPumpElecPower + vrf.DefrostPower);
1302 : } else {
1303 1 : vrf.OperatingCoolingCOP = 0.0;
1304 : }
1305 : }
1306 4645 : if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && HeatingPLR > 0.0) {
1307 2336 : if (vrf.ElecHeatingPower != 0.0) {
1308 : // this calc should use delivered capacity, not condenser capacity, use VRF(VRFCond)%TUHeatingLoad
1309 2335 : vrf.OperatingHeatingCOP =
1310 2335 : (vrf.TotalHeatingCapacity) / (vrf.ElecHeatingPower + vrf.CrankCaseHeaterPower + vrf.EvapCondPumpElecPower + vrf.DefrostPower);
1311 : } else {
1312 1 : vrf.OperatingHeatingCOP = 0.0;
1313 : }
1314 : }
1315 :
1316 4645 : TotPower = TUParasiticPower + TUFanPower + vrf.ElecHeatingPower + vrf.ElecCoolingPower + vrf.CrankCaseHeaterPower + vrf.EvapCondPumpElecPower +
1317 4645 : vrf.DefrostPower;
1318 4645 : if (TotPower > 0.0) {
1319 4643 : vrf.OperatingCOP = (vrf.TUCoolingLoad + vrf.TUHeatingLoad) / TotPower;
1320 4643 : vrf.SCHE = vrf.OperatingCOP * 3.412141633; // see StandardRatings::ConvFromSIToIP
1321 : }
1322 :
1323 : // limit the TU capacity when the condenser is maxed out on capacity
1324 : // I think this next line will make the max cap report variable match the coil objects, will probably change the answer though
1325 : // IF(CoolingLoad(VRFCond) .AND. NumTUInCoolingMode .GT. 0 .AND. MaxCoolingCapacity(VRFCond) == MaxCap)THEN
1326 4645 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && NumTUInCoolingMode > 0) {
1327 :
1328 : // IF TU capacity is greater than condenser capacity find maximum allowed TU capacity (i.e., conserve energy)
1329 2309 : if (TUCoolingLoad > TotalTUCoolingCapacity) {
1330 1 : LimitTUCapacity(state,
1331 : VRFCond,
1332 : NumTUInList,
1333 : TotalTUCoolingCapacity,
1334 1 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad,
1335 1 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond),
1336 : TotalTUHeatingCapacity,
1337 1 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad,
1338 1 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
1339 : }
1340 2336 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && NumTUInHeatingMode > 0) {
1341 : // IF TU capacity is greater than condenser capacity
1342 2336 : if (TUHeatingLoad > TotalTUHeatingCapacity) {
1343 0 : LimitTUCapacity(state,
1344 : VRFCond,
1345 : NumTUInList,
1346 : TotalTUHeatingCapacity,
1347 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad,
1348 0 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond),
1349 : TotalTUCoolingCapacity,
1350 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad,
1351 0 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond));
1352 : }
1353 : } else {
1354 : }
1355 : }
1356 :
1357 19 : void GetVRFInput(EnergyPlusData &state)
1358 : {
1359 :
1360 : // SUBROUTINE INFORMATION:
1361 : // AUTHOR Richard Raustad, FSEC
1362 : // DATE WRITTEN August 2015
1363 : // MODIFIED na
1364 : // RE-ENGINEERED na
1365 :
1366 : // PURPOSE OF THIS SUBROUTINE:
1367 : // Manages GetInput processing and program termination
1368 :
1369 : // METHODOLOGY EMPLOYED:
1370 : // Calls "Get" routines to read in data.
1371 :
1372 : // SUBROUTINE PARAMETER DEFINITIONS:
1373 : static constexpr std::string_view RoutineName("GetVRFInput: "); // include trailing blank space
1374 :
1375 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1376 19 : bool ErrorsFound(false); // If errors detected in input
1377 :
1378 19 : GetVRFInputData(state, ErrorsFound);
1379 :
1380 19 : if (ErrorsFound) {
1381 0 : ShowFatalError(
1382 : state,
1383 0 : format("{}Errors found in getting AirConditioner:VariableRefrigerantFlow system input. Preceding condition(s) causes termination.",
1384 : RoutineName));
1385 : }
1386 19 : }
1387 :
1388 23 : void GetVRFInputData(EnergyPlusData &state, bool &ErrorsFound)
1389 : {
1390 :
1391 : // SUBROUTINE INFORMATION:
1392 : // AUTHOR Richard Raustad, FSEC
1393 : // DATE WRITTEN August 2010
1394 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
1395 : // RE-ENGINEERED na
1396 :
1397 : // PURPOSE OF THIS SUBROUTINE:
1398 : // Obtains input data for VRF systems and stores it in data structures
1399 :
1400 : using namespace DataLoopNode;
1401 : using BranchNodeConnections::SetUpCompSets;
1402 : using BranchNodeConnections::TestCompSet;
1403 : using Curve::checkCurveIsNormalizedToOne;
1404 : using Curve::CurveValue;
1405 : using Curve::GetCurveIndex;
1406 : using DXCoils::GetDXCoilIndex;
1407 :
1408 : using DataSizing::AutoSize;
1409 : using DXCoils::GetCoilCondenserInletNode;
1410 : using DXCoils::GetCoilTypeNum;
1411 : using DXCoils::GetDXCoilCapFTCurveIndex;
1412 : using DXCoils::GetDXCoilName;
1413 : using DXCoils::RatedInletAirTempHeat;
1414 : using DXCoils::RatedInletWetBulbTemp;
1415 : using DXCoils::RatedOutdoorAirTemp;
1416 : using DXCoils::RatedOutdoorAirTempHeat;
1417 : using DXCoils::RatedOutdoorWetBulbTempHeat;
1418 : using DXCoils::SetDXCoolingCoilData;
1419 : using MixedAir::GetOAMixerNodeNumbers;
1420 : using NodeInputManager::GetOnlySingleNode;
1421 : using OutAirNodeManager::CheckOutAirNodeNumber;
1422 : using SingleDuct::GetATMixer;
1423 : using WaterManager::SetupTankDemandComponent;
1424 : using WaterManager::SetupTankSupplyComponent;
1425 :
1426 : static constexpr std::string_view RoutineName("GetVRFInput: "); // include trailing blank space
1427 : static constexpr std::string_view routineName = "GetVRFInput";
1428 :
1429 23 : std::string cCurrentModuleObject;
1430 :
1431 23 : Array1D_int OANodeNums(4); // Node numbers of OA mixer (OA, EA, RA, MA)
1432 :
1433 : // InputProcessor routines
1434 23 : int NumParams = 0; // Number of arguments
1435 23 : int NumAlphas = 0; // Number of alpha arguments
1436 23 : int NumNums = 0; // Number of real arguments
1437 : int IOStat; // Status
1438 : bool errFlag; // error flag for mining functions
1439 : bool IsNotOK; // Flag to verify name
1440 :
1441 : // Compute for allocation
1442 23 : int MaxAlphas = 0;
1443 23 : int MaxNumbers = 0;
1444 :
1445 : {
1446 : // Terminal Units
1447 :
1448 : // The number of VRF constant volume TUs (anticipating different types of TU's)
1449 23 : int NumVRFCTU = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:TerminalUnit:VariableRefrigerantFlow");
1450 23 : if (NumVRFCTU > 0) {
1451 23 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1452 : state, "ZoneHVAC:TerminalUnit:VariableRefrigerantFlow", NumParams, NumAlphas, NumNums);
1453 23 : MaxAlphas = max(MaxAlphas, NumAlphas);
1454 23 : MaxNumbers = max(MaxNumbers, NumNums);
1455 : }
1456 :
1457 23 : state.dataHVACVarRefFlow->NumVRFTU = NumVRFCTU;
1458 23 : if (state.dataHVACVarRefFlow->NumVRFTU > 0) {
1459 23 : state.dataHVACVarRefFlow->VRFTU.allocate(state.dataHVACVarRefFlow->NumVRFTU);
1460 23 : state.dataHVACVarRefFlow->CheckEquipName.dimension(state.dataHVACVarRefFlow->NumVRFTU, true);
1461 23 : state.dataHVACVarRefFlow->VRFTUNumericFields.allocate(state.dataHVACVarRefFlow->NumVRFTU);
1462 : }
1463 : }
1464 :
1465 : {
1466 : // VRF AirConditioners
1467 :
1468 46 : state.dataHVACVarRefFlow->NumVRFCond_SysCurve =
1469 23 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirConditioner:VariableRefrigerantFlow");
1470 23 : if (state.dataHVACVarRefFlow->NumVRFCond_SysCurve > 0) {
1471 16 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1472 : state, "AirConditioner:VariableRefrigerantFlow", NumParams, NumAlphas, NumNums);
1473 16 : MaxAlphas = max(MaxAlphas, NumAlphas);
1474 16 : MaxNumbers = max(MaxNumbers, NumNums);
1475 : }
1476 :
1477 46 : state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HP =
1478 23 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl");
1479 23 : if (state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HP > 0) {
1480 6 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1481 : state, "AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl", NumParams, NumAlphas, NumNums);
1482 6 : MaxAlphas = max(MaxAlphas, NumAlphas);
1483 6 : MaxNumbers = max(MaxNumbers, NumNums);
1484 : }
1485 :
1486 46 : state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HR =
1487 23 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl:HR");
1488 23 : if (state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HR > 0) {
1489 3 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1490 : state, "AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl:HR", NumParams, NumAlphas, NumNums);
1491 3 : MaxAlphas = max(MaxAlphas, NumAlphas);
1492 3 : MaxNumbers = max(MaxNumbers, NumNums);
1493 : }
1494 :
1495 23 : state.dataHVACVarRefFlow->NumVRFCond = state.dataHVACVarRefFlow->NumVRFCond_SysCurve + state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HP +
1496 23 : state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HR;
1497 :
1498 23 : if (state.dataHVACVarRefFlow->NumVRFCond > 0) {
1499 23 : state.dataHVACVarRefFlow->VRF.allocate(state.dataHVACVarRefFlow->NumVRFCond);
1500 23 : state.dataHVACVarRefFlow->VrfUniqueNames.reserve(static_cast<unsigned>(state.dataHVACVarRefFlow->NumVRFCond));
1501 23 : state.dataHVACVarRefFlow->MaxCoolingCapacity.allocate(state.dataHVACVarRefFlow->NumVRFCond);
1502 23 : state.dataHVACVarRefFlow->MaxHeatingCapacity.allocate(state.dataHVACVarRefFlow->NumVRFCond);
1503 23 : state.dataHVACVarRefFlow->CoolCombinationRatio.allocate(state.dataHVACVarRefFlow->NumVRFCond);
1504 23 : state.dataHVACVarRefFlow->HeatCombinationRatio.allocate(state.dataHVACVarRefFlow->NumVRFCond);
1505 23 : state.dataHVACVarRefFlow->MaxCoolingCapacity = Constant::MaxCap;
1506 23 : state.dataHVACVarRefFlow->MaxHeatingCapacity = Constant::MaxCap;
1507 23 : state.dataHVACVarRefFlow->CoolCombinationRatio = 1.0;
1508 23 : state.dataHVACVarRefFlow->HeatCombinationRatio = 1.0;
1509 : }
1510 : }
1511 :
1512 : {
1513 : // ZoneTerminalUnitList
1514 :
1515 23 : state.dataHVACVarRefFlow->NumVRFTULists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneTerminalUnitList");
1516 23 : if (state.dataHVACVarRefFlow->NumVRFTULists > 0) {
1517 23 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "ZoneTerminalUnitList", NumParams, NumAlphas, NumNums);
1518 23 : MaxAlphas = max(MaxAlphas, NumAlphas);
1519 23 : MaxNumbers = max(MaxNumbers, NumNums);
1520 :
1521 23 : state.dataHVACVarRefFlow->TerminalUnitList.allocate(state.dataHVACVarRefFlow->NumVRFTULists);
1522 : }
1523 : }
1524 :
1525 23 : Array1D_string cAlphaFieldNames;
1526 23 : cAlphaFieldNames.allocate(MaxAlphas);
1527 23 : Array1D_string cAlphaArgs;
1528 23 : cAlphaArgs.allocate(MaxAlphas);
1529 23 : Array1D_bool lAlphaFieldBlanks;
1530 23 : lAlphaFieldBlanks.dimension(MaxAlphas, false);
1531 :
1532 23 : Array1D_string cNumericFieldNames;
1533 23 : cNumericFieldNames.allocate(MaxNumbers);
1534 23 : Array1D<Real64> rNumericArgs;
1535 23 : rNumericArgs.dimension(MaxNumbers, 0.0);
1536 23 : Array1D_bool lNumericFieldBlanks;
1537 23 : lNumericFieldBlanks.dimension(MaxNumbers, false);
1538 :
1539 : // read all terminal unit list objects
1540 23 : cCurrentModuleObject = "ZoneTerminalUnitList";
1541 50 : for (int TUListNum = 1; TUListNum <= state.dataHVACVarRefFlow->NumVRFTULists; ++TUListNum) {
1542 27 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1543 : cCurrentModuleObject,
1544 : TUListNum,
1545 : cAlphaArgs,
1546 : NumAlphas,
1547 : rNumericArgs,
1548 : NumNums,
1549 : IOStat,
1550 : lNumericFieldBlanks,
1551 : lAlphaFieldBlanks,
1552 : cAlphaFieldNames,
1553 : cNumericFieldNames);
1554 27 : Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
1555 :
1556 27 : auto &thisTUList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum);
1557 27 : thisTUList.Name = cAlphaArgs(1);
1558 27 : thisTUList.NumTUInList = NumAlphas - 1;
1559 27 : thisTUList.ZoneTUPtr.allocate(thisTUList.NumTUInList);
1560 27 : thisTUList.ZoneTUName.allocate(thisTUList.NumTUInList);
1561 27 : thisTUList.IsSimulated.allocate(thisTUList.NumTUInList);
1562 27 : thisTUList.TotalCoolLoad.allocate(thisTUList.NumTUInList);
1563 27 : thisTUList.TotalHeatLoad.allocate(thisTUList.NumTUInList);
1564 27 : thisTUList.CoolingCoilPresent.allocate(thisTUList.NumTUInList);
1565 27 : thisTUList.HeatingCoilPresent.allocate(thisTUList.NumTUInList);
1566 27 : thisTUList.TerminalUnitNotSizedYet.allocate(thisTUList.NumTUInList);
1567 27 : thisTUList.HRHeatRequest.allocate(thisTUList.NumTUInList);
1568 27 : thisTUList.HRCoolRequest.allocate(thisTUList.NumTUInList);
1569 27 : thisTUList.CoolingCoilAvailable.allocate(thisTUList.NumTUInList);
1570 27 : thisTUList.HeatingCoilAvailable.allocate(thisTUList.NumTUInList);
1571 27 : thisTUList.coolingCoilAvailScheds.allocate(thisTUList.NumTUInList);
1572 27 : thisTUList.heatingCoilAvailScheds.allocate(thisTUList.NumTUInList);
1573 27 : thisTUList.ZoneTUPtr = 0;
1574 27 : thisTUList.IsSimulated = false;
1575 27 : thisTUList.TotalCoolLoad = 0.0;
1576 27 : thisTUList.TotalHeatLoad = 0.0;
1577 27 : thisTUList.CoolingCoilPresent = true;
1578 27 : thisTUList.HeatingCoilPresent = true;
1579 27 : thisTUList.TerminalUnitNotSizedYet = true;
1580 27 : thisTUList.HRHeatRequest = false;
1581 27 : thisTUList.HRCoolRequest = false;
1582 27 : thisTUList.CoolingCoilAvailable = false;
1583 27 : thisTUList.HeatingCoilAvailable = false;
1584 27 : thisTUList.coolingCoilAvailScheds = nullptr;
1585 27 : thisTUList.heatingCoilAvailScheds = nullptr;
1586 :
1587 61 : for (int TUNum = 1; TUNum <= thisTUList.NumTUInList; ++TUNum) {
1588 34 : thisTUList.ZoneTUName(TUNum) = cAlphaArgs(TUNum + 1);
1589 : }
1590 : }
1591 :
1592 34 : auto checkCurveMinMaxOutput = [&state](int CurveIndex) -> std::array<Real64, 4> {
1593 34 : Real64 MinCurveVal = 999.0;
1594 34 : Real64 MaxCurveVal = -999.0;
1595 34 : Real64 MinCurvePLR = 0.0;
1596 34 : Real64 MaxCurvePLR = 1.0;
1597 :
1598 3468 : for (int i = 0; i <= 100; ++i) { // 0 to 1.0 with 0.01 increment
1599 3434 : const Real64 CurveInput = i / 100.0;
1600 3434 : Real64 CurveVal = CurveValue(state, CurveIndex, CurveInput);
1601 3434 : if (CurveVal < MinCurveVal) {
1602 34 : MinCurveVal = CurveVal;
1603 34 : MinCurvePLR = CurveInput;
1604 : }
1605 3434 : if (CurveVal > MaxCurveVal) {
1606 3434 : MaxCurveVal = CurveVal;
1607 3434 : MaxCurvePLR = CurveInput;
1608 : }
1609 : }
1610 34 : return {MinCurvePLR, MinCurveVal, MaxCurvePLR, MaxCurveVal};
1611 23 : };
1612 :
1613 : // read all VRF condenser objects: Algorithm Type 1_system curve based model
1614 23 : cCurrentModuleObject = "AirConditioner:VariableRefrigerantFlow";
1615 41 : for (int VRFNum = 1; VRFNum <= state.dataHVACVarRefFlow->NumVRFCond_SysCurve; ++VRFNum) {
1616 18 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1617 : cCurrentModuleObject,
1618 : VRFNum,
1619 : cAlphaArgs,
1620 : NumAlphas,
1621 : rNumericArgs,
1622 : NumNums,
1623 : IOStat,
1624 : lNumericFieldBlanks,
1625 : lAlphaFieldBlanks,
1626 : cAlphaFieldNames,
1627 : cNumericFieldNames);
1628 :
1629 18 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
1630 18 : GlobalNames::VerifyUniqueInterObjectName(
1631 36 : state, state.dataHVACVarRefFlow->VrfUniqueNames, cAlphaArgs(1), cCurrentModuleObject, cAlphaFieldNames(1), ErrorsFound);
1632 :
1633 18 : auto &thisVrfSys = state.dataHVACVarRefFlow->VRF(VRFNum);
1634 18 : thisVrfSys.Name = cAlphaArgs(1);
1635 18 : thisVrfSys.VRFSystemTypeNum = VRF_HeatPump;
1636 18 : thisVrfSys.VRFAlgorithmType = AlgorithmType::SysCurve;
1637 :
1638 18 : if (lAlphaFieldBlanks(2)) {
1639 5 : thisVrfSys.availSched = Sched::GetScheduleAlwaysOn(state);
1640 13 : } else if ((thisVrfSys.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
1641 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
1642 0 : ErrorsFound = true;
1643 : }
1644 :
1645 18 : thisVrfSys.CoolingCapacity = rNumericArgs(1);
1646 18 : thisVrfSys.CoolingCOP = rNumericArgs(2);
1647 18 : thisVrfSys.MinOATCooling = rNumericArgs(3);
1648 18 : thisVrfSys.MaxOATCooling = rNumericArgs(4);
1649 :
1650 18 : thisVrfSys.CoolCapFT = GetCurveIndex(state, cAlphaArgs(3));
1651 18 : if (thisVrfSys.CoolCapFT > 0) {
1652 : // Verify Curve Object, only legal type is biquadratic
1653 36 : ErrorsFound |= Curve::CheckCurveDims(state,
1654 : thisVrfSys.CoolCapFT, // Curve index
1655 : {2}, // Valid dimensions
1656 : RoutineName, // Routine name
1657 : cCurrentModuleObject, // Object Type
1658 : thisVrfSys.Name, // Object Name
1659 18 : cAlphaFieldNames(3)); // Field Name
1660 :
1661 18 : if (!ErrorsFound) {
1662 18 : checkCurveIsNormalizedToOne(state,
1663 54 : std::string{RoutineName} + cCurrentModuleObject,
1664 18 : thisVrfSys.Name,
1665 : thisVrfSys.CoolCapFT,
1666 18 : cAlphaFieldNames(3),
1667 18 : cAlphaArgs(3),
1668 : RatedInletWetBulbTemp,
1669 : RatedOutdoorAirTemp);
1670 : }
1671 : }
1672 :
1673 18 : thisVrfSys.CoolBoundaryCurvePtr = GetCurveIndex(state, cAlphaArgs(4));
1674 18 : if (thisVrfSys.CoolBoundaryCurvePtr > 0) {
1675 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1676 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1677 : thisVrfSys.CoolBoundaryCurvePtr, // Curve index
1678 : {1}, // Valid dimensions
1679 : RoutineName, // Routine name
1680 : cCurrentModuleObject, // Object Type
1681 : thisVrfSys.Name, // Object Name
1682 17 : cAlphaFieldNames(4)); // Field Name
1683 : }
1684 :
1685 18 : thisVrfSys.CoolCapFTHi = GetCurveIndex(state, cAlphaArgs(5));
1686 18 : if (thisVrfSys.CoolCapFTHi > 0) {
1687 : // Verify Curve Object, only legal type is biquadratic
1688 54 : ErrorsFound |= Curve::CheckCurveDims(state,
1689 : thisVrfSys.CoolCapFTHi, // Curve index
1690 : {2}, // Valid dimensions
1691 : RoutineName, // Routine name
1692 : cCurrentModuleObject, // Object Type
1693 : thisVrfSys.Name, // Object Name
1694 18 : cAlphaFieldNames(5)); // Field Name
1695 : }
1696 :
1697 18 : thisVrfSys.CoolEIRFT = GetCurveIndex(state, cAlphaArgs(6));
1698 18 : if (thisVrfSys.CoolEIRFT > 0) {
1699 : // Verify Curve Object, only legal type is biquadratic
1700 54 : ErrorsFound |= Curve::CheckCurveDims(state,
1701 : thisVrfSys.CoolEIRFT, // Curve index
1702 : {2}, // Valid dimensions
1703 : RoutineName, // Routine name
1704 : cCurrentModuleObject, // Object Type
1705 : thisVrfSys.Name, // Object Name
1706 18 : cAlphaFieldNames(6)); // Field Name
1707 : }
1708 :
1709 18 : thisVrfSys.EIRCoolBoundaryCurvePtr = GetCurveIndex(state, cAlphaArgs(7));
1710 18 : if (thisVrfSys.EIRCoolBoundaryCurvePtr > 0) {
1711 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1712 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1713 : thisVrfSys.EIRCoolBoundaryCurvePtr, // Curve index
1714 : {1}, // Valid dimensions
1715 : RoutineName, // Routine name
1716 : cCurrentModuleObject, // Object Type
1717 : thisVrfSys.Name, // Object Name
1718 17 : cAlphaFieldNames(7)); // Field Name
1719 : }
1720 :
1721 18 : thisVrfSys.CoolEIRFTHi = GetCurveIndex(state, cAlphaArgs(8));
1722 18 : if (thisVrfSys.CoolEIRFTHi > 0) {
1723 : // Verify Curve Object, only legal type is biquadratic
1724 54 : ErrorsFound |= Curve::CheckCurveDims(state,
1725 : thisVrfSys.CoolEIRFTHi, // Curve index
1726 : {2}, // Valid dimensions
1727 : RoutineName, // Routine name
1728 : cCurrentModuleObject, // Object Type
1729 : thisVrfSys.Name, // Object Name
1730 18 : cAlphaFieldNames(8)); // Field Name
1731 : }
1732 :
1733 18 : thisVrfSys.CoolEIRFPLR1 = GetCurveIndex(state, cAlphaArgs(9));
1734 18 : if (thisVrfSys.CoolEIRFPLR1 > 0) {
1735 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1736 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1737 : thisVrfSys.CoolEIRFPLR1, // Curve index
1738 : {1}, // Valid dimensions
1739 : RoutineName, // Routine name
1740 : cCurrentModuleObject, // Object Type
1741 : thisVrfSys.Name, // Object Name
1742 17 : cAlphaFieldNames(9)); // Field Name
1743 : }
1744 :
1745 18 : thisVrfSys.CoolEIRFPLR2 = GetCurveIndex(state, cAlphaArgs(10));
1746 18 : if (thisVrfSys.CoolEIRFPLR2 > 0) {
1747 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1748 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1749 : thisVrfSys.CoolEIRFPLR2, // Curve index
1750 : {1}, // Valid dimensions
1751 : RoutineName, // Routine name
1752 : cCurrentModuleObject, // Object Type
1753 : thisVrfSys.Name, // Object Name
1754 17 : cAlphaFieldNames(10)); // Field Name
1755 : }
1756 :
1757 18 : thisVrfSys.CoolCombRatioPTR = GetCurveIndex(state, cAlphaArgs(11));
1758 18 : if (thisVrfSys.CoolCombRatioPTR > 0) {
1759 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1760 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1761 : thisVrfSys.CoolCombRatioPTR, // Curve index
1762 : {1}, // Valid dimensions
1763 : RoutineName, // Routine name
1764 : cCurrentModuleObject, // Object Type
1765 : thisVrfSys.Name, // Object Name
1766 17 : cAlphaFieldNames(11)); // Field Name
1767 : }
1768 :
1769 18 : thisVrfSys.CoolPLFFPLR = GetCurveIndex(state, cAlphaArgs(12));
1770 18 : if (thisVrfSys.CoolPLFFPLR > 0) {
1771 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1772 34 : ErrorsFound |= Curve::CheckCurveDims(state,
1773 : thisVrfSys.CoolPLFFPLR, // Curve index
1774 : {1}, // Valid dimensions
1775 : RoutineName, // Routine name
1776 : cCurrentModuleObject, // Object Type
1777 : thisVrfSys.Name, // Object Name
1778 17 : cAlphaFieldNames(12)); // Field Name
1779 17 : if (!ErrorsFound) {
1780 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
1781 17 : auto [MinCurvePLR, MinCurveVal, MaxCurvePLR, MaxCurveVal] = checkCurveMinMaxOutput(thisVrfSys.CoolPLFFPLR);
1782 :
1783 17 : if (MinCurveVal < 0.7) {
1784 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
1785 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFieldNames(12), cAlphaArgs(12)));
1786 0 : ShowContinueError(state,
1787 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
1788 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
1789 0 : Curve::SetCurveOutputMinValue(state, thisVrfSys.CoolPLFFPLR, ErrorsFound, 0.7);
1790 : }
1791 :
1792 17 : if (MaxCurveVal > 1.0) {
1793 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
1794 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFieldNames(12), cAlphaArgs(12)));
1795 0 : ShowContinueError(state,
1796 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
1797 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
1798 0 : Curve::SetCurveOutputMaxValue(state, thisVrfSys.CoolPLFFPLR, ErrorsFound, 1.0);
1799 : }
1800 : }
1801 : }
1802 :
1803 18 : thisVrfSys.HeatingCapacity = rNumericArgs(5);
1804 18 : thisVrfSys.HeatingCapacitySizeRatio = rNumericArgs(6);
1805 18 : if (!lNumericFieldBlanks(6) && thisVrfSys.HeatingCapacity == AutoSize) {
1806 5 : thisVrfSys.LockHeatingCapacity = true;
1807 : }
1808 18 : thisVrfSys.HeatingCOP = rNumericArgs(7);
1809 18 : thisVrfSys.MinOATHeating = rNumericArgs(8);
1810 18 : thisVrfSys.MaxOATHeating = rNumericArgs(9);
1811 18 : if (thisVrfSys.MinOATHeating >= thisVrfSys.MaxOATHeating) {
1812 0 : ShowSevereError(state, format("{}, \"{}\"", cCurrentModuleObject, thisVrfSys.Name));
1813 0 : ShowContinueError(state,
1814 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
1815 : cNumericFieldNames(8),
1816 0 : thisVrfSys.MinOATHeating,
1817 0 : thisVrfSys.MaxOATHeating));
1818 0 : ErrorsFound = true;
1819 : }
1820 :
1821 18 : thisVrfSys.HeatCapFT = GetCurveIndex(state, cAlphaArgs(13));
1822 18 : if (thisVrfSys.HeatCapFT > 0) {
1823 : // Verify Curve Object, only legal type is biquadratic
1824 36 : ErrorsFound |= Curve::CheckCurveDims(state,
1825 : thisVrfSys.HeatCapFT, // Curve index
1826 : {2}, // Valid dimensions
1827 : RoutineName, // Routine name
1828 : cCurrentModuleObject, // Object Type
1829 : thisVrfSys.Name, // Object Name
1830 18 : cAlphaFieldNames(13)); // Field Name
1831 :
1832 18 : if (!ErrorsFound) {
1833 18 : if (Util::SameString(cAlphaArgs(19), "WETBULBTEMPERATURE")) {
1834 18 : checkCurveIsNormalizedToOne(state,
1835 54 : std::string{RoutineName} + cCurrentModuleObject,
1836 18 : thisVrfSys.Name,
1837 : thisVrfSys.HeatCapFT,
1838 18 : cAlphaFieldNames(13),
1839 18 : cAlphaArgs(13),
1840 : RatedInletAirTempHeat,
1841 : RatedOutdoorWetBulbTempHeat);
1842 0 : } else if (Util::SameString(cAlphaArgs(19), "DRYBULBTEMPERATURE")) {
1843 0 : checkCurveIsNormalizedToOne(state,
1844 0 : std::string{RoutineName} + cCurrentModuleObject,
1845 0 : thisVrfSys.Name,
1846 : thisVrfSys.HeatCapFT,
1847 0 : cAlphaFieldNames(13),
1848 0 : cAlphaArgs(13),
1849 : RatedInletAirTempHeat,
1850 : RatedOutdoorAirTempHeat);
1851 : }
1852 : }
1853 : }
1854 :
1855 18 : thisVrfSys.HeatBoundaryCurvePtr = GetCurveIndex(state, cAlphaArgs(14));
1856 18 : if (thisVrfSys.HeatBoundaryCurvePtr > 0) {
1857 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1858 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1859 : thisVrfSys.HeatBoundaryCurvePtr, // Curve index
1860 : {1}, // Valid dimensions
1861 : RoutineName, // Routine name
1862 : cCurrentModuleObject, // Object Type
1863 : thisVrfSys.Name, // Object Name
1864 17 : cAlphaFieldNames(14)); // Field Name
1865 : }
1866 :
1867 18 : thisVrfSys.HeatCapFTHi = GetCurveIndex(state, cAlphaArgs(15));
1868 18 : if (thisVrfSys.HeatCapFTHi > 0) {
1869 : // Verify Curve Object, only legal type is biquadratic
1870 54 : ErrorsFound |= Curve::CheckCurveDims(state,
1871 : thisVrfSys.HeatCapFTHi, // Curve index
1872 : {2}, // Valid dimensions
1873 : RoutineName, // Routine name
1874 : cCurrentModuleObject, // Object Type
1875 : thisVrfSys.Name, // Object Name
1876 18 : cAlphaFieldNames(15)); // Field Name
1877 : }
1878 :
1879 18 : thisVrfSys.HeatEIRFT = GetCurveIndex(state, cAlphaArgs(16));
1880 18 : if (thisVrfSys.HeatEIRFT > 0) {
1881 : // Verify Curve Object, only legal type is biquadratic
1882 54 : ErrorsFound |= Curve::CheckCurveDims(state,
1883 : thisVrfSys.HeatEIRFT, // Curve index
1884 : {2}, // Valid dimensions
1885 : RoutineName, // Routine name
1886 : cCurrentModuleObject, // Object Type
1887 : thisVrfSys.Name, // Object Name
1888 18 : cAlphaFieldNames(16)); // Field Name
1889 : }
1890 :
1891 18 : thisVrfSys.EIRHeatBoundaryCurvePtr = GetCurveIndex(state, cAlphaArgs(17));
1892 18 : if (thisVrfSys.EIRHeatBoundaryCurvePtr > 0) {
1893 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1894 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1895 : thisVrfSys.EIRHeatBoundaryCurvePtr, // Curve index
1896 : {1}, // Valid dimensions
1897 : RoutineName, // Routine name
1898 : cCurrentModuleObject, // Object Type
1899 : thisVrfSys.Name, // Object Name
1900 17 : cAlphaFieldNames(17)); // Field Name
1901 : }
1902 :
1903 18 : thisVrfSys.HeatEIRFTHi = GetCurveIndex(state, cAlphaArgs(18));
1904 18 : if (thisVrfSys.HeatEIRFTHi > 0) {
1905 : // Verify Curve Object, only legal type is biquadratic
1906 54 : ErrorsFound |= Curve::CheckCurveDims(state,
1907 : thisVrfSys.HeatEIRFTHi, // Curve index
1908 : {2}, // Valid dimensions
1909 : RoutineName, // Routine name
1910 : cCurrentModuleObject, // Object Type
1911 : thisVrfSys.Name, // Object Name
1912 18 : cAlphaFieldNames(18)); // Field Name
1913 : }
1914 :
1915 18 : if (Util::SameString(cAlphaArgs(19), "WETBULBTEMPERATURE")) {
1916 18 : thisVrfSys.HeatingPerformanceOATType = HVAC::OATType::WetBulb;
1917 0 : } else if (Util::SameString(cAlphaArgs(19), "DRYBULBTEMPERATURE")) {
1918 0 : thisVrfSys.HeatingPerformanceOATType = HVAC::OATType::DryBulb;
1919 : } else {
1920 0 : ShowSevereError(
1921 : state,
1922 0 : format(
1923 0 : "{}, \"{}\" illegal {} input for this object = {}", cCurrentModuleObject, thisVrfSys.Name, cAlphaFieldNames(19), cAlphaArgs(19)));
1924 0 : ShowContinueError(state, "... input must be WETBULBTEMPERATURE or DRYBULBTEMPERATURE.");
1925 0 : ErrorsFound = true;
1926 : }
1927 :
1928 18 : thisVrfSys.HeatEIRFPLR1 = GetCurveIndex(state, cAlphaArgs(20));
1929 18 : if (thisVrfSys.HeatEIRFPLR1 > 0) {
1930 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1931 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1932 : thisVrfSys.HeatEIRFPLR1, // Curve index
1933 : {1}, // Valid dimensions
1934 : RoutineName, // Routine name
1935 : cCurrentModuleObject, // Object Type
1936 : thisVrfSys.Name, // Object Name
1937 17 : cAlphaFieldNames(20)); // Field Name
1938 : }
1939 :
1940 18 : thisVrfSys.HeatEIRFPLR2 = GetCurveIndex(state, cAlphaArgs(21));
1941 18 : if (thisVrfSys.HeatEIRFPLR2 > 0) {
1942 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1943 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1944 : thisVrfSys.HeatEIRFPLR2, // Curve index
1945 : {1}, // Valid dimensions
1946 : RoutineName, // Routine name
1947 : cCurrentModuleObject, // Object Type
1948 : thisVrfSys.Name, // Object Name
1949 17 : cAlphaFieldNames(21)); // Field Name
1950 : }
1951 :
1952 18 : thisVrfSys.HeatCombRatioPTR = GetCurveIndex(state, cAlphaArgs(22));
1953 18 : if (thisVrfSys.HeatCombRatioPTR > 0) {
1954 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1955 51 : ErrorsFound |= Curve::CheckCurveDims(state,
1956 : thisVrfSys.HeatCombRatioPTR, // Curve index
1957 : {1}, // Valid dimensions
1958 : RoutineName, // Routine name
1959 : cCurrentModuleObject, // Object Type
1960 : thisVrfSys.Name, // Object Name
1961 17 : cAlphaFieldNames(22)); // Field Name
1962 : }
1963 18 : thisVrfSys.HeatPLFFPLR = GetCurveIndex(state, cAlphaArgs(23));
1964 18 : if (thisVrfSys.HeatPLFFPLR > 0) {
1965 : // Verify Curve Object, only legal type is linear, quadratic, or cubic
1966 34 : ErrorsFound |= Curve::CheckCurveDims(state,
1967 : thisVrfSys.HeatPLFFPLR, // Curve index
1968 : {1}, // Valid dimensions
1969 : RoutineName, // Routine name
1970 : cCurrentModuleObject, // Object Type
1971 : thisVrfSys.Name, // Object Name
1972 17 : cAlphaFieldNames(23)); // Field Name
1973 :
1974 17 : if (!ErrorsFound) {
1975 17 : auto [MinCurvePLR, MinCurveVal, MaxCurvePLR, MaxCurveVal] = checkCurveMinMaxOutput(thisVrfSys.HeatPLFFPLR);
1976 :
1977 17 : if (MinCurveVal < 0.7) {
1978 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
1979 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFieldNames(23), cAlphaArgs(23)));
1980 0 : ShowContinueError(state,
1981 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
1982 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
1983 0 : Curve::SetCurveOutputMinValue(state, thisVrfSys.HeatPLFFPLR, ErrorsFound, 0.7);
1984 : }
1985 :
1986 17 : if (MaxCurveVal > 1.0) {
1987 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
1988 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFieldNames(23), cAlphaArgs(23)));
1989 0 : ShowContinueError(state,
1990 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
1991 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
1992 0 : Curve::SetCurveOutputMaxValue(state, thisVrfSys.HeatPLFFPLR, ErrorsFound, 1.0);
1993 : }
1994 : }
1995 : }
1996 :
1997 18 : thisVrfSys.MinPLR = rNumericArgs(10);
1998 18 : Real64 minEIRfLowPLRXInput = 0.0;
1999 18 : Real64 maxEIRfLowPLRXInput = 0.0;
2000 :
2001 18 : if (thisVrfSys.CoolEIRFPLR1 > 0) {
2002 17 : Curve::GetCurveMinMaxValues(state, thisVrfSys.CoolEIRFPLR1, minEIRfLowPLRXInput, maxEIRfLowPLRXInput);
2003 17 : if (minEIRfLowPLRXInput > thisVrfSys.MinPLR) {
2004 1 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
2005 1 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFieldNames(9), cAlphaArgs(9)));
2006 2 : ShowContinueError(state,
2007 2 : format("...Curve minimum value of X = {:.3T} must be <= Minimum Heat Pump Part-Load Ratio = {:.3T}.",
2008 : minEIRfLowPLRXInput,
2009 1 : thisVrfSys.MinPLR));
2010 1 : ErrorsFound = true;
2011 : }
2012 17 : if (maxEIRfLowPLRXInput < 1.0) {
2013 0 : ShowWarningError(state, format("{}{}=\"{}\", suspicious", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
2014 0 : ShowContinueError(state, format("...{} = {} has unexpected value.", cAlphaFieldNames(9), cAlphaArgs(9)));
2015 0 : ShowContinueError(state,
2016 0 : format("...Curve maximum value of X = {:.3T} should be 1 and will result in lower energy use than expected.",
2017 : maxEIRfLowPLRXInput));
2018 : }
2019 17 : minEIRfLowPLRXInput = 0.0;
2020 17 : maxEIRfLowPLRXInput = 0.0;
2021 : }
2022 18 : if (thisVrfSys.HeatEIRFPLR1 > 0) {
2023 17 : Curve::GetCurveMinMaxValues(state, thisVrfSys.HeatEIRFPLR1, minEIRfLowPLRXInput, maxEIRfLowPLRXInput);
2024 17 : if (minEIRfLowPLRXInput > thisVrfSys.MinPLR) {
2025 1 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
2026 1 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFieldNames(20), cAlphaArgs(20)));
2027 2 : ShowContinueError(state,
2028 2 : format("...Curve minimum value of X = {:.3T} must be <= Minimum Heat Pump Part-Load Ratio = {:.3T}.",
2029 : minEIRfLowPLRXInput,
2030 1 : thisVrfSys.MinPLR));
2031 1 : ErrorsFound = true;
2032 : }
2033 17 : if (maxEIRfLowPLRXInput < 1.0) {
2034 0 : ShowWarningError(state, format("{}{}=\"{}\", suspicious", RoutineName, cCurrentModuleObject, thisVrfSys.Name));
2035 0 : ShowContinueError(state, format("...{} = {} has unexpected value.", cAlphaFieldNames(20), cAlphaArgs(20)));
2036 0 : ShowContinueError(state,
2037 0 : format("...Curve maximum value of X = {:.3T} should be 1 and will result in lower energy use than expected.",
2038 : maxEIRfLowPLRXInput));
2039 : }
2040 : }
2041 :
2042 18 : thisVrfSys.MasterZonePtr = Util::FindItemInList(cAlphaArgs(24), state.dataHeatBal->Zone);
2043 :
2044 18 : thisVrfSys.ThermostatPriority = static_cast<ThermostatCtrlType>(getEnumValue(ThermostatCtrlTypeUC, cAlphaArgs(25)));
2045 :
2046 18 : if (thisVrfSys.ThermostatPriority == ThermostatCtrlType::MasterThermostatPriority) {
2047 0 : if (thisVrfSys.MasterZonePtr == 0) {
2048 0 : ShowSevereError(state, format("{} = \"{}\"", cCurrentModuleObject, thisVrfSys.Name));
2049 0 : ShowContinueError(state, format("{} must be entered when {} = {}", cAlphaFieldNames(24), cAlphaFieldNames(25), cAlphaArgs(25)));
2050 0 : ErrorsFound = true;
2051 : }
2052 18 : } else if (thisVrfSys.ThermostatPriority == ThermostatCtrlType::Invalid) {
2053 0 : ShowSevereError(state, format("{} = \"{}\"", cCurrentModuleObject, thisVrfSys.Name));
2054 0 : ShowContinueError(state, format("Illegal {} = {}", cAlphaFieldNames(25), cAlphaArgs(25)));
2055 0 : ErrorsFound = true;
2056 : }
2057 :
2058 18 : if (thisVrfSys.ThermostatPriority == ThermostatCtrlType::ScheduledPriority) {
2059 0 : if (lAlphaFieldBlanks(26)) {
2060 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(26), cAlphaFieldNames(25), cAlphaArgs(25));
2061 0 : } else if ((thisVrfSys.prioritySched = Sched::GetSchedule(state, cAlphaArgs(26))) == nullptr) {
2062 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(26), cAlphaArgs(26));
2063 0 : ErrorsFound = true;
2064 : }
2065 : }
2066 :
2067 18 : thisVrfSys.ZoneTUListPtr = Util::FindItemInList(cAlphaArgs(27), state.dataHVACVarRefFlow->TerminalUnitList);
2068 18 : if (thisVrfSys.ZoneTUListPtr == 0) {
2069 0 : ShowSevereError(state, format("{} = \"{}\"", cCurrentModuleObject, thisVrfSys.Name));
2070 0 : ShowContinueError(state, format("{} = {} not found.", cAlphaFieldNames(27), cAlphaArgs(27)));
2071 0 : ErrorsFound = true;
2072 : }
2073 :
2074 18 : thisVrfSys.HeatRecoveryUsed = false;
2075 18 : if (!lAlphaFieldBlanks(28)) {
2076 18 : if (Util::SameString(cAlphaArgs(28), "No")) {
2077 16 : thisVrfSys.HeatRecoveryUsed = false;
2078 2 : } else if (Util::SameString(cAlphaArgs(28), "Yes")) {
2079 2 : thisVrfSys.HeatRecoveryUsed = true;
2080 : } else {
2081 0 : ShowSevereError(state, format("{} = \"{}\"", cCurrentModuleObject, thisVrfSys.Name));
2082 0 : ShowContinueError(state, format("Illegal {} = {}", cAlphaFieldNames(28), cAlphaArgs(28)));
2083 0 : ErrorsFound = true;
2084 : }
2085 : }
2086 :
2087 18 : thisVrfSys.EquivPipeLngthCool = rNumericArgs(11);
2088 18 : thisVrfSys.VertPipeLngth = rNumericArgs(12);
2089 18 : thisVrfSys.PCFLengthCoolPtr = GetCurveIndex(state, cAlphaArgs(29));
2090 18 : if (thisVrfSys.PCFLengthCoolPtr > 0) {
2091 : // Verify Curve Object, only legal type is linear, quadratic, cubic, or biquadratic
2092 54 : ErrorsFound |= Curve::CheckCurveDims(state,
2093 : thisVrfSys.PCFLengthCoolPtr, // Curve index
2094 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2095 : RoutineName, // Routine name
2096 : cCurrentModuleObject, // Object Type
2097 : thisVrfSys.Name, // Object Name
2098 18 : cAlphaFieldNames(29)); // Field Name
2099 : }
2100 18 : thisVrfSys.PCFHeightCool = rNumericArgs(13);
2101 :
2102 18 : thisVrfSys.EquivPipeLngthHeat = rNumericArgs(14);
2103 18 : thisVrfSys.PCFLengthHeatPtr = GetCurveIndex(state, cAlphaArgs(30));
2104 18 : if (thisVrfSys.PCFLengthHeatPtr > 0) {
2105 : // Verify Curve Object, only legal type is linear, quadratic, cubic, or biquadratic
2106 15 : ErrorsFound |= Curve::CheckCurveDims(state,
2107 : thisVrfSys.PCFLengthHeatPtr, // Curve index
2108 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2109 : RoutineName, // Routine name
2110 : cCurrentModuleObject, // Object Type
2111 : thisVrfSys.Name, // Object Name
2112 5 : cAlphaFieldNames(30)); // Field Name
2113 : }
2114 :
2115 18 : thisVrfSys.PCFHeightHeat = rNumericArgs(15);
2116 :
2117 18 : thisVrfSys.CCHeaterPower = rNumericArgs(16);
2118 18 : thisVrfSys.NumCompressors = rNumericArgs(17);
2119 18 : thisVrfSys.CompressorSizeRatio = rNumericArgs(18);
2120 18 : thisVrfSys.MaxOATCCHeater = rNumericArgs(19);
2121 :
2122 18 : if (!lAlphaFieldBlanks(31)) {
2123 18 : thisVrfSys.DefrostStrategy = static_cast<StandardRatings::DefrostStrat>(getEnumValue(StandardRatings::DefrostStratUC, cAlphaArgs(31)));
2124 18 : if (thisVrfSys.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
2125 0 : ShowSevereError(state,
2126 0 : format("{}, \"{}\" {} not found: {}", cCurrentModuleObject, thisVrfSys.Name, cAlphaFieldNames(31), cAlphaArgs(31)));
2127 0 : ErrorsFound = true;
2128 : }
2129 : } else {
2130 0 : thisVrfSys.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
2131 : }
2132 :
2133 18 : if (!lAlphaFieldBlanks(32)) {
2134 18 : thisVrfSys.DefrostControl =
2135 18 : static_cast<StandardRatings::HPdefrostControl>(getEnumValue(StandardRatings::HPdefrostControlUC, cAlphaArgs(32)));
2136 :
2137 18 : if (thisVrfSys.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
2138 0 : ShowSevereError(state,
2139 0 : format("{}, \"{}\" {} not found: {}", cCurrentModuleObject, thisVrfSys.Name, cAlphaFieldNames(32), cAlphaArgs(32)));
2140 :
2141 0 : ErrorsFound = true;
2142 : }
2143 : } else {
2144 0 : thisVrfSys.DefrostControl = StandardRatings::HPdefrostControl::Timed;
2145 : }
2146 :
2147 18 : if (!lAlphaFieldBlanks(33)) {
2148 11 : thisVrfSys.DefrostEIRPtr = GetCurveIndex(state, cAlphaArgs(33));
2149 11 : if (thisVrfSys.DefrostEIRPtr > 0) {
2150 : // Verify Curve Object, expected type is BiQuadratic
2151 33 : ErrorsFound |= Curve::CheckCurveDims(state,
2152 : thisVrfSys.DefrostEIRPtr, // Curve index
2153 : {2}, // Valid dimensions
2154 : RoutineName, // Routine name
2155 : cCurrentModuleObject, // Object Type
2156 : thisVrfSys.Name, // Object Name
2157 11 : cAlphaFieldNames(33)); // Field Name
2158 : } else {
2159 0 : if (thisVrfSys.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
2160 0 : ShowSevereError(
2161 0 : state, format("{}, \"{}\" {} not found: {}", cCurrentModuleObject, thisVrfSys.Name, cAlphaFieldNames(33), cAlphaArgs(33)));
2162 0 : ErrorsFound = true;
2163 : }
2164 : }
2165 : } else {
2166 7 : if (thisVrfSys.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
2167 0 : ShowSevereError(state,
2168 0 : format("{}, \"{}\" {} not found: {}", cCurrentModuleObject, thisVrfSys.Name, cAlphaFieldNames(33), cAlphaArgs(33)));
2169 0 : ErrorsFound = true;
2170 : }
2171 : }
2172 :
2173 18 : thisVrfSys.DefrostFraction = rNumericArgs(20);
2174 18 : thisVrfSys.DefrostCapacity = rNumericArgs(21);
2175 18 : if (thisVrfSys.DefrostCapacity == 0.0 && thisVrfSys.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
2176 0 : ShowWarningError(
2177 : state,
2178 0 : format("{}, \"{}\" {} = 0.0 for defrost strategy = RESISTIVE.", cCurrentModuleObject, thisVrfSys.Name, cNumericFieldNames(21)));
2179 : }
2180 :
2181 18 : thisVrfSys.MaxOATDefrost = rNumericArgs(22);
2182 :
2183 18 : if (!lAlphaFieldBlanks(35)) {
2184 18 : if (Util::SameString(cAlphaArgs(34), "AirCooled")) {
2185 17 : thisVrfSys.CondenserType = DataHeatBalance::RefrigCondenserType::Air;
2186 : }
2187 18 : if (Util::SameString(cAlphaArgs(34), "EvaporativelyCooled")) {
2188 0 : thisVrfSys.CondenserType = DataHeatBalance::RefrigCondenserType::Evap;
2189 : }
2190 18 : if (Util::SameString(cAlphaArgs(34), "WaterCooled")) {
2191 1 : thisVrfSys.CondenserType = DataHeatBalance::RefrigCondenserType::Water;
2192 1 : thisVrfSys.VRFType = PlantEquipmentType::HeatPumpVRF;
2193 1 : if (thisVrfSys.HeatingPerformanceOATType == HVAC::OATType::WetBulb) {
2194 1 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisVrfSys.Name));
2195 1 : ShowContinueError(state, format("{} = {}", cAlphaFieldNames(34), cAlphaArgs(34)));
2196 1 : ShowContinueError(state, format("Illegal {} input for this object = {}", cAlphaFieldNames(19), cAlphaArgs(19)));
2197 2 : ShowContinueError(state, "... input must be DRYBULBTEMPERATURE when Condenser Type is WaterCooled.");
2198 1 : ShowContinueError(state, format("... {} will be reset to DRYBULBTEMPERATURE and simulation continues.", cAlphaFieldNames(19)));
2199 : }
2200 : }
2201 18 : if (thisVrfSys.CondenserType == DataHeatBalance::RefrigCondenserType::Invalid) {
2202 0 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfSys.Name);
2203 0 : ShowContinueError(state, "Illegal " + cAlphaFieldNames(34) + " = " + cAlphaArgs(34));
2204 0 : ErrorsFound = true;
2205 : }
2206 : } else {
2207 0 : thisVrfSys.CondenserType = DataHeatBalance::RefrigCondenserType::Air;
2208 : }
2209 :
2210 : // outdoor condenser node
2211 18 : if (lAlphaFieldBlanks(35)) {
2212 0 : thisVrfSys.CondenserNodeNum = 0;
2213 : } else {
2214 18 : switch (thisVrfSys.CondenserType) {
2215 17 : case DataHeatBalance::RefrigCondenserType::Air:
2216 : case DataHeatBalance::RefrigCondenserType::Evap: {
2217 17 : thisVrfSys.CondenserNodeNum = GetOnlySingleNode(state,
2218 17 : cAlphaArgs(35),
2219 : ErrorsFound,
2220 : DataLoopNode::ConnectionObjectType::AirConditionerVariableRefrigerantFlow,
2221 17 : thisVrfSys.Name,
2222 : DataLoopNode::NodeFluidType::Air,
2223 : DataLoopNode::ConnectionType::OutsideAirReference,
2224 : NodeInputManager::CompFluidStream::Primary,
2225 : ObjectIsNotParent);
2226 17 : if (!CheckOutAirNodeNumber(state, thisVrfSys.CondenserNodeNum)) {
2227 0 : ShowSevereError(state,
2228 0 : format("{}, \"{}\" {} not a valid Outdoor Air Node = {}",
2229 : cCurrentModuleObject,
2230 0 : thisVrfSys.Name,
2231 : cAlphaFieldNames(35),
2232 : cAlphaArgs(35)));
2233 0 : ShowContinueError(state, "...node name does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
2234 0 : ErrorsFound = true;
2235 : }
2236 17 : } break;
2237 1 : case DataHeatBalance::RefrigCondenserType::Water: {
2238 1 : thisVrfSys.CondenserNodeNum = GetOnlySingleNode(state,
2239 1 : cAlphaArgs(35),
2240 : ErrorsFound,
2241 : DataLoopNode::ConnectionObjectType::AirConditionerVariableRefrigerantFlow,
2242 1 : thisVrfSys.Name,
2243 : DataLoopNode::NodeFluidType::Water,
2244 : DataLoopNode::ConnectionType::Inlet,
2245 : NodeInputManager::CompFluidStream::Secondary,
2246 : ObjectIsNotParent);
2247 1 : } break;
2248 0 : default:
2249 0 : break;
2250 : }
2251 : }
2252 :
2253 18 : if (!lAlphaFieldBlanks(36) && thisVrfSys.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
2254 2 : thisVrfSys.CondenserOutletNodeNum = GetOnlySingleNode(state,
2255 1 : cAlphaArgs(36),
2256 : ErrorsFound,
2257 : DataLoopNode::ConnectionObjectType::AirConditionerVariableRefrigerantFlow,
2258 1 : thisVrfSys.Name,
2259 : DataLoopNode::NodeFluidType::Water,
2260 : DataLoopNode::ConnectionType::Outlet,
2261 : NodeInputManager::CompFluidStream::Secondary,
2262 : ObjectIsNotParent);
2263 2 : TestCompSet(state, cCurrentModuleObject, thisVrfSys.Name, cAlphaArgs(35), cAlphaArgs(36), "Condenser Water Nodes");
2264 17 : } else if (lAlphaFieldBlanks(36) && thisVrfSys.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
2265 0 : ShowSevereError(state, format("{}, \"{}\" {} is blank.", cCurrentModuleObject, thisVrfSys.Name, cAlphaFieldNames(36)));
2266 0 : ShowContinueError(state, "...node name must be entered when Condenser Type = WaterCooled.");
2267 0 : ErrorsFound = true;
2268 : }
2269 :
2270 18 : if (lAlphaFieldBlanks(23)) {
2271 0 : if (thisVrfSys.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
2272 0 : ShowSevereError(state, format("{}, \"{}\" {} is blank.", cCurrentModuleObject, thisVrfSys.Name, cNumericFieldNames(23)));
2273 0 : ShowContinueError(state, format("...input is required when {} = {}", cAlphaFieldNames(34), cAlphaArgs(34)));
2274 0 : ErrorsFound = true;
2275 : }
2276 : } else {
2277 18 : thisVrfSys.WaterCondVolFlowRate = rNumericArgs(23);
2278 : }
2279 18 : thisVrfSys.EvapCondEffectiveness = rNumericArgs(24);
2280 18 : thisVrfSys.EvapCondAirVolFlowRate = rNumericArgs(25);
2281 18 : thisVrfSys.EvapCondPumpPower = rNumericArgs(26);
2282 :
2283 : // Get Water System tank connections
2284 : // A37, \field Supply Water Storage Tank Name
2285 18 : thisVrfSys.EvapWaterSupplyName = cAlphaArgs(37);
2286 18 : if (lAlphaFieldBlanks(37)) {
2287 18 : thisVrfSys.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
2288 : } else {
2289 0 : thisVrfSys.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
2290 0 : SetupTankDemandComponent(state,
2291 : thisVrfSys.Name,
2292 : cCurrentModuleObject,
2293 : thisVrfSys.EvapWaterSupplyName,
2294 : ErrorsFound,
2295 0 : thisVrfSys.EvapWaterSupTankID,
2296 0 : thisVrfSys.EvapWaterTankDemandARRID);
2297 : }
2298 :
2299 : // Basin heater power as a function of temperature must be greater than or equal to 0
2300 18 : thisVrfSys.BasinHeaterPowerFTempDiff = rNumericArgs(27);
2301 18 : if (rNumericArgs(27) < 0.0) {
2302 0 : ShowSevereError(state, format("{}, \"{}\" {} must be >= 0", cCurrentModuleObject, thisVrfSys.Name, cNumericFieldNames(27)));
2303 0 : ErrorsFound = true;
2304 : }
2305 :
2306 18 : thisVrfSys.BasinHeaterSetPointTemp = rNumericArgs(28);
2307 18 : if (thisVrfSys.BasinHeaterPowerFTempDiff > 0.0) {
2308 0 : if (NumNums < 27) {
2309 0 : thisVrfSys.BasinHeaterSetPointTemp = 2.0;
2310 : }
2311 0 : if (thisVrfSys.BasinHeaterSetPointTemp < 2.0) {
2312 0 : ShowWarningError(
2313 : state,
2314 0 : format(
2315 0 : "{}, \"{}\" {} is less than 2 deg C. Freezing could occur.", cCurrentModuleObject, thisVrfSys.Name, cNumericFieldNames(28)));
2316 : }
2317 : }
2318 :
2319 18 : if (!lAlphaFieldBlanks(38)) {
2320 5 : if ((thisVrfSys.basinHeaterSched = Sched::GetSchedule(state, cAlphaArgs(38))) == nullptr) {
2321 0 : ShowWarningItemNotFound(
2322 0 : state, eoh, cAlphaFieldNames(38), cAlphaArgs(38), "Basin heater will be available to operate throughout the simulation.");
2323 : }
2324 : }
2325 :
2326 18 : if (!lAlphaFieldBlanks(39)) {
2327 : // A39; \field Fuel type, Validate fuel type input
2328 18 : if ((thisVrfSys.fuel = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, cAlphaArgs(39)))) == Constant::eFuel::Invalid) {
2329 0 : ShowSevereInvalidKey(state, eoh, cAlphaFieldNames(39), cAlphaArgs(39));
2330 0 : ErrorsFound = true;
2331 : }
2332 : }
2333 :
2334 18 : if (thisVrfSys.HeatRecoveryUsed) {
2335 2 : if (lAlphaFieldBlanks(29)) {
2336 0 : thisVrfSys.MinOATHeatRecovery = max(thisVrfSys.MinOATCooling, thisVrfSys.MinOATHeating);
2337 : } else {
2338 2 : thisVrfSys.MinOATHeatRecovery = rNumericArgs(29);
2339 2 : if (thisVrfSys.MinOATHeatRecovery < thisVrfSys.MinOATCooling || thisVrfSys.MinOATHeatRecovery < thisVrfSys.MinOATHeating) {
2340 4 : ShowWarningError(state,
2341 6 : format("{} = \"{}\", {} is less than the minimum temperature in heat pump mode.",
2342 : cCurrentModuleObject,
2343 2 : thisVrfSys.Name,
2344 : cNumericFieldNames(29)));
2345 2 : ShowContinueError(state, format("...{} = {:.2T} C", cNumericFieldNames(29), thisVrfSys.MinOATHeatRecovery));
2346 2 : ShowContinueError(state, format("...Minimum Outdoor Temperature in Cooling Mode = {:.2T} C", thisVrfSys.MinOATCooling));
2347 2 : ShowContinueError(state, format("...Minimum Outdoor Temperature in Heating Mode = {:.2T} C", thisVrfSys.MinOATHeating));
2348 4 : ShowContinueError(state,
2349 : "...Minimum Outdoor Temperature in Heat Recovery Mode reset to greater of cooling or heating minimum "
2350 : "temperature and simulation continues.");
2351 2 : thisVrfSys.MinOATHeatRecovery = max(thisVrfSys.MinOATCooling, thisVrfSys.MinOATHeating);
2352 2 : ShowContinueError(state, format("... adjusted {} = {:.2T} C", cNumericFieldNames(29), thisVrfSys.MinOATHeatRecovery));
2353 : }
2354 : }
2355 2 : if (lAlphaFieldBlanks(30)) {
2356 0 : thisVrfSys.MaxOATHeatRecovery = min(thisVrfSys.MaxOATCooling, thisVrfSys.MaxOATHeating);
2357 : } else {
2358 2 : thisVrfSys.MaxOATHeatRecovery = rNumericArgs(30);
2359 2 : if (thisVrfSys.MaxOATHeatRecovery > thisVrfSys.MaxOATCooling || thisVrfSys.MaxOATHeatRecovery > thisVrfSys.MaxOATHeating) {
2360 0 : ShowWarningError(state,
2361 0 : format("{} = \"{}\", {} is greater than the maximum temperature in heat pump mode.",
2362 : cCurrentModuleObject,
2363 0 : thisVrfSys.Name,
2364 : cNumericFieldNames(30)));
2365 0 : ShowContinueError(state, format("...{} = {:.2T} C", cNumericFieldNames(30), thisVrfSys.MaxOATHeatRecovery));
2366 0 : ShowContinueError(state, format("...Maximum Outdoor Temperature in Cooling Mode = {:.2T} C", thisVrfSys.MaxOATCooling));
2367 0 : ShowContinueError(state, format("...Maximum Outdoor Temperature in Heating Mode = {:.2T} C", thisVrfSys.MaxOATHeating));
2368 0 : ShowContinueError(state,
2369 : "...Maximum Outdoor Temperature in Heat Recovery Mode reset to lesser of cooling or heating minimum "
2370 : "temperature and simulation continues.");
2371 0 : thisVrfSys.MaxOATHeatRecovery = min(thisVrfSys.MaxOATCooling, thisVrfSys.MaxOATHeating);
2372 0 : ShowContinueError(state, format("... adjusted {} = {:.2T} C", cNumericFieldNames(30), thisVrfSys.MaxOATHeatRecovery));
2373 : }
2374 : }
2375 :
2376 2 : thisVrfSys.HRCAPFTCool = GetCurveIndex(state, cAlphaArgs(40));
2377 2 : if (thisVrfSys.HRCAPFTCool > 0) {
2378 : // Verify Curve Object, only legal type is bi-quadratic or linear, quadratic, or cubic
2379 6 : ErrorsFound |= Curve::CheckCurveDims(state,
2380 : thisVrfSys.HRCAPFTCool, // Curve index
2381 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2382 : RoutineName, // Routine name
2383 : cCurrentModuleObject, // Object Type
2384 : thisVrfSys.Name, // Object Name
2385 2 : cAlphaFieldNames(40)); // Field Name
2386 : }
2387 2 : if (!lNumericFieldBlanks(31)) {
2388 2 : thisVrfSys.HRInitialCoolCapFrac = rNumericArgs(31);
2389 : }
2390 2 : thisVrfSys.HRCoolCapTC = rNumericArgs(32);
2391 2 : thisVrfSys.HREIRFTCool = GetCurveIndex(state, cAlphaArgs(41));
2392 2 : if (thisVrfSys.HREIRFTCool > 0) {
2393 : // Verify Curve Object, only legal type is bi-quadratic or linear, quadratic, or cubic
2394 6 : ErrorsFound |= Curve::CheckCurveDims(state,
2395 : thisVrfSys.HREIRFTCool, // Curve index
2396 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2397 : RoutineName, // Routine name
2398 : cCurrentModuleObject, // Object Type
2399 : thisVrfSys.Name, // Object Name
2400 2 : cAlphaFieldNames(41)); // Field Name
2401 : }
2402 2 : thisVrfSys.HRInitialCoolEIRFrac = rNumericArgs(33);
2403 2 : thisVrfSys.HRCoolEIRTC = rNumericArgs(34);
2404 :
2405 : // INTEGER :: HRCAPFTHeat =0 ! Index to heat capacity as a function of temperature curve for heat recovery
2406 : // REAL(r64) :: HRInitialHeatCapFrac =0.0d0 ! Fractional heating degradation at the start of heat recovery from heating mode
2407 : // REAL(r64) :: HRHeatCapTC =0.0d0 ! Time constant used to recover from initial degradation in heating heat
2408 : // recovery
2409 2 : thisVrfSys.HRCAPFTHeat = GetCurveIndex(state, cAlphaArgs(42));
2410 2 : if (thisVrfSys.HRCAPFTHeat > 0) {
2411 : // Verify Curve Object, only legal type is bi-quadratic or linear, quadratic, or cubic
2412 6 : ErrorsFound |= Curve::CheckCurveDims(state,
2413 : thisVrfSys.HRCAPFTHeat, // Curve index
2414 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2415 : RoutineName, // Routine name
2416 : cCurrentModuleObject, // Object Type
2417 : thisVrfSys.Name, // Object Name
2418 2 : cAlphaFieldNames(42)); // Field Name
2419 : }
2420 2 : thisVrfSys.HRInitialHeatCapFrac = rNumericArgs(35);
2421 2 : thisVrfSys.HRHeatCapTC = rNumericArgs(36);
2422 :
2423 : // INTEGER :: HREIRFTHeat =0 ! Index to heat EIR as a function of temperature curve for heat recovery
2424 : // REAL(r64) :: HRInitialHeatEIRFrac =0.0d0 ! Fractional EIR degradation at the start of heat recovery from heating mode
2425 : // REAL(r64) :: HRHeatEIRTC =0.0d0 ! Time constant used to recover from initial degradation in heating heat
2426 : // recovery
2427 2 : thisVrfSys.HREIRFTHeat = GetCurveIndex(state, cAlphaArgs(43));
2428 2 : if (thisVrfSys.HREIRFTHeat > 0) {
2429 : // Verify Curve Object, only legal type is bi-quadratic or linear, quadratic, or cubic
2430 6 : ErrorsFound |= Curve::CheckCurveDims(state,
2431 : thisVrfSys.HREIRFTHeat, // Curve index
2432 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2433 : RoutineName, // Routine name
2434 : cCurrentModuleObject, // Object Type
2435 : thisVrfSys.Name, // Object Name
2436 2 : cAlphaFieldNames(43)); // Field Name
2437 : }
2438 2 : thisVrfSys.HRInitialHeatEIRFrac = rNumericArgs(37);
2439 2 : thisVrfSys.HRHeatEIRTC = rNumericArgs(38);
2440 : }
2441 : }
2442 :
2443 : // Read all VRF condenser objects: Algorithm Type 2_physics based model (VRF-FluidTCtrl-HP)
2444 23 : cCurrentModuleObject = "AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl";
2445 29 : for (int thisNum = 1; thisNum <= state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HP; ++thisNum) {
2446 :
2447 6 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2448 : cCurrentModuleObject,
2449 : thisNum,
2450 : cAlphaArgs,
2451 : NumAlphas,
2452 : rNumericArgs,
2453 : NumNums,
2454 : IOStat,
2455 : lNumericFieldBlanks,
2456 : lAlphaFieldBlanks,
2457 : cAlphaFieldNames,
2458 : cNumericFieldNames);
2459 :
2460 6 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
2461 :
2462 6 : GlobalNames::VerifyUniqueInterObjectName(
2463 12 : state, state.dataHVACVarRefFlow->VrfUniqueNames, cAlphaArgs(1), cCurrentModuleObject, cAlphaFieldNames(1), ErrorsFound);
2464 :
2465 6 : int VRFNum = state.dataHVACVarRefFlow->NumVRFCond_SysCurve + thisNum;
2466 6 : auto &thisVrfFluidCtrl = state.dataHVACVarRefFlow->VRF(VRFNum);
2467 6 : thisVrfFluidCtrl.Name = cAlphaArgs(1);
2468 6 : thisVrfFluidCtrl.VRFSystemTypeNum = VRF_HeatPump;
2469 6 : thisVrfFluidCtrl.VRFAlgorithmType = AlgorithmType::FluidTCtrl;
2470 6 : thisVrfFluidCtrl.fuel = Constant::eFuel::Electricity;
2471 :
2472 6 : if (lAlphaFieldBlanks(2)) {
2473 2 : thisVrfFluidCtrl.availSched = Sched::GetScheduleAlwaysOn(state);
2474 4 : } else if ((thisVrfFluidCtrl.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
2475 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
2476 0 : ErrorsFound = true;
2477 : }
2478 :
2479 6 : thisVrfFluidCtrl.ZoneTUListPtr =
2480 6 : Util::FindItemInList(cAlphaArgs(3), state.dataHVACVarRefFlow->TerminalUnitList, state.dataHVACVarRefFlow->NumVRFTULists);
2481 6 : if (thisVrfFluidCtrl.ZoneTUListPtr == 0) {
2482 0 : ShowSevereError(state, cCurrentModuleObject + " = \"" + thisVrfFluidCtrl.Name + "\"");
2483 0 : ShowContinueError(state, cAlphaFieldNames(3) + " = " + cAlphaArgs(3) + " not found.");
2484 0 : ErrorsFound = true;
2485 : }
2486 :
2487 : // Refrigerant type
2488 6 : thisVrfFluidCtrl.refrigName = cAlphaArgs(4);
2489 6 : thisVrfFluidCtrl.refrig = Fluid::GetRefrig(state, thisVrfFluidCtrl.refrigName);
2490 6 : if (thisVrfFluidCtrl.refrig == nullptr) {
2491 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(4), cAlphaArgs(4));
2492 0 : ErrorsFound = true;
2493 : }
2494 :
2495 6 : thisVrfFluidCtrl.RatedEvapCapacity = rNumericArgs(1);
2496 6 : thisVrfFluidCtrl.RatedCompPowerPerCapcity = rNumericArgs(2);
2497 6 : thisVrfFluidCtrl.RatedCompPower = thisVrfFluidCtrl.RatedCompPowerPerCapcity * thisVrfFluidCtrl.RatedEvapCapacity;
2498 6 : thisVrfFluidCtrl.CoolingCapacity = thisVrfFluidCtrl.RatedEvapCapacity;
2499 6 : thisVrfFluidCtrl.RatedHeatCapacity = thisVrfFluidCtrl.RatedEvapCapacity * (1 + thisVrfFluidCtrl.RatedCompPowerPerCapcity);
2500 6 : thisVrfFluidCtrl.HeatingCapacity = thisVrfFluidCtrl.RatedHeatCapacity;
2501 :
2502 : // Reference system COP
2503 6 : thisVrfFluidCtrl.CoolingCOP = 1 / thisVrfFluidCtrl.RatedCompPowerPerCapcity;
2504 6 : thisVrfFluidCtrl.HeatingCOP = 1 / thisVrfFluidCtrl.RatedCompPowerPerCapcity + 1;
2505 :
2506 : // OA temperature range for VRF-HP operations
2507 6 : thisVrfFluidCtrl.MinOATCooling = rNumericArgs(3);
2508 6 : thisVrfFluidCtrl.MaxOATCooling = rNumericArgs(4);
2509 6 : thisVrfFluidCtrl.MinOATHeating = rNumericArgs(5);
2510 6 : thisVrfFluidCtrl.MaxOATHeating = rNumericArgs(6);
2511 6 : if (thisVrfFluidCtrl.MinOATCooling >= thisVrfFluidCtrl.MaxOATCooling) {
2512 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\"");
2513 0 : ShowContinueError(state,
2514 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2515 : cNumericFieldNames(3),
2516 0 : thisVrfFluidCtrl.MinOATCooling,
2517 0 : thisVrfFluidCtrl.MaxOATCooling));
2518 0 : ErrorsFound = true;
2519 : }
2520 6 : if (thisVrfFluidCtrl.MinOATHeating >= thisVrfFluidCtrl.MaxOATHeating) {
2521 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\"");
2522 0 : ShowContinueError(state,
2523 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2524 : cNumericFieldNames(5),
2525 0 : thisVrfFluidCtrl.MinOATHeating,
2526 0 : thisVrfFluidCtrl.MaxOATHeating));
2527 0 : ErrorsFound = true;
2528 : }
2529 :
2530 : // Reference OU SH/SC
2531 6 : thisVrfFluidCtrl.SH = rNumericArgs(7);
2532 6 : thisVrfFluidCtrl.SC = rNumericArgs(8);
2533 :
2534 6 : if (Util::SameString(cAlphaArgs(5), "VariableTemp")) {
2535 0 : thisVrfFluidCtrl.AlgorithmIUCtrl = 1;
2536 6 : } else if (Util::SameString(cAlphaArgs(5), "ConstantTemp")) {
2537 6 : thisVrfFluidCtrl.AlgorithmIUCtrl = 2;
2538 : } else {
2539 0 : thisVrfFluidCtrl.AlgorithmIUCtrl = 1;
2540 : }
2541 :
2542 : // Reference IU Te/Tc for IU Control Algorithm: ConstantTemp
2543 6 : thisVrfFluidCtrl.EvapTempFixed = rNumericArgs(9);
2544 6 : thisVrfFluidCtrl.CondTempFixed = rNumericArgs(10);
2545 :
2546 : // Bounds of Te/Tc for IU Control Algorithm: VariableTemp
2547 6 : thisVrfFluidCtrl.IUEvapTempLow = rNumericArgs(11);
2548 6 : thisVrfFluidCtrl.IUEvapTempHigh = rNumericArgs(12);
2549 6 : thisVrfFluidCtrl.IUCondTempLow = rNumericArgs(13);
2550 6 : thisVrfFluidCtrl.IUCondTempHigh = rNumericArgs(14);
2551 6 : if (thisVrfFluidCtrl.IUEvapTempLow >= thisVrfFluidCtrl.IUEvapTempHigh) {
2552 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\"");
2553 0 : ShowContinueError(state,
2554 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2555 : cNumericFieldNames(11),
2556 0 : thisVrfFluidCtrl.IUEvapTempLow,
2557 0 : thisVrfFluidCtrl.IUEvapTempHigh));
2558 0 : ErrorsFound = true;
2559 : }
2560 6 : if (thisVrfFluidCtrl.IUCondTempLow >= thisVrfFluidCtrl.IUCondTempHigh) {
2561 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\"");
2562 0 : ShowContinueError(state,
2563 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2564 : cNumericFieldNames(13),
2565 0 : thisVrfFluidCtrl.IUCondTempLow,
2566 0 : thisVrfFluidCtrl.IUCondTempHigh));
2567 0 : ErrorsFound = true;
2568 : }
2569 :
2570 : // Get OU fan data
2571 6 : thisVrfFluidCtrl.RatedOUFanPowerPerCapcity = rNumericArgs(15);
2572 6 : thisVrfFluidCtrl.OUAirFlowRatePerCapcity = rNumericArgs(16);
2573 6 : thisVrfFluidCtrl.RatedOUFanPower = thisVrfFluidCtrl.RatedOUFanPowerPerCapcity * thisVrfFluidCtrl.RatedEvapCapacity;
2574 6 : thisVrfFluidCtrl.OUAirFlowRate = thisVrfFluidCtrl.OUAirFlowRatePerCapcity * thisVrfFluidCtrl.RatedEvapCapacity;
2575 :
2576 : // OUEvapTempCurve
2577 6 : int indexOUEvapTempCurve = GetCurveIndex(state, cAlphaArgs(6)); // convert curve name to index number
2578 : // Verify curve name and type
2579 6 : if (indexOUEvapTempCurve == 0) {
2580 0 : if (lAlphaFieldBlanks(6)) {
2581 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", missing");
2582 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(6) + " is blank.");
2583 : } else {
2584 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", invalid");
2585 0 : ShowContinueError(state, "...not found " + cAlphaFieldNames(6) + "=\"" + cAlphaArgs(6) + "\".");
2586 : }
2587 0 : ErrorsFound = true;
2588 : } else {
2589 : {
2590 6 : if (state.dataCurveManager->curves(indexOUEvapTempCurve)->curveType == Curve::CurveType::Quadratic) {
2591 6 : thisVrfFluidCtrl.C1Te = state.dataCurveManager->curves(indexOUEvapTempCurve)->coeff[0];
2592 6 : thisVrfFluidCtrl.C2Te = state.dataCurveManager->curves(indexOUEvapTempCurve)->coeff[1];
2593 6 : thisVrfFluidCtrl.C3Te = state.dataCurveManager->curves(indexOUEvapTempCurve)->coeff[2];
2594 :
2595 : } else {
2596 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", invalid");
2597 0 : ShowContinueError(state,
2598 0 : format("...illegal {} type for this object = {}",
2599 : cAlphaFieldNames(6),
2600 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexOUEvapTempCurve)->curveType)]));
2601 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
2602 0 : ErrorsFound = true;
2603 : }
2604 : }
2605 : }
2606 :
2607 : // OUCondTempCurve
2608 6 : int indexOUCondTempCurve = GetCurveIndex(state, cAlphaArgs(7)); // convert curve name to index number
2609 : // Verify curve name and type
2610 6 : if (indexOUCondTempCurve == 0) {
2611 0 : if (lAlphaFieldBlanks(7)) {
2612 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", missing");
2613 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(7) + " is blank.");
2614 : } else {
2615 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", invalid");
2616 0 : ShowContinueError(state, "...not found " + cAlphaFieldNames(7) + "=\"" + cAlphaArgs(7) + "\".");
2617 : }
2618 0 : ErrorsFound = true;
2619 : } else {
2620 : {
2621 6 : if (state.dataCurveManager->curves(indexOUCondTempCurve)->curveType == Curve::CurveType::Quadratic) {
2622 6 : thisVrfFluidCtrl.C1Tc = state.dataCurveManager->curves(indexOUCondTempCurve)->coeff[0];
2623 6 : thisVrfFluidCtrl.C2Tc = state.dataCurveManager->curves(indexOUCondTempCurve)->coeff[1];
2624 6 : thisVrfFluidCtrl.C3Tc = state.dataCurveManager->curves(indexOUCondTempCurve)->coeff[2];
2625 :
2626 : } else {
2627 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", invalid");
2628 0 : ShowContinueError(state,
2629 0 : format("...illegal {} type for this object = {}",
2630 : cAlphaFieldNames(7),
2631 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexOUCondTempCurve)->curveType)]));
2632 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
2633 0 : ErrorsFound = true;
2634 : }
2635 : }
2636 : }
2637 :
2638 : // Pipe parameters
2639 6 : thisVrfFluidCtrl.RefPipDiaSuc = rNumericArgs(17);
2640 6 : thisVrfFluidCtrl.RefPipDiaDis = rNumericArgs(17);
2641 6 : thisVrfFluidCtrl.RefPipLen = rNumericArgs(18);
2642 6 : thisVrfFluidCtrl.RefPipEquLen = rNumericArgs(19);
2643 6 : thisVrfFluidCtrl.RefPipHei = rNumericArgs(20);
2644 6 : thisVrfFluidCtrl.RefPipInsThi = rNumericArgs(21);
2645 6 : thisVrfFluidCtrl.RefPipInsCon = rNumericArgs(22);
2646 :
2647 : // Check the RefPipEquLen
2648 6 : if (lNumericFieldBlanks(19) && !lNumericFieldBlanks(18)) {
2649 0 : thisVrfFluidCtrl.RefPipEquLen = 1.2 * thisVrfFluidCtrl.RefPipLen;
2650 0 : ShowWarningError(
2651 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\", \" " + cNumericFieldNames(19) + "\" is calculated based on");
2652 0 : ShowContinueError(state, "...the provided \"" + cNumericFieldNames(18) + "\" value.");
2653 : }
2654 6 : if (thisVrfFluidCtrl.RefPipEquLen < thisVrfFluidCtrl.RefPipLen) {
2655 0 : thisVrfFluidCtrl.RefPipEquLen = 1.2 * thisVrfFluidCtrl.RefPipLen;
2656 0 : ShowWarningError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\", invalid \" " + cNumericFieldNames(19) + "\" value.");
2657 0 : ShowContinueError(state, "...Equivalent length of main pipe should be greater than or equal to the actual length.");
2658 0 : ShowContinueError(state, format("...The value is recalculated based on the provided \"{}\" value.", cNumericFieldNames(18)));
2659 : }
2660 :
2661 : // Crank case
2662 6 : thisVrfFluidCtrl.CCHeaterPower = rNumericArgs(23);
2663 6 : thisVrfFluidCtrl.NumCompressors = rNumericArgs(24);
2664 6 : thisVrfFluidCtrl.CompressorSizeRatio = rNumericArgs(25);
2665 6 : thisVrfFluidCtrl.MaxOATCCHeater = rNumericArgs(26);
2666 :
2667 : // Defrost
2668 6 : if (!lAlphaFieldBlanks(8)) {
2669 0 : if (Util::SameString(cAlphaArgs(8), "ReverseCycle")) {
2670 0 : thisVrfFluidCtrl.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
2671 : }
2672 0 : if (Util::SameString(cAlphaArgs(8), "Resistive")) {
2673 0 : thisVrfFluidCtrl.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
2674 : }
2675 0 : if (thisVrfFluidCtrl.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
2676 0 : ShowSevereError(state,
2677 0 : cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\" " + cAlphaFieldNames(8) + " not found: " + cAlphaArgs(8));
2678 0 : ErrorsFound = true;
2679 : }
2680 : } else {
2681 6 : thisVrfFluidCtrl.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
2682 : }
2683 :
2684 6 : if (!lAlphaFieldBlanks(9)) {
2685 0 : if (Util::SameString(cAlphaArgs(9), "Timed")) {
2686 0 : thisVrfFluidCtrl.DefrostControl = StandardRatings::HPdefrostControl::Timed;
2687 : }
2688 0 : if (Util::SameString(cAlphaArgs(9), "OnDemand")) {
2689 0 : thisVrfFluidCtrl.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
2690 : }
2691 0 : if (thisVrfFluidCtrl.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
2692 0 : ShowSevereError(state,
2693 0 : cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\" " + cAlphaFieldNames(9) + " not found: " + cAlphaArgs(9));
2694 0 : ErrorsFound = true;
2695 : }
2696 : } else {
2697 6 : thisVrfFluidCtrl.DefrostControl = StandardRatings::HPdefrostControl::Timed;
2698 : }
2699 :
2700 6 : if (!lAlphaFieldBlanks(10)) {
2701 0 : thisVrfFluidCtrl.DefrostEIRPtr = GetCurveIndex(state, cAlphaArgs(10));
2702 0 : if (thisVrfFluidCtrl.DefrostEIRPtr > 0) {
2703 : // Verify Curve Object, expected type is BiQuadratic
2704 0 : ErrorsFound |= Curve::CheckCurveDims(state,
2705 : thisVrfFluidCtrl.DefrostEIRPtr, // Curve index
2706 : {2}, // Valid dimensions
2707 : RoutineName, // Routine name
2708 : cCurrentModuleObject, // Object Type
2709 : thisVrfFluidCtrl.Name, // Object Name
2710 0 : cAlphaFieldNames(10)); // Field Name
2711 : } else {
2712 0 : if (thisVrfFluidCtrl.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle &&
2713 0 : thisVrfFluidCtrl.DefrostControl == StandardRatings::HPdefrostControl::OnDemand) {
2714 0 : ShowSevereError(
2715 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\" " + cAlphaFieldNames(10) + " not found:" + cAlphaArgs(10));
2716 0 : ErrorsFound = true;
2717 : }
2718 : }
2719 : } else {
2720 6 : if (thisVrfFluidCtrl.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle &&
2721 6 : thisVrfFluidCtrl.DefrostControl == StandardRatings::HPdefrostControl::OnDemand) {
2722 0 : ShowSevereError(
2723 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\" " + cAlphaFieldNames(10) + " not found:" + cAlphaArgs(10));
2724 0 : ErrorsFound = true;
2725 : }
2726 : }
2727 :
2728 6 : thisVrfFluidCtrl.DefrostFraction = rNumericArgs(27);
2729 6 : thisVrfFluidCtrl.DefrostCapacity = rNumericArgs(28);
2730 6 : thisVrfFluidCtrl.MaxOATDefrost = rNumericArgs(29);
2731 6 : if (thisVrfFluidCtrl.DefrostCapacity == 0.0 && thisVrfFluidCtrl.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
2732 0 : ShowWarningError(state,
2733 0 : cCurrentModuleObject + ", \"" + thisVrfFluidCtrl.Name + "\" " + cNumericFieldNames(28) +
2734 : " = 0.0 for defrost strategy = RESISTIVE.");
2735 : }
2736 :
2737 6 : thisVrfFluidCtrl.CompMaxDeltaP = rNumericArgs(30);
2738 :
2739 : //@@ The control type
2740 6 : std::string ThermostatPriorityType = "LoadPriority"; // cAlphaArgs( 25 )
2741 6 : if (Util::SameString(ThermostatPriorityType, "LoadPriority")) {
2742 6 : thisVrfFluidCtrl.ThermostatPriority = ThermostatCtrlType::LoadPriority;
2743 0 : } else if (Util::SameString(ThermostatPriorityType, "ZonePriority")) {
2744 0 : thisVrfFluidCtrl.ThermostatPriority = ThermostatCtrlType::ZonePriority;
2745 0 : } else if (Util::SameString(ThermostatPriorityType, "ThermostatOffsetPriority")) {
2746 0 : thisVrfFluidCtrl.ThermostatPriority = ThermostatCtrlType::ThermostatOffsetPriority;
2747 0 : } else if (Util::SameString(ThermostatPriorityType, "Scheduled")) {
2748 0 : thisVrfFluidCtrl.ThermostatPriority = ThermostatCtrlType::ScheduledPriority;
2749 0 : } else if (Util::SameString(ThermostatPriorityType, "MasterThermostatPriority")) {
2750 0 : thisVrfFluidCtrl.ThermostatPriority = ThermostatCtrlType::MasterThermostatPriority;
2751 0 : if (thisVrfFluidCtrl.MasterZonePtr == 0) {
2752 0 : ShowSevereError(state, cCurrentModuleObject + " = \"" + thisVrfFluidCtrl.Name + "\"");
2753 : //** ShowContinueError(state, cAlphaFieldNames( 24 ) + " must be entered when " + cAlphaFieldNames( 25 ) + " = " + cAlphaArgs( 25 )
2754 : //);
2755 0 : ErrorsFound = true;
2756 : }
2757 : } else {
2758 0 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfFluidCtrl.Name);
2759 : // ShowContinueError(state, "Illegal " + cAlphaFieldNames( 25 ) + " = " + cAlphaArgs( 25 ) );
2760 0 : ErrorsFound = true;
2761 : }
2762 :
2763 : // The new VRF model is Air cooled
2764 6 : thisVrfFluidCtrl.CondenserType = DataHeatBalance::RefrigCondenserType::Air;
2765 6 : thisVrfFluidCtrl.CondenserNodeNum = 0;
2766 :
2767 : // Evaporative Capacity & Compressor Power Curves corresponding to each Loading Index / compressor speed
2768 6 : int NumOfCompSpd = rNumericArgs(31);
2769 6 : thisVrfFluidCtrl.CompressorSpeed.dimension(NumOfCompSpd);
2770 6 : thisVrfFluidCtrl.OUCoolingCAPFT.dimension(NumOfCompSpd);
2771 6 : thisVrfFluidCtrl.OUCoolingPWRFT.dimension(NumOfCompSpd);
2772 6 : int Count1Index = 31; // the index of the last numeric field before compressor speed entries
2773 6 : int Count2Index = 9; // the index of the last alpha field before capacity/power curves
2774 24 : for (int NumCompSpd = 1; NumCompSpd <= NumOfCompSpd; NumCompSpd++) {
2775 18 : thisVrfFluidCtrl.CompressorSpeed(NumCompSpd) = rNumericArgs(Count1Index + NumCompSpd);
2776 :
2777 : // Evaporating Capacity Curve
2778 18 : if (!lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd)) {
2779 18 : int indexOUEvapCapCurve = GetCurveIndex(state, cAlphaArgs(Count2Index + 2 * NumCompSpd)); // convert curve name to index number
2780 18 : if (indexOUEvapCapCurve == 0) { // Verify curve name and type
2781 0 : if (lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd)) {
2782 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", missing");
2783 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(Count2Index + 2 * NumCompSpd) + " is blank.");
2784 : } else {
2785 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", invalid");
2786 0 : ShowContinueError(state,
2787 0 : format("...not found {}=\"{}\".",
2788 0 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd),
2789 0 : cAlphaArgs(Count2Index + 2 * NumCompSpd)));
2790 : }
2791 0 : ErrorsFound = true;
2792 : } else {
2793 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2794 : indexOUEvapCapCurve, // Curve index
2795 : {2}, // Valid dimensions
2796 : RoutineName, // Routine name
2797 : cCurrentModuleObject, // Object Type
2798 : thisVrfFluidCtrl.Name, // Object Name
2799 18 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd)); // Field Name
2800 :
2801 18 : if (!ErrorsFound) {
2802 18 : thisVrfFluidCtrl.OUCoolingCAPFT(NumCompSpd) = indexOUEvapCapCurve;
2803 : }
2804 : }
2805 : }
2806 :
2807 : // Compressor Power Curve
2808 18 : if (!lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd + 1)) {
2809 18 : int indexOUCompPwrCurve = GetCurveIndex(state, cAlphaArgs(Count2Index + 2 * NumCompSpd + 1)); // convert curve name to index number
2810 18 : if (indexOUCompPwrCurve == 0) { // Verify curve name and type
2811 0 : if (lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd + 1)) {
2812 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", missing");
2813 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(Count2Index + 2 * NumCompSpd + 1) + " is blank.");
2814 : } else {
2815 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrl.Name + "\", invalid");
2816 0 : ShowContinueError(state,
2817 0 : format("...not found {}=\"{}\".",
2818 0 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd + 1),
2819 0 : cAlphaArgs(Count2Index + 2 * NumCompSpd + 1)));
2820 : }
2821 0 : ErrorsFound = true;
2822 : } else {
2823 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2824 : indexOUCompPwrCurve, // Curve index
2825 : {2}, // Valid dimensions
2826 : RoutineName, // Routine name
2827 : cCurrentModuleObject, // Object Type
2828 : thisVrfFluidCtrl.Name, // Object Name
2829 18 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd + 1)); // Field Name
2830 :
2831 18 : if (!ErrorsFound) {
2832 18 : thisVrfFluidCtrl.OUCoolingPWRFT(NumCompSpd) = indexOUCompPwrCurve;
2833 : }
2834 : }
2835 : }
2836 : }
2837 6 : }
2838 :
2839 : // Read all VRF condenser objects: Algorithm Type 2_physics based model (VRF-FluidTCtrl-HR)
2840 23 : cCurrentModuleObject = "AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl:HR";
2841 26 : for (int thisNum = 1; thisNum <= state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HR; ++thisNum) {
2842 :
2843 3 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2844 : cCurrentModuleObject,
2845 : thisNum,
2846 : cAlphaArgs,
2847 : NumAlphas,
2848 : rNumericArgs,
2849 : NumNums,
2850 : IOStat,
2851 : lNumericFieldBlanks,
2852 : lAlphaFieldBlanks,
2853 : cAlphaFieldNames,
2854 : cNumericFieldNames);
2855 :
2856 3 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
2857 :
2858 3 : GlobalNames::VerifyUniqueInterObjectName(
2859 6 : state, state.dataHVACVarRefFlow->VrfUniqueNames, cAlphaArgs(1), cCurrentModuleObject, cAlphaFieldNames(1), ErrorsFound);
2860 :
2861 3 : int VRFNum = state.dataHVACVarRefFlow->NumVRFCond_SysCurve + state.dataHVACVarRefFlow->NumVRFCond_FluidTCtrl_HP + thisNum;
2862 3 : auto &thisVrfFluidCtrlHR = state.dataHVACVarRefFlow->VRF(VRFNum);
2863 :
2864 3 : thisVrfFluidCtrlHR.Name = cAlphaArgs(1);
2865 :
2866 3 : thisVrfFluidCtrlHR.ThermostatPriority = ThermostatCtrlType::LoadPriority;
2867 3 : thisVrfFluidCtrlHR.HeatRecoveryUsed = true;
2868 3 : thisVrfFluidCtrlHR.VRFSystemTypeNum = VRF_HeatPump;
2869 3 : thisVrfFluidCtrlHR.VRFAlgorithmType = AlgorithmType::FluidTCtrl;
2870 3 : thisVrfFluidCtrlHR.fuel = Constant::eFuel::Electricity;
2871 :
2872 3 : if (lAlphaFieldBlanks(2)) {
2873 1 : thisVrfFluidCtrlHR.availSched = Sched::GetScheduleAlwaysOn(state);
2874 2 : } else if ((thisVrfFluidCtrlHR.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
2875 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
2876 0 : ErrorsFound = true;
2877 : }
2878 :
2879 3 : thisVrfFluidCtrlHR.ZoneTUListPtr =
2880 3 : Util::FindItemInList(cAlphaArgs(3), state.dataHVACVarRefFlow->TerminalUnitList, state.dataHVACVarRefFlow->NumVRFTULists);
2881 3 : if (thisVrfFluidCtrlHR.ZoneTUListPtr == 0) {
2882 0 : ShowSevereError(state, cCurrentModuleObject + " = \"" + thisVrfFluidCtrlHR.Name + "\"");
2883 0 : ShowContinueError(state, cAlphaFieldNames(3) + " = " + cAlphaArgs(3) + " not found.");
2884 0 : ErrorsFound = true;
2885 : }
2886 :
2887 : // Refrigerant type
2888 3 : thisVrfFluidCtrlHR.refrigName = cAlphaArgs(4);
2889 3 : if ((thisVrfFluidCtrlHR.refrig = Fluid::GetRefrig(state, thisVrfFluidCtrlHR.refrigName)) == nullptr) {
2890 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(4), cAlphaArgs(4));
2891 0 : ErrorsFound = true;
2892 : }
2893 :
2894 3 : thisVrfFluidCtrlHR.RatedEvapCapacity = rNumericArgs(1);
2895 3 : thisVrfFluidCtrlHR.RatedCompPowerPerCapcity = rNumericArgs(2);
2896 3 : thisVrfFluidCtrlHR.RatedCompPower = thisVrfFluidCtrlHR.RatedCompPowerPerCapcity * thisVrfFluidCtrlHR.RatedEvapCapacity;
2897 3 : thisVrfFluidCtrlHR.CoolingCapacity = thisVrfFluidCtrlHR.RatedEvapCapacity;
2898 3 : thisVrfFluidCtrlHR.HeatingCapacity = thisVrfFluidCtrlHR.RatedEvapCapacity * (1 + thisVrfFluidCtrlHR.RatedCompPowerPerCapcity);
2899 3 : thisVrfFluidCtrlHR.RatedHeatCapacity = thisVrfFluidCtrlHR.HeatingCapacity;
2900 :
2901 : // Reference system COP
2902 3 : thisVrfFluidCtrlHR.CoolingCOP = 1 / thisVrfFluidCtrlHR.RatedCompPowerPerCapcity;
2903 3 : thisVrfFluidCtrlHR.HeatingCOP = 1 / thisVrfFluidCtrlHR.RatedCompPowerPerCapcity + 1;
2904 :
2905 : // OA temperature range for VRF-HP operations
2906 3 : thisVrfFluidCtrlHR.MinOATCooling = rNumericArgs(3);
2907 3 : thisVrfFluidCtrlHR.MaxOATCooling = rNumericArgs(4);
2908 3 : thisVrfFluidCtrlHR.MinOATHeating = rNumericArgs(5);
2909 3 : thisVrfFluidCtrlHR.MaxOATHeating = rNumericArgs(6);
2910 3 : thisVrfFluidCtrlHR.MinOATHeatRecovery = rNumericArgs(7);
2911 3 : thisVrfFluidCtrlHR.MaxOATHeatRecovery = rNumericArgs(8);
2912 3 : if (thisVrfFluidCtrlHR.MinOATCooling >= thisVrfFluidCtrlHR.MaxOATCooling) {
2913 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\"");
2914 0 : ShowContinueError(state,
2915 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2916 : cNumericFieldNames(3),
2917 0 : thisVrfFluidCtrlHR.MinOATCooling,
2918 0 : thisVrfFluidCtrlHR.MaxOATCooling));
2919 0 : ErrorsFound = true;
2920 : }
2921 3 : if (thisVrfFluidCtrlHR.MinOATHeating >= thisVrfFluidCtrlHR.MaxOATHeating) {
2922 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\"");
2923 0 : ShowContinueError(state,
2924 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2925 : cNumericFieldNames(5),
2926 0 : thisVrfFluidCtrlHR.MinOATHeating,
2927 0 : thisVrfFluidCtrlHR.MaxOATHeating));
2928 0 : ErrorsFound = true;
2929 : }
2930 3 : if (thisVrfFluidCtrlHR.MinOATHeatRecovery >= thisVrfFluidCtrlHR.MaxOATHeatRecovery) {
2931 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\"");
2932 0 : ShowContinueError(state,
2933 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2934 : cNumericFieldNames(7),
2935 0 : thisVrfFluidCtrlHR.MinOATHeating,
2936 0 : thisVrfFluidCtrlHR.MaxOATHeating));
2937 0 : ErrorsFound = true;
2938 : }
2939 3 : if (thisVrfFluidCtrlHR.MinOATHeatRecovery < thisVrfFluidCtrlHR.MinOATCooling &&
2940 3 : thisVrfFluidCtrlHR.MinOATHeatRecovery < thisVrfFluidCtrlHR.MinOATHeating) {
2941 0 : ShowWarningError(state,
2942 0 : cCurrentModuleObject + " = \"" + thisVrfFluidCtrlHR.Name + "\", " + cNumericFieldNames(7) +
2943 : " is less than the minimum temperature in heat pump mode.");
2944 0 : ShowContinueError(state, format("...{} = {:.2T} C", cNumericFieldNames(7), thisVrfFluidCtrlHR.MinOATHeatRecovery));
2945 0 : ShowContinueError(state, format("...Minimum Outdoor Temperature in Cooling Mode = {:.2T} C", thisVrfFluidCtrlHR.MinOATCooling));
2946 0 : ShowContinueError(state, format("...Minimum Outdoor Temperature in Heating Mode = {:.2T} C", thisVrfFluidCtrlHR.MinOATHeating));
2947 0 : ShowContinueError(state,
2948 : "...Minimum Outdoor Temperature in Heat Recovery Mode reset to lesser of cooling or heating minimum temperature "
2949 : "and simulation continues.");
2950 0 : thisVrfFluidCtrlHR.MinOATHeatRecovery = min(thisVrfFluidCtrlHR.MinOATCooling, thisVrfFluidCtrlHR.MinOATHeating);
2951 0 : ShowContinueError(state, format("... adjusted {} = {:.2T} C", cNumericFieldNames(7), thisVrfFluidCtrlHR.MinOATHeatRecovery));
2952 : }
2953 3 : if (thisVrfFluidCtrlHR.MaxOATHeatRecovery > thisVrfFluidCtrlHR.MaxOATCooling &&
2954 0 : thisVrfFluidCtrlHR.MaxOATHeatRecovery > thisVrfFluidCtrlHR.MaxOATHeating) {
2955 0 : ShowWarningError(state,
2956 0 : cCurrentModuleObject + " = \"" + thisVrfFluidCtrlHR.Name + "\", " + cNumericFieldNames(8) +
2957 : " is greater than the maximum temperature in heat pump mode.");
2958 0 : ShowContinueError(state, format("...{} = {:.2T} C", cNumericFieldNames(8), thisVrfFluidCtrlHR.MaxOATHeatRecovery));
2959 0 : ShowContinueError(state, format("...Maximum Outdoor Temperature in Cooling Mode = {:.2T} C", thisVrfFluidCtrlHR.MaxOATCooling));
2960 0 : ShowContinueError(state, format("...Maximum Outdoor Temperature in Heating Mode = {:.2T} C", thisVrfFluidCtrlHR.MaxOATHeating));
2961 0 : ShowContinueError(state,
2962 : "...Maximum Outdoor Temperature in Heat Recovery Mode reset to greater of cooling or heating maximum temperature "
2963 : "and simulation continues.");
2964 0 : thisVrfFluidCtrlHR.MaxOATHeatRecovery = max(thisVrfFluidCtrlHR.MaxOATCooling, thisVrfFluidCtrlHR.MaxOATHeating);
2965 0 : ShowContinueError(state, format("... adjusted {} = {:.2T} C", cNumericFieldNames(8), thisVrfFluidCtrlHR.MaxOATHeatRecovery));
2966 : }
2967 :
2968 : // IU Control Type
2969 3 : if (Util::SameString(cAlphaArgs(5), "VariableTemp")) {
2970 0 : thisVrfFluidCtrlHR.AlgorithmIUCtrl = 1;
2971 3 : } else if (Util::SameString(cAlphaArgs(5), "ConstantTemp")) {
2972 3 : thisVrfFluidCtrlHR.AlgorithmIUCtrl = 2;
2973 : } else {
2974 0 : thisVrfFluidCtrlHR.AlgorithmIUCtrl = 1;
2975 : }
2976 :
2977 : // Reference IU Te/Tc for IU Control Algorithm: ConstantTemp
2978 3 : thisVrfFluidCtrlHR.EvapTempFixed = rNumericArgs(9);
2979 3 : thisVrfFluidCtrlHR.CondTempFixed = rNumericArgs(10);
2980 :
2981 : // Bounds of Te/Tc for IU Control Algorithm: VariableTemp
2982 3 : thisVrfFluidCtrlHR.IUEvapTempLow = rNumericArgs(11);
2983 3 : thisVrfFluidCtrlHR.IUEvapTempHigh = rNumericArgs(12);
2984 3 : thisVrfFluidCtrlHR.IUCondTempLow = rNumericArgs(13);
2985 3 : thisVrfFluidCtrlHR.IUCondTempHigh = rNumericArgs(14);
2986 3 : if (thisVrfFluidCtrlHR.IUEvapTempLow >= thisVrfFluidCtrlHR.IUEvapTempHigh) {
2987 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\"");
2988 0 : ShowContinueError(state,
2989 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2990 : cNumericFieldNames(11),
2991 0 : thisVrfFluidCtrlHR.IUEvapTempLow,
2992 0 : thisVrfFluidCtrlHR.IUEvapTempHigh));
2993 0 : ErrorsFound = true;
2994 : }
2995 3 : if (thisVrfFluidCtrlHR.IUCondTempLow >= thisVrfFluidCtrlHR.IUCondTempHigh) {
2996 0 : ShowSevereError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\"");
2997 0 : ShowContinueError(state,
2998 0 : format("... {} ({:.3T}) must be less than maximum ({:.3T}).",
2999 : cNumericFieldNames(13),
3000 0 : thisVrfFluidCtrlHR.IUCondTempLow,
3001 0 : thisVrfFluidCtrlHR.IUCondTempHigh));
3002 0 : ErrorsFound = true;
3003 : }
3004 :
3005 : // Reference OU SH/SC
3006 3 : thisVrfFluidCtrlHR.SH = rNumericArgs(15);
3007 3 : thisVrfFluidCtrlHR.SC = rNumericArgs(16);
3008 3 : if (thisVrfFluidCtrlHR.SH > 20) {
3009 0 : ShowWarningError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\", \" " + cNumericFieldNames(15));
3010 0 : ShowContinueError(state, "...is higher than 20C, which is usually the maximum of normal range.");
3011 : }
3012 3 : if (thisVrfFluidCtrlHR.SC > 20) {
3013 0 : ShowWarningError(state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\", \" " + cNumericFieldNames(15));
3014 0 : ShowContinueError(state, "...is higher than 20C, which is usually the maximum of normal range.");
3015 : }
3016 :
3017 : // OU Heat Exchanger Rated Bypass Factor
3018 3 : thisVrfFluidCtrlHR.RateBFOUEvap = rNumericArgs(17);
3019 3 : thisVrfFluidCtrlHR.RateBFOUCond = rNumericArgs(18);
3020 :
3021 : // Difference between Outdoor Unit Te and OAT during Simultaneous Heating and Cooling operations
3022 3 : thisVrfFluidCtrlHR.DiffOUTeTo = rNumericArgs(19);
3023 :
3024 : // HR OU Heat Exchanger Capacity Ratio
3025 3 : thisVrfFluidCtrlHR.HROUHexRatio = rNumericArgs(20);
3026 :
3027 : // Get OU fan data
3028 3 : thisVrfFluidCtrlHR.RatedOUFanPowerPerCapcity = rNumericArgs(21);
3029 3 : thisVrfFluidCtrlHR.OUAirFlowRatePerCapcity = rNumericArgs(22);
3030 3 : thisVrfFluidCtrlHR.RatedOUFanPower = thisVrfFluidCtrlHR.RatedOUFanPowerPerCapcity * thisVrfFluidCtrlHR.RatedEvapCapacity;
3031 3 : thisVrfFluidCtrlHR.OUAirFlowRate = thisVrfFluidCtrlHR.OUAirFlowRatePerCapcity * thisVrfFluidCtrlHR.RatedEvapCapacity;
3032 :
3033 : // OUEvapTempCurve
3034 3 : int indexOUEvapTempCurve = GetCurveIndex(state, cAlphaArgs(6)); // convert curve name to index number
3035 : // Verify curve name and type
3036 3 : if (indexOUEvapTempCurve == 0) {
3037 0 : if (lAlphaFieldBlanks(6)) {
3038 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", missing");
3039 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(6) + " is blank.");
3040 : } else {
3041 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", invalid");
3042 0 : ShowContinueError(state, "...not found " + cAlphaFieldNames(6) + "=\"" + cAlphaArgs(6) + "\".");
3043 : }
3044 0 : ErrorsFound = true;
3045 : } else {
3046 3 : if (state.dataCurveManager->curves(indexOUEvapTempCurve)->curveType == Curve::CurveType::Quadratic) {
3047 3 : thisVrfFluidCtrlHR.C1Te = state.dataCurveManager->curves(indexOUEvapTempCurve)->coeff[0];
3048 3 : thisVrfFluidCtrlHR.C2Te = state.dataCurveManager->curves(indexOUEvapTempCurve)->coeff[1];
3049 3 : thisVrfFluidCtrlHR.C3Te = state.dataCurveManager->curves(indexOUEvapTempCurve)->coeff[2];
3050 : } else {
3051 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", invalid");
3052 0 : ShowContinueError(state,
3053 0 : format("...illegal {} type for this object = {}",
3054 : cAlphaFieldNames(6),
3055 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexOUEvapTempCurve)->curveType)]));
3056 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
3057 0 : ErrorsFound = true;
3058 : }
3059 : }
3060 :
3061 : // OUCondTempCurve
3062 3 : int indexOUCondTempCurve = GetCurveIndex(state, cAlphaArgs(7)); // convert curve name to index number
3063 : // Verify curve name and type
3064 3 : if (indexOUCondTempCurve == 0) {
3065 0 : if (lAlphaFieldBlanks(7)) {
3066 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", missing");
3067 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(7) + " is blank.");
3068 : } else {
3069 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", invalid");
3070 0 : ShowContinueError(state, "...not found " + cAlphaFieldNames(7) + "=\"" + cAlphaArgs(7) + "\".");
3071 : }
3072 0 : ErrorsFound = true;
3073 : } else {
3074 3 : if (state.dataCurveManager->curves(indexOUCondTempCurve)->curveType == Curve::CurveType::Quadratic) {
3075 3 : thisVrfFluidCtrlHR.C1Tc = state.dataCurveManager->curves(indexOUCondTempCurve)->coeff[0];
3076 3 : thisVrfFluidCtrlHR.C2Tc = state.dataCurveManager->curves(indexOUCondTempCurve)->coeff[1];
3077 3 : thisVrfFluidCtrlHR.C3Tc = state.dataCurveManager->curves(indexOUCondTempCurve)->coeff[2];
3078 : } else {
3079 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", invalid");
3080 0 : ShowContinueError(state,
3081 0 : format("...illegal {} type for this object = {}",
3082 : cAlphaFieldNames(7),
3083 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexOUCondTempCurve)->curveType)]));
3084 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
3085 0 : ErrorsFound = true;
3086 : }
3087 : }
3088 :
3089 : // Pipe parameters
3090 3 : thisVrfFluidCtrlHR.RefPipDiaSuc = rNumericArgs(23);
3091 3 : thisVrfFluidCtrlHR.RefPipDiaDis = rNumericArgs(24);
3092 3 : thisVrfFluidCtrlHR.RefPipLen = rNumericArgs(25);
3093 3 : thisVrfFluidCtrlHR.RefPipEquLen = rNumericArgs(26);
3094 3 : thisVrfFluidCtrlHR.RefPipHei = rNumericArgs(27);
3095 3 : thisVrfFluidCtrlHR.RefPipInsThi = rNumericArgs(28);
3096 3 : thisVrfFluidCtrlHR.RefPipInsCon = rNumericArgs(29);
3097 :
3098 : // Check the RefPipEquLen
3099 3 : if (lNumericFieldBlanks(26) && !lNumericFieldBlanks(25)) {
3100 0 : thisVrfFluidCtrlHR.RefPipEquLen = 1.2 * thisVrfFluidCtrlHR.RefPipLen;
3101 0 : ShowWarningError(
3102 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\", \" " + cNumericFieldNames(26) + "\" is calculated based on");
3103 0 : ShowContinueError(state, "...the provided \"" + cNumericFieldNames(25) + "\" value.");
3104 : }
3105 3 : if (thisVrfFluidCtrlHR.RefPipEquLen < thisVrfFluidCtrlHR.RefPipLen) {
3106 0 : thisVrfFluidCtrlHR.RefPipEquLen = 1.2 * thisVrfFluidCtrlHR.RefPipLen;
3107 0 : ShowWarningError(state,
3108 0 : cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\", invalid \" " + cNumericFieldNames(26) + "\" value.");
3109 0 : ShowContinueError(state, "...Equivalent length of main pipe should be greater than or equal to the actual length.");
3110 0 : ShowContinueError(state, format("...The value is recalculated based on the provided \"{}\" value.", cNumericFieldNames(25)));
3111 : }
3112 :
3113 : // Crank case
3114 3 : thisVrfFluidCtrlHR.CCHeaterPower = rNumericArgs(30);
3115 3 : thisVrfFluidCtrlHR.NumCompressors = rNumericArgs(31);
3116 3 : thisVrfFluidCtrlHR.CompressorSizeRatio = rNumericArgs(32);
3117 3 : thisVrfFluidCtrlHR.MaxOATCCHeater = rNumericArgs(33);
3118 :
3119 : // Defrost
3120 3 : if (!lAlphaFieldBlanks(8)) {
3121 0 : if (Util::SameString(cAlphaArgs(8), "ReverseCycle")) {
3122 0 : thisVrfFluidCtrlHR.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
3123 : }
3124 0 : if (Util::SameString(cAlphaArgs(8), "Resistive")) {
3125 0 : thisVrfFluidCtrlHR.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
3126 : }
3127 0 : if (thisVrfFluidCtrlHR.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
3128 0 : ShowSevereError(
3129 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\" " + cAlphaFieldNames(8) + " not found: " + cAlphaArgs(8));
3130 0 : ErrorsFound = true;
3131 : }
3132 : } else {
3133 3 : thisVrfFluidCtrlHR.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
3134 : }
3135 :
3136 3 : if (!lAlphaFieldBlanks(9)) {
3137 0 : if (Util::SameString(cAlphaArgs(9), "Timed")) {
3138 0 : thisVrfFluidCtrlHR.DefrostControl = StandardRatings::HPdefrostControl::Timed;
3139 : }
3140 0 : if (Util::SameString(cAlphaArgs(9), "OnDemand")) {
3141 0 : thisVrfFluidCtrlHR.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
3142 : }
3143 0 : if (thisVrfFluidCtrlHR.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
3144 0 : ShowSevereError(
3145 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\" " + cAlphaFieldNames(9) + " not found: " + cAlphaArgs(9));
3146 0 : ErrorsFound = true;
3147 : }
3148 : } else {
3149 3 : thisVrfFluidCtrlHR.DefrostControl = StandardRatings::HPdefrostControl::Timed;
3150 : }
3151 :
3152 3 : if (!lAlphaFieldBlanks(10)) {
3153 0 : thisVrfFluidCtrlHR.DefrostEIRPtr = GetCurveIndex(state, cAlphaArgs(10));
3154 0 : if (thisVrfFluidCtrlHR.DefrostEIRPtr > 0) {
3155 : // Verify Curve Object, expected type is BiQuadratic
3156 0 : ErrorsFound |= Curve::CheckCurveDims(state,
3157 : thisVrfFluidCtrlHR.DefrostEIRPtr, // Curve index
3158 : {2}, // Valid dimensions
3159 : RoutineName, // Routine name
3160 : cCurrentModuleObject, // Object Type
3161 : thisVrfFluidCtrlHR.Name, // Object Name
3162 0 : cAlphaFieldNames(10)); // Field Name
3163 : } else {
3164 0 : if (thisVrfFluidCtrlHR.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle &&
3165 0 : thisVrfFluidCtrlHR.DefrostControl == StandardRatings::HPdefrostControl::OnDemand) {
3166 0 : ShowSevereError(state,
3167 0 : cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\" " + cAlphaFieldNames(10) +
3168 0 : " not found:" + cAlphaArgs(10));
3169 0 : ErrorsFound = true;
3170 : }
3171 : }
3172 : } else {
3173 3 : if (thisVrfFluidCtrlHR.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle &&
3174 3 : thisVrfFluidCtrlHR.DefrostControl == StandardRatings::HPdefrostControl::OnDemand) {
3175 0 : ShowSevereError(
3176 0 : state, cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\" " + cAlphaFieldNames(10) + " not found:" + cAlphaArgs(10));
3177 0 : ErrorsFound = true;
3178 : }
3179 : }
3180 :
3181 3 : thisVrfFluidCtrlHR.DefrostFraction = rNumericArgs(34);
3182 3 : thisVrfFluidCtrlHR.DefrostCapacity = rNumericArgs(35);
3183 3 : thisVrfFluidCtrlHR.MaxOATDefrost = rNumericArgs(36);
3184 3 : if (thisVrfFluidCtrlHR.DefrostCapacity == 0.0 && thisVrfFluidCtrlHR.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
3185 0 : ShowWarningError(state,
3186 0 : cCurrentModuleObject + ", \"" + thisVrfFluidCtrlHR.Name + "\" " + cNumericFieldNames(35) +
3187 : " = 0.0 for defrost strategy = RESISTIVE.");
3188 : }
3189 :
3190 : // HR mode transition
3191 3 : thisVrfFluidCtrlHR.HRInitialCoolCapFrac = rNumericArgs(37);
3192 3 : thisVrfFluidCtrlHR.HRCoolCapTC = rNumericArgs(38);
3193 3 : thisVrfFluidCtrlHR.HRInitialCoolEIRFrac = rNumericArgs(39);
3194 3 : thisVrfFluidCtrlHR.HRCoolEIRTC = rNumericArgs(40);
3195 3 : thisVrfFluidCtrlHR.HRInitialHeatCapFrac = rNumericArgs(41);
3196 3 : thisVrfFluidCtrlHR.HRHeatCapTC = rNumericArgs(42);
3197 3 : thisVrfFluidCtrlHR.HRInitialHeatEIRFrac = rNumericArgs(43);
3198 3 : thisVrfFluidCtrlHR.HRHeatEIRTC = rNumericArgs(44);
3199 :
3200 : // Compressor configuration
3201 3 : thisVrfFluidCtrlHR.CompMaxDeltaP = rNumericArgs(45);
3202 3 : thisVrfFluidCtrlHR.EffCompInverter = rNumericArgs(46);
3203 3 : thisVrfFluidCtrlHR.CoffEvapCap = rNumericArgs(47);
3204 :
3205 : // The new VRF model is Air cooled
3206 3 : thisVrfFluidCtrlHR.CondenserType = DataHeatBalance::RefrigCondenserType::Air;
3207 3 : thisVrfFluidCtrlHR.CondenserNodeNum = 0;
3208 :
3209 : // Evaporative Capacity & Compressor Power Curves corresponding to each Loading Index / compressor speed
3210 3 : int NumOfCompSpd = rNumericArgs(48);
3211 3 : thisVrfFluidCtrlHR.CompressorSpeed.dimension(NumOfCompSpd);
3212 3 : thisVrfFluidCtrlHR.OUCoolingCAPFT.dimension(NumOfCompSpd);
3213 3 : thisVrfFluidCtrlHR.OUCoolingPWRFT.dimension(NumOfCompSpd);
3214 3 : int Count1Index = 48; // the index of the last numeric field before compressor speed entries
3215 3 : int Count2Index = 9; // the index of the last alpha field before capacity/power curves
3216 12 : for (int NumCompSpd = 1; NumCompSpd <= NumOfCompSpd; NumCompSpd++) {
3217 9 : thisVrfFluidCtrlHR.CompressorSpeed(NumCompSpd) = rNumericArgs(Count1Index + NumCompSpd);
3218 :
3219 : // Evaporating Capacity Curve
3220 9 : if (!lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd)) {
3221 9 : int indexOUEvapCapCurve = GetCurveIndex(state, cAlphaArgs(Count2Index + 2 * NumCompSpd)); // convert curve name to index number
3222 9 : if (indexOUEvapCapCurve == 0) { // Verify curve name and type
3223 0 : if (lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd)) {
3224 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", missing");
3225 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(Count2Index + 2 * NumCompSpd) + " is blank.");
3226 : } else {
3227 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", invalid");
3228 0 : ShowContinueError(state,
3229 0 : format("...not found {}=\"{}\".",
3230 0 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd),
3231 0 : cAlphaArgs(Count2Index + 2 * NumCompSpd)));
3232 : }
3233 0 : ErrorsFound = true;
3234 : } else {
3235 18 : ErrorsFound |= Curve::CheckCurveDims(state,
3236 : indexOUEvapCapCurve, // Curve index
3237 : {2}, // Valid dimensions
3238 : RoutineName, // Routine name
3239 : cCurrentModuleObject, // Object Type
3240 : thisVrfFluidCtrlHR.Name, // Object Name
3241 9 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd)); // Field Name
3242 :
3243 9 : if (!ErrorsFound) {
3244 9 : thisVrfFluidCtrlHR.OUCoolingCAPFT(NumCompSpd) = indexOUEvapCapCurve;
3245 : }
3246 : }
3247 : }
3248 :
3249 : // Compressor Power Curve
3250 9 : if (!lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd + 1)) {
3251 9 : int indexOUCompPwrCurve = GetCurveIndex(state, cAlphaArgs(Count2Index + 2 * NumCompSpd + 1)); // convert curve name to index number
3252 9 : if (indexOUCompPwrCurve == 0) { // Verify curve name and type
3253 0 : if (lAlphaFieldBlanks(Count2Index + 2 * NumCompSpd + 1)) {
3254 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", missing");
3255 0 : ShowContinueError(state, "...required " + cAlphaFieldNames(Count2Index + 2 * NumCompSpd + 1) + " is blank.");
3256 : } else {
3257 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisVrfFluidCtrlHR.Name + "\", invalid");
3258 0 : ShowContinueError(state,
3259 0 : format("...not found {}=\"{}\".",
3260 0 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd + 1),
3261 0 : cAlphaArgs(Count2Index + 2 * NumCompSpd + 1)));
3262 : }
3263 0 : ErrorsFound = true;
3264 : } else {
3265 18 : ErrorsFound |= Curve::CheckCurveDims(state,
3266 : indexOUCompPwrCurve, // Curve index
3267 : {2}, // Valid dimensions
3268 : RoutineName, // Routine name
3269 : cCurrentModuleObject, // Object Type
3270 : thisVrfFluidCtrlHR.Name, // Object Name
3271 9 : cAlphaFieldNames(Count2Index + 2 * NumCompSpd + 1)); // Field Name
3272 :
3273 9 : if (!ErrorsFound) {
3274 9 : thisVrfFluidCtrlHR.OUCoolingPWRFT(NumCompSpd) = indexOUCompPwrCurve;
3275 : }
3276 : }
3277 : }
3278 : }
3279 : }
3280 :
3281 23 : cCurrentModuleObject = "ZoneHVAC:TerminalUnit:VariableRefrigerantFlow";
3282 57 : for (int VRFTUNum = 1; VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU; ++VRFTUNum) {
3283 :
3284 : // initialize local node number variables
3285 34 : int CCoilInletNodeNum = 0;
3286 34 : int CCoilOutletNodeNum = 0;
3287 34 : int HCoilInletNodeNum = 0;
3288 34 : int HCoilOutletNodeNum = 0;
3289 34 : OANodeNums = 0;
3290 :
3291 34 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3292 : cCurrentModuleObject,
3293 : VRFTUNum,
3294 : cAlphaArgs,
3295 : NumAlphas,
3296 : rNumericArgs,
3297 : NumNums,
3298 : IOStat,
3299 : lNumericFieldBlanks,
3300 : lAlphaFieldBlanks,
3301 : cAlphaFieldNames,
3302 : cNumericFieldNames);
3303 :
3304 34 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
3305 :
3306 34 : state.dataHVACVarRefFlow->VRFTUNumericFields(VRFTUNum).FieldNames.allocate(NumNums);
3307 34 : state.dataHVACVarRefFlow->VRFTUNumericFields(VRFTUNum).FieldNames = cNumericFieldNames;
3308 34 : Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
3309 :
3310 34 : auto &thisVrfTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
3311 34 : thisVrfTU.Name = cAlphaArgs(1);
3312 42 : for (int NumList = 1; NumList <= state.dataHVACVarRefFlow->NumVRFTULists; ++NumList) {
3313 41 : int ZoneTerminalUnitListNum = Util::FindItemInList(thisVrfTU.Name,
3314 41 : state.dataHVACVarRefFlow->TerminalUnitList(NumList).ZoneTUName,
3315 41 : state.dataHVACVarRefFlow->TerminalUnitList(NumList).NumTUInList);
3316 41 : if (ZoneTerminalUnitListNum > 0) {
3317 33 : thisVrfTU.IndexToTUInTUList = ZoneTerminalUnitListNum;
3318 33 : state.dataHVACVarRefFlow->TerminalUnitList(NumList).ZoneTUPtr(ZoneTerminalUnitListNum) = VRFTUNum;
3319 33 : thisVrfTU.TUListIndex = NumList;
3320 33 : break;
3321 : }
3322 : }
3323 34 : if (thisVrfTU.TUListIndex == 0) {
3324 1 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfTU.Name);
3325 2 : ShowContinueError(state, "Terminal unit not found on any ZoneTerminalUnitList.");
3326 1 : ErrorsFound = true;
3327 : }
3328 :
3329 41 : for (int NumCond = 1; NumCond <= state.dataHVACVarRefFlow->NumVRFCond; ++NumCond) {
3330 40 : if (state.dataHVACVarRefFlow->VRF(NumCond).ZoneTUListPtr != thisVrfTU.TUListIndex) {
3331 7 : continue;
3332 : }
3333 33 : thisVrfTU.VRFSysNum = NumCond;
3334 33 : break;
3335 : }
3336 34 : thisVrfTU.type = TUType::ConstantVolume;
3337 34 : if (lAlphaFieldBlanks(2)) {
3338 4 : thisVrfTU.availSched = Sched::GetScheduleAlwaysOn(state);
3339 30 : } else if ((thisVrfTU.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
3340 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
3341 0 : ErrorsFound = true;
3342 : }
3343 :
3344 34 : thisVrfTU.VRFTUInletNodeNum = GetOnlySingleNode(state,
3345 34 : cAlphaArgs(3),
3346 : ErrorsFound,
3347 : DataLoopNode::ConnectionObjectType::ZoneHVACTerminalUnitVariableRefrigerantFlow,
3348 34 : thisVrfTU.Name,
3349 : DataLoopNode::NodeFluidType::Air,
3350 : DataLoopNode::ConnectionType::Inlet,
3351 : NodeInputManager::CompFluidStream::Primary,
3352 : ObjectIsParent);
3353 :
3354 34 : thisVrfTU.VRFTUOutletNodeNum = GetOnlySingleNode(state,
3355 34 : cAlphaArgs(4),
3356 : ErrorsFound,
3357 : DataLoopNode::ConnectionObjectType::ZoneHVACTerminalUnitVariableRefrigerantFlow,
3358 34 : thisVrfTU.Name,
3359 : DataLoopNode::NodeFluidType::Air,
3360 : DataLoopNode::ConnectionType::Outlet,
3361 : NodeInputManager::CompFluidStream::Primary,
3362 : ObjectIsParent);
3363 :
3364 34 : thisVrfTU.MaxCoolAirVolFlow = rNumericArgs(1);
3365 34 : thisVrfTU.MaxNoCoolAirVolFlow = rNumericArgs(2);
3366 34 : thisVrfTU.MaxHeatAirVolFlow = rNumericArgs(3);
3367 34 : thisVrfTU.MaxNoHeatAirVolFlow = rNumericArgs(4);
3368 34 : thisVrfTU.CoolOutAirVolFlow = rNumericArgs(5);
3369 34 : thisVrfTU.HeatOutAirVolFlow = rNumericArgs(6);
3370 34 : thisVrfTU.NoCoolHeatOutAirVolFlow = rNumericArgs(7);
3371 :
3372 34 : if (lAlphaFieldBlanks(5)) {
3373 0 : thisVrfTU.fanOp = HVAC::FanOp::Continuous;
3374 34 : } else if ((thisVrfTU.fanOpModeSched = Sched::GetSchedule(state, cAlphaArgs(5))) == nullptr) {
3375 18 : ShowWarningItemNotFound(
3376 9 : state, eoh, cAlphaFieldNames(5), cAlphaArgs(5), "Defaulting to constant fan operating mode and simulation continues.");
3377 9 : thisVrfTU.fanOp = HVAC::FanOp::Continuous;
3378 : }
3379 :
3380 34 : thisVrfTU.fanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, cAlphaArgs(6)));
3381 34 : assert(thisVrfTU.fanPlace != HVAC::FanPlace::Invalid);
3382 :
3383 34 : if (!lAlphaFieldBlanks(7) && !lAlphaFieldBlanks(8)) {
3384 : // Get fan data
3385 34 : std::string FanName = cAlphaArgs(8);
3386 :
3387 34 : thisVrfTU.fanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, cAlphaArgs(7)));
3388 :
3389 34 : if (thisVrfTU.fanType != HVAC::FanType::OnOff && thisVrfTU.fanType != HVAC::FanType::Constant &&
3390 20 : thisVrfTU.fanType != HVAC::FanType::VAV && thisVrfTU.fanType != HVAC::FanType::SystemModel) {
3391 0 : ShowSevereInvalidKey(state,
3392 : eoh,
3393 0 : cAlphaFieldNames(7),
3394 0 : cAlphaArgs(7),
3395 : "Only types Fan:ConstantVolume, Fan:VAV, Fan:OnOff, and Fan:SystemModel are supported");
3396 0 : ErrorsFound = true;
3397 : }
3398 :
3399 34 : if ((thisVrfTU.FanIndex = Fans::GetFanIndex(state, FanName)) == 0) {
3400 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(8), FanName);
3401 0 : ErrorsFound = true;
3402 :
3403 34 : } else if (thisVrfTU.fanType != state.dataFans->fans(thisVrfTU.FanIndex)->type) {
3404 0 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfTU.Name);
3405 0 : ShowContinueError(state, "Fan type specified = " + cAlphaArgs(7));
3406 0 : ShowContinueError(state, format("Actual type of fan {} = {}", FanName, HVAC::fanTypeNames[(int)thisVrfTU.fanType]));
3407 0 : ErrorsFound = true;
3408 : }
3409 :
3410 34 : if (thisVrfTU.VRFSysNum > 0) {
3411 : // VRFTU Supply Air Fan Object Type must be Fan:VariableVolume if VRF Algorithm Type is AlgorithmTypeFluidTCtrl
3412 44 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFAlgorithmType == AlgorithmType::FluidTCtrl &&
3413 11 : !(thisVrfTU.fanType == HVAC::FanType::VAV || thisVrfTU.fanType == HVAC::FanType::SystemModel)) {
3414 0 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfTU.Name);
3415 0 : ShowContinueError(state, "Fan type specified = " + cAlphaArgs(7));
3416 0 : ShowContinueError(
3417 : state, "Fan Object Type must be Fan:VariableVolume if VRF AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl");
3418 0 : ShowContinueError(state, "is used to model VRF outdoor unit.");
3419 0 : ErrorsFound = true;
3420 : }
3421 : // VRFTU Supply Air Fan Object Type must be Fan:OnOff or Fan:ConstantVolume if VRF Algorithm Type is AlgorithmTypeSysCurve
3422 55 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFAlgorithmType == AlgorithmType::SysCurve &&
3423 22 : !(thisVrfTU.fanType == HVAC::FanType::OnOff || thisVrfTU.fanType == HVAC::FanType::Constant ||
3424 9 : thisVrfTU.fanType == HVAC::FanType::SystemModel)) {
3425 0 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfTU.Name);
3426 0 : ShowContinueError(state, "Fan type specified = " + cAlphaArgs(7));
3427 0 : ShowContinueError(state,
3428 : "Fan Object Type must be Fan:SystemModel, Fan:OnOff, or Fan:ConstantVolume if VRF "
3429 : "AirConditioner:VariableRefrigerantFlow");
3430 0 : ShowContinueError(state, "is used to model VRF outdoor unit.");
3431 0 : ErrorsFound = true;
3432 : }
3433 : }
3434 :
3435 34 : auto *fan = state.dataFans->fans(thisVrfTU.FanIndex);
3436 :
3437 34 : thisVrfTU.fanInletNode = fan->inletNodeNum;
3438 34 : thisVrfTU.fanOutletNode = fan->outletNodeNum;
3439 :
3440 34 : Real64 FanVolFlowRate = fan->maxAirFlowRate;
3441 34 : thisVrfTU.ActualFanVolFlowRate = FanVolFlowRate;
3442 34 : int FanInletNodeNum = fan->inletNodeNum;
3443 34 : int FanOutletNodeNum = fan->outletNodeNum;
3444 34 : thisVrfTU.fanAvailSched = fan->availSched;
3445 :
3446 : // Check fan's schedule for cycling fan operation if constant volume fan is used
3447 34 : if (thisVrfTU.fanOpModeSched != nullptr && thisVrfTU.fanType == HVAC::FanType::Constant) {
3448 7 : if (!thisVrfTU.fanOpModeSched->checkMinMaxVals(state, Clusive::Ex, 0.0, Clusive::In, 1.0)) {
3449 0 : Sched::ShowSevereBadMinMax(state,
3450 : eoh,
3451 0 : cAlphaFieldNames(5),
3452 0 : cAlphaArgs(5),
3453 : Clusive::Ex,
3454 : 0.0,
3455 : Clusive::In,
3456 : 1.0,
3457 0 : format("For fan type = {}, operating mode must be continuous (schedule values > 0).",
3458 0 : HVAC::fanTypeNames[(int)HVAC::FanType::Constant]));
3459 0 : ErrorsFound = true;
3460 : }
3461 : } // IF (FanType_Num == HVAC::FanType_SimpleOnOff .OR. FanType_Num == HVAC::FanType_SimpleConstVolume)THEN
3462 :
3463 : // Add TU to component sets array
3464 102 : SetUpCompSets(state,
3465 : cCurrentModuleObject,
3466 : thisVrfTU.Name,
3467 34 : HVAC::fanTypeNames[(int)thisVrfTU.fanType],
3468 : FanName,
3469 34 : state.dataLoopNodes->NodeID(FanInletNodeNum),
3470 34 : state.dataLoopNodes->NodeID(FanOutletNodeNum));
3471 :
3472 34 : } else {
3473 0 : thisVrfTU.fanPlace = HVAC::FanPlace::Invalid; // reset fan placement when fan is not used so as not to call the fan
3474 0 : thisVrfTU.fanAvailSched =
3475 0 : Sched::GetScheduleAlwaysOn(state); // A missing fan is the same as a fan that is always on for availability purposes
3476 : }
3477 :
3478 : // Get OA mixer data
3479 34 : std::string OAMixerType = cAlphaArgs(9);
3480 :
3481 34 : if (!lAlphaFieldBlanks(10)) {
3482 26 : thisVrfTU.OAMixerName = cAlphaArgs(10);
3483 26 : errFlag = false;
3484 26 : OANodeNums = GetOAMixerNodeNumbers(state, thisVrfTU.OAMixerName, errFlag);
3485 :
3486 : // OANodeNums(1) = OAMixer(OAMixerNum)%InletNode
3487 : // OANodeNums(2) = OAMixer(OAMixerNum)%RelNode
3488 : // OANodeNums(3) = OAMixer(OAMixerNum)%RetNode
3489 : // OANodeNums(4) = OAMixer(OAMixerNum)%MixNode
3490 :
3491 26 : if (errFlag) {
3492 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
3493 0 : ErrorsFound = true;
3494 : } else {
3495 26 : thisVrfTU.OAMixerUsed = true;
3496 : }
3497 26 : thisVrfTU.VRFTUOAMixerOANodeNum = OANodeNums(1);
3498 26 : thisVrfTU.VRFTUOAMixerRelNodeNum = OANodeNums(2);
3499 26 : thisVrfTU.VRFTUOAMixerRetNodeNum = OANodeNums(3);
3500 26 : thisVrfTU.VRFTUOAMixerMixedNodeNum = OANodeNums(4);
3501 : }
3502 :
3503 : // Get DX cooling coil data
3504 34 : std::string DXCoolingCoilType = cAlphaArgs(11);
3505 :
3506 34 : errFlag = false;
3507 34 : thisVrfTU.DXCoolCoilType_Num = GetCoilTypeNum(state, DXCoolingCoilType, cAlphaArgs(12), errFlag, false);
3508 34 : if (thisVrfTU.DXCoolCoilType_Num == 0) {
3509 0 : thisVrfTU.CoolingCoilPresent = false;
3510 0 : if (thisVrfTU.TUListIndex > 0 && thisVrfTU.IndexToTUInTUList > 0) {
3511 0 : state.dataHVACVarRefFlow->TerminalUnitList(thisVrfTU.TUListIndex).CoolingCoilPresent(thisVrfTU.IndexToTUInTUList) = false;
3512 : }
3513 : } else {
3514 34 : if (thisVrfTU.VRFSysNum > 0) {
3515 33 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
3516 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
3517 :
3518 11 : if (Util::SameString(HVAC::cAllCoilTypes(thisVrfTU.DXCoolCoilType_Num), HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling))) {
3519 11 : errFlag = false;
3520 11 : if (thisVrfTU.TUListIndex > 0 && thisVrfTU.IndexToTUInTUList > 0) {
3521 11 : state.dataHVACVarRefFlow->TerminalUnitList(thisVrfTU.TUListIndex).coolingCoilAvailScheds(thisVrfTU.IndexToTUInTUList) =
3522 22 : DXCoils::GetDXCoilAvailSched(state, DXCoolingCoilType, cAlphaArgs(12), errFlag);
3523 : }
3524 22 : GetDXCoilIndex(
3525 11 : state, cAlphaArgs(12), thisVrfTU.CoolCoilIndex, errFlag, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling));
3526 : CCoilInletNodeNum =
3527 11 : DXCoils::GetCoilInletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling), cAlphaArgs(12), errFlag);
3528 : CCoilOutletNodeNum =
3529 11 : DXCoils::GetCoilOutletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling), cAlphaArgs(12), errFlag);
3530 11 : thisVrfTU.coolCoilAirInNode = CCoilInletNodeNum;
3531 11 : thisVrfTU.coolCoilAirOutNode = CCoilOutletNodeNum;
3532 :
3533 11 : if (errFlag) {
3534 0 : ShowContinueError(state, "...occurs in " + cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3535 : }
3536 :
3537 11 : if (thisVrfTU.VRFSysNum > 0) {
3538 22 : SetDXCoolingCoilData(
3539 11 : state, thisVrfTU.CoolCoilIndex, ErrorsFound, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserType);
3540 22 : SetDXCoolingCoilData(state,
3541 : thisVrfTU.CoolCoilIndex,
3542 : ErrorsFound,
3543 : _,
3544 : _,
3545 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserNodeNum);
3546 22 : SetDXCoolingCoilData(state,
3547 : thisVrfTU.CoolCoilIndex,
3548 : ErrorsFound,
3549 : _,
3550 : _,
3551 : _,
3552 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATCCHeater);
3553 22 : SetDXCoolingCoilData(state,
3554 : thisVrfTU.CoolCoilIndex,
3555 : ErrorsFound,
3556 : _,
3557 : _,
3558 : _,
3559 : _,
3560 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MinOATCooling);
3561 22 : SetDXCoolingCoilData(state,
3562 : thisVrfTU.CoolCoilIndex,
3563 : ErrorsFound,
3564 : _,
3565 : _,
3566 : _,
3567 : _,
3568 : _,
3569 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATCooling);
3570 :
3571 11 : state.dataDXCoils->DXCoil(thisVrfTU.CoolCoilIndex).VRFIUPtr = VRFTUNum;
3572 11 : state.dataDXCoils->DXCoil(thisVrfTU.CoolCoilIndex).VRFOUPtr = thisVrfTU.VRFSysNum;
3573 11 : state.dataDXCoils->DXCoil(thisVrfTU.CoolCoilIndex).SupplyFanIndex = thisVrfTU.FanIndex;
3574 :
3575 11 : if (thisVrfTU.FanIndex > 0) {
3576 11 : state.dataDXCoils->DXCoil(thisVrfTU.CoolCoilIndex).RatedAirVolFlowRate(1) =
3577 11 : state.dataFans->fans(thisVrfTU.FanIndex)->maxAirFlowRate;
3578 : } else {
3579 0 : state.dataDXCoils->DXCoil(thisVrfTU.CoolCoilIndex).RatedAirVolFlowRate(1) = AutoSize;
3580 : }
3581 :
3582 : } else {
3583 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3584 0 : ShowContinueError(
3585 0 : state, "... when checking " + HVAC::cAllCoilTypes(thisVrfTU.DXCoolCoilType_Num) + " \"" + cAlphaArgs(12) + "\"");
3586 0 : ShowContinueError(state, "... terminal unit not connected to condenser.");
3587 0 : ShowContinueError(state, "... check that terminal unit is specified in a terminal unit list object.");
3588 0 : ShowContinueError(state,
3589 : "... also check that the terminal unit list name is specified in an "
3590 : "AirConditioner:VariableRefrigerantFlow object.");
3591 0 : ErrorsFound = true;
3592 : }
3593 : } else {
3594 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3595 0 : ShowContinueError(state, "... illegal " + cAlphaFieldNames(12) + " = " + cAlphaArgs(12));
3596 0 : ErrorsFound = true;
3597 : }
3598 :
3599 : } else {
3600 : // Algorithm Type: VRF model based on system curve
3601 :
3602 22 : if (Util::SameString(HVAC::cAllCoilTypes(thisVrfTU.DXCoolCoilType_Num), HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling))) {
3603 22 : if (thisVrfTU.TUListIndex > 0 && thisVrfTU.IndexToTUInTUList > 0) {
3604 22 : state.dataHVACVarRefFlow->TerminalUnitList(thisVrfTU.TUListIndex).coolingCoilAvailScheds(thisVrfTU.IndexToTUInTUList) =
3605 44 : DXCoils::GetDXCoilAvailSched(state, DXCoolingCoilType, cAlphaArgs(12), errFlag);
3606 : } else {
3607 0 : thisVrfTU.CoolingCoilPresent = false;
3608 : }
3609 22 : errFlag = false;
3610 22 : GetDXCoilIndex(state, cAlphaArgs(12), thisVrfTU.CoolCoilIndex, errFlag, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling));
3611 22 : CCoilInletNodeNum = DXCoils::GetCoilInletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling), cAlphaArgs(12), errFlag);
3612 22 : CCoilOutletNodeNum = DXCoils::GetCoilOutletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling), cAlphaArgs(12), errFlag);
3613 22 : thisVrfTU.coolCoilAirInNode = CCoilInletNodeNum;
3614 22 : thisVrfTU.coolCoilAirOutNode = CCoilOutletNodeNum;
3615 :
3616 22 : if (errFlag) {
3617 0 : ShowContinueError(state, "...occurs in " + cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3618 : }
3619 :
3620 44 : SetDXCoolingCoilData(
3621 22 : state, thisVrfTU.CoolCoilIndex, ErrorsFound, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserType);
3622 44 : SetDXCoolingCoilData(
3623 22 : state, thisVrfTU.CoolCoilIndex, ErrorsFound, _, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserNodeNum);
3624 44 : SetDXCoolingCoilData(
3625 22 : state, thisVrfTU.CoolCoilIndex, ErrorsFound, _, _, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATCCHeater);
3626 44 : SetDXCoolingCoilData(state,
3627 : thisVrfTU.CoolCoilIndex,
3628 : ErrorsFound,
3629 : _,
3630 : _,
3631 : _,
3632 : _,
3633 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MinOATCooling);
3634 44 : SetDXCoolingCoilData(state,
3635 : thisVrfTU.CoolCoilIndex,
3636 : ErrorsFound,
3637 : _,
3638 : _,
3639 : _,
3640 : _,
3641 : _,
3642 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATCooling);
3643 :
3644 : } else {
3645 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3646 0 : ShowContinueError(state, "... illegal " + cAlphaFieldNames(12) + " = " + cAlphaArgs(12));
3647 0 : ErrorsFound = true;
3648 : }
3649 : }
3650 : } else {
3651 1 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3652 1 : ShowContinueError(state, "... when checking " + HVAC::cAllCoilTypes(thisVrfTU.DXCoolCoilType_Num) + " \"" + cAlphaArgs(12) + "\"");
3653 2 : ShowContinueError(state, "... terminal unit not connected to condenser.");
3654 2 : ShowContinueError(state, "... check that terminal unit is specified in a terminal unit list object.");
3655 2 : ShowContinueError(
3656 : state, "... also check that the terminal unit list name is specified in an AirConditioner:VariableRefrigerantFlow object.");
3657 1 : ErrorsFound = true;
3658 : }
3659 : }
3660 :
3661 : // Get DX heating coil data
3662 34 : std::string DXHeatingCoilType = cAlphaArgs(13);
3663 :
3664 : // Get the heating to cooling sizing ratio input before writing to DX heating coil data
3665 34 : if (!lNumericFieldBlanks(10)) {
3666 0 : thisVrfTU.HeatingCapacitySizeRatio = rNumericArgs(10);
3667 : }
3668 :
3669 34 : errFlag = false;
3670 34 : thisVrfTU.DXHeatCoilType_Num = GetCoilTypeNum(state, DXHeatingCoilType, cAlphaArgs(14), errFlag, false);
3671 34 : if (thisVrfTU.DXHeatCoilType_Num == 0) {
3672 0 : thisVrfTU.HeatingCoilPresent = false;
3673 0 : if (thisVrfTU.TUListIndex > 0 && thisVrfTU.IndexToTUInTUList > 0) {
3674 0 : state.dataHVACVarRefFlow->TerminalUnitList(thisVrfTU.TUListIndex).HeatingCoilPresent(thisVrfTU.IndexToTUInTUList) = false;
3675 : }
3676 : } else {
3677 34 : if (thisVrfTU.VRFSysNum > 0) {
3678 33 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
3679 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
3680 :
3681 11 : if (Util::SameString(HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num), HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating))) {
3682 11 : errFlag = false;
3683 11 : if (thisVrfTU.TUListIndex > 0 && thisVrfTU.IndexToTUInTUList > 0) {
3684 11 : state.dataHVACVarRefFlow->TerminalUnitList(thisVrfTU.TUListIndex).heatingCoilAvailScheds(thisVrfTU.IndexToTUInTUList) =
3685 22 : DXCoils::GetDXCoilAvailSched(state, DXHeatingCoilType, cAlphaArgs(14), errFlag);
3686 : }
3687 22 : GetDXCoilIndex(
3688 11 : state, cAlphaArgs(14), thisVrfTU.HeatCoilIndex, errFlag, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating));
3689 : HCoilInletNodeNum =
3690 11 : DXCoils::GetCoilInletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating), cAlphaArgs(14), errFlag);
3691 : HCoilOutletNodeNum =
3692 11 : DXCoils::GetCoilOutletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating), cAlphaArgs(14), errFlag);
3693 11 : thisVrfTU.heatCoilAirInNode = HCoilInletNodeNum;
3694 11 : thisVrfTU.heatCoilAirOutNode = HCoilOutletNodeNum;
3695 :
3696 11 : if (errFlag) {
3697 0 : ShowContinueError(state, "...occurs in " + cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3698 : }
3699 :
3700 11 : if (thisVrfTU.VRFSysNum > 0) {
3701 22 : SetDXCoolingCoilData(
3702 11 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserType);
3703 22 : SetDXCoolingCoilData(state,
3704 : thisVrfTU.HeatCoilIndex,
3705 : ErrorsFound,
3706 : _,
3707 : _,
3708 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserNodeNum);
3709 22 : SetDXCoolingCoilData(state,
3710 : thisVrfTU.HeatCoilIndex,
3711 : ErrorsFound,
3712 : _,
3713 : _,
3714 : _,
3715 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATCCHeater);
3716 22 : SetDXCoolingCoilData(state,
3717 : thisVrfTU.HeatCoilIndex,
3718 : ErrorsFound,
3719 : _,
3720 : _,
3721 : _,
3722 : _,
3723 : _,
3724 : _,
3725 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MinOATHeating);
3726 22 : SetDXCoolingCoilData(state,
3727 : thisVrfTU.HeatCoilIndex,
3728 : ErrorsFound,
3729 : _,
3730 : _,
3731 : _,
3732 : _,
3733 : _,
3734 : _,
3735 : _,
3736 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATHeating);
3737 22 : SetDXCoolingCoilData(state,
3738 : thisVrfTU.HeatCoilIndex,
3739 : ErrorsFound,
3740 : _,
3741 : _,
3742 : _,
3743 : _,
3744 : _,
3745 : _,
3746 : _,
3747 : _,
3748 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingPerformanceOATType);
3749 : // Set defrost controls in child object to trip child object defrost calculations
3750 22 : SetDXCoolingCoilData(state,
3751 : thisVrfTU.HeatCoilIndex,
3752 : ErrorsFound,
3753 : _,
3754 : _,
3755 : _,
3756 : _,
3757 : _,
3758 : _,
3759 : _,
3760 : _,
3761 : _,
3762 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostStrategy);
3763 22 : SetDXCoolingCoilData(state,
3764 : thisVrfTU.HeatCoilIndex,
3765 : ErrorsFound,
3766 : _,
3767 : _,
3768 : _,
3769 : _,
3770 : _,
3771 : _,
3772 : _,
3773 : _,
3774 : _,
3775 : _,
3776 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostControl);
3777 22 : SetDXCoolingCoilData(state,
3778 : thisVrfTU.HeatCoilIndex,
3779 : ErrorsFound,
3780 : _,
3781 : _,
3782 : _,
3783 : _,
3784 : _,
3785 : _,
3786 : _,
3787 : _,
3788 : _,
3789 : _,
3790 : _,
3791 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostEIRPtr);
3792 22 : SetDXCoolingCoilData(state,
3793 : thisVrfTU.HeatCoilIndex,
3794 : ErrorsFound,
3795 : _,
3796 : _,
3797 : _,
3798 : _,
3799 : _,
3800 : _,
3801 : _,
3802 : _,
3803 : _,
3804 : _,
3805 : _,
3806 : _,
3807 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostFraction);
3808 22 : SetDXCoolingCoilData(state,
3809 : thisVrfTU.HeatCoilIndex,
3810 : ErrorsFound,
3811 : _,
3812 : _,
3813 : _,
3814 : _,
3815 : _,
3816 : _,
3817 : _,
3818 : _,
3819 : _,
3820 : _,
3821 : _,
3822 : _,
3823 : _,
3824 : _,
3825 11 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATDefrost);
3826 : // If defrost is disabled in the VRF condenser, it must be disabled in the DX coil
3827 : // Defrost primarily handled in parent object, set defrost capacity to 1 to avoid autosizing.
3828 : // Defrost capacity is used for nothing more than setting defrost power/consumption report
3829 : // variables which are not reported. The coil's defrost algorithm IS used to derate the coil
3830 33 : SetDXCoolingCoilData(state,
3831 : thisVrfTU.HeatCoilIndex,
3832 : ErrorsFound,
3833 : _,
3834 : _,
3835 : _,
3836 : _,
3837 : _,
3838 : _,
3839 : _,
3840 : _,
3841 : _,
3842 : _,
3843 : _,
3844 : _,
3845 : _,
3846 22 : 1.0); // DefrostCapacity=1.0
3847 :
3848 11 : state.dataDXCoils->DXCoil(thisVrfTU.HeatCoilIndex).VRFIUPtr = VRFTUNum;
3849 11 : state.dataDXCoils->DXCoil(thisVrfTU.HeatCoilIndex).VRFOUPtr = thisVrfTU.VRFSysNum;
3850 11 : state.dataDXCoils->DXCoil(thisVrfTU.HeatCoilIndex).SupplyFanIndex = thisVrfTU.FanIndex;
3851 :
3852 11 : if (thisVrfTU.FanIndex > 0) {
3853 11 : state.dataDXCoils->DXCoil(thisVrfTU.HeatCoilIndex).RatedAirVolFlowRate(1) =
3854 11 : state.dataFans->fans(thisVrfTU.FanIndex)->maxAirFlowRate;
3855 : } else {
3856 0 : state.dataDXCoils->DXCoil(thisVrfTU.HeatCoilIndex).RatedAirVolFlowRate(1) = AutoSize;
3857 : }
3858 :
3859 : // Terminal unit heating to cooling sizing ratio has precedence over VRF system sizing ratio
3860 11 : if (thisVrfTU.HeatingCapacitySizeRatio > 1.0) {
3861 0 : SetDXCoolingCoilData(state,
3862 : thisVrfTU.HeatCoilIndex,
3863 : ErrorsFound,
3864 : _,
3865 : _,
3866 : _,
3867 : _,
3868 : _,
3869 : _,
3870 : _,
3871 : _,
3872 : _,
3873 : _,
3874 : _,
3875 : _,
3876 : _,
3877 : _,
3878 : _,
3879 : _,
3880 : _,
3881 0 : thisVrfTU.HeatingCapacitySizeRatio);
3882 11 : } else if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingCapacitySizeRatio > 1.0) {
3883 0 : SetDXCoolingCoilData(state,
3884 : thisVrfTU.HeatCoilIndex,
3885 : ErrorsFound,
3886 : _,
3887 : _,
3888 : _,
3889 : _,
3890 : _,
3891 : _,
3892 : _,
3893 : _,
3894 : _,
3895 : _,
3896 : _,
3897 : _,
3898 : _,
3899 : _,
3900 : _,
3901 : _,
3902 : _,
3903 0 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingCapacitySizeRatio);
3904 : }
3905 : } else {
3906 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3907 0 : ShowContinueError(
3908 0 : state, "... when checking " + HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num) + " \"" + cAlphaArgs(14) + "\"");
3909 0 : ShowContinueError(state, "... terminal unit not connected to condenser.");
3910 0 : ShowContinueError(state, "... check that terminal unit is specified in a terminal unit list object.");
3911 0 : ShowContinueError(state,
3912 : "... also check that the terminal unit list name is specified in an "
3913 : "AirConditioner:VariableRefrigerantFlow object.");
3914 0 : ErrorsFound = true;
3915 : }
3916 : } else {
3917 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3918 0 : ShowContinueError(state, "... illegal " + cAlphaFieldNames(14) + " = " + cAlphaArgs(14));
3919 0 : ErrorsFound = true;
3920 : }
3921 :
3922 : } else {
3923 : // Algorithm Type: VRF model based on system curve
3924 22 : if (Util::SameString(HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num), HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating))) {
3925 22 : if (thisVrfTU.TUListIndex > 0 && thisVrfTU.IndexToTUInTUList > 0) {
3926 22 : state.dataHVACVarRefFlow->TerminalUnitList(thisVrfTU.TUListIndex).heatingCoilAvailScheds(thisVrfTU.IndexToTUInTUList) =
3927 44 : DXCoils::GetDXCoilAvailSched(state, DXHeatingCoilType, cAlphaArgs(14), errFlag);
3928 : } else {
3929 0 : thisVrfTU.HeatingCoilPresent = false;
3930 : }
3931 22 : errFlag = false;
3932 22 : GetDXCoilIndex(state, cAlphaArgs(14), thisVrfTU.HeatCoilIndex, errFlag, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating));
3933 22 : HCoilInletNodeNum = DXCoils::GetCoilInletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating), cAlphaArgs(14), errFlag);
3934 22 : HCoilOutletNodeNum = DXCoils::GetCoilOutletNode(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating), cAlphaArgs(14), errFlag);
3935 22 : thisVrfTU.heatCoilAirInNode = HCoilInletNodeNum;
3936 22 : thisVrfTU.heatCoilAirOutNode = HCoilOutletNodeNum;
3937 :
3938 22 : if (errFlag) {
3939 0 : ShowContinueError(state, "...occurs in " + cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
3940 : }
3941 :
3942 44 : SetDXCoolingCoilData(
3943 22 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserType);
3944 44 : SetDXCoolingCoilData(
3945 22 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, _, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CondenserNodeNum);
3946 44 : SetDXCoolingCoilData(
3947 22 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, _, _, _, state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATCCHeater);
3948 44 : SetDXCoolingCoilData(state,
3949 : thisVrfTU.HeatCoilIndex,
3950 : ErrorsFound,
3951 : _,
3952 : _,
3953 : _,
3954 : _,
3955 : _,
3956 : _,
3957 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MinOATHeating);
3958 44 : SetDXCoolingCoilData(state,
3959 : thisVrfTU.HeatCoilIndex,
3960 : ErrorsFound,
3961 : _,
3962 : _,
3963 : _,
3964 : _,
3965 : _,
3966 : _,
3967 : _,
3968 : _,
3969 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingPerformanceOATType);
3970 : // Set defrost controls in child object to trip child object defrost calculations
3971 44 : SetDXCoolingCoilData(state,
3972 : thisVrfTU.HeatCoilIndex,
3973 : ErrorsFound,
3974 : _,
3975 : _,
3976 : _,
3977 : _,
3978 : _,
3979 : _,
3980 : _,
3981 : _,
3982 : _,
3983 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostStrategy);
3984 44 : SetDXCoolingCoilData(state,
3985 : thisVrfTU.HeatCoilIndex,
3986 : ErrorsFound,
3987 : _,
3988 : _,
3989 : _,
3990 : _,
3991 : _,
3992 : _,
3993 : _,
3994 : _,
3995 : _,
3996 : _,
3997 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostControl);
3998 44 : SetDXCoolingCoilData(state,
3999 : thisVrfTU.HeatCoilIndex,
4000 : ErrorsFound,
4001 : _,
4002 : _,
4003 : _,
4004 : _,
4005 : _,
4006 : _,
4007 : _,
4008 : _,
4009 : _,
4010 : _,
4011 : _,
4012 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostEIRPtr);
4013 44 : SetDXCoolingCoilData(state,
4014 : thisVrfTU.HeatCoilIndex,
4015 : ErrorsFound,
4016 : _,
4017 : _,
4018 : _,
4019 : _,
4020 : _,
4021 : _,
4022 : _,
4023 : _,
4024 : _,
4025 : _,
4026 : _,
4027 : _,
4028 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).DefrostFraction);
4029 44 : SetDXCoolingCoilData(state,
4030 : thisVrfTU.HeatCoilIndex,
4031 : ErrorsFound,
4032 : _,
4033 : _,
4034 : _,
4035 : _,
4036 : _,
4037 : _,
4038 : _,
4039 : _,
4040 : _,
4041 : _,
4042 : _,
4043 : _,
4044 : _,
4045 : _,
4046 22 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).MaxOATDefrost);
4047 : // If defrost is disabled in the VRF condenser, it must be disabled in the DX coil
4048 : // Defrost primarily handled in parent object, set defrost capacity to 1 to avoid autosizing.
4049 : // Defrost capacity is used for nothing more than setting defrost power/consumption report
4050 : // variables which are not reported. The coil's defrost algorithm IS used to derate the coil
4051 66 : SetDXCoolingCoilData(state,
4052 : thisVrfTU.HeatCoilIndex,
4053 : ErrorsFound,
4054 : _,
4055 : _,
4056 : _,
4057 : _,
4058 : _,
4059 : _,
4060 : _,
4061 : _,
4062 : _,
4063 : _,
4064 : _,
4065 : _,
4066 : _,
4067 44 : 1.0); // DefrostCapacity=1.0
4068 : // Terminal unit heating to cooling sizing ratio has precedence over VRF system sizing ratio
4069 22 : if (thisVrfTU.HeatingCapacitySizeRatio > 1.0) {
4070 0 : SetDXCoolingCoilData(state,
4071 : thisVrfTU.HeatCoilIndex,
4072 : ErrorsFound,
4073 : _,
4074 : _,
4075 : _,
4076 : _,
4077 : _,
4078 : _,
4079 : _,
4080 : _,
4081 : _,
4082 : _,
4083 : _,
4084 : _,
4085 : _,
4086 : _,
4087 : _,
4088 : _,
4089 : _,
4090 0 : thisVrfTU.HeatingCapacitySizeRatio);
4091 22 : } else if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingCapacitySizeRatio > 1.0) {
4092 0 : SetDXCoolingCoilData(state,
4093 : thisVrfTU.HeatCoilIndex,
4094 : ErrorsFound,
4095 : _,
4096 : _,
4097 : _,
4098 : _,
4099 : _,
4100 : _,
4101 : _,
4102 : _,
4103 : _,
4104 : _,
4105 : _,
4106 : _,
4107 : _,
4108 : _,
4109 : _,
4110 : _,
4111 : _,
4112 0 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingCapacitySizeRatio);
4113 : }
4114 : // Check VRF DX heating coil heating capacity as a function of temperature performance curve. Only report here for
4115 : // biquadratic curve type.
4116 44 : if (thisVrfTU.VRFSysNum > 0 && thisVrfTU.HeatCoilIndex > 0 &&
4117 22 : state.dataCurveManager->curves(GetDXCoilCapFTCurveIndex(state, thisVrfTU.HeatCoilIndex, ErrorsFound))->numDims == 2) {
4118 0 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingPerformanceOATType == HVAC::OATType::WetBulb) {
4119 0 : checkCurveIsNormalizedToOne(
4120 : state,
4121 0 : "GetDXCoils: " + HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num),
4122 0 : DXCoils::GetDXCoilName(
4123 0 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num)),
4124 : GetDXCoilCapFTCurveIndex(state, thisVrfTU.HeatCoilIndex, ErrorsFound),
4125 : "Heating Capacity Ratio Modifier Function of Temperature Curve Name",
4126 0 : Curve::GetCurveName(state, GetDXCoilCapFTCurveIndex(state, thisVrfTU.HeatCoilIndex, ErrorsFound)),
4127 : RatedInletAirTempHeat,
4128 : RatedOutdoorWetBulbTempHeat);
4129 0 : } else if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingPerformanceOATType == HVAC::OATType::DryBulb) {
4130 0 : checkCurveIsNormalizedToOne(
4131 : state,
4132 0 : "GetDXCoils: " + HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num),
4133 0 : DXCoils::GetDXCoilName(
4134 0 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num)),
4135 : GetDXCoilCapFTCurveIndex(state, thisVrfTU.HeatCoilIndex, ErrorsFound),
4136 : "Heating Capacity Ratio Modifier Function of Temperature Curve Name",
4137 0 : Curve::GetCurveName(state, GetDXCoilCapFTCurveIndex(state, thisVrfTU.HeatCoilIndex, ErrorsFound)),
4138 : RatedInletAirTempHeat,
4139 : RatedOutdoorAirTempHeat);
4140 : }
4141 : }
4142 :
4143 : } else {
4144 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4145 0 : ShowContinueError(state, "... illegal " + cAlphaFieldNames(14) + " = " + cAlphaArgs(14));
4146 0 : ErrorsFound = true;
4147 : }
4148 : }
4149 : } else {
4150 1 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4151 1 : ShowContinueError(state, "... when checking " + HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num) + " \"" + cAlphaArgs(14) + "\"");
4152 2 : ShowContinueError(state, "... terminal unit not connected to condenser.");
4153 2 : ShowContinueError(state, "... check that terminal unit is specified in a terminal unit list object.");
4154 2 : ShowContinueError(
4155 : state, "... also check that the terminal unit list name is specified in an AirConditioner:VariableRefrigerantFlow object.");
4156 1 : ErrorsFound = true;
4157 : }
4158 : }
4159 :
4160 34 : if (!thisVrfTU.CoolingCoilPresent && thisVrfTU.DXCoolCoilType_Num == 0 && !thisVrfTU.HeatingCoilPresent &&
4161 0 : thisVrfTU.DXHeatCoilType_Num == 0) {
4162 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4163 0 : ShowContinueError(state, "... no valid coils entered for this terminal unit. Simulation will not proceed.");
4164 0 : ErrorsFound = true;
4165 : }
4166 :
4167 34 : if (!lAlphaFieldBlanks(15)) {
4168 0 : thisVrfTU.AvailManagerListName = cAlphaArgs(15);
4169 : }
4170 34 : thisVrfTU.ParasiticElec = rNumericArgs(8);
4171 34 : thisVrfTU.ParasiticOffElec = rNumericArgs(9);
4172 :
4173 34 : thisVrfTU.HVACSizingIndex = 0;
4174 34 : if (!lAlphaFieldBlanks(16)) {
4175 0 : thisVrfTU.HVACSizingIndex = Util::FindItemInList(cAlphaArgs(16), state.dataSize->ZoneHVACSizing);
4176 0 : if (thisVrfTU.HVACSizingIndex == 0) {
4177 0 : ShowSevereError(state, cAlphaFieldNames(16) + " = " + cAlphaArgs(16) + " not found.");
4178 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4179 0 : ErrorsFound = true;
4180 : }
4181 : }
4182 :
4183 : // supplemental heating coil
4184 34 : if (!lAlphaFieldBlanks(17) && !lAlphaFieldBlanks(18)) {
4185 :
4186 10 : thisVrfTU.SuppHeatCoilType = cAlphaArgs(17);
4187 10 : thisVrfTU.SuppHeatCoilName = cAlphaArgs(18);
4188 :
4189 10 : errFlag = false;
4190 10 : if (Util::SameString(thisVrfTU.SuppHeatCoilType, "Coil:Heating:Water")) {
4191 1 : thisVrfTU.SuppHeatCoilType_Num = HVAC::Coil_HeatingWater;
4192 9 : } else if (Util::SameString(thisVrfTU.SuppHeatCoilType, "Coil:Heating:Steam")) {
4193 1 : thisVrfTU.SuppHeatCoilType_Num = HVAC::Coil_HeatingSteam;
4194 14 : } else if (Util::SameString(thisVrfTU.SuppHeatCoilType, "Coil:Heating:Fuel") ||
4195 14 : Util::SameString(thisVrfTU.SuppHeatCoilType, "Coil:Heating:Electric")) {
4196 8 : thisVrfTU.SuppHeatCoilType_Num =
4197 8 : HeatingCoils::GetHeatingCoilTypeNum(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, errFlag);
4198 : }
4199 :
4200 10 : thisVrfTU.SuppHeatingCoilPresent = true;
4201 :
4202 10 : if (thisVrfTU.SuppHeatCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || thisVrfTU.SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric) {
4203 8 : errFlag = false;
4204 8 : thisVrfTU.SuppHeatCoilType_Num =
4205 8 : HeatingCoils::GetHeatingCoilTypeNum(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, errFlag);
4206 8 : if (errFlag) {
4207 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4208 0 : ErrorsFound = true;
4209 : } else {
4210 8 : ValidateComponent(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, IsNotOK, cCurrentModuleObject);
4211 8 : if (IsNotOK) {
4212 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4213 0 : ErrorsFound = true;
4214 : } else { // mine data from supplemental heating coil
4215 : // Get the supplemental heating coil index
4216 8 : thisVrfTU.SuppHeatCoilIndex =
4217 8 : HeatingCoils::GetHeatingCoilIndex(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, IsNotOK);
4218 8 : if (IsNotOK) {
4219 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4220 0 : ErrorsFound = true;
4221 : }
4222 : // Get the design supplemental heating capacity
4223 8 : errFlag = false;
4224 8 : thisVrfTU.DesignSuppHeatingCapacity =
4225 8 : HeatingCoils::GetCoilCapacity(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, errFlag);
4226 8 : if (errFlag) {
4227 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4228 0 : ErrorsFound = true;
4229 : }
4230 : // Get the supplemental heating Coil air inlet node
4231 8 : errFlag = false;
4232 8 : thisVrfTU.SuppHeatCoilAirInletNode =
4233 8 : HeatingCoils::GetCoilInletNode(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, errFlag);
4234 8 : if (errFlag) {
4235 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4236 0 : ErrorsFound = true;
4237 : }
4238 : // Get the supplemental heating Coil air outlet node
4239 8 : errFlag = false;
4240 8 : thisVrfTU.SuppHeatCoilAirOutletNode =
4241 8 : HeatingCoils::GetCoilOutletNode(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, errFlag);
4242 8 : if (errFlag) {
4243 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4244 0 : ErrorsFound = true;
4245 : }
4246 : } // IF (IsNotOK) THEN
4247 : }
4248 :
4249 2 : } else if (thisVrfTU.SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
4250 :
4251 1 : ValidateComponent(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, IsNotOK, cCurrentModuleObject);
4252 1 : if (IsNotOK) {
4253 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4254 0 : ErrorsFound = true;
4255 : } else { // mine data from heating coil object
4256 :
4257 : // Get the supplemental heating coil water Inlet or control node number
4258 1 : errFlag = false;
4259 1 : thisVrfTU.SuppHeatCoilFluidInletNode =
4260 1 : WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", thisVrfTU.SuppHeatCoilName, errFlag);
4261 1 : if (errFlag) {
4262 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4263 0 : ErrorsFound = true;
4264 : }
4265 : // Get the supplemental heating coil hot water max volume flow rate
4266 1 : errFlag = false;
4267 1 : thisVrfTU.SuppHeatCoilFluidMaxFlow =
4268 1 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", thisVrfTU.SuppHeatCoilName, errFlag);
4269 1 : if (errFlag) {
4270 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4271 0 : ErrorsFound = true;
4272 : }
4273 : // Get the supplemental heating Coil air inlet node
4274 1 : errFlag = false;
4275 1 : thisVrfTU.SuppHeatCoilAirInletNode =
4276 1 : WaterCoils::GetCoilInletNode(state, "Coil:Heating:Water", thisVrfTU.SuppHeatCoilName, errFlag);
4277 1 : if (errFlag) {
4278 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4279 0 : ErrorsFound = true;
4280 : }
4281 : // Get the supplemental heating coil air outlet node
4282 1 : errFlag = false;
4283 1 : thisVrfTU.SuppHeatCoilAirOutletNode =
4284 1 : WaterCoils::GetCoilOutletNode(state, "Coil:Heating:Water", thisVrfTU.SuppHeatCoilName, errFlag);
4285 1 : if (errFlag) {
4286 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4287 0 : ErrorsFound = true;
4288 : }
4289 : }
4290 :
4291 1 : } else if (thisVrfTU.SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
4292 :
4293 1 : ValidateComponent(state, thisVrfTU.SuppHeatCoilType, thisVrfTU.SuppHeatCoilName, IsNotOK, cCurrentModuleObject);
4294 1 : if (IsNotOK) {
4295 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4296 0 : ErrorsFound = true;
4297 : } else { // mine data from supplemental heating coil object
4298 1 : errFlag = false;
4299 1 : thisVrfTU.SuppHeatCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", thisVrfTU.SuppHeatCoilName, errFlag);
4300 1 : if (thisVrfTU.SuppHeatCoilIndex == 0) {
4301 0 : ShowSevereError(state, cCurrentModuleObject + " = " + thisVrfTU.Name);
4302 0 : ErrorsFound = true;
4303 : }
4304 : // Get the supplemental heating Coil steam inlet node number
4305 1 : errFlag = false;
4306 1 : thisVrfTU.SuppHeatCoilFluidInletNode =
4307 2 : SteamCoils::GetCoilSteamInletNode(state, "Coil:Heating:Steam", thisVrfTU.SuppHeatCoilName, errFlag);
4308 1 : if (errFlag) {
4309 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4310 0 : ErrorsFound = true;
4311 : }
4312 : // Get the supplemental heating coil steam max volume flow rate
4313 1 : thisVrfTU.SuppHeatCoilFluidMaxFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, thisVrfTU.SuppHeatCoilIndex, errFlag);
4314 1 : if (thisVrfTU.SuppHeatCoilFluidMaxFlow > 0.0) {
4315 0 : Real64 TempSteamIn = 100.0;
4316 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, RoutineName);
4317 0 : thisVrfTU.SuppHeatCoilFluidMaxFlow =
4318 0 : SteamCoils::GetCoilMaxSteamFlowRate(state, thisVrfTU.SuppHeatCoilIndex, errFlag) * SteamDensity;
4319 : }
4320 : // Get the supplemental heating coil air inlet node
4321 1 : errFlag = false;
4322 1 : thisVrfTU.SuppHeatCoilAirInletNode =
4323 1 : SteamCoils::GetCoilAirInletNode(state, thisVrfTU.SuppHeatCoilIndex, thisVrfTU.SuppHeatCoilName, errFlag);
4324 1 : if (errFlag) {
4325 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4326 0 : ErrorsFound = true;
4327 : }
4328 : // Get the supplemental heating coil air outlet node
4329 1 : errFlag = false;
4330 1 : thisVrfTU.SuppHeatCoilAirOutletNode =
4331 1 : SteamCoils::GetCoilAirOutletNode(state, thisVrfTU.SuppHeatCoilIndex, thisVrfTU.SuppHeatCoilName, errFlag);
4332 1 : if (errFlag) {
4333 0 : ShowContinueError(state, "Occurs in " + cCurrentModuleObject + " = " + thisVrfTU.Name);
4334 0 : ErrorsFound = true;
4335 : }
4336 : }
4337 : }
4338 : } else { // if (!lAlphaFieldBlanks(17) && !lAlphaFieldBlanks(18)) {
4339 24 : if (!lAlphaFieldBlanks(17) && lAlphaFieldBlanks(18)) {
4340 0 : ShowWarningError(state, cCurrentModuleObject + " = " + thisVrfTU.Name + "\"");
4341 0 : ShowContinueError(state, "...Supplemental heating coil type = " + cAlphaArgs(17));
4342 0 : ShowContinueError(state, "...But missing the associated supplemental heating coil name. ");
4343 0 : ShowContinueError(state, "...The supplemental heating coil will not be simulated. ");
4344 : }
4345 24 : if (lAlphaFieldBlanks(17) && !lAlphaFieldBlanks(18)) {
4346 0 : ShowWarningError(state, cCurrentModuleObject + " = " + thisVrfTU.Name + "\"");
4347 0 : ShowContinueError(state, "...Supplemental heating coil name = " + cAlphaArgs(18));
4348 0 : ShowContinueError(state, "...But missing the associated supplemental heating coil type. ");
4349 0 : ShowContinueError(state, "...The supplemental heating coil will not be simulated. ");
4350 : }
4351 : }
4352 :
4353 34 : if (!lAlphaFieldBlanks(19)) {
4354 0 : thisVrfTU.ZoneNum = Util::FindItemInList(cAlphaArgs(19), state.dataHeatBal->Zone);
4355 0 : if (thisVrfTU.ZoneNum == 0) {
4356 0 : ShowSevereError(state, cCurrentModuleObject + " = " + cAlphaArgs(1));
4357 0 : ShowContinueError(state, "Illegal " + cAlphaFieldNames(19) + " = " + cAlphaArgs(19));
4358 0 : ErrorsFound = true;
4359 : }
4360 : }
4361 :
4362 34 : auto &vrfTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
4363 34 : if (!lAlphaFieldBlanks(20) && !lAlphaFieldBlanks(21)) {
4364 0 : vrfTU.DesignSpecMultispeedHPType = cAlphaArgs(20);
4365 0 : vrfTU.DesignSpecMultispeedHPName = cAlphaArgs(21);
4366 0 : vrfTU.DesignSpecMSHPIndex = UnitarySystems::getDesignSpecMSHPIndex(state, cAlphaArgs(21));
4367 0 : auto const &designSpecFan = state.dataUnitarySystems->designSpecMSHP[vrfTU.DesignSpecMSHPIndex];
4368 0 : if (vrfTU.DXCoolCoilType_Num == HVAC::CoilVRF_Cooling) {
4369 0 : int NumSpeeds = designSpecFan.numOfSpeedCooling;
4370 0 : vrfTU.NumOfSpeedCooling = NumSpeeds;
4371 0 : vrfTU.CoolVolumeFlowRate.resize(NumSpeeds + 1);
4372 0 : vrfTU.CoolMassFlowRate.resize(NumSpeeds + 1);
4373 0 : if (vrfTU.MaxCoolAirVolFlow != DataSizing::AutoSize) {
4374 0 : Real64 AirFlowRate = vrfTU.MaxCoolAirVolFlow;
4375 0 : for (int i = 1; i <= vrfTU.NumOfSpeedCooling; ++i) {
4376 0 : if (state.dataUnitarySystems->designSpecMSHP[vrfTU.DesignSpecMSHPIndex].coolingVolFlowRatio[i] == DataSizing::AutoSize) {
4377 0 : vrfTU.CoolVolumeFlowRate[i] = double(i) / double(vrfTU.NumOfSpeedCooling) * AirFlowRate;
4378 : } else {
4379 0 : vrfTU.CoolVolumeFlowRate[i] =
4380 0 : state.dataUnitarySystems->designSpecMSHP[vrfTU.DesignSpecMSHPIndex].coolingVolFlowRatio[i] * AirFlowRate;
4381 : }
4382 0 : vrfTU.CoolMassFlowRate[i] = vrfTU.CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
4383 : }
4384 : }
4385 : }
4386 0 : if (vrfTU.DXHeatCoilType_Num == HVAC::CoilVRF_Heating) {
4387 0 : int NumSpeeds = designSpecFan.numOfSpeedHeating;
4388 0 : vrfTU.NumOfSpeedHeating = NumSpeeds;
4389 0 : vrfTU.HeatVolumeFlowRate.resize(NumSpeeds + 1);
4390 0 : vrfTU.HeatMassFlowRate.resize(NumSpeeds + 1);
4391 0 : if (vrfTU.MaxHeatAirVolFlow != DataSizing::AutoSize) {
4392 0 : Real64 AirFlowRate = vrfTU.MaxHeatAirVolFlow;
4393 0 : for (int i = 1; i <= vrfTU.NumOfSpeedHeating; ++i) {
4394 0 : if (state.dataUnitarySystems->designSpecMSHP[vrfTU.DesignSpecMSHPIndex].heatingVolFlowRatio[i] == DataSizing::AutoSize) {
4395 0 : vrfTU.HeatVolumeFlowRate[i] = double(i) / double(vrfTU.NumOfSpeedHeating) * AirFlowRate;
4396 : } else {
4397 0 : vrfTU.HeatVolumeFlowRate[i] =
4398 0 : state.dataUnitarySystems->designSpecMSHP[vrfTU.DesignSpecMSHPIndex].heatingVolFlowRatio[i] * AirFlowRate;
4399 : }
4400 0 : vrfTU.HeatMassFlowRate[i] = vrfTU.HeatVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
4401 : }
4402 : }
4403 : }
4404 : } else {
4405 34 : if (vrfTU.fanType == HVAC::FanType::SystemModel) {
4406 20 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(vrfTU.FanIndex));
4407 20 : assert(fanSystem != nullptr);
4408 :
4409 20 : if (fanSystem->speedControl == Fans::SpeedControl::Discrete) {
4410 11 : if (fanSystem->numSpeeds > 1) {
4411 2 : if (vrfTU.DXCoolCoilType_Num == HVAC::CoilVRF_Cooling) {
4412 2 : vrfTU.NumOfSpeedCooling = fanSystem->numSpeeds;
4413 2 : vrfTU.CoolVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
4414 2 : vrfTU.CoolMassFlowRate.resize(fanSystem->numSpeeds + 1);
4415 : }
4416 2 : if (vrfTU.DXHeatCoilType_Num == HVAC::CoilVRF_Heating) {
4417 2 : vrfTU.NumOfSpeedHeating = fanSystem->numSpeeds;
4418 2 : vrfTU.HeatVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
4419 2 : vrfTU.HeatMassFlowRate.resize(fanSystem->numSpeeds + 1);
4420 : }
4421 4 : ShowWarningError(state,
4422 4 : cCurrentModuleObject + " = " + thisVrfTU.Name + " with Fan:SystemModel is used in " + cAlphaArgs(8) + "\"");
4423 2 : ShowContinueError(state, format("...The number of speed = {:.0R}.", double(fanSystem->numSpeeds)));
4424 6 : ShowContinueError(state, "...Multiple speed fan will be applied to this unit. The speed number is determined by load.");
4425 : }
4426 : }
4427 : }
4428 : }
4429 :
4430 : // set supplemental heating coil operation temperature limits
4431 34 : if (thisVrfTU.SuppHeatingCoilPresent) {
4432 : // Set maximum supply air temperature for supplemental heating coil
4433 10 : if (NumNums < 11) {
4434 0 : thisVrfTU.MaxSATFromSuppHeatCoil = DataSizing::AutoSize;
4435 : } else {
4436 10 : thisVrfTU.MaxSATFromSuppHeatCoil = rNumericArgs(11);
4437 : }
4438 : // set maximum outdoor dry-bulb temperature for supplemental heating coil operation
4439 10 : if (NumNums < 12) {
4440 0 : thisVrfTU.MaxOATSuppHeatingCoil = 21.0;
4441 : } else {
4442 10 : thisVrfTU.MaxOATSuppHeatingCoil = rNumericArgs(12);
4443 : }
4444 : }
4445 :
4446 : // Add cooling coil to component sets array
4447 34 : if (thisVrfTU.CoolingCoilPresent) {
4448 :
4449 68 : SetUpCompSets(state,
4450 : cCurrentModuleObject,
4451 : thisVrfTU.Name,
4452 34 : HVAC::cAllCoilTypes(thisVrfTU.DXCoolCoilType_Num),
4453 34 : cAlphaArgs(12),
4454 34 : state.dataLoopNodes->NodeID(CCoilInletNodeNum),
4455 34 : state.dataLoopNodes->NodeID(CCoilOutletNodeNum));
4456 : // set heating coil present flag
4457 68 : SetDXCoolingCoilData(
4458 34 : state, thisVrfTU.CoolCoilIndex, ErrorsFound, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, thisVrfTU.HeatingCoilPresent);
4459 :
4460 : // check that curve types are present in VRF Condenser if cooling coil is present in terminal unit (can be blank)
4461 : // all curves are checked for correct type if a curve name is entered in the VRF condenser object. Check that the
4462 : // curve is present if the corresponding coil is entered in the terminal unit.
4463 34 : if (thisVrfTU.VRFSysNum > 0) {
4464 :
4465 33 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFAlgorithmType != AlgorithmType::FluidTCtrl) {
4466 :
4467 35 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CoolingCapacity <= 0 &&
4468 13 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).CoolingCapacity != AutoSize) {
4469 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4470 0 : ShowContinueError(state,
4471 : "...This terminal unit contains a cooling coil and rated cooling capacity is also required in the "
4472 : "associated condenser object.");
4473 0 : ShowContinueError(state,
4474 0 : "...Rated Cooling Capacity must also be specified for condenser = " +
4475 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFSystemTypeNum)) + " \"" +
4476 0 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).Name + "\".");
4477 0 : ErrorsFound = true;
4478 : }
4479 : }
4480 : }
4481 : }
4482 :
4483 : // Add heating coil to component sets array
4484 34 : if (thisVrfTU.HeatingCoilPresent) {
4485 :
4486 68 : SetUpCompSets(state,
4487 : cCurrentModuleObject,
4488 : thisVrfTU.Name,
4489 34 : HVAC::cAllCoilTypes(thisVrfTU.DXHeatCoilType_Num),
4490 34 : cAlphaArgs(14),
4491 34 : state.dataLoopNodes->NodeID(HCoilInletNodeNum),
4492 34 : state.dataLoopNodes->NodeID(HCoilOutletNodeNum));
4493 : // set cooling coil present flag
4494 68 : SetDXCoolingCoilData(
4495 34 : state, thisVrfTU.HeatCoilIndex, ErrorsFound, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, thisVrfTU.CoolingCoilPresent);
4496 :
4497 34 : if (thisVrfTU.VRFSysNum > 0) {
4498 :
4499 33 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFAlgorithmType != AlgorithmType::FluidTCtrl) {
4500 :
4501 41 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingCapacity <= 0 &&
4502 19 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatingCapacity != AutoSize) {
4503 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4504 0 : ShowContinueError(state,
4505 : "...This terminal unit contains a heating coil and rated heating capacity is also required in the "
4506 : "associated condenser object.");
4507 0 : ShowContinueError(state,
4508 0 : "...Rated Heating Capacity must also be specified for condenser = " +
4509 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFSystemTypeNum)) + " \"" +
4510 0 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).Name + "\".");
4511 0 : ErrorsFound = true;
4512 : }
4513 :
4514 22 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatCapFT == 0) {
4515 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4516 0 : ShowContinueError(state,
4517 : "...This terminal unit contains a heating coil and heating performance curves are also required in the "
4518 : "associated condenser object.");
4519 0 : ShowContinueError(
4520 : state,
4521 0 : "...Heating Capacity Ratio Modifier Function of Low Temperature Curve must also be specified for condenser = " +
4522 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFSystemTypeNum)) + " \"" +
4523 0 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).Name + "\".");
4524 0 : ErrorsFound = true;
4525 : }
4526 :
4527 22 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatEIRFT == 0) {
4528 0 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4529 0 : ShowContinueError(state,
4530 : "...This terminal unit contains a heating coil and heating performance curves are also required in the "
4531 : "associated condenser object.");
4532 0 : ShowContinueError(
4533 : state,
4534 0 : "...Heating Energy Input Ratio Modifier Function of Low Temperature Curve must also be specified for condenser = " +
4535 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFSystemTypeNum)) + " \"" +
4536 0 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).Name + "\".");
4537 0 : ErrorsFound = true;
4538 : }
4539 :
4540 22 : if (state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).HeatEIRFPLR1 == 0) {
4541 1 : ShowSevereError(state, cCurrentModuleObject + " \"" + thisVrfTU.Name + "\"");
4542 2 : ShowContinueError(state,
4543 : "...This terminal unit contains a heating coil and heating performance curves are also required in the "
4544 : "associated condenser object.");
4545 2 : ShowContinueError(state,
4546 : "...Heating Energy Input Ratio Modifier Function of Low Part-Load Ratio Curve must also be specified "
4547 2 : "for condenser = " +
4548 4 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).VRFSystemTypeNum)) + " \"" +
4549 4 : state.dataHVACVarRefFlow->VRF(thisVrfTU.VRFSysNum).Name + "\".");
4550 : }
4551 : }
4552 : }
4553 : }
4554 :
4555 : // Add supplemental heating coil to component sets array
4556 34 : if (thisVrfTU.SuppHeatingCoilPresent) {
4557 30 : SetUpCompSets(state,
4558 : cCurrentModuleObject,
4559 : thisVrfTU.Name,
4560 10 : HVAC::cAllCoilTypes(thisVrfTU.SuppHeatCoilType_Num),
4561 : thisVrfTU.SuppHeatCoilName,
4562 10 : state.dataLoopNodes->NodeID(thisVrfTU.SuppHeatCoilAirInletNode),
4563 10 : state.dataLoopNodes->NodeID(thisVrfTU.SuppHeatCoilAirOutletNode));
4564 : }
4565 : // Set up component set for OA mixer - use OA node and Mixed air node
4566 34 : if (thisVrfTU.OAMixerUsed) {
4567 52 : SetUpCompSets(state,
4568 : cCurrentModuleObject,
4569 : thisVrfTU.Name,
4570 : "UNDEFINED",
4571 : thisVrfTU.OAMixerName,
4572 26 : state.dataLoopNodes->NodeID(OANodeNums(1)),
4573 26 : state.dataLoopNodes->NodeID(OANodeNums(4)));
4574 : }
4575 :
4576 : // Get AirTerminal mixer data
4577 34 : GetATMixer(state,
4578 34 : thisVrfTU.Name,
4579 34 : thisVrfTU.ATMixerName,
4580 34 : thisVrfTU.ATMixerIndex,
4581 34 : thisVrfTU.ATMixerType,
4582 34 : thisVrfTU.ATMixerPriNode,
4583 34 : thisVrfTU.ATMixerSecNode,
4584 34 : thisVrfTU.ATMixerOutNode,
4585 : thisVrfTU.VRFTUOutletNodeNum);
4586 34 : if (thisVrfTU.ATMixerType == HVAC::MixerType::InletSide || thisVrfTU.ATMixerType == HVAC::MixerType::SupplySide) {
4587 4 : thisVrfTU.ATMixerExists = true;
4588 : }
4589 : // check that the VRF TU have local outside air and DOA
4590 34 : if (thisVrfTU.ATMixerExists && OANodeNums(4) > 0) {
4591 0 : ShowSevereError(
4592 0 : state, cCurrentModuleObject + " = \"" + thisVrfTU.Name + "\". VRF terminal unit has local as well as central outdoor air specified");
4593 0 : ErrorsFound = true;
4594 : }
4595 :
4596 : // for ZoneHVAC check that TU inlet node is a zone exhaust node otherwise ZoneAirNode and ZoneNum = 0
4597 34 : if (!thisVrfTU.ATMixerExists || thisVrfTU.ATMixerType == HVAC::MixerType::SupplySide) {
4598 100 : for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
4599 68 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) {
4600 0 : continue;
4601 : }
4602 107 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumExhaustNodes; ++NodeNum) {
4603 68 : if (thisVrfTU.VRFTUInletNodeNum == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ExhaustNode(NodeNum)) {
4604 29 : thisVrfTU.ZoneAirNode = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ZoneNode;
4605 29 : thisVrfTU.ZoneNum = CtrlZone;
4606 29 : break;
4607 : }
4608 : }
4609 : }
4610 34 : } else if (thisVrfTU.ATMixerType == HVAC::MixerType::InletSide) {
4611 4 : for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
4612 2 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) {
4613 0 : continue;
4614 : }
4615 2 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) {
4616 2 : if (thisVrfTU.VRFTUOutletNodeNum == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) {
4617 2 : thisVrfTU.ZoneAirNode = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ZoneNode;
4618 2 : thisVrfTU.ZoneNum = CtrlZone;
4619 2 : break;
4620 : }
4621 : }
4622 : }
4623 : }
4624 34 : CheckVRFTUNodeConnections(state, VRFTUNum, ErrorsFound);
4625 34 : } // end Number of VRF Terminal Unit Loop
4626 :
4627 : // perform additional error checking
4628 50 : for (auto const &thisTUList : state.dataHVACVarRefFlow->TerminalUnitList) {
4629 61 : for (int VRFTUNum = 1; VRFTUNum <= thisTUList.NumTUInList; ++VRFTUNum) {
4630 34 : int const tuPtr = thisTUList.ZoneTUPtr(VRFTUNum);
4631 34 : if (tuPtr == 0) {
4632 : // TU name in zone terminal unit list not found
4633 1 : ShowSevereError(state, format("ZoneTerminalUnitList \"{}\"", thisTUList.Name));
4634 1 : ShowContinueError(state, format("...Zone Terminal Unit = {} improperly connected to system.", thisTUList.ZoneTUName(VRFTUNum)));
4635 2 : ShowContinueError(state, "...either the ZoneHVAC:TerminalUnit:VariableRefrigerantFlow object does not exist,");
4636 2 : ShowContinueError(state, "...the ZoneHVAC:TerminalUnit:VariableRefrigerantFlow object name is misspelled,");
4637 2 : ShowContinueError(state, "...or the ZoneTerminalUnitList object is not named in an AirConditioner:VariableRefrigerantFlow object.");
4638 1 : ErrorsFound = true;
4639 : } else {
4640 33 : int const sysNum = state.dataHVACVarRefFlow->VRFTU(tuPtr).VRFSysNum;
4641 33 : if (sysNum > 0) {
4642 33 : auto &thisVRFSys = state.dataHVACVarRefFlow->VRF(sysNum);
4643 33 : if (thisTUList.NumTUInList == 1 && thisVRFSys.VRFAlgorithmType == AlgorithmType::SysCurve) {
4644 15 : if (thisVRFSys.HeatRecoveryUsed) {
4645 1 : ShowWarningError(state, format("ZoneTerminalUnitList \"{}\"", thisTUList.Name));
4646 2 : ShowWarningError(state, "...Only 1 Terminal Unit connected to system and heat recovery is selected.");
4647 1 : ShowContinueError(state, format("...Heat recovery will be disabled for {}.", thisVRFSys.Name));
4648 1 : thisVRFSys.HeatRecoveryUsed = false;
4649 : }
4650 : }
4651 : }
4652 : }
4653 : }
4654 23 : }
4655 :
4656 : // warn when number of ZoneTerminalUnitList different from number of AirConditioner:VariableRefrigerantFlow
4657 23 : if (state.dataHVACVarRefFlow->NumVRFTULists != state.dataHVACVarRefFlow->NumVRFCond) {
4658 0 : ShowSevereError(state,
4659 0 : format("The number of AirConditioner:VariableRefrigerantFlow objects ({}) does not match the number of "
4660 : "ZoneTerminalUnitList objects ({}).",
4661 0 : state.dataHVACVarRefFlow->NumVRFCond,
4662 0 : state.dataHVACVarRefFlow->NumVRFTULists));
4663 0 : for (int NumCond = 1; NumCond <= state.dataHVACVarRefFlow->NumVRFCond; ++NumCond) {
4664 0 : if (state.dataHVACVarRefFlow->VRF(NumCond).ZoneTUListPtr > 0) {
4665 0 : ShowContinueError(state,
4666 0 : format("...AirConditioner:VariableRefrigerantFlow = {} specifies Zone Terminal Unit List Name = {}",
4667 0 : state.dataHVACVarRefFlow->VRF(NumCond).Name,
4668 0 : state.dataHVACVarRefFlow->TerminalUnitList(state.dataHVACVarRefFlow->VRF(NumCond).ZoneTUListPtr).Name));
4669 : } else {
4670 0 : ShowContinueError(state,
4671 0 : format("...AirConditioner:VariableRefrigerantFlow = {} Zone Terminal Unit List Name not found.",
4672 0 : state.dataHVACVarRefFlow->VRF(NumCond).Name));
4673 : }
4674 : }
4675 0 : ShowContinueError(state, "...listing ZoneTerminalUnitList objects.");
4676 0 : for (int NumList = 1; NumList <= state.dataHVACVarRefFlow->NumVRFTULists; ++NumList) {
4677 0 : ShowContinueError(state, "...ZoneTerminalUnitList = " + state.dataHVACVarRefFlow->TerminalUnitList(NumList).Name);
4678 : }
4679 0 : ErrorsFound = true;
4680 : }
4681 :
4682 : // Set up output variables
4683 57 : for (int VRFTUNum = 1; VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU; ++VRFTUNum) {
4684 34 : auto &thisVrfTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
4685 34 : if (thisVrfTU.CoolingCoilPresent) {
4686 68 : SetupOutputVariable(state,
4687 : "Zone VRF Air Terminal Cooling Electricity Rate",
4688 : Constant::Units::W,
4689 34 : thisVrfTU.ParasiticCoolElecPower,
4690 : OutputProcessor::TimeStepType::System,
4691 : OutputProcessor::StoreType::Average,
4692 34 : thisVrfTU.Name);
4693 68 : SetupOutputVariable(state,
4694 : "Zone VRF Air Terminal Cooling Electricity Energy",
4695 : Constant::Units::J,
4696 34 : thisVrfTU.ParasiticElecCoolConsumption,
4697 : OutputProcessor::TimeStepType::System,
4698 : OutputProcessor::StoreType::Sum,
4699 34 : thisVrfTU.Name,
4700 : Constant::eResource::Electricity,
4701 : OutputProcessor::Group::HVAC,
4702 : OutputProcessor::EndUseCat::Cooling);
4703 68 : SetupOutputVariable(state,
4704 : "Zone VRF Air Terminal Total Cooling Rate",
4705 : Constant::Units::W,
4706 34 : thisVrfTU.TotalCoolingRate,
4707 : OutputProcessor::TimeStepType::System,
4708 : OutputProcessor::StoreType::Average,
4709 34 : thisVrfTU.Name);
4710 68 : SetupOutputVariable(state,
4711 : "Zone VRF Air Terminal Sensible Cooling Rate",
4712 : Constant::Units::W,
4713 34 : thisVrfTU.SensibleCoolingRate,
4714 : OutputProcessor::TimeStepType::System,
4715 : OutputProcessor::StoreType::Average,
4716 34 : thisVrfTU.Name);
4717 68 : SetupOutputVariable(state,
4718 : "Zone VRF Air Terminal Latent Cooling Rate",
4719 : Constant::Units::W,
4720 34 : thisVrfTU.LatentCoolingRate,
4721 : OutputProcessor::TimeStepType::System,
4722 : OutputProcessor::StoreType::Average,
4723 34 : thisVrfTU.Name);
4724 68 : SetupOutputVariable(state,
4725 : "Zone VRF Air Terminal Total Cooling Energy",
4726 : Constant::Units::J,
4727 34 : thisVrfTU.TotalCoolingEnergy,
4728 : OutputProcessor::TimeStepType::System,
4729 : OutputProcessor::StoreType::Sum,
4730 34 : thisVrfTU.Name);
4731 68 : SetupOutputVariable(state,
4732 : "Zone VRF Air Terminal Sensible Cooling Energy",
4733 : Constant::Units::J,
4734 34 : thisVrfTU.SensibleCoolingEnergy,
4735 : OutputProcessor::TimeStepType::System,
4736 : OutputProcessor::StoreType::Sum,
4737 34 : thisVrfTU.Name);
4738 68 : SetupOutputVariable(state,
4739 : "Zone VRF Air Terminal Latent Cooling Energy",
4740 : Constant::Units::J,
4741 34 : thisVrfTU.LatentCoolingEnergy,
4742 : OutputProcessor::TimeStepType::System,
4743 : OutputProcessor::StoreType::Sum,
4744 34 : thisVrfTU.Name);
4745 : }
4746 34 : if (thisVrfTU.HeatingCoilPresent) {
4747 68 : SetupOutputVariable(state,
4748 : "Zone VRF Air Terminal Heating Electricity Rate",
4749 : Constant::Units::W,
4750 34 : thisVrfTU.ParasiticHeatElecPower,
4751 : OutputProcessor::TimeStepType::System,
4752 : OutputProcessor::StoreType::Average,
4753 34 : thisVrfTU.Name);
4754 68 : SetupOutputVariable(state,
4755 : "Zone VRF Air Terminal Heating Electricity Energy",
4756 : Constant::Units::J,
4757 34 : thisVrfTU.ParasiticElecHeatConsumption,
4758 : OutputProcessor::TimeStepType::System,
4759 : OutputProcessor::StoreType::Sum,
4760 34 : thisVrfTU.Name,
4761 : Constant::eResource::Electricity,
4762 : OutputProcessor::Group::HVAC,
4763 : OutputProcessor::EndUseCat::Heating);
4764 68 : SetupOutputVariable(state,
4765 : "Zone VRF Air Terminal Total Heating Rate",
4766 : Constant::Units::W,
4767 34 : thisVrfTU.TotalHeatingRate,
4768 : OutputProcessor::TimeStepType::System,
4769 : OutputProcessor::StoreType::Average,
4770 34 : thisVrfTU.Name);
4771 68 : SetupOutputVariable(state,
4772 : "Zone VRF Air Terminal Sensible Heating Rate",
4773 : Constant::Units::W,
4774 34 : thisVrfTU.SensibleHeatingRate,
4775 : OutputProcessor::TimeStepType::System,
4776 : OutputProcessor::StoreType::Average,
4777 34 : thisVrfTU.Name);
4778 68 : SetupOutputVariable(state,
4779 : "Zone VRF Air Terminal Latent Heating Rate",
4780 : Constant::Units::W,
4781 34 : thisVrfTU.LatentHeatingRate,
4782 : OutputProcessor::TimeStepType::System,
4783 : OutputProcessor::StoreType::Average,
4784 34 : thisVrfTU.Name);
4785 68 : SetupOutputVariable(state,
4786 : "Zone VRF Air Terminal Total Heating Energy",
4787 : Constant::Units::J,
4788 34 : thisVrfTU.TotalHeatingEnergy,
4789 : OutputProcessor::TimeStepType::System,
4790 : OutputProcessor::StoreType::Sum,
4791 34 : thisVrfTU.Name);
4792 68 : SetupOutputVariable(state,
4793 : "Zone VRF Air Terminal Sensible Heating Energy",
4794 : Constant::Units::J,
4795 34 : thisVrfTU.SensibleHeatingEnergy,
4796 : OutputProcessor::TimeStepType::System,
4797 : OutputProcessor::StoreType::Sum,
4798 34 : thisVrfTU.Name);
4799 68 : SetupOutputVariable(state,
4800 : "Zone VRF Air Terminal Latent Heating Energy",
4801 : Constant::Units::J,
4802 34 : thisVrfTU.LatentHeatingEnergy,
4803 : OutputProcessor::TimeStepType::System,
4804 : OutputProcessor::StoreType::Sum,
4805 34 : thisVrfTU.Name);
4806 : }
4807 34 : SetupOutputVariable(state,
4808 : "Zone VRF Air Terminal Fan Availability Status",
4809 : Constant::Units::None,
4810 34 : (int &)thisVrfTU.availStatus,
4811 : OutputProcessor::TimeStepType::System,
4812 : OutputProcessor::StoreType::Average,
4813 34 : thisVrfTU.Name);
4814 34 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
4815 0 : SetupEMSActuator(state,
4816 : "Variable Refrigerant Flow Terminal Unit",
4817 : thisVrfTU.Name,
4818 : "Part Load Ratio",
4819 : "[fraction]",
4820 0 : thisVrfTU.EMSOverridePartLoadFrac,
4821 0 : thisVrfTU.EMSValueForPartLoadFrac);
4822 : }
4823 34 : if (thisVrfTU.NumOfSpeedCooling > 1 || thisVrfTU.NumOfSpeedHeating > 1) {
4824 4 : SetupOutputVariable(state,
4825 : "Zone VRF Air Terminal Multispeed Fan Cycling Ratio",
4826 : Constant::Units::None,
4827 2 : thisVrfTU.CycRatio,
4828 : OutputProcessor::TimeStepType::System,
4829 : OutputProcessor::StoreType::Average,
4830 2 : thisVrfTU.Name);
4831 4 : SetupOutputVariable(state,
4832 : "Zone VRF Air Terminal Multispeed Fan Speed Ratio",
4833 : Constant::Units::None,
4834 2 : thisVrfTU.SpeedRatio,
4835 : OutputProcessor::TimeStepType::System,
4836 : OutputProcessor::StoreType::Average,
4837 2 : thisVrfTU.Name);
4838 2 : SetupOutputVariable(state,
4839 : "Zone VRF Air Terminal Multispeed Fan Speed Level",
4840 : Constant::Units::None,
4841 2 : thisVrfTU.SpeedNum,
4842 : OutputProcessor::TimeStepType::System,
4843 : OutputProcessor::StoreType::Average,
4844 2 : thisVrfTU.Name);
4845 : }
4846 : }
4847 :
4848 50 : for (int NumCond = 1; NumCond <= state.dataHVACVarRefFlow->NumVRFCond; ++NumCond) {
4849 27 : auto &thisVrf = state.dataHVACVarRefFlow->VRF(NumCond);
4850 27 : std::string_view const sFuelType = Constant::eFuelNames[static_cast<int>(thisVrf.fuel)];
4851 54 : SetupOutputVariable(state,
4852 : "VRF Heat Pump Total Cooling Rate",
4853 : Constant::Units::W,
4854 27 : thisVrf.TotalCoolingCapacity,
4855 : OutputProcessor::TimeStepType::System,
4856 : OutputProcessor::StoreType::Average,
4857 27 : thisVrf.Name);
4858 54 : SetupOutputVariable(state,
4859 : "VRF Heat Pump Total Heating Rate",
4860 : Constant::Units::W,
4861 27 : thisVrf.TotalHeatingCapacity,
4862 : OutputProcessor::TimeStepType::System,
4863 : OutputProcessor::StoreType::Average,
4864 27 : thisVrf.Name);
4865 81 : SetupOutputVariable(state,
4866 54 : format("VRF Heat Pump Cooling {} Rate", sFuelType),
4867 : Constant::Units::W,
4868 27 : thisVrf.ElecCoolingPower,
4869 : OutputProcessor::TimeStepType::System,
4870 : OutputProcessor::StoreType::Average,
4871 27 : thisVrf.Name);
4872 81 : SetupOutputVariable(state,
4873 54 : format("VRF Heat Pump Cooling {} Energy", sFuelType),
4874 : Constant::Units::J,
4875 27 : thisVrf.CoolElecConsumption,
4876 : OutputProcessor::TimeStepType::System,
4877 : OutputProcessor::StoreType::Sum,
4878 27 : thisVrf.Name,
4879 27 : Constant::eFuel2eResource[(int)thisVrf.fuel],
4880 : OutputProcessor::Group::HVAC,
4881 : OutputProcessor::EndUseCat::Cooling);
4882 81 : SetupOutputVariable(state,
4883 54 : format("VRF Heat Pump Heating {} Rate", sFuelType),
4884 : Constant::Units::W,
4885 27 : thisVrf.ElecHeatingPower,
4886 : OutputProcessor::TimeStepType::System,
4887 : OutputProcessor::StoreType::Average,
4888 27 : thisVrf.Name);
4889 81 : SetupOutputVariable(state,
4890 54 : format("VRF Heat Pump Heating {} Energy", sFuelType),
4891 : Constant::Units::J,
4892 27 : thisVrf.HeatElecConsumption,
4893 : OutputProcessor::TimeStepType::System,
4894 : OutputProcessor::StoreType::Sum,
4895 27 : thisVrf.Name,
4896 27 : Constant::eFuel2eResource[(int)thisVrf.fuel],
4897 : OutputProcessor::Group::HVAC,
4898 : OutputProcessor::EndUseCat::Heating);
4899 :
4900 54 : SetupOutputVariable(state,
4901 : "VRF Heat Pump Cooling COP",
4902 : Constant::Units::None,
4903 27 : thisVrf.OperatingCoolingCOP,
4904 : OutputProcessor::TimeStepType::System,
4905 : OutputProcessor::StoreType::Average,
4906 27 : thisVrf.Name);
4907 54 : SetupOutputVariable(state,
4908 : "VRF Heat Pump Heating COP",
4909 : Constant::Units::None,
4910 27 : thisVrf.OperatingHeatingCOP,
4911 : OutputProcessor::TimeStepType::System,
4912 : OutputProcessor::StoreType::Average,
4913 27 : thisVrf.Name);
4914 54 : SetupOutputVariable(state,
4915 : "VRF Heat Pump COP",
4916 : Constant::Units::None,
4917 27 : thisVrf.OperatingCOP,
4918 : OutputProcessor::TimeStepType::System,
4919 : OutputProcessor::StoreType::Average,
4920 27 : thisVrf.Name);
4921 :
4922 27 : if (thisVrf.VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
4923 : // For VRF_FluidTCtrl Model
4924 18 : SetupOutputVariable(state,
4925 : "VRF Heat Pump Compressor Electricity Rate",
4926 : Constant::Units::W,
4927 9 : thisVrf.Ncomp,
4928 : OutputProcessor::TimeStepType::System,
4929 : OutputProcessor::StoreType::Average,
4930 9 : thisVrf.Name);
4931 18 : SetupOutputVariable(state,
4932 : "VRF Heat Pump Outdoor Unit Fan Power",
4933 : Constant::Units::W,
4934 9 : thisVrf.OUFanPower,
4935 : OutputProcessor::TimeStepType::System,
4936 : OutputProcessor::StoreType::Average,
4937 9 : thisVrf.Name);
4938 18 : SetupOutputVariable(state,
4939 : "VRF Heat Pump Compressor Rotating Speed",
4940 : Constant::Units::rev_min,
4941 9 : thisVrf.CompActSpeed,
4942 : OutputProcessor::TimeStepType::System,
4943 : OutputProcessor::StoreType::Average,
4944 9 : thisVrf.Name);
4945 18 : SetupOutputVariable(state,
4946 : "VRF Heat Pump Indoor Unit Evaporating Temperature",
4947 : Constant::Units::C,
4948 9 : thisVrf.IUEvaporatingTemp,
4949 : OutputProcessor::TimeStepType::System,
4950 : OutputProcessor::StoreType::Average,
4951 9 : thisVrf.Name);
4952 18 : SetupOutputVariable(state,
4953 : "VRF Heat Pump Outdoor Unit Condensing Temperature",
4954 : Constant::Units::C,
4955 9 : thisVrf.CondensingTemp,
4956 : OutputProcessor::TimeStepType::System,
4957 : OutputProcessor::StoreType::Average,
4958 9 : thisVrf.Name);
4959 18 : SetupOutputVariable(state,
4960 : "VRF Heat Pump Indoor Unit Condensing Temperature",
4961 : Constant::Units::C,
4962 9 : thisVrf.IUCondensingTemp,
4963 : OutputProcessor::TimeStepType::System,
4964 : OutputProcessor::StoreType::Average,
4965 9 : thisVrf.Name);
4966 18 : SetupOutputVariable(state,
4967 : "VRF Heat Pump Outdoor Unit Evaporating Temperature",
4968 : Constant::Units::C,
4969 9 : thisVrf.EvaporatingTemp,
4970 : OutputProcessor::TimeStepType::System,
4971 : OutputProcessor::StoreType::Average,
4972 9 : thisVrf.Name);
4973 18 : SetupOutputVariable(state,
4974 : "VRF Heat Pump Cooling Capacity at Max Compressor Speed",
4975 : Constant::Units::W,
4976 9 : thisVrf.CoolingCapacity,
4977 : OutputProcessor::TimeStepType::System,
4978 : OutputProcessor::StoreType::Average,
4979 9 : thisVrf.Name);
4980 18 : SetupOutputVariable(state,
4981 : "VRF Heat Pump Heating Capacity at Max Compressor Speed",
4982 : Constant::Units::W,
4983 9 : thisVrf.HeatingCapacity,
4984 : OutputProcessor::TimeStepType::System,
4985 : OutputProcessor::StoreType::Average,
4986 9 : thisVrf.Name);
4987 18 : SetupOutputVariable(state,
4988 : "VRF Heat Pump Indoor Unit Piping Correction for Cooling",
4989 : Constant::Units::None,
4990 9 : thisVrf.PipingCorrectionCooling,
4991 : OutputProcessor::TimeStepType::System,
4992 : OutputProcessor::StoreType::Average,
4993 9 : thisVrf.Name);
4994 18 : SetupOutputVariable(state,
4995 : "VRF Heat Pump Indoor Unit Piping Correction for Heating",
4996 : Constant::Units::None,
4997 9 : thisVrf.PipingCorrectionHeating,
4998 : OutputProcessor::TimeStepType::System,
4999 : OutputProcessor::StoreType::Average,
5000 9 : thisVrf.Name);
5001 18 : SetupOutputVariable(state,
5002 : "VRF Heat Pump Outdoor Unit Evaporator Heat Extract Rate",
5003 : Constant::Units::W,
5004 9 : thisVrf.OUEvapHeatRate,
5005 : OutputProcessor::TimeStepType::System,
5006 : OutputProcessor::StoreType::Average,
5007 9 : thisVrf.Name);
5008 18 : SetupOutputVariable(state,
5009 : "VRF Heat Pump Outdoor Unit Condenser Heat Release Rate",
5010 : Constant::Units::W,
5011 9 : thisVrf.OUCondHeatRate,
5012 : OutputProcessor::TimeStepType::System,
5013 : OutputProcessor::StoreType::Average,
5014 9 : thisVrf.Name);
5015 :
5016 : } else {
5017 : // For VRF_SysCurve Model
5018 36 : SetupOutputVariable(state,
5019 : "VRF Heat Pump Maximum Capacity Cooling Rate",
5020 : Constant::Units::W,
5021 18 : state.dataHVACVarRefFlow->MaxCoolingCapacity(NumCond),
5022 : OutputProcessor::TimeStepType::System,
5023 : OutputProcessor::StoreType::Average,
5024 18 : thisVrf.Name);
5025 36 : SetupOutputVariable(state,
5026 : "VRF Heat Pump Maximum Capacity Heating Rate",
5027 : Constant::Units::W,
5028 18 : state.dataHVACVarRefFlow->MaxHeatingCapacity(NumCond),
5029 : OutputProcessor::TimeStepType::System,
5030 : OutputProcessor::StoreType::Average,
5031 18 : thisVrf.Name);
5032 : }
5033 :
5034 27 : if (thisVrf.DefrostStrategy == StandardRatings::DefrostStrat::Resistive ||
5035 15 : (thisVrf.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle && thisVrf.fuel == Constant::eFuel::Electricity)) {
5036 54 : SetupOutputVariable(state,
5037 : "VRF Heat Pump Defrost Electricity Rate",
5038 : Constant::Units::W,
5039 27 : thisVrf.DefrostPower,
5040 : OutputProcessor::TimeStepType::System,
5041 : OutputProcessor::StoreType::Average,
5042 27 : thisVrf.Name);
5043 54 : SetupOutputVariable(state,
5044 : "VRF Heat Pump Defrost Electricity Energy",
5045 : Constant::Units::J,
5046 27 : thisVrf.DefrostConsumption,
5047 : OutputProcessor::TimeStepType::System,
5048 : OutputProcessor::StoreType::Sum,
5049 27 : thisVrf.Name,
5050 : Constant::eResource::Electricity,
5051 : OutputProcessor::Group::HVAC,
5052 : OutputProcessor::EndUseCat::Heating);
5053 :
5054 : } else { // defrost energy applied to fuel type
5055 0 : SetupOutputVariable(state,
5056 0 : format("VRF Heat Pump Defrost {} Rate", sFuelType),
5057 : Constant::Units::W,
5058 0 : thisVrf.DefrostPower,
5059 : OutputProcessor::TimeStepType::System,
5060 : OutputProcessor::StoreType::Average,
5061 0 : thisVrf.Name);
5062 0 : SetupOutputVariable(state,
5063 0 : format("VRF Heat Pump Defrost {} Energy", sFuelType),
5064 : Constant::Units::J,
5065 0 : thisVrf.DefrostConsumption,
5066 : OutputProcessor::TimeStepType::System,
5067 : OutputProcessor::StoreType::Sum,
5068 0 : thisVrf.Name,
5069 0 : Constant::eFuel2eResource[(int)thisVrf.fuel],
5070 : OutputProcessor::Group::HVAC,
5071 : OutputProcessor::EndUseCat::Heating);
5072 : }
5073 :
5074 54 : SetupOutputVariable(state,
5075 : "VRF Heat Pump Part Load Ratio",
5076 : Constant::Units::None,
5077 27 : thisVrf.VRFCondPLR,
5078 : OutputProcessor::TimeStepType::System,
5079 : OutputProcessor::StoreType::Average,
5080 27 : thisVrf.Name);
5081 54 : SetupOutputVariable(state,
5082 : "VRF Heat Pump Runtime Fraction",
5083 : Constant::Units::None,
5084 27 : thisVrf.VRFCondRTF,
5085 : OutputProcessor::TimeStepType::System,
5086 : OutputProcessor::StoreType::Average,
5087 27 : thisVrf.Name);
5088 54 : SetupOutputVariable(state,
5089 : "VRF Heat Pump Cycling Ratio",
5090 : Constant::Units::None,
5091 27 : thisVrf.VRFCondCyclingRatio,
5092 : OutputProcessor::TimeStepType::System,
5093 : OutputProcessor::StoreType::Average,
5094 27 : thisVrf.Name);
5095 :
5096 27 : SetupOutputVariable(state,
5097 : "VRF Heat Pump Operating Mode",
5098 : Constant::Units::None,
5099 27 : thisVrf.OperatingMode,
5100 : OutputProcessor::TimeStepType::System,
5101 : OutputProcessor::StoreType::Average,
5102 27 : thisVrf.Name);
5103 54 : SetupOutputVariable(state,
5104 : "VRF Heat Pump Condenser Inlet Temperature",
5105 : Constant::Units::C,
5106 27 : thisVrf.CondenserInletTemp,
5107 : OutputProcessor::TimeStepType::System,
5108 : OutputProcessor::StoreType::Average,
5109 27 : thisVrf.Name);
5110 :
5111 54 : SetupOutputVariable(state,
5112 : "VRF Heat Pump Crankcase Heater Electricity Rate",
5113 : Constant::Units::W,
5114 27 : thisVrf.CrankCaseHeaterPower,
5115 : OutputProcessor::TimeStepType::System,
5116 : OutputProcessor::StoreType::Average,
5117 27 : thisVrf.Name);
5118 54 : SetupOutputVariable(state,
5119 : "VRF Heat Pump Crankcase Heater Electricity Energy",
5120 : Constant::Units::J,
5121 27 : thisVrf.CrankCaseHeaterElecConsumption,
5122 : OutputProcessor::TimeStepType::System,
5123 : OutputProcessor::StoreType::Sum,
5124 27 : thisVrf.Name,
5125 : Constant::eResource::Electricity,
5126 : OutputProcessor::Group::HVAC,
5127 : OutputProcessor::EndUseCat::Cooling);
5128 54 : SetupOutputVariable(state,
5129 : "VRF Heat Pump Terminal Unit Cooling Load Rate",
5130 : Constant::Units::W,
5131 27 : thisVrf.TUCoolingLoad,
5132 : OutputProcessor::TimeStepType::System,
5133 : OutputProcessor::StoreType::Average,
5134 27 : thisVrf.Name);
5135 54 : SetupOutputVariable(state,
5136 : "VRF Heat Pump Terminal Unit Heating Load Rate",
5137 : Constant::Units::W,
5138 27 : thisVrf.TUHeatingLoad,
5139 : OutputProcessor::TimeStepType::System,
5140 : OutputProcessor::StoreType::Average,
5141 27 : thisVrf.Name);
5142 27 : if (thisVrf.HeatRecoveryUsed) {
5143 8 : SetupOutputVariable(state,
5144 : "VRF Heat Pump Heat Recovery Status Change Multiplier",
5145 : Constant::Units::None,
5146 4 : thisVrf.SUMultiplier,
5147 : OutputProcessor::TimeStepType::System,
5148 : OutputProcessor::StoreType::Average,
5149 4 : thisVrf.Name);
5150 8 : SetupOutputVariable(state,
5151 : "VRF Heat Pump Simultaneous Cooling and Heating Efficiency",
5152 : Constant::Units::Btu_h_W,
5153 4 : thisVrf.SCHE,
5154 : OutputProcessor::TimeStepType::System,
5155 : OutputProcessor::StoreType::Average,
5156 4 : thisVrf.Name);
5157 8 : SetupOutputVariable(state,
5158 : "VRF Heat Pump Heat Recovery Rate",
5159 : Constant::Units::W,
5160 4 : thisVrf.VRFHeatRec,
5161 : OutputProcessor::TimeStepType::System,
5162 : OutputProcessor::StoreType::Average,
5163 4 : thisVrf.Name);
5164 8 : SetupOutputVariable(state,
5165 : "VRF Heat Pump Heat Recovery Energy",
5166 : Constant::Units::J,
5167 4 : thisVrf.VRFHeatEnergyRec,
5168 : OutputProcessor::TimeStepType::System,
5169 : OutputProcessor::StoreType::Sum,
5170 4 : thisVrf.Name,
5171 : Constant::eResource::EnergyTransfer,
5172 : OutputProcessor::Group::Plant,
5173 : OutputProcessor::EndUseCat::HeatRecovery);
5174 : }
5175 :
5176 27 : if (thisVrf.CondenserType == DataHeatBalance::RefrigCondenserType::Evap) {
5177 0 : SetupOutputVariable(state,
5178 : "VRF Heat Pump Evaporative Condenser Water Use Volume",
5179 : Constant::Units::m3,
5180 0 : thisVrf.EvapWaterConsumpRate,
5181 : OutputProcessor::TimeStepType::System,
5182 : OutputProcessor::StoreType::Sum,
5183 0 : thisVrf.Name,
5184 : Constant::eResource::Water,
5185 : OutputProcessor::Group::HVAC,
5186 : OutputProcessor::EndUseCat::Cooling);
5187 0 : SetupOutputVariable(state,
5188 : "VRF Heat Pump Evaporative Condenser Pump Electricity Rate",
5189 : Constant::Units::W,
5190 0 : thisVrf.EvapCondPumpElecPower,
5191 : OutputProcessor::TimeStepType::System,
5192 : OutputProcessor::StoreType::Average,
5193 0 : thisVrf.Name);
5194 0 : SetupOutputVariable(state,
5195 : "VRF Heat Pump Evaporative Condenser Pump Electricity Energy",
5196 : Constant::Units::J,
5197 0 : thisVrf.EvapCondPumpElecConsumption,
5198 : OutputProcessor::TimeStepType::System,
5199 : OutputProcessor::StoreType::Sum,
5200 0 : thisVrf.Name,
5201 : Constant::eResource::Electricity,
5202 : OutputProcessor::Group::HVAC,
5203 : OutputProcessor::EndUseCat::Cooling);
5204 :
5205 0 : if (thisVrf.BasinHeaterPowerFTempDiff > 0.0) {
5206 0 : SetupOutputVariable(state,
5207 : "VRF Heat Pump Basin Heater Electricity Rate",
5208 : Constant::Units::W,
5209 0 : thisVrf.BasinHeaterPower,
5210 : OutputProcessor::TimeStepType::System,
5211 : OutputProcessor::StoreType::Average,
5212 0 : thisVrf.Name);
5213 0 : SetupOutputVariable(state,
5214 : "VRF Heat Pump Basin Heater Electricity Energy",
5215 : Constant::Units::J,
5216 0 : thisVrf.BasinHeaterConsumption,
5217 : OutputProcessor::TimeStepType::System,
5218 : OutputProcessor::StoreType::Sum,
5219 0 : thisVrf.Name,
5220 : Constant::eResource::Electricity,
5221 : OutputProcessor::Group::HVAC,
5222 : OutputProcessor::EndUseCat::Cooling);
5223 : }
5224 :
5225 27 : } else if (thisVrf.CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
5226 2 : SetupOutputVariable(state,
5227 : "VRF Heat Pump Condenser Outlet Temperature",
5228 : Constant::Units::C,
5229 1 : thisVrf.CondenserSideOutletTemp,
5230 : OutputProcessor::TimeStepType::System,
5231 : OutputProcessor::StoreType::Average,
5232 1 : thisVrf.Name);
5233 2 : SetupOutputVariable(state,
5234 : "VRF Heat Pump Condenser Mass Flow Rate",
5235 : Constant::Units::kg_s,
5236 1 : thisVrf.WaterCondenserMassFlow,
5237 : OutputProcessor::TimeStepType::System,
5238 : OutputProcessor::StoreType::Average,
5239 1 : thisVrf.Name);
5240 2 : SetupOutputVariable(state,
5241 : "VRF Heat Pump Condenser Heat Transfer Rate",
5242 : Constant::Units::W,
5243 1 : thisVrf.QCondenser,
5244 : OutputProcessor::TimeStepType::System,
5245 : OutputProcessor::StoreType::Average,
5246 1 : thisVrf.Name);
5247 2 : SetupOutputVariable(state,
5248 : "VRF Heat Pump Condenser Heat Transfer Energy",
5249 : Constant::Units::J,
5250 1 : thisVrf.QCondEnergy,
5251 : OutputProcessor::TimeStepType::System,
5252 : OutputProcessor::StoreType::Sum,
5253 1 : thisVrf.Name);
5254 : }
5255 :
5256 27 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
5257 0 : SetupEMSActuator(state,
5258 : "Variable Refrigerant Flow Heat Pump",
5259 : thisVrf.Name,
5260 : "Operating Mode",
5261 : "[integer]",
5262 0 : thisVrf.EMSOverrideHPOperatingMode,
5263 0 : thisVrf.EMSValueForHPOperatingMode);
5264 : }
5265 : }
5266 23 : }
5267 :
5268 48 : void CheckVRFTUNodeConnections(EnergyPlusData &state, int const VRFTUNum, bool &ErrorsFound)
5269 : {
5270 :
5271 : constexpr static std::string_view cTerminalUnitType("ZoneHVAC:TerminalUnit:VariableRefrigerantFlow");
5272 48 : auto const &nodeID = state.dataLoopNodes->NodeID;
5273 48 : auto &vrfTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
5274 48 : std::string const cTUName(vrfTU.Name);
5275 48 : bool const CoolingCoilPresent = vrfTU.CoolingCoilPresent;
5276 48 : bool const HeatingCoilPresent = vrfTU.HeatingCoilPresent;
5277 48 : bool const SuppHeatingCoilPresent = vrfTU.SuppHeatingCoilPresent;
5278 48 : HVAC::FanPlace const fanPlace = vrfTU.fanPlace;
5279 48 : bool const FanPresent = fanPlace != HVAC::FanPlace::Invalid;
5280 48 : bool const OAMixerUsed = vrfTU.OAMixerUsed;
5281 48 : int const VRFTUInletNodeNum = vrfTU.VRFTUInletNodeNum;
5282 48 : int const VRFTUOutletNodeNum = vrfTU.VRFTUOutletNodeNum;
5283 48 : int const coolCoilAirInNode = vrfTU.coolCoilAirInNode;
5284 48 : int const coolCoilAirOutNode = vrfTU.coolCoilAirOutNode;
5285 48 : int const heatCoilAirInNode = vrfTU.heatCoilAirInNode;
5286 48 : int const heatCoilAirOutNode = vrfTU.heatCoilAirOutNode;
5287 48 : int const fanInletNode = vrfTU.fanInletNode;
5288 48 : int const fanOutletNode = vrfTU.fanOutletNode;
5289 48 : int const SuppHeatCoilAirInletNode = vrfTU.SuppHeatCoilAirInletNode;
5290 48 : int const SuppHeatCoilAirOutletNode = vrfTU.SuppHeatCoilAirOutletNode;
5291 48 : int const VRFTUOAMixerRetNodeNum = vrfTU.VRFTUOAMixerRetNodeNum;
5292 48 : int const VRFTUOAMixerMixedNodeNum = vrfTU.VRFTUOAMixerMixedNodeNum;
5293 :
5294 : // check that TU object internal nodes (TU inlet to TU outlet) are correctly connected
5295 : // the following is checked regardless of fan placement
5296 48 : if (CoolingCoilPresent && HeatingCoilPresent) {
5297 48 : if (coolCoilAirOutNode != heatCoilAirInNode) {
5298 8 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5299 8 : ShowContinueError(state, "The cooling coil air outlet node name must match the heating coil air inlet node name.");
5300 4 : if (coolCoilAirOutNode > 0 && heatCoilAirInNode > 0) {
5301 4 : ShowContinueError(state, format("... Cooling coil air outlet node = {}", nodeID(coolCoilAirOutNode)));
5302 4 : ShowContinueError(state, format("... Heating coil air inlet node = {}", nodeID(heatCoilAirInNode)));
5303 : }
5304 4 : ErrorsFound = true;
5305 : }
5306 : }
5307 :
5308 : // check the TU inlet node name with the first component
5309 48 : if (fanPlace == HVAC::FanPlace::DrawThru || !FanPresent) {
5310 38 : if (OAMixerUsed) {
5311 30 : if (VRFTUInletNodeNum != VRFTUOAMixerRetNodeNum) {
5312 10 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5313 10 : ShowContinueError(state,
5314 : "... For draw thru or no fan when an OA mixer is specified the terminal unit "
5315 : "inlet node name must match the OA mixer return air stream node name.");
5316 5 : if (VRFTUInletNodeNum > 0 && VRFTUOAMixerRetNodeNum > 0) {
5317 5 : ShowContinueError(state, format("... Terminal unit inlet node name = {}.", nodeID(VRFTUInletNodeNum)));
5318 5 : ShowContinueError(state, format("... OA mixer return air stream node name = {}.", nodeID(VRFTUOAMixerRetNodeNum)));
5319 : }
5320 5 : ErrorsFound = true;
5321 : }
5322 : // check mixer outlet with next component
5323 30 : if (CoolingCoilPresent) {
5324 30 : if (VRFTUOAMixerMixedNodeNum != coolCoilAirInNode) {
5325 6 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5326 6 : ShowContinueError(state,
5327 : "... For draw thru or no fan when an OA mixer is specified and a cooling coil is present "
5328 : "the OA mixer mixed air node name must match the cooling coil inlet node name.");
5329 3 : if (VRFTUOAMixerMixedNodeNum > 0 && coolCoilAirInNode > 0) {
5330 2 : ShowContinueError(state, format("... OA mixer mixed air node name = {}.", nodeID(VRFTUOAMixerMixedNodeNum)));
5331 2 : ShowContinueError(state, format("... Cooling coil inlet node name = {}.", nodeID(coolCoilAirInNode)));
5332 : }
5333 3 : ErrorsFound = true;
5334 : }
5335 0 : } else if (HeatingCoilPresent) {
5336 0 : if (VRFTUOAMixerMixedNodeNum != heatCoilAirInNode) {
5337 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5338 0 : ShowContinueError(state,
5339 : "... For draw thru or no fan when an OA mixer is specified and a cooling coil is not present "
5340 : "the OA mixer mixed air node name must match the heating coil inlet node name.");
5341 0 : if (VRFTUOAMixerMixedNodeNum > 0 && heatCoilAirInNode > 0) {
5342 0 : ShowContinueError(state, format("... OA mixer mixed air node name = {}.", nodeID(VRFTUOAMixerMixedNodeNum)));
5343 0 : ShowContinueError(state, format("... Heating coil inlet node name = {}.", nodeID(heatCoilAirInNode)));
5344 : }
5345 0 : ErrorsFound = true;
5346 : }
5347 : }
5348 : } else { // OAMixer not used
5349 8 : if (CoolingCoilPresent) {
5350 8 : if (VRFTUInletNodeNum != coolCoilAirInNode) {
5351 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5352 0 : ShowContinueError(
5353 : state,
5354 : "... For draw thru or no fan when no OA mixer is specified and a cooling coil is present the terminal unit inlet "
5355 : "node name must match the cooling coil inlet node name.");
5356 0 : if (VRFTUInletNodeNum > 0 && coolCoilAirInNode > 0) {
5357 0 : ShowContinueError(state, format("... Terminal unit inlet node name = {}.", nodeID(VRFTUInletNodeNum)));
5358 0 : ShowContinueError(state, format("... Cooling coil inlet node name = {}.", nodeID(coolCoilAirInNode)));
5359 : }
5360 0 : ErrorsFound = true;
5361 : }
5362 0 : } else if (HeatingCoilPresent) {
5363 0 : if (VRFTUInletNodeNum != heatCoilAirInNode) {
5364 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5365 0 : ShowContinueError(state,
5366 : "... For draw thru or no fan when no cooling coil or OA mixer is specified the terminal unit inlet "
5367 : "node name must match the heating coil inlet node name.");
5368 0 : if (VRFTUInletNodeNum > 0 && heatCoilAirInNode > 0) {
5369 0 : ShowContinueError(state, format("... Terminal unit inlet node name = {}.", nodeID(VRFTUInletNodeNum)));
5370 0 : ShowContinueError(state, format("... Heating coil inlet node name = {}.", nodeID(heatCoilAirInNode)));
5371 : }
5372 0 : ErrorsFound = true;
5373 : }
5374 : }
5375 : }
5376 : }
5377 48 : if (fanPlace == HVAC::FanPlace::BlowThru && !OAMixerUsed) {
5378 0 : if (VRFTUInletNodeNum != fanInletNode) {
5379 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5380 0 : ShowContinueError(state,
5381 : "... For blow thru fan when no OA mixer is specified the terminal unit inlet "
5382 : "node name must match the fan inlet node name.");
5383 0 : if (VRFTUInletNodeNum > 0 && fanInletNode > 0) {
5384 0 : ShowContinueError(state, format("... Terminal unit inlet node name = {}.", nodeID(VRFTUInletNodeNum)));
5385 0 : ShowContinueError(state, format("... Fan inlet node name = {}.", nodeID(fanInletNode)));
5386 : }
5387 0 : ErrorsFound = true;
5388 : }
5389 48 : } else if (OAMixerUsed) { // when OA mixer is used TU inlet = OAMixer return node regardless of fan placement
5390 40 : if (VRFTUInletNodeNum != VRFTUOAMixerRetNodeNum) {
5391 12 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5392 12 : ShowContinueError(state,
5393 : "... When an OA mixer is specified the terminal unit inlet "
5394 : "node name must match the OA mixer return node name.");
5395 6 : if (VRFTUInletNodeNum > 0 && VRFTUOAMixerRetNodeNum > 0) {
5396 6 : ShowContinueError(state, format("... Terminal unit inlet node name = {}.", nodeID(VRFTUInletNodeNum)));
5397 6 : ShowContinueError(state, format("... Fan inlet node name = {}.", nodeID(VRFTUOAMixerRetNodeNum)));
5398 : }
5399 6 : ErrorsFound = true;
5400 : }
5401 : }
5402 : // check the next component
5403 48 : if (CoolingCoilPresent) {
5404 48 : if (fanPlace == HVAC::FanPlace::BlowThru) {
5405 10 : if (fanOutletNode != coolCoilAirInNode) {
5406 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5407 0 : ShowContinueError(state,
5408 : "... For blow thru fan when a cooling coil is present "
5409 : "fan outlet node name must match the cooling coil inlet node name.");
5410 0 : if (fanOutletNode > 0 && coolCoilAirInNode > 0) {
5411 0 : ShowContinueError(state, format("... The fan outlet node name = {}.", nodeID(fanOutletNode)));
5412 0 : ShowContinueError(state, format("... Cooling coil inlet node name = {}.", nodeID(coolCoilAirInNode)));
5413 : }
5414 0 : ErrorsFound = true;
5415 : }
5416 : }
5417 48 : if (!HeatingCoilPresent && fanPlace == HVAC::FanPlace::DrawThru) {
5418 0 : if (coolCoilAirOutNode != fanInletNode) {
5419 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5420 0 : ShowContinueError(state,
5421 : "... For draw thru fan when a heating coil is not present "
5422 : "the cooling coil outlet node name must match the fan inlet node name.");
5423 0 : if (coolCoilAirOutNode > 0 && fanInletNode > 0) {
5424 0 : ShowContinueError(state, format("... Cooling coil outlet node name = {}.", nodeID(coolCoilAirOutNode)));
5425 0 : ShowContinueError(state, format("... The fan inlet node name = {}.", nodeID(fanInletNode)));
5426 : }
5427 0 : ErrorsFound = true;
5428 : }
5429 : }
5430 : }
5431 48 : if (HeatingCoilPresent) {
5432 48 : if (fanPlace == HVAC::FanPlace::DrawThru) {
5433 32 : if (heatCoilAirOutNode != fanInletNode) {
5434 4 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5435 4 : ShowContinueError(state,
5436 : "... For draw thru fan when a heating coil is present "
5437 : "the heating coil outlet node name must match the fan inlet node name.");
5438 2 : if (heatCoilAirOutNode > 0 && fanInletNode > 0) {
5439 1 : ShowContinueError(state, format("... Heating coil outlet node name = {}.", nodeID(heatCoilAirOutNode)));
5440 1 : ShowContinueError(state, format("... The fan inlet node name = {}.", nodeID(fanInletNode)));
5441 : }
5442 2 : ErrorsFound = true;
5443 : }
5444 : }
5445 : }
5446 48 : if (SuppHeatingCoilPresent) {
5447 10 : if (SuppHeatCoilAirOutletNode != VRFTUOutletNodeNum) {
5448 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5449 0 : ShowContinueError(state, "... The supplemental heating coil outlet node name must match the terminal unit outlet node name.");
5450 0 : if (SuppHeatCoilAirOutletNode > 0 && VRFTUOutletNodeNum > 0) {
5451 0 : ShowContinueError(state, format("... Supplemental heating coil outlet node name = {}.", nodeID(SuppHeatCoilAirOutletNode)));
5452 0 : ShowContinueError(state, format("... Terminal unit outlet node name = {}.", nodeID(VRFTUOutletNodeNum)));
5453 : }
5454 0 : ErrorsFound = true;
5455 : }
5456 10 : if (fanPlace == HVAC::FanPlace::DrawThru) {
5457 9 : if (fanOutletNode != SuppHeatCoilAirInletNode) {
5458 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5459 0 : ShowContinueError(state,
5460 : "... For draw thru fan when a supplemental heating coil is present "
5461 : "the fan outlet node name must match the supplemental heating coil inlet node name.");
5462 0 : if (fanOutletNode > 0 && SuppHeatCoilAirInletNode > 0) {
5463 0 : ShowContinueError(state, format("... Fan outlet node name = {}.", nodeID(fanOutletNode)));
5464 0 : ShowContinueError(state, format("... Supplemental heating coil inlet node name = {}.", nodeID(SuppHeatCoilAirInletNode)));
5465 : }
5466 0 : ErrorsFound = true;
5467 : }
5468 : } else {
5469 1 : if (heatCoilAirOutNode != SuppHeatCoilAirInletNode) {
5470 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5471 0 : ShowContinueError(state,
5472 : "... For blow thru or no fan when a supplemental heating coil is present the heating "
5473 : "coil outlet node name must match the supplemental heating coil inlet node name.");
5474 0 : if (heatCoilAirOutNode > 0 && SuppHeatCoilAirInletNode > 0) {
5475 0 : ShowContinueError(state, format("... Heating coil outlet node name = {}.", nodeID(heatCoilAirOutNode)));
5476 0 : ShowContinueError(state, format("... Supplemental heating coil inlet node name = {}.", nodeID(SuppHeatCoilAirInletNode)));
5477 : }
5478 0 : ErrorsFound = true;
5479 : }
5480 : }
5481 38 : } else if (CoolingCoilPresent && !HeatingCoilPresent && (fanPlace == HVAC::FanPlace::BlowThru || !FanPresent)) {
5482 0 : if (coolCoilAirOutNode != VRFTUOutletNodeNum) {
5483 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5484 0 : ShowContinueError(state,
5485 : "... For blow through or no fan and no heating or supplemental heating coil the cooling coil outlet node name must "
5486 : "match the terminal unit outlet node name.");
5487 0 : if (coolCoilAirOutNode > 0 && VRFTUOutletNodeNum > 0) {
5488 0 : ShowContinueError(state, format("... Cooling coil outlet node name = {}.", nodeID(coolCoilAirOutNode)));
5489 0 : ShowContinueError(state, format("... Terminal unit outlet node name = {}.", nodeID(VRFTUOutletNodeNum)));
5490 : }
5491 0 : ErrorsFound = true;
5492 : }
5493 0 : if (fanPlace == HVAC::FanPlace::DrawThru) {
5494 0 : if (fanOutletNode != VRFTUOutletNodeNum) {
5495 0 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5496 0 : ShowContinueError(state,
5497 : "... For draw through fan and no supplemental heating coil the fan outlet node name must "
5498 : "match the terminal unit outlet node name.");
5499 0 : if (fanOutletNode > 0 && VRFTUOutletNodeNum > 0) {
5500 0 : ShowContinueError(state, format("... Fan outlet node name = {}.", nodeID(fanOutletNode)));
5501 0 : ShowContinueError(state, format("... Terminal unit outlet node name = {}.", nodeID(VRFTUOutletNodeNum)));
5502 : }
5503 0 : ErrorsFound = true;
5504 : }
5505 : }
5506 38 : } else if (fanPlace == HVAC::FanPlace::DrawThru) {
5507 23 : if (fanOutletNode != VRFTUOutletNodeNum) {
5508 2 : ShowSevereError(state, fmt::format("{}=\"{}\",", cTerminalUnitType, cTUName));
5509 2 : ShowContinueError(state,
5510 : "... For draw through fan and no supplemental heating coil the fan outlet node name must "
5511 : "match the terminal unit outlet node name.");
5512 1 : if (fanOutletNode > 0 && VRFTUOutletNodeNum > 0) {
5513 1 : ShowContinueError(state, format("... Fan outlet node name = {}.", nodeID(fanOutletNode)));
5514 1 : ShowContinueError(state, format("... Terminal unit outlet node name = {}.", nodeID(VRFTUOutletNodeNum)));
5515 : }
5516 1 : ErrorsFound = true;
5517 : }
5518 : }
5519 48 : }
5520 :
5521 7115 : void InitVRF(EnergyPlusData &state, int const VRFTUNum, int const ZoneNum, bool const FirstHVACIteration, Real64 &OnOffAirFlowRatio, Real64 &QZnReq)
5522 : {
5523 :
5524 : // SUBROUTINE INFORMATION:
5525 : // AUTHOR Richard Raustad, FSEC
5526 : // DATE WRITTEN August 2010
5527 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
5528 : // RE-ENGINEERED na
5529 :
5530 : // PURPOSE OF THIS SUBROUTINE:
5531 : // This subroutine is for initializations of the VRF Components.
5532 :
5533 : // METHODOLOGY EMPLOYED:
5534 : // Uses the status flags to trigger initializations.
5535 :
5536 : using DataSizing::AutoSize;
5537 : using DataZoneEquipment::CheckZoneEquipmentList;
5538 :
5539 : using PlantUtilities::InitComponentNodes;
5540 : using SingleDuct::SimATMixer;
5541 :
5542 : static constexpr std::string_view RoutineName("InitVRF");
5543 :
5544 : int InNode; // TU inlet node
5545 : int OutNode; // TU outlet node
5546 : int OutsideAirNode; // TU mixer outside air inlet node
5547 : int NumTULoop; // loop counter, number of TU's in list
5548 : int ELLoop; // loop counter, number of zone equipment lists
5549 : int ListLoop; // loop counter, number of equipment is each list
5550 : int VRFCond; // index to VRF condenser
5551 : int TUIndex; // index to TU
5552 : int TUListNum; // index to VRF AC system terminal unit list
5553 : int TUListIndex; // pointer to TU list for this VRF system
5554 : int IndexToTUInTUList; // index to TU in TerminalUnilList
5555 : Real64 RhoAir; // air density at InNode
5556 : Real64 CurrentEndTime; // end time of current time step
5557 7115 : Real64 TimeStepSysLast(0.0); // system time step on last time step
5558 : Real64 TempOutput; // Sensible output of TU
5559 : Real64 LoadToCoolingSP; // thermostat load to cooling setpoint (W)
5560 : Real64 LoadToHeatingSP; // thermostat load to heating setpoint (W)
5561 : bool EnableSystem; // use to turn on secondary operating mode if OA temp limits exceeded
5562 : bool ErrorsFound; // flag returned from mining call
5563 : Real64 rho; // density of water (kg/m3)
5564 : Real64 OutsideDryBulbTemp; // Outdoor air temperature at external node height
5565 : bool errFlag; // local error flag
5566 : Real64 SuppHeatCoilLoad; // additional heating required by supplemental heater (W)
5567 : Real64 SuppHeatCoilCapacity; // supplemental heating coil size (W)
5568 :
5569 : // ALLOCATE and Initialize subroutine variables
5570 7115 : if (state.dataHVACVarRefFlow->MyOneTimeFlag) {
5571 :
5572 13 : state.dataHVACVarRefFlow->MyEnvrnFlag.allocate(state.dataHVACVarRefFlow->NumVRFTU);
5573 13 : state.dataHVACVarRefFlow->MySizeFlag.allocate(state.dataHVACVarRefFlow->NumVRFTU);
5574 13 : state.dataHVACVarRefFlow->MyVRFFlag.allocate(state.dataHVACVarRefFlow->NumVRFTU);
5575 13 : state.dataHVACVarRefFlow->MyZoneEqFlag.allocate(state.dataHVACVarRefFlow->NumVRFTU);
5576 13 : state.dataHVACVarRefFlow->MyBeginTimeStepFlag.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5577 13 : state.dataHVACVarRefFlow->MaxDeltaT.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5578 13 : state.dataHVACVarRefFlow->MinDeltaT.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5579 13 : state.dataHVACVarRefFlow->LastModeCooling.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5580 13 : state.dataHVACVarRefFlow->LastModeHeating.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5581 13 : state.dataHVACVarRefFlow->HeatingLoad.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5582 13 : state.dataHVACVarRefFlow->CoolingLoad.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5583 13 : state.dataHVACVarRefFlow->NumCoolingLoads.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5584 13 : state.dataHVACVarRefFlow->SumCoolingLoads.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5585 13 : state.dataHVACVarRefFlow->NumHeatingLoads.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5586 13 : state.dataHVACVarRefFlow->SumHeatingLoads.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5587 13 : state.dataHVACVarRefFlow->MyVRFCondFlag.allocate(state.dataHVACVarRefFlow->NumVRFCond);
5588 13 : state.dataHVACVarRefFlow->MyEnvrnFlag = true;
5589 13 : state.dataHVACVarRefFlow->MySizeFlag = true;
5590 13 : state.dataHVACVarRefFlow->MyVRFFlag = true;
5591 13 : state.dataHVACVarRefFlow->MyZoneEqFlag = true;
5592 13 : state.dataHVACVarRefFlow->MyBeginTimeStepFlag = true;
5593 13 : state.dataHVACVarRefFlow->MaxDeltaT = 0.0;
5594 13 : state.dataHVACVarRefFlow->MinDeltaT = 0.0;
5595 13 : state.dataHVACVarRefFlow->LastModeCooling = false;
5596 13 : state.dataHVACVarRefFlow->LastModeHeating = true;
5597 13 : state.dataHVACVarRefFlow->NumCoolingLoads = 0;
5598 13 : state.dataHVACVarRefFlow->SumCoolingLoads = 0.0;
5599 13 : state.dataHVACVarRefFlow->NumHeatingLoads = 0;
5600 13 : state.dataHVACVarRefFlow->SumHeatingLoads = 0.0;
5601 :
5602 13 : state.dataHVACVarRefFlow->MyOneTimeFlag = false;
5603 13 : state.dataHVACVarRefFlow->MyVRFCondFlag = true;
5604 :
5605 : } // IF (MyOneTimeFlag) THEN
5606 :
5607 : // identify VRF condenser connected to this TU
5608 7115 : VRFCond = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum;
5609 7115 : TUListIndex = state.dataHVACVarRefFlow->VRF(VRFCond).ZoneTUListPtr;
5610 7115 : InNode = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum;
5611 7115 : OutNode = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum;
5612 7115 : OutsideAirNode = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum;
5613 7115 : IndexToTUInTUList = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).IndexToTUInTUList;
5614 :
5615 7115 : SuppHeatCoilCapacity = 0.0;
5616 7115 : SuppHeatCoilLoad = 0.0;
5617 7115 : LoadToCoolingSP = 0.0;
5618 7115 : LoadToHeatingSP = 0.0;
5619 7115 : ErrorsFound = false;
5620 7115 : bool SetPointErrorFlag = false;
5621 :
5622 : // set condenser inlet temp, used as surrogate for OAT (used to check limits of operation)
5623 7115 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
5624 5 : OutsideDryBulbTemp = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRF(VRFCond).CondenserNodeNum).Temp;
5625 : } else {
5626 7110 : if (OutsideAirNode == 0) {
5627 1 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
5628 : } else {
5629 7109 : OutsideDryBulbTemp = state.dataLoopNodes->Node(OutsideAirNode).Temp;
5630 : }
5631 : }
5632 :
5633 7115 : if (allocated(state.dataAvail->ZoneComp)) {
5634 7083 : auto &availMgr = state.dataAvail->ZoneComp(DataZoneEquipment::ZoneEquipType::VariableRefrigerantFlowTerminal).ZoneCompAvailMgrs(VRFTUNum);
5635 7083 : if (state.dataHVACVarRefFlow->MyZoneEqFlag(VRFTUNum)) { // initialize the name of each availability manager list and zone number
5636 4 : availMgr.AvailManagerListName = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).AvailManagerListName;
5637 4 : availMgr.ZoneNum = ZoneNum;
5638 4 : state.dataHVACVarRefFlow->MyZoneEqFlag(VRFTUNum) = false;
5639 : }
5640 7083 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).availStatus = availMgr.availStatus;
5641 : }
5642 :
5643 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MySuppCoilPlantScanFlag && allocated(state.dataPlnt->PlantLoop)) {
5644 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
5645 : // hot water supplemental heating coil
5646 0 : errFlag = false;
5647 0 : PlantUtilities::ScanPlantLoopsForObject(state,
5648 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
5649 : PlantEquipmentType::CoilWaterSimpleHeating,
5650 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc,
5651 : errFlag,
5652 : _,
5653 : _,
5654 : _,
5655 : _,
5656 : _);
5657 :
5658 0 : WaterCoils::SetCoilDesFlow(state,
5659 0 : HVAC::cAllCoilTypes(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num),
5660 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
5661 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow,
5662 : errFlag);
5663 :
5664 0 : if (errFlag) {
5665 0 : ShowFatalError(state, format("{}: Program terminated for previous conditions.", RoutineName));
5666 : }
5667 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow = WaterCoils::GetCoilMaxWaterFlowRate(
5668 0 : state, "Coil:Heating:Water", state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName, ErrorsFound);
5669 :
5670 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow > 0.0) {
5671 0 : rho = state.dataPlnt->PlantLoop(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc.loopNum)
5672 0 : .glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
5673 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow =
5674 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow * rho;
5675 : }
5676 :
5677 : // fill fluid outlet node for hot water coil SuppHeatCoilFluidOutletNode
5678 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode =
5679 0 : DataPlant::CompData::getPlantComponent(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc).NodeNumOut;
5680 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MySuppCoilPlantScanFlag = false;
5681 :
5682 5 : } else if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
5683 : // steam supplemental heating coil
5684 0 : errFlag = false;
5685 0 : PlantUtilities::ScanPlantLoopsForObject(state,
5686 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
5687 : PlantEquipmentType::CoilSteamAirHeating,
5688 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc,
5689 : errFlag,
5690 : _,
5691 : _,
5692 : _,
5693 : _,
5694 : _);
5695 0 : if (errFlag) {
5696 0 : ShowFatalError(state, format("{}: Program terminated for previous conditions.", RoutineName));
5697 : }
5698 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow =
5699 0 : SteamCoils::GetCoilMaxSteamFlowRate(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex, ErrorsFound);
5700 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow > 0.0) {
5701 0 : Real64 TempSteamIn = 100.0;
5702 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, RoutineName);
5703 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow =
5704 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow * SteamDensity;
5705 : }
5706 :
5707 : // fill fluid outlet node for steam coil SuppHeatCoilFluidOutletNode
5708 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode =
5709 0 : DataPlant::CompData::getPlantComponent(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc).NodeNumOut;
5710 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MySuppCoilPlantScanFlag = false;
5711 :
5712 : } else { // VRF terminal unit not connected to plant
5713 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MySuppCoilPlantScanFlag = false;
5714 : }
5715 7110 : } else if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MySuppCoilPlantScanFlag && !state.dataGlobal->AnyPlantInModel) {
5716 10 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MySuppCoilPlantScanFlag = false;
5717 : }
5718 :
5719 : // one-time check to see if VRF TU's are on ZoneHVAC:EquipmentList or AirloopHVAC or issue warning
5720 7115 : if (state.dataHVACVarRefFlow->ZoneEquipmentListNotChecked) {
5721 19 : if (state.dataAirLoop->AirLoopInputsFilled) {
5722 13 : state.dataHVACVarRefFlow->ZoneEquipmentListNotChecked = false;
5723 : }
5724 19 : bool AirLoopFound = false;
5725 19 : bool errorsFound = false;
5726 19 : bool AirNodeFound = false;
5727 19 : int ctrlZoneNum = 0;
5728 19 : std::string const cCurrentModuleObject = "ZoneHVAC:TerminalUnit:VariableRefrigerantFlow";
5729 38 : for (TUListNum = 1; TUListNum <= state.dataHVACVarRefFlow->NumVRFTULists; ++TUListNum) {
5730 40 : for (NumTULoop = 1; NumTULoop <= state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList; ++NumTULoop) {
5731 21 : AirLoopFound = false; // reset for next TU
5732 21 : ctrlZoneNum = 0; // reset for next TU
5733 21 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTULoop);
5734 21 : std::string const thisObjectName = state.dataHVACVarRefFlow->VRFTU(TUIndex).Name;
5735 21 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).isInZone) {
5736 6 : goto EquipList_exit; // already found previously
5737 : }
5738 23 : for (ELLoop = 1; ELLoop <= state.dataGlobal->NumOfZones; ++ELLoop) { // NumOfZoneEquipLists
5739 21 : if (state.dataZoneEquip->ZoneEquipList(ELLoop).Name == "") {
5740 4 : continue; // dimensioned by NumOfZones. Only valid ones have names.
5741 : }
5742 20 : for (ListLoop = 1; ListLoop <= state.dataZoneEquip->ZoneEquipList(ELLoop).NumOfEquipTypes; ++ListLoop) {
5743 16 : if (!Util::SameString(state.dataZoneEquip->ZoneEquipList(ELLoop).EquipTypeName(ListLoop),
5744 16 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(TUIndex).type])) {
5745 1 : continue;
5746 : }
5747 15 : if (!Util::SameString(state.dataZoneEquip->ZoneEquipList(ELLoop).EquipName(ListLoop),
5748 15 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name)) {
5749 2 : continue;
5750 : }
5751 13 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum = ELLoop;
5752 13 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isInZone = true;
5753 13 : if (state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFSysNum).MasterZonePtr == ELLoop) {
5754 4 : state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFSysNum).MasterZoneTUIndex = TUIndex;
5755 : }
5756 13 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneAirNode == 0) {
5757 0 : bool ZoneNodeNotFound = true;
5758 0 : for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
5759 0 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) {
5760 0 : continue;
5761 : }
5762 0 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumExhaustNodes; ++NodeNum) {
5763 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum ==
5764 0 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ExhaustNode(NodeNum)) {
5765 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneAirNode =
5766 0 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ZoneNode;
5767 0 : ZoneNodeNotFound = false;
5768 0 : break;
5769 : }
5770 : }
5771 0 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) {
5772 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum ==
5773 0 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) {
5774 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneAirNode =
5775 0 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ZoneNode;
5776 0 : ZoneNodeNotFound = false;
5777 0 : break;
5778 : }
5779 : }
5780 0 : if (!ZoneNodeNotFound) {
5781 0 : break;
5782 : }
5783 : }
5784 0 : if (ZoneNodeNotFound) {
5785 0 : ShowSevereError(state,
5786 0 : format("ZoneHVAC:TerminalUnit:VariableRefrigerantFlow \"{}\" Zone terminal unit air inlet node name "
5787 : "must be the same as a zone inlet or exhaust node name.",
5788 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
5789 0 : ShowContinueError(state,
5790 : "... Zone inlet and exhaust node name is specified in ZoneHVAC:EquipmentConnections object.");
5791 0 : ShowContinueError(state,
5792 0 : format("... Zone terminal unit inlet node name = {}",
5793 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum)));
5794 0 : ShowContinueError(state,
5795 0 : format("... Zone terminal unit outlet node name = {}",
5796 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum)));
5797 : }
5798 : }
5799 13 : goto EquipList_exit;
5800 : }
5801 : }
5802 : // check if the TU is connected to an air loop
5803 2 : if (!state.dataHVACVarRefFlow->VRFTU(TUIndex).isInAirLoop) {
5804 2 : for (int AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
5805 1 : for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) {
5806 1 : for (int CompNum = 1;
5807 1 : CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents;
5808 : ++CompNum) {
5809 1 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).Name,
5810 2 : thisObjectName) &&
5811 1 : Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).TypeOf,
5812 : cCurrentModuleObject)) {
5813 1 : state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum = AirLoopNum;
5814 1 : AirLoopFound = true;
5815 1 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isInAirLoop = true;
5816 2 : BranchNodeConnections::TestCompSet(
5817 : state,
5818 : cCurrentModuleObject,
5819 : thisObjectName,
5820 1 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum),
5821 1 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum),
5822 : "Air Nodes");
5823 1 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum > 0) {
5824 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneAirNode =
5825 0 : state.dataZoneEquip->ZoneEquipConfig(state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum).ZoneNode;
5826 0 : int ControlledZoneNum = state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum;
5827 0 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
5828 0 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum !=
5829 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum) {
5830 0 : continue;
5831 : }
5832 0 : state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFSysNum).MasterZoneTUIndex =
5833 : TUIndex;
5834 0 : AirNodeFound = true;
5835 0 : ctrlZoneNum = ControlledZoneNum;
5836 0 : goto EquipList_exit;
5837 : }
5838 0 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
5839 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum !=
5840 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum) {
5841 0 : continue;
5842 : }
5843 0 : state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFSysNum).MasterZoneTUIndex =
5844 : TUIndex;
5845 0 : AirNodeFound = true;
5846 0 : ctrlZoneNum = ControlledZoneNum;
5847 0 : goto EquipList_exit;
5848 : }
5849 0 : if (!AirNodeFound && state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum > 0) {
5850 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
5851 0 : ShowContinueError(state, "Did not find Air node (Zone with Thermostat or Thermal Comfort Thermostat).");
5852 : // ShowContinueError(state, format("specified Controlling Zone or Thermostat Location name = {}{}", //,
5853 : // loc_controlZoneName));
5854 0 : errorsFound = true;
5855 : }
5856 1 : } else if (AirLoopFound) { // control zone name not entered in TU object input
5857 1 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled = true;
5858 : }
5859 : }
5860 1 : if (AirLoopFound) {
5861 1 : break;
5862 : }
5863 : }
5864 1 : if (AirLoopFound) {
5865 1 : break;
5866 : }
5867 : }
5868 1 : if (AirLoopFound) {
5869 1 : break;
5870 : }
5871 : }
5872 : }
5873 :
5874 : // check if the TU is connected to an outside air system
5875 2 : if (!AirLoopFound && !state.dataHVACVarRefFlow->VRFTU(TUIndex).isInOASys) {
5876 1 : for (int OASysNum = 1; OASysNum <= state.dataAirLoop->NumOASystems; ++OASysNum) {
5877 0 : for (int OACompNum = 1; OACompNum <= state.dataAirLoop->OutsideAirSys(OASysNum).NumComponents; ++OACompNum) {
5878 0 : if (!Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentName(OACompNum),
5879 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name) ||
5880 0 : !Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentType(OACompNum), cCurrentModuleObject)) {
5881 0 : continue;
5882 : }
5883 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum = 0; // need air loop number here?
5884 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isInOASys = true;
5885 0 : AirLoopFound = true;
5886 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled = true;
5887 : // user may have inadvertently entered a zone name in the OA system TU object
5888 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum = 0;
5889 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneAirNode = 0;
5890 0 : BranchNodeConnections::TestCompSet(
5891 : state,
5892 : cCurrentModuleObject,
5893 : thisObjectName,
5894 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum),
5895 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum),
5896 : "Air Nodes");
5897 0 : goto EquipList_exit;
5898 : }
5899 : }
5900 : }
5901 1 : EquipList_exit:;
5902 21 : if (ctrlZoneNum > 0) {
5903 0 : int inletNodeADUNum = 0;
5904 0 : DataZoneEquipment::ZoneEquipType sysType_Num = DataZoneEquipment::ZoneEquipType::Invalid;
5905 0 : std::string sysName = "";
5906 0 : for (int inletNode = 1; inletNode <= state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).NumInletNodes; inletNode++) {
5907 0 : if (state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).InletNodeAirLoopNum(inletNode) !=
5908 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum) {
5909 0 : continue;
5910 : }
5911 0 : inletNodeADUNum = state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).InletNodeADUNum(inletNode);
5912 0 : if (inletNodeADUNum > 0 && inletNodeADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size()) {
5913 0 : sysType_Num = DataZoneEquipment::ZoneEquipType::AirDistributionUnit;
5914 0 : sysName = state.dataDefineEquipment->AirDistUnit(inletNodeADUNum).Name;
5915 0 : break;
5916 : }
5917 : }
5918 0 : if (inletNodeADUNum > 0) {
5919 0 : if (state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).EquipListIndex > 0) {
5920 0 : for (int EquipNum = 1;
5921 0 : EquipNum <=
5922 0 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).EquipListIndex).NumOfEquipTypes;
5923 : ++EquipNum) {
5924 0 : if ((state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).EquipListIndex)
5925 0 : .EquipType(EquipNum) != sysType_Num) ||
5926 0 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).EquipListIndex)
5927 0 : .EquipName(EquipNum) != sysName) {
5928 0 : continue;
5929 : }
5930 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).zoneSequenceCoolingNum =
5931 0 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).EquipListIndex)
5932 0 : .CoolingPriority(EquipNum);
5933 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).zoneSequenceHeatingNum =
5934 0 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).EquipListIndex)
5935 0 : .HeatingPriority(EquipNum);
5936 0 : break;
5937 : }
5938 : }
5939 : } else {
5940 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
5941 0 : ShowContinueError(state, "Did not find ZoneHVAC:EquipmentList connected to this VRF terminal unit.");
5942 0 : errorsFound = true;
5943 : }
5944 0 : }
5945 :
5946 : // Find the number of zones (zone Inlet nodes) attached to an air loop from the air loop number
5947 21 : if (AirLoopFound || state.dataHVACVarRefFlow->VRFTU(TUIndex).isInAirLoop) {
5948 1 : int NumAirLoopZones = 0;
5949 1 : bool initLoadBasedControlFlowFracFlagReady = false;
5950 1 : Real64 initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax = 0.0;
5951 1 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum > 0) {
5952 0 : NumAirLoopZones = state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum).NumZonesCooled +
5953 0 : state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum).NumZonesHeated;
5954 : }
5955 1 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo)) {
5956 0 : initLoadBasedControlFlowFracFlagReady = true;
5957 0 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
5958 : // zone inlet nodes for cooling
5959 0 : if (state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum).NumZonesCooled > 0) {
5960 0 : if (state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5961 0 : .TermUnitCoolInletNodes(ZoneInSysIndex) == -999) {
5962 : // the data structure for the zones inlet nodes has not been filled
5963 0 : initLoadBasedControlFlowFracFlagReady = false;
5964 : } else {
5965 0 : int ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5966 0 : .TermUnitCoolInletNodes(ZoneInSysIndex);
5967 0 : if (state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax == -999.0) {
5968 : // the node mass flow rate has not been set
5969 0 : initLoadBasedControlFlowFracFlagReady = false;
5970 : }
5971 : }
5972 : }
5973 : // zone inlet nodes for heating
5974 0 : if (state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum).NumZonesHeated > 0) {
5975 0 : if (state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5976 0 : .TermUnitHeatInletNodes(ZoneInSysIndex) == -999) {
5977 : // the data structure for the zones inlet nodes has not been filled
5978 0 : initLoadBasedControlFlowFracFlagReady = false;
5979 : } else {
5980 0 : int ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5981 0 : .TermUnitHeatInletNodes(ZoneInSysIndex);
5982 0 : if (state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax == -999.0) {
5983 : // the node mass flow rate has not been set
5984 0 : initLoadBasedControlFlowFracFlagReady = false;
5985 : }
5986 : }
5987 : }
5988 : }
5989 : }
5990 1 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && initLoadBasedControlFlowFracFlagReady) {
5991 0 : Real64 SumOfMassFlowRateMax = 0.0; // initialize the sum of the maximum flows
5992 0 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
5993 0 : int ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5994 0 : .TermUnitCoolInletNodes(ZoneInSysIndex);
5995 0 : SumOfMassFlowRateMax += state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
5996 0 : if (state.dataAirLoop->AirToZoneNodeInfo(state.dataHVACVarRefFlow->VRFTU(TUIndex).airLoopNum)
5997 0 : .CoolCtrlZoneNums(ZoneInSysIndex) == state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum) {
5998 0 : initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax =
5999 0 : state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
6000 : }
6001 : }
6002 0 : if (SumOfMassFlowRateMax != 0.0 && state.dataAirLoop->AirLoopInputsFilled) {
6003 0 : if (initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax >= HVAC::SmallAirVolFlow) {
6004 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).controlZoneMassFlowFrac =
6005 0 : initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax / SumOfMassFlowRateMax;
6006 0 : BaseSizer::reportSizerOutput(state,
6007 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(TUIndex).type],
6008 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name,
6009 : "Fraction of Supply Air Flow That Goes Through the Controlling Zone",
6010 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).controlZoneMassFlowFrac);
6011 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled = false; // redundant
6012 : } else {
6013 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).isInAirLoop && state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum == 0 &&
6014 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneAirNode == 0) {
6015 : // TU must be set point controlled and use constant fan mode (or coil out T won't change with PLR/air flow)
6016 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled = true;
6017 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanOpModeSched != nullptr) {
6018 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanOpModeSched->getCurrentVal() == 0.0) {
6019 0 : ShowSevereError(state,
6020 0 : format("{} = {}",
6021 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(TUIndex).type],
6022 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
6023 0 : ShowContinueError(state,
6024 : "When using set point control, fan operating mode must be continuous (fan "
6025 : "operating mode schedule values > 0).");
6026 0 : ShowContinueError(state,
6027 0 : format("Error found in Supply Air Fan Operating Mode Schedule Name = {}",
6028 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).fanOpModeSched->Name));
6029 0 : ShowContinueError(state, "...schedule values must be (>0., <=1.)");
6030 0 : ErrorsFound = true;
6031 : }
6032 : }
6033 : } else {
6034 0 : ShowSevereError(state,
6035 0 : format("{} = {}",
6036 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(TUIndex).type],
6037 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
6038 0 : ShowContinueError(state, " The Fraction of Supply Air Flow That Goes Through the Controlling Zone is set to 1.");
6039 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).controlZoneMassFlowFrac = 1.0;
6040 0 : BaseSizer::reportSizerOutput(state,
6041 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(TUIndex).type],
6042 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name,
6043 : "Fraction of Supply Air Flow That Goes Through the Controlling Zone",
6044 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).controlZoneMassFlowFrac);
6045 : }
6046 : }
6047 0 : } else if (state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum == 0) {
6048 : // TU must be set point controlled and use constant fan mode (or coil outlet T won't change with PLR/air flow rate)
6049 : // TU inlet air flow rate is also determined by OA system, not TU
6050 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled = true;
6051 : }
6052 : }
6053 : }
6054 :
6055 21 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).isInZone && state.dataAirLoop->AirLoopInputsFilled) {
6056 13 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanPlace == HVAC::FanPlace::Invalid) {
6057 0 : ShowSevereError(state,
6058 0 : format("ZoneHVAC:TerminalUnit:VariableRefrigerantFlow = {}", state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
6059 0 : ShowContinueError(state, "Illegal Supply Air Fan Placement.");
6060 0 : ErrorsFound = true;
6061 : }
6062 13 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).FanIndex == 0) {
6063 0 : ShowSevereError(state,
6064 0 : format("ZoneHVAC:TerminalUnit:VariableRefrigerantFlow = {}", state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
6065 0 : ShowContinueError(state, "VRF Terminal Unit fan is required when used as zone equipment.");
6066 0 : ErrorsFound = true;
6067 : }
6068 : }
6069 :
6070 21 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled && state.dataAirLoop->AirLoopInputsFilled) {
6071 1 : bool missingSetPoint = false;
6072 1 : Real64 TUOutNodeSP = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum).TempSetPoint;
6073 1 : Real64 coolCoilOutNodeSP = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirOutNode).TempSetPoint;
6074 1 : Real64 heatCoilOutNodeSP = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirOutNode).TempSetPoint;
6075 : // SP can be at outlet of TU or at outlet of coils
6076 : // if supp heat coil is present, a SP must be at the outlet of the TU
6077 1 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).SuppHeatingCoilPresent) {
6078 0 : if (TUOutNodeSP == DataLoopNode::SensedNodeFlagValue) {
6079 0 : missingSetPoint = true;
6080 : }
6081 : } else {
6082 1 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanPlace == HVAC::FanPlace::DrawThru) {
6083 : // then SP must be at TU outlet
6084 0 : if (TUOutNodeSP == DataLoopNode::SensedNodeFlagValue) {
6085 0 : missingSetPoint = true;
6086 : }
6087 : // or at coil outlet nodes
6088 0 : if (missingSetPoint) {
6089 0 : if (coolCoilOutNodeSP != DataLoopNode::SensedNodeFlagValue &&
6090 : heatCoilOutNodeSP != DataLoopNode::SensedNodeFlagValue) {
6091 0 : missingSetPoint = false;
6092 : }
6093 : }
6094 : } else {
6095 : // else fan is blow thru or missing
6096 1 : if (TUOutNodeSP == DataLoopNode::SensedNodeFlagValue) {
6097 0 : missingSetPoint = true;
6098 : }
6099 : }
6100 : }
6101 1 : if (missingSetPoint) {
6102 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
6103 0 : ShowSevereError(state,
6104 0 : format("ZoneHVAC:TerminalUnit:VariableRefrigerantFlow: Missing temperature setpoint for {}",
6105 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
6106 0 : ShowContinueError(state, "...use a Setpoint Manager to establish a setpoint at the TU or coil(s) outlet node.");
6107 0 : ErrorsFound = true;
6108 0 : } else if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
6109 0 : bool SPNotFound = false;
6110 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(
6111 0 : state, state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum, HVAC::CtrlVarType::Temp, SetPointErrorFlag);
6112 0 : SPNotFound = SPNotFound || SetPointErrorFlag;
6113 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(
6114 0 : state, state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirOutNode, HVAC::CtrlVarType::Temp, SetPointErrorFlag);
6115 0 : SPNotFound = SPNotFound || SetPointErrorFlag;
6116 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(
6117 0 : state, state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirOutNode, HVAC::CtrlVarType::Temp, SetPointErrorFlag);
6118 0 : SPNotFound = SPNotFound || SetPointErrorFlag;
6119 :
6120 : // We disable the check at end (if API), because one of the nodes is enough, so there's an almost certainty
6121 : // that it will throw as you're unlikely going to actuate all three nodes
6122 : // It's not ideal, but it's better to let slide a bad condition rather than throw false positives...
6123 0 : state.dataLoopNodes->NodeSetpointCheck(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum)
6124 0 : .needsSetpointChecking = false;
6125 0 : state.dataLoopNodes->NodeSetpointCheck(state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirOutNode)
6126 0 : .needsSetpointChecking = false;
6127 0 : state.dataLoopNodes->NodeSetpointCheck(state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirOutNode)
6128 0 : .needsSetpointChecking = false;
6129 :
6130 0 : if (SPNotFound && state.dataAirLoop->AirLoopInputsFilled) {
6131 0 : ShowSevereError(
6132 : state,
6133 0 : format("ZoneHVAC:TerminalUnit:VariableRefrigerantFlow: Missing temperature setpoint for unitary system = {}",
6134 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
6135 0 : ShowContinueError(state, "...use a Setpoint Manager to establish a setpoint at the TU or coil(s) outlet node.");
6136 0 : ShowContinueError(state, "...or use an EMS actuator to establish a temperature setpoint at the coil control node.");
6137 0 : ErrorsFound = true;
6138 : }
6139 : }
6140 : }
6141 : }
6142 :
6143 41 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).isInAirLoop || state.dataHVACVarRefFlow->VRFTU(TUIndex).isInOASys ||
6144 20 : state.dataHVACVarRefFlow->VRFTU(TUIndex).isInZone) {
6145 20 : continue;
6146 : }
6147 1 : if (!state.dataAirLoop->AirLoopInputsFilled) {
6148 0 : continue;
6149 : }
6150 2 : ShowSevereError(state,
6151 2 : format("InitVRF: VRF Terminal Unit = [{},{}] is not on any ZoneHVAC:EquipmentList, AirloopHVAC or "
6152 : "AirLoopHVAC:OutdoorAirSystem:EquipmentList. It will not be simulated.",
6153 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(TUIndex).type],
6154 1 : state.dataHVACVarRefFlow->VRFTU(TUIndex).Name));
6155 2 : ShowContinueError(state, "...The VRF AC System associated with this terminal unit may also not be simulated.");
6156 21 : }
6157 : }
6158 :
6159 : // TU inlet node must be the same as a zone exhaust node and the OA Mixer return node
6160 : // check that TU inlet node is a zone exhaust node.
6161 36 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone &&
6162 17 : (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists ||
6163 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerType == HVAC::MixerType::SupplySide)) {
6164 17 : bool ZoneNodeNotFound = true;
6165 17 : for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
6166 17 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) {
6167 0 : continue;
6168 : }
6169 17 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumExhaustNodes; ++NodeNum) {
6170 17 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum ==
6171 17 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ExhaustNode(NodeNum)) {
6172 17 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneAirNode = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ZoneNode;
6173 17 : ZoneNodeNotFound = false;
6174 17 : break;
6175 : }
6176 : }
6177 17 : if (!ZoneNodeNotFound) {
6178 17 : break;
6179 : }
6180 : }
6181 17 : if (ZoneNodeNotFound && !state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInAirLoop) {
6182 0 : ShowSevereError(state,
6183 0 : format("{} \"{}\" Zone terminal unit air inlet node name must be the same as a zone exhaust node name.",
6184 : cCurrentModuleObject,
6185 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6186 0 : ShowContinueError(state, "... Zone exhaust node name is specified in ZoneHVAC:EquipmentConnections object.");
6187 0 : ShowContinueError(state,
6188 0 : format("... Zone terminal unit inlet node name = {}",
6189 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum)));
6190 0 : ErrorsFound = true;
6191 : }
6192 : }
6193 : // check OA Mixer return node
6194 36 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone && !state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists &&
6195 17 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6196 16 : Array1D_int OANodeNums = MixedAir::GetOAMixerNodeNumbers(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, errFlag);
6197 16 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum != OANodeNums(3)) {
6198 0 : ShowSevereError(
6199 : state,
6200 0 : format("{} \"{}\" Zone terminal unit air inlet node name must be the same as the OutdoorAir:Mixer return air node name.",
6201 : cCurrentModuleObject,
6202 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6203 0 : ShowContinueError(state,
6204 0 : format("... Zone terminal unit air inlet node name = {}",
6205 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum)));
6206 0 : ShowContinueError(state, format("... OutdoorAir:Mixer return air node name = {}", state.dataLoopNodes->NodeID(OANodeNums(3))));
6207 0 : ErrorsFound = true;
6208 : }
6209 16 : }
6210 : // check that TU outlet node is a zone inlet node.
6211 36 : if ((state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone &&
6212 17 : (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists ||
6213 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerType == HVAC::MixerType::InletSide))) {
6214 17 : bool ZoneNodeNotFound = true;
6215 17 : for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
6216 17 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) {
6217 0 : continue;
6218 : }
6219 17 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) {
6220 17 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum ==
6221 17 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) {
6222 17 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneAirNode = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ZoneNode;
6223 17 : ZoneNodeNotFound = false;
6224 17 : break;
6225 : }
6226 : }
6227 17 : if (!ZoneNodeNotFound) {
6228 17 : break;
6229 : }
6230 : }
6231 17 : if (ZoneNodeNotFound) {
6232 0 : ShowSevereError(state,
6233 0 : format("{} \"{}\" Zone terminal unit air outlet node name must be the same as a zone inlet node name.",
6234 : cCurrentModuleObject,
6235 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6236 0 : ShowContinueError(state, "... Zone inlet node name is specified in ZoneHVAC:EquipmentConnections object.");
6237 0 : ShowContinueError(state,
6238 0 : format("... Zone terminal unit outlet node name = {}",
6239 0 : state.dataLoopNodes->NodeID(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum)));
6240 0 : ErrorsFound = true;
6241 : }
6242 : }
6243 :
6244 19 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone && state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists) {
6245 : // check that OA flow in cooling must be set to zero when connected to DOAS
6246 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow != 0) {
6247 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6248 0 : ShowContinueError(state, format(".. Cooling Outdoor Air Flow Rate must be zero when {}", cCurrentModuleObject));
6249 0 : ShowContinueError(state, "..object is connected to central dedicated outdoor air system via AirTerminal:SingleDuct:Mixer");
6250 0 : ShowContinueError(state, ".. Cooling Outdoor Air Flow Rate is set to 0 and simulation continues.");
6251 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow = 0;
6252 : }
6253 : // check that OA flow in heating must be set to zero when connected to DOAS
6254 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow != 0) {
6255 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6256 0 : ShowContinueError(state, format(".. Heating Outdoor Air Flow Rate must be zero when {}", cCurrentModuleObject));
6257 0 : ShowContinueError(state, "..object is connected to central dedicated outdoor air system via AirTerminal:SingleDuct:Mixer");
6258 0 : ShowContinueError(state, ".. Heating Outdoor Air Flow Rate is set to 0 and simulation continues.");
6259 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow = 0;
6260 : }
6261 : // check that OA flow in no cooling and no heating must be set to zero when connected to DOAS
6262 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow != 0) {
6263 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6264 0 : ShowContinueError(state, format(".. No Load Outdoor Air Flow Rate must be zero when {}", cCurrentModuleObject));
6265 0 : ShowContinueError(state, "..object is connected to central dedicated outdoor air system via AirTerminal:SingleDuct:Mixer");
6266 0 : ShowContinueError(state, ".. No Load Outdoor Air Flow Rate is set to 0 and simulation continues.");
6267 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow = 0;
6268 : }
6269 : }
6270 19 : } // IF(ZoneEquipmentListNotChecked)THEN
6271 :
6272 : // Size TU
6273 7115 : if (state.dataHVACVarRefFlow->MySizeFlag(VRFTUNum)) {
6274 18 : if (!state.dataGlobal->ZoneSizingCalc && !state.dataGlobal->SysSizingCalc) {
6275 13 : SizeVRF(state, VRFTUNum);
6276 13 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).TerminalUnitNotSizedYet(IndexToTUInTUList) = false;
6277 13 : state.dataHVACVarRefFlow->MySizeFlag(VRFTUNum) = false;
6278 : } // IF ( .NOT. ZoneSizingCalc) THEN
6279 : } // IF (MySizeFlag(VRFTUNum)) THEN
6280 :
6281 : // Do the Begin Environment initializations
6282 7115 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHVACVarRefFlow->MyEnvrnFlag(VRFTUNum)) {
6283 :
6284 : // Change the Volume Flow Rates to Mass Flow Rates
6285 :
6286 24 : RhoAir = state.dataEnvrn->StdRhoAir;
6287 : // set the mass flow rates from the input volume flow rates
6288 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow = RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow;
6289 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow = RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow;
6290 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow = RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow;
6291 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow = RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow;
6292 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow = RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow;
6293 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow = RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow;
6294 24 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow =
6295 24 : RhoAir * state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow;
6296 : // set the node max and min mass flow rates
6297 : // outside air mixer is optional, check that node num > 0
6298 24 : if (OutsideAirNode > 0) {
6299 23 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMax =
6300 23 : max(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow);
6301 23 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMin = 0.0;
6302 23 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = 0.0;
6303 : }
6304 24 : state.dataLoopNodes->Node(OutNode).MassFlowRateMax =
6305 24 : max(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow);
6306 24 : state.dataLoopNodes->Node(OutNode).MassFlowRateMin = 0.0;
6307 24 : state.dataLoopNodes->Node(OutNode).MassFlowRateMinAvail = 0.0;
6308 24 : state.dataLoopNodes->Node(InNode).MassFlowRateMax =
6309 24 : max(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow);
6310 24 : state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
6311 24 : state.dataLoopNodes->Node(InNode).MassFlowRateMinAvail = 0.0;
6312 24 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRelNodeNum > 0) {
6313 23 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRelNodeNum).MassFlowRateMinAvail = 0.0;
6314 : }
6315 :
6316 24 : state.dataHVACVarRefFlow->MyEnvrnFlag(VRFTUNum) = false;
6317 :
6318 24 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
6319 1 : rho = state.dataPlnt->PlantLoop(state.dataHVACVarRefFlow->VRF(VRFCond).SourcePlantLoc.loopNum)
6320 1 : .glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
6321 1 : state.dataHVACVarRefFlow->VRF(VRFCond).WaterCondenserDesignMassFlow = state.dataHVACVarRefFlow->VRF(VRFCond).WaterCondVolFlowRate * rho;
6322 :
6323 3 : InitComponentNodes(state,
6324 : 0.0,
6325 1 : state.dataHVACVarRefFlow->VRF(VRFCond).WaterCondenserDesignMassFlow,
6326 1 : state.dataHVACVarRefFlow->VRF(VRFCond).CondenserNodeNum,
6327 1 : state.dataHVACVarRefFlow->VRF(VRFCond).CondenserOutletNodeNum);
6328 : }
6329 : // IF(MyVRFCondFlag(VRFCond))THEN
6330 24 : state.dataHVACVarRefFlow->VRF(VRFCond).HRTimer = 0.0;
6331 24 : state.dataHVACVarRefFlow->VRF(VRFCond).ModeChange = false;
6332 24 : state.dataHVACVarRefFlow->VRF(VRFCond).HRModeChange = false;
6333 24 : state.dataHVACVarRefFlow->MyVRFCondFlag(VRFCond) = false;
6334 : // END IF
6335 :
6336 24 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode > 0) {
6337 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
6338 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow == DataSizing::AutoSize) {
6339 0 : WaterCoils::SimulateWaterCoilComponents(state,
6340 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
6341 : FirstHVACIteration,
6342 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex);
6343 : // design hot water volume flow rate
6344 0 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
6345 0 : state, "Coil:Heating:Water", state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName, ErrorsFound);
6346 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
6347 0 : rho = state.dataPlnt->PlantLoop(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc.loopNum)
6348 0 : .glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
6349 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow = CoilMaxVolFlowRate * rho;
6350 : }
6351 : }
6352 : }
6353 :
6354 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
6355 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow == DataSizing::AutoSize) {
6356 0 : SteamCoils::SimulateSteamCoilComponents(state,
6357 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
6358 : FirstHVACIteration,
6359 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex,
6360 0 : 1.0);
6361 : // design steam volume flow rate
6362 : Real64 CoilMaxVolFlowRate =
6363 0 : SteamCoils::GetCoilMaxSteamFlowRate(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex, ErrorsFound);
6364 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
6365 0 : Real64 TempSteamIn = 100.0;
6366 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, RoutineName);
6367 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow = CoilMaxVolFlowRate * SteamDensity;
6368 : }
6369 : }
6370 : }
6371 : // init water/steam coils min and max flow rates
6372 0 : InitComponentNodes(state,
6373 : 0.0,
6374 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow,
6375 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode,
6376 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode);
6377 : }
6378 :
6379 : // the first time an air loop VRF TU is simulated set isSimulated = true so that the TU initialization
6380 : // will occur with the first TU simulated this time step. Zone VRF TUs are called during sizing which, if air
6381 : // loop TUs are included, alters when all TUs appear to have been simulated. Also, BeginEnvrnFlag is true multiple
6382 : // times during the simulation, reset each time to avoid a different order during sizing and simulation
6383 24 : if (state.dataHVACVarRefFlow->TerminalUnitList(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex).reset_isSimulatedFlags) {
6384 : // if no TUs are in the air loop or outdoor air system they will all be simulated during ManageZoneEquipment
6385 : // and there is no need to adjust the order of simulation (i.e., when isSimulated are all true for a given system)
6386 24 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInAirLoop || state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInOASys) {
6387 1 : state.dataHVACVarRefFlow->TerminalUnitList(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex).IsSimulated = true;
6388 1 : state.dataHVACVarRefFlow->TerminalUnitList(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex).reset_isSimulatedFlags = false;
6389 : }
6390 : }
6391 :
6392 : } // IF (BeginEnvrnFlag .and. MyEnvrnFlag(VRFTUNum)) THEN
6393 :
6394 : // reset environment flag for next environment
6395 7115 : if (!state.dataGlobal->BeginEnvrnFlag) {
6396 7021 : state.dataHVACVarRefFlow->MyEnvrnFlag(VRFTUNum) = true;
6397 7021 : state.dataHVACVarRefFlow->MyVRFCondFlag(VRFCond) = true;
6398 7021 : state.dataHVACVarRefFlow->TerminalUnitList(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex).reset_isSimulatedFlags = true;
6399 : }
6400 :
6401 : // If all VRF Terminal Units on this VRF AC System have been simulated, reset the IsSimulated flag
6402 : // The condenser will be simulated after all terminal units have been simulated (see Sub SimulateVRF)
6403 7115 : if (all(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).IsSimulated)) {
6404 : // this should be the first time through on the next iteration. All TU's and condenser have been simulated.
6405 : // reset simulation flag for each terminal unit
6406 7094 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).IsSimulated = false;
6407 : // after all TU's have been simulated, reset operating mode flag if necessary
6408 7094 : if (state.dataHVACVarRefFlow->LastModeHeating(VRFCond) && state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
6409 10 : state.dataHVACVarRefFlow->LastModeCooling(VRFCond) = true;
6410 10 : state.dataHVACVarRefFlow->LastModeHeating(VRFCond) = false;
6411 : // SwitchedMode(VRFCond) = .TRUE.
6412 : }
6413 7094 : if (state.dataHVACVarRefFlow->LastModeCooling(VRFCond) && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
6414 5 : state.dataHVACVarRefFlow->LastModeHeating(VRFCond) = true;
6415 5 : state.dataHVACVarRefFlow->LastModeCooling(VRFCond) = false;
6416 : // SwitchedMode(VRFCond) = .TRUE.
6417 : }
6418 : } // IF(ALL(TerminalUnitList(VRFTU(VRFTUNum)%TUListIndex)%IsSimulated))THEN
6419 :
6420 : // get operating capacity of water and steam coil
6421 7115 : if (FirstHVACIteration) {
6422 3588 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode > 0) {
6423 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
6424 : // set hot water full flow rate for sizing
6425 0 : Real64 mdot = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow;
6426 0 : PlantUtilities::SetComponentFlowRate(state,
6427 : mdot,
6428 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode,
6429 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode,
6430 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc);
6431 :
6432 : // simulate water coil to find operating capacity
6433 0 : WaterCoils::SimulateWaterCoilComponents(state,
6434 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
6435 : FirstHVACIteration,
6436 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex,
6437 : SuppHeatCoilCapacity);
6438 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSuppHeatingCapacity = SuppHeatCoilCapacity;
6439 : } // from iF VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingWater
6440 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
6441 : // set hot water full flow rate for sizing
6442 0 : Real64 mdot = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow;
6443 0 : PlantUtilities::SetComponentFlowRate(state,
6444 : mdot,
6445 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode,
6446 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode,
6447 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc);
6448 :
6449 : // simulate steam coil to find operating capacity
6450 0 : SteamCoils::SimulateSteamCoilComponents(state,
6451 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
6452 : FirstHVACIteration,
6453 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex,
6454 0 : 1.0,
6455 : ErrorsFound); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
6456 0 : SuppHeatCoilCapacity =
6457 0 : SteamCoils::GetCoilCapacity(state, "Coil:Heating:Steam", state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName, ErrorsFound);
6458 :
6459 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSuppHeatingCapacity = SuppHeatCoilCapacity;
6460 : } // from if VRFTU( VRFTUNum ).SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam
6461 : }
6462 : }
6463 : // initialize water/steam coil inlet flow rate to zero
6464 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode > 0) {
6465 0 : Real64 mdot = 0.0;
6466 0 : PlantUtilities::SetComponentFlowRate(state,
6467 : mdot,
6468 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode,
6469 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode,
6470 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilPlantLoc);
6471 : }
6472 :
6473 : // one-time checks of flow rate vs fan flow rate
6474 7115 : if (state.dataHVACVarRefFlow->MyVRFFlag(VRFTUNum)) {
6475 22 : if (!state.dataGlobal->ZoneSizingCalc && !state.dataGlobal->SysSizingCalc) {
6476 17 : auto &vrfTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
6477 17 : if (vrfTU.fanPlace != HVAC::FanPlace::Invalid) { // was > 0 (is 0 invalid?)
6478 16 : if (vrfTU.ActualFanVolFlowRate != AutoSize) {
6479 :
6480 5 : if (vrfTU.fanType == HVAC::FanType::SystemModel) {
6481 3 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(vrfTU.FanIndex));
6482 6 : if (fanSystem->speedControl == Fans::SpeedControl::Discrete &&
6483 3 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex < 0) {
6484 3 : if (fanSystem->numSpeeds > 1) {
6485 2 : if (vrfTU.DXCoolCoilType_Num == HVAC::CoilVRF_Cooling) {
6486 2 : if (vrfTU.MaxCoolAirVolFlow != DataSizing::AutoSize) {
6487 6 : for (int i = 1; i <= vrfTU.NumOfSpeedCooling; ++i) {
6488 4 : vrfTU.CoolMassFlowRate[i] = fanSystem->massFlowAtSpeed[i - 1];
6489 : }
6490 : }
6491 : }
6492 2 : if (vrfTU.DXHeatCoilType_Num == HVAC::CoilVRF_Heating) {
6493 2 : if (vrfTU.MaxHeatAirVolFlow != DataSizing::AutoSize) {
6494 6 : for (int i = 1; i <= vrfTU.NumOfSpeedCooling; ++i) {
6495 4 : vrfTU.HeatMassFlowRate[i] = fanSystem->massFlowAtSpeed[i - 1];
6496 : }
6497 : }
6498 : }
6499 : }
6500 : }
6501 : }
6502 :
6503 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow >
6504 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate) {
6505 0 : ShowWarningError(state,
6506 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6507 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6508 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6509 0 : ShowContinueError(state, "... has Supply Air Flow Rate During Cooling Operation > Max Fan Volume Flow Rate, should be <=");
6510 0 : ShowContinueError(state,
6511 0 : format("... Supply Air Flow Rate During Cooling Operation = {:.4R} m3/s",
6512 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow));
6513 0 : ShowContinueError(state,
6514 0 : format("... Max Fan Volume Flow Rate = {:.4R} m3/s",
6515 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate));
6516 0 : ShowContinueError(
6517 : state, "...the supply air flow rate during cooling operation will be reduced to match and the simulation continues.");
6518 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6519 : }
6520 :
6521 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow >
6522 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate) {
6523 0 : ShowWarningError(state,
6524 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6525 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6526 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6527 0 : ShowContinueError(state, "... has Supply Air Flow Rate When No Cooling is Needed > Max Fan Volume Flow Rate, should be <=");
6528 0 : ShowContinueError(state,
6529 0 : format("... Supply Air Flow Rate When No Cooling is Needed = {:.4R} m3/s",
6530 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow));
6531 0 : ShowContinueError(state,
6532 0 : format("... Max Fan Volume Flow Rate = {:.4R} m3/s",
6533 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate));
6534 0 : ShowContinueError(
6535 : state, "...the supply air flow rate when no cooling is needed will be reduced to match and the simulation continues.");
6536 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow =
6537 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6538 : }
6539 :
6540 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow > state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow) {
6541 0 : ShowWarningError(state,
6542 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6543 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6544 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6545 0 : ShowContinueError(
6546 : state,
6547 : "...The Outdoor Air Flow Rate During Cooling Operation exceeds the Supply Air Flow Rate During Cooling Operation.");
6548 0 : ShowContinueError(state,
6549 0 : format("...Outdoor Air Flow Rate During Cooling Operation = {:.4R} m3/s",
6550 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow));
6551 0 : ShowContinueError(state,
6552 0 : format("... Supply Air Flow Rate During Cooling Operation = {:.4R} m3/s",
6553 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow));
6554 0 : ShowContinueError(state, "...the outdoor air flow rate will be reduced to match and the simulation continues.");
6555 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow;
6556 : }
6557 :
6558 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow >
6559 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate) {
6560 0 : ShowWarningError(state,
6561 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6562 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6563 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6564 0 : ShowContinueError(state, "... has Supply Air Flow Rate During Heating Operation > Max Fan Volume Flow Rate, should be <=");
6565 0 : ShowContinueError(state,
6566 0 : format("... Supply Air Flow Rate During Heating Operation = {:.4R} m3/s",
6567 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow));
6568 0 : ShowContinueError(state,
6569 0 : format("... Max Fan Volume Flow Rate = {:.4R} m3/s",
6570 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate));
6571 0 : ShowContinueError(
6572 : state, "...the supply air flow rate during cooling operation will be reduced to match and the simulation continues.");
6573 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6574 : }
6575 :
6576 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow >
6577 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate) {
6578 0 : ShowWarningError(state,
6579 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6580 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6581 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6582 0 : ShowContinueError(state, "... has Supply Air Flow Rate When No Heating is Needed > Max Fan Volume Flow Rate, should be <=");
6583 0 : ShowContinueError(state,
6584 0 : format("... Supply Air Flow Rate When No Heating is Needed = {:.4R} m3/s",
6585 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow));
6586 0 : ShowContinueError(state,
6587 0 : format("... Max Fan Volume Flow Rate = {:.4R} m3/s",
6588 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate));
6589 0 : ShowContinueError(
6590 : state, "...the supply air flow rate when no cooling is needed will be reduced to match and the simulation continues.");
6591 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow =
6592 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6593 : }
6594 :
6595 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow > state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow) {
6596 0 : ShowWarningError(state,
6597 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6598 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6599 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6600 0 : ShowContinueError(
6601 : state,
6602 : "...The Outdoor Air Flow Rate During Heating Operation exceeds the Supply Air Flow Rate During Heating Operation.");
6603 0 : ShowContinueError(state,
6604 0 : format("...Outdoor Air Flow Rate During Heating Operation = {:.4R} m3/s",
6605 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow));
6606 0 : ShowContinueError(state,
6607 0 : format("... Supply Air Flow Rate During Heating Operation = {:.4R} m3/s",
6608 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow));
6609 0 : ShowContinueError(state, "...the outdoor air flow rate will be reduced to match and the simulation continues.");
6610 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow;
6611 : }
6612 :
6613 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow >
6614 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate) {
6615 0 : ShowWarningError(state,
6616 0 : format("InitVRF: VRF Terminal Unit = [{}, \"{}\"]",
6617 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
6618 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
6619 0 : ShowContinueError(
6620 : state, "... has a Outdoor Air Flow Rate When No Cooling or Heating is Needed > Max Fan Volume Flow Rate, should be <=");
6621 0 : ShowContinueError(state,
6622 0 : format("... Outdoor Air Flow Rate When No Cooling or Heating is Needed = {:.4R} m3/s",
6623 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow));
6624 0 : ShowContinueError(state,
6625 0 : format("... Max Fan Volume Flow Rate = {:.4R} m3/s",
6626 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate));
6627 0 : ShowContinueError(state,
6628 : "...the outdoor air flow rate when no cooling or heating is needed will be reduced to match and the "
6629 : "simulation continues.");
6630 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow =
6631 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6632 : }
6633 :
6634 5 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate > 0.0) {
6635 10 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow /
6636 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6637 10 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow /
6638 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6639 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio =
6640 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow /
6641 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6642 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio =
6643 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow /
6644 5 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate;
6645 : }
6646 :
6647 5 : state.dataHVACVarRefFlow->MyVRFFlag(VRFTUNum) = false;
6648 : } else {
6649 11 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ActualFanVolFlowRate =
6650 11 : state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex)->maxAirFlowRate;
6651 : }
6652 : } else {
6653 1 : state.dataHVACVarRefFlow->MyVRFFlag(VRFTUNum) = false;
6654 : }
6655 : }
6656 : } // IF(MyVRFFlag(VRFTUNum))THEN
6657 :
6658 : // calculate end time of current time step to determine if max capacity reset is required
6659 7115 : CurrentEndTime = double((state.dataGlobal->DayOfSim - 1) * 24) + state.dataGlobal->CurrentTime - state.dataGlobal->TimeStepZone +
6660 7115 : state.dataHVACGlobal->SysTimeElapsed;
6661 :
6662 : // Initialize the maximum allowed terminal unit capacity. Total terminal unit capacity must not
6663 : // exceed the available condenser capacity. This variable is used to limit the terminal units
6664 : // providing more capacity than allowed. Example: TU loads are 1-ton, 2-ton, 3-ton, and 4-ton connected
6665 : // to a condenser having only 9-tons available. This variable will be set to 3-tons and the 4-ton
6666 : // terminal unit will be limited to 3-tons (see SimVRFCondenser where this variable is calculated).
6667 7214 : if (CurrentEndTime > state.dataHVACVarRefFlow->CurrentEndTimeLast || TimeStepSysLast > state.dataHVACGlobal->TimeStepSys ||
6668 99 : (FirstHVACIteration && state.dataHVACVarRefFlow->MyBeginTimeStepFlag(VRFCond))) {
6669 3540 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond) = Constant::MaxCap;
6670 3540 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) = Constant::MaxCap;
6671 3540 : state.dataHVACVarRefFlow->MyBeginTimeStepFlag(VRFCond) = false;
6672 : }
6673 :
6674 7115 : if (!FirstHVACIteration) {
6675 3527 : state.dataHVACVarRefFlow->MyBeginTimeStepFlag(VRFCond) = true;
6676 : }
6677 :
6678 : // Do the following initializations (every time step).
6679 :
6680 7115 : TimeStepSysLast = state.dataHVACGlobal->TimeStepSys;
6681 7115 : state.dataHVACVarRefFlow->CurrentEndTimeLast = CurrentEndTime;
6682 :
6683 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOpModeSched != nullptr) {
6684 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOpModeSched->getCurrentVal() == 0.0) {
6685 2387 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp = HVAC::FanOp::Cycling;
6686 : } else {
6687 4728 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp = HVAC::FanOp::Continuous;
6688 : }
6689 : }
6690 :
6691 : // if condenser is off, all terminal unit coils are off
6692 7115 : if (state.dataHVACVarRefFlow->VRF(VRFCond).availSched->getCurrentVal() == 0.0) {
6693 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
6694 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
6695 : } else {
6696 :
6697 : //*** Operating Mode Initialization done at beginning of each iteration ***!
6698 : //*** assumes all TU's and Condenser were simulated last iteration ***!
6699 : //*** this code is done ONCE each iteration when all TU's IsSimulated flag is FALSE ***!
6700 : // Determine operating mode prior to simulating any terminal units connected to a VRF condenser
6701 : // this should happen at the beginning of a time step where all TU's are polled to see what
6702 : // mode the heat pump condenser will operate in
6703 7115 : if (!any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).IsSimulated)) {
6704 7115 : InitializeOperatingMode(state, FirstHVACIteration, VRFCond, TUListIndex, OnOffAirFlowRatio);
6705 : }
6706 : //*** End of Operating Mode Initialization done at beginning of each iteration ***!
6707 :
6708 : // disable VRF system when outside limits of operation based on OAT
6709 7115 : EnableSystem = false; // flag used to switch operating modes when OAT is outside operating limits
6710 7115 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
6711 3490 : if ((OutsideDryBulbTemp < state.dataHVACVarRefFlow->VRF(VRFCond).MinOATCooling ||
6712 3492 : OutsideDryBulbTemp > state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATCooling) &&
6713 2 : any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).CoolingCoilPresent)) {
6714 2 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
6715 : // test if heating load exists, account for thermostat control type
6716 2 : switch (state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority) {
6717 2 : case ThermostatCtrlType::LoadPriority:
6718 : case ThermostatCtrlType::ZonePriority: {
6719 2 : if (state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) > 0.0) {
6720 0 : EnableSystem = true;
6721 : }
6722 2 : } break;
6723 0 : case ThermostatCtrlType::ThermostatOffsetPriority: {
6724 0 : if (state.dataHVACVarRefFlow->MinDeltaT(VRFCond) < 0.0) {
6725 0 : EnableSystem = true;
6726 : }
6727 0 : } break;
6728 0 : case ThermostatCtrlType::ScheduledPriority:
6729 : case ThermostatCtrlType::MasterThermostatPriority: {
6730 : // can't switch modes if scheduled (i.e., would be switching to unscheduled mode)
6731 : // or master TSTAT used (i.e., master zone only has a specific load - can't switch)
6732 0 : } break;
6733 0 : default:
6734 0 : break;
6735 : }
6736 2 : if (EnableSystem) {
6737 0 : if ((OutsideDryBulbTemp >= state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeating &&
6738 0 : OutsideDryBulbTemp <= state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeating) &&
6739 0 : any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HeatingCoilPresent)) {
6740 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
6741 : } else {
6742 0 : if (any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).CoolingCoilAvailable)) {
6743 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CoolingMaxTempLimitIndex == 0) {
6744 0 : ShowWarningMessage(state,
6745 0 : format("{} \"{}\".",
6746 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
6747 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name));
6748 0 : ShowContinueError(state,
6749 : "...InitVRF: VRF Heat Pump Min/Max Operating Temperature in Cooling Mode Limits have been "
6750 : "exceeded and VRF system is disabled.");
6751 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
6752 0 : ShowContinueError(state,
6753 0 : format("... Outdoor Unit Inlet Water Temperature = {:.3T}", OutsideDryBulbTemp));
6754 : } else {
6755 0 : ShowContinueError(state,
6756 0 : format("... Outdoor Unit Inlet Air Temperature = {:.3T}", OutsideDryBulbTemp));
6757 : }
6758 0 : ShowContinueError(state,
6759 0 : format("... Cooling Minimum Outdoor Unit Inlet Temperature = {:.3T}",
6760 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MinOATCooling));
6761 0 : ShowContinueError(state,
6762 0 : format("... Cooling Maximum Outdoor Unit Inlet Temperature = {:.3T}",
6763 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATCooling));
6764 0 : ShowContinueErrorTimeStamp(state, "... Check VRF Heat Pump Min/Max Outdoor Temperature in Cooling Mode limits.");
6765 : }
6766 0 : ShowRecurringWarningErrorAtEnd(state,
6767 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)) + " \"" +
6768 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name +
6769 : "\" -- Exceeded VRF Heat Pump min/max cooling temperature limit error continues...",
6770 0 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingMaxTempLimitIndex,
6771 : OutsideDryBulbTemp,
6772 : OutsideDryBulbTemp);
6773 : }
6774 : }
6775 : } else {
6776 2 : if (any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).CoolingCoilAvailable)) {
6777 2 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CoolingMaxTempLimitIndex == 0) {
6778 2 : ShowWarningMessage(state,
6779 2 : format("{} \"{}\".",
6780 1 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
6781 1 : state.dataHVACVarRefFlow->VRF(VRFCond).Name));
6782 2 : ShowContinueError(state,
6783 : "...InitVRF: VRF Heat Pump Min/Max Operating Temperature in Cooling Mode Limits have been exceeded "
6784 : "and VRF system is disabled.");
6785 1 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
6786 0 : ShowContinueError(state, format("... Outdoor Unit Inlet Water Temperature = {:.3T}", OutsideDryBulbTemp));
6787 : } else {
6788 2 : ShowContinueError(state,
6789 2 : format("... Outdoor Unit Inlet Air Temperature = {:.3T}", OutsideDryBulbTemp));
6790 : }
6791 2 : ShowContinueError(state,
6792 2 : format("... Cooling Minimum Outdoor Unit Inlet Temperature = {:.3T}",
6793 1 : state.dataHVACVarRefFlow->VRF(VRFCond).MinOATCooling));
6794 2 : ShowContinueError(state,
6795 2 : format("... Cooling Maximum Outdoor Unit Inlet Temperature = {:.3T}",
6796 1 : state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATCooling));
6797 3 : ShowContinueErrorTimeStamp(state, "... Check VRF Heat Pump Min/Max Outdoor Temperature in Cooling Mode limits.");
6798 : }
6799 16 : ShowRecurringWarningErrorAtEnd(state,
6800 4 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)) + " \"" +
6801 8 : state.dataHVACVarRefFlow->VRF(VRFCond).Name +
6802 : "\" -- Exceeded VRF Heat Pump min/max cooling temperature limit error continues...",
6803 2 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingMaxTempLimitIndex,
6804 : OutsideDryBulbTemp,
6805 : OutsideDryBulbTemp);
6806 : }
6807 : }
6808 : }
6809 3625 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
6810 3497 : if ((OutsideDryBulbTemp < state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeating ||
6811 3503 : OutsideDryBulbTemp > state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeating) &&
6812 6 : any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HeatingCoilPresent)) {
6813 6 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
6814 : // test if cooling load exists, account for thermostat control type
6815 6 : switch (state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority) {
6816 4 : case ThermostatCtrlType::LoadPriority:
6817 : case ThermostatCtrlType::ZonePriority: {
6818 4 : if (state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) < 0.0) {
6819 0 : EnableSystem = true;
6820 : }
6821 4 : } break;
6822 2 : case ThermostatCtrlType::ThermostatOffsetPriority: {
6823 2 : if (state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) > 0.0) {
6824 0 : EnableSystem = true;
6825 : }
6826 2 : } break;
6827 0 : case ThermostatCtrlType::ScheduledPriority:
6828 : case ThermostatCtrlType::MasterThermostatPriority: {
6829 0 : } break;
6830 0 : default:
6831 0 : break;
6832 : }
6833 6 : if (EnableSystem) {
6834 0 : if ((OutsideDryBulbTemp >= state.dataHVACVarRefFlow->VRF(VRFCond).MinOATCooling &&
6835 0 : OutsideDryBulbTemp <= state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATCooling) &&
6836 0 : any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).CoolingCoilPresent)) {
6837 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
6838 : } else {
6839 0 : if (any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HeatingCoilAvailable)) {
6840 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatingMaxTempLimitIndex == 0) {
6841 0 : ShowWarningMessage(state,
6842 0 : format("{} \"{}\".",
6843 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
6844 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name));
6845 0 : ShowContinueError(state,
6846 : "...InitVRF: VRF Heat Pump Min/Max Operating Temperature in Heating Mode Limits have been "
6847 : "exceeded and VRF system is disabled.");
6848 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
6849 0 : ShowContinueError(state,
6850 0 : format("... Outdoor Unit Inlet Water Temperature = {:.3T}", OutsideDryBulbTemp));
6851 : } else {
6852 0 : ShowContinueError(state,
6853 0 : format("... Outdoor Unit Inlet Air Temperature = {:.3T}", OutsideDryBulbTemp));
6854 : }
6855 0 : ShowContinueError(state,
6856 0 : format("... Heating Minimum Outdoor Unit Inlet Temperature = {:.3T}",
6857 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeating));
6858 0 : ShowContinueError(state,
6859 0 : format("... Heating Maximum Outdoor Unit Inlet Temperature = {:.3T}",
6860 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeating));
6861 0 : ShowContinueErrorTimeStamp(state, "... Check VRF Heat Pump Min/Max Outdoor Temperature in Heating Mode limits.");
6862 : }
6863 0 : ShowRecurringWarningErrorAtEnd(state,
6864 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)) + " \"" +
6865 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name +
6866 : "\" -- Exceeded VRF Heat Pump min/max heating temperature limit error continues...",
6867 0 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingMaxTempLimitIndex,
6868 : OutsideDryBulbTemp,
6869 : OutsideDryBulbTemp);
6870 : }
6871 : }
6872 : } else {
6873 6 : if (any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HeatingCoilAvailable)) {
6874 6 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatingMaxTempLimitIndex == 0) {
6875 6 : ShowWarningMessage(state,
6876 6 : format("{} \"{}\".",
6877 3 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
6878 3 : state.dataHVACVarRefFlow->VRF(VRFCond).Name));
6879 6 : ShowContinueError(state,
6880 : "...InitVRF: VRF Heat Pump Min/Max Operating Temperature in Heating Mode Limits have been exceeded "
6881 : "and VRF system is disabled.");
6882 3 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
6883 1 : ShowContinueError(state, format("... Outdoor Unit Inlet Water Temperature = {:.3T}", OutsideDryBulbTemp));
6884 : } else {
6885 2 : ShowContinueError(state, format("... Outdoor Unit Inlet Air Temperature = {:.3T}", OutsideDryBulbTemp));
6886 : }
6887 6 : ShowContinueError(state,
6888 6 : format("... Heating Minimum Outdoor Unit Inlet Temperature = {:.3T}",
6889 3 : state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeating));
6890 6 : ShowContinueError(state,
6891 6 : format("... Heating Maximum Outdoor Unit Inlet Temperature = {:.3T}",
6892 3 : state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeating));
6893 9 : ShowContinueErrorTimeStamp(state, "... Check VRF Heat Pump Min/Max Outdoor Temperature in Heating Mode limits.");
6894 : }
6895 48 : ShowRecurringWarningErrorAtEnd(state,
6896 12 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)) + " \"" +
6897 24 : state.dataHVACVarRefFlow->VRF(VRFCond).Name +
6898 : "\" -- Exceeded VRF Heat Pump min/max heating temperature limit error continues...",
6899 6 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingMaxTempLimitIndex,
6900 : OutsideDryBulbTemp,
6901 : OutsideDryBulbTemp);
6902 : }
6903 : }
6904 : }
6905 : }
6906 :
6907 : } // IF (GetCurrentScheduleValue(state, VRF(VRFCond)%SchedPtr) .EQ. 0.0) THEN
6908 :
6909 : // initialize terminal unit flow rate
6910 10739 : if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) ||
6911 3624 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
6912 1 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList))) {
6913 3491 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6914 3491 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
6915 3491 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
6916 3491 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
6917 : } else {
6918 0 : if (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInOASys) {
6919 0 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
6920 : }
6921 : }
6922 3760 : } else if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) ||
6923 136 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
6924 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList))) {
6925 3488 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6926 3487 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
6927 3487 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
6928 3487 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
6929 : } else {
6930 1 : if (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInOASys) {
6931 1 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
6932 : }
6933 : }
6934 : } else {
6935 136 : if (state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
6936 40 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6937 40 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
6938 40 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
6939 40 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
6940 : } else {
6941 0 : if (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInOASys) {
6942 0 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
6943 : }
6944 : }
6945 96 : } else if (state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
6946 96 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6947 96 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
6948 96 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
6949 96 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
6950 : } else {
6951 0 : if (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInOASys) {
6952 0 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
6953 : }
6954 : }
6955 : }
6956 : }
6957 :
6958 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists) {
6959 : // There is an air terminal mixer
6960 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
6961 : // set the primary air inlet mass flow rate
6962 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerPriNode).MassFlowRate =
6963 0 : min(state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerPriNode).MassFlowRateMaxAvail,
6964 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum).MassFlowRate);
6965 : // now calculate the the mixer outlet air conditions (and the secondary air inlet flow rate). The mixer outlet flow rate has already
6966 : // been set above (it is the "inlet" node flow rate)
6967 0 : SimATMixer(state,
6968 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerName,
6969 : FirstHVACIteration,
6970 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerIndex);
6971 : }
6972 : } else {
6973 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
6974 7114 : MixedAir::SimOAMixer(
6975 7114 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
6976 : }
6977 : }
6978 7115 : OnOffAirFlowRatio = 1.0;
6979 :
6980 : // these flags are used in Subroutine CalcVRF to turn on the correct coil (heating or cooling)
6981 : // valid operating modes
6982 : // Heat Pump (heat recovery flags are set to FALSE):
6983 : // CoolingLoad(VRFCond) - TU can only operate in this mode if heat recovery is not used and there is a cooling load
6984 : // HeatingLoad(VRFCond) - TU can only operate in this mode if heat recovery is not used and there is a heating load
6985 : // Heat Recovery (heat pump flags are set same as for Heat Pump operation):
6986 : // TerminalUnitList(TUListIndex)%HRCoolRequest(IndexToTUInTUList) - TU will operate in this mode if heat recovery is used
6987 : // TerminalUnitList(TUListIndex)%HRHeatRequest(IndexToTUInTUList) - TU will operate in this mode if heat recovery is used
6988 :
6989 7115 : getVRFTUZoneLoad(state, VRFTUNum, QZnReq, LoadToHeatingSP, LoadToCoolingSP, false);
6990 :
6991 7115 : if (std::abs(QZnReq) < HVAC::SmallLoad) {
6992 133 : QZnReq = 0.0;
6993 : }
6994 : // set initial terminal unit operating mode for heat recovery
6995 : // operating mode for non-heat recovery set above using CoolingLoad(VRFCond) or HeatingLoad(VRFCond) variables
6996 : // first turn off terminal unit
6997 7115 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
6998 7115 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
6999 : // then set according to LoadToXXXXingSP variables
7000 7115 : if (LoadToCoolingSP < -1.0 * HVAC::SmallLoad) {
7001 3494 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) ||
7002 7 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) { // don't allow heat recovery if control logic dictates unit is off
7003 3480 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
7004 : }
7005 : }
7006 7115 : if (LoadToHeatingSP > HVAC::SmallLoad) {
7007 6988 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) ||
7008 3493 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) { // don't allow heat recovery if control logic dictates unit is off
7009 3489 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7010 : }
7011 : }
7012 7115 : if (LoadToCoolingSP > 0.0 && LoadToHeatingSP < 0.0) {
7013 126 : QZnReq = 0.0;
7014 : }
7015 :
7016 : // next check for overshoot when constant fan mode is used
7017 : // check operating load to see if OA will overshoot setpoint temperature when constant fan mode is used
7018 11843 : if ((state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Continuous || state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists) &&
7019 4728 : !state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isSetPointControlled) {
7020 4721 : SetCompFlowRate(state, VRFTUNum, VRFCond, true);
7021 :
7022 4721 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
7023 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
7024 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
7025 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7026 : } else {
7027 : // Algorithm Type: VRF model based on system curve
7028 4721 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
7029 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7030 : }
7031 :
7032 : // If the Terminal Unit has a net cooling capacity (TempOutput < 0) and
7033 : // the zone temp is above the Tstat heating setpoint (QToHeatSetPt < 0)
7034 : // see if the terminal unit operation will exceed the setpoint
7035 : // 4 tests here to cover all possibilities:
7036 : // IF(TempOutput < 0.0d0 .AND. LoadToHeatingSP .LT. 0.0d0)THEN
7037 : // ELSE IF(TempOutput .GT. 0.0d0 .AND. LoadToCoolingSP .GT. 0.0d0)THEN
7038 : // ELSE IF(TempOutput .GT. 0.0d0 .AND. LoadToCoolingSP .LT. 0.0d0)THEN
7039 : // ELSE IF(TempOutput < 0.0d0 .AND. LoadToHeatingSP .GT. 0.0d0)THEN
7040 : // END IF
7041 : // could compress these to 2 complex IF's but logic inside each would get more complex
7042 4721 : if (TempOutput < 0.0 && LoadToHeatingSP < 0.0) {
7043 : // If the net cooling capacity overshoots the heating setpoint count as heating load
7044 41 : if (TempOutput < LoadToHeatingSP) {
7045 : // Don't count as heating load unless mode is allowed. Also check for floating zone.
7046 8 : if (state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleCool &&
7047 4 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::Uncontrolled) {
7048 4 : if (!state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
7049 : // system last operated in cooling mode, change air flows and repeat coil off capacity test
7050 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
7051 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
7052 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7053 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum).MassFlowRate =
7054 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7055 0 : MixedAir::SimOAMixer(
7056 0 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
7057 : } else {
7058 0 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7059 : }
7060 :
7061 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
7062 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
7063 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
7064 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7065 : } else {
7066 : // Algorithm Type: VRF model based on system curve
7067 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
7068 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7069 : }
7070 :
7071 : // if zone temp will overshoot, pass the LoadToHeatingSP as the load to meet
7072 0 : if (TempOutput < LoadToHeatingSP) {
7073 0 : QZnReq = LoadToHeatingSP;
7074 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7075 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7076 : }
7077 : } else {
7078 : // last mode was heating, zone temp will overshoot heating setpoint, reset QznReq to LoadtoHeatingSP
7079 4 : QZnReq = LoadToHeatingSP;
7080 4 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7081 4 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7082 : }
7083 : }
7084 37 : } else if (TempOutput > LoadToCoolingSP && LoadToCoolingSP < 0.0) {
7085 : // If the net cooling capacity does not meet the zone cooling load enable cooling
7086 1 : QZnReq = LoadToCoolingSP;
7087 1 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7088 1 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
7089 36 : } else if (TempOutput < LoadToCoolingSP && LoadToCoolingSP < 0.0) {
7090 : // If the net cooling capacity meets the zone cooling load but does not overshoot heating setpoint
7091 0 : QZnReq = 0.0;
7092 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7093 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7094 : }
7095 : // If the terminal unit has a net heating capacity and the zone temp is below the Tstat cooling setpoint
7096 : // see if the terminal unit operation will exceed the setpoint
7097 4680 : } else if (TempOutput > 0.0 && LoadToCoolingSP > 0.0) {
7098 : // If the net heating capacity overshoots the cooling setpoint count as cooling load
7099 2351 : if (TempOutput > LoadToCoolingSP) {
7100 : // Don't count as cooling load unless mode is allowed. Also check for floating zone.
7101 12 : if (state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleHeat &&
7102 6 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::Uncontrolled) {
7103 6 : if (!state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
7104 4 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
7105 4 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
7106 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7107 4 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum).MassFlowRate =
7108 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7109 4 : MixedAir::SimOAMixer(
7110 4 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
7111 : } else {
7112 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum).MassFlowRate =
7113 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7114 : }
7115 :
7116 4 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
7117 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
7118 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
7119 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7120 : } else {
7121 : // Algorithm Type: VRF model based on system curve
7122 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
7123 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7124 : }
7125 :
7126 : // if zone temp will overshoot, pass the LoadToCoolingSP as the load to meet
7127 4 : if (TempOutput > LoadToCoolingSP) {
7128 4 : QZnReq = LoadToCoolingSP;
7129 4 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
7130 4 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7131 : }
7132 : } else {
7133 2 : QZnReq = LoadToCoolingSP;
7134 2 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
7135 2 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7136 : }
7137 : }
7138 2345 : } else if (TempOutput < LoadToHeatingSP) {
7139 : // Don't count as heating load unless mode is allowed. Also check for floating zone.
7140 4634 : if (state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleCool &&
7141 2317 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::Uncontrolled) {
7142 2317 : if (!state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
7143 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
7144 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
7145 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7146 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum).MassFlowRate =
7147 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7148 0 : MixedAir::SimOAMixer(
7149 0 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
7150 : } else {
7151 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum).MassFlowRate =
7152 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7153 : }
7154 :
7155 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
7156 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
7157 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
7158 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7159 : } else {
7160 : // Algorithm Type: VRF model based on system curve
7161 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
7162 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7163 : }
7164 :
7165 : // if zone temp will overshoot, pass the LoadToHeatingSP as the load to meet
7166 0 : if (TempOutput < LoadToHeatingSP) {
7167 0 : QZnReq = LoadToHeatingSP;
7168 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7169 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7170 : }
7171 : } else {
7172 2317 : QZnReq = LoadToHeatingSP;
7173 2317 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7174 2317 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7175 : }
7176 : }
7177 28 : } else if (TempOutput > LoadToHeatingSP && TempOutput < LoadToCoolingSP) {
7178 : // If the net capacity does not overshoot either setpoint
7179 28 : QZnReq = 0.0;
7180 28 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7181 28 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7182 : } else {
7183 : // If the net heating capacity meets the zone heating load but does not overshoot cooling setpoint
7184 0 : QZnReq = 0.0;
7185 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7186 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7187 : }
7188 : // If the terminal unit has a net heating capacity and the zone temp is above the Tstat cooling setpoint
7189 : // see if the terminal unit operation will exceed the setpoint
7190 2329 : } else if (TempOutput > 0.0 && LoadToCoolingSP < 0.0) {
7191 : // If the net heating capacity overshoots the cooling setpoint count as cooling load
7192 : // Don't count as cooling load unless mode is allowed. Also check for floating zone.
7193 6906 : if (state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleHeat &&
7194 2302 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::Uncontrolled) {
7195 2302 : if (!state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
7196 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
7197 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
7198 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7199 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum).MassFlowRate =
7200 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7201 0 : MixedAir::SimOAMixer(
7202 0 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
7203 : } else {
7204 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum).MassFlowRate =
7205 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7206 : }
7207 :
7208 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
7209 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
7210 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
7211 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7212 : } else {
7213 : // Algorithm Type: VRF model based on system curve
7214 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
7215 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7216 : }
7217 :
7218 : // if zone temp will overshoot, pass the LoadToCoolingSP as the load to meet
7219 0 : if (TempOutput > LoadToCoolingSP) {
7220 0 : QZnReq = LoadToCoolingSP;
7221 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
7222 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7223 : }
7224 : // last mode was cooling, zone temp will overshoot cooling setpoint, reset QznReq to LoadtoCoolingSP
7225 : } else {
7226 2302 : QZnReq = LoadToCoolingSP;
7227 2302 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
7228 2302 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7229 : }
7230 : }
7231 : // If the Terminal Unit has a net cooling capacity (TempOutput < 0) and
7232 : // the zone temp is below the Tstat heating setpoint (QToHeatSetPt > 0)
7233 : // see if the terminal unit operation will exceed the setpoint
7234 27 : } else if (TempOutput < 0.0 && LoadToHeatingSP > 0.0) {
7235 : // Don't count as heating load unless mode is allowed. Also check for floating zone.
7236 10 : if (state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleCool &&
7237 5 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::Uncontrolled) {
7238 5 : if (!state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
7239 : // system last operated in cooling mode, change air flows and repeat coil off capacity test
7240 2 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
7241 2 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum).MassFlowRate =
7242 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7243 2 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum).MassFlowRate =
7244 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7245 2 : MixedAir::SimOAMixer(
7246 2 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
7247 : } else {
7248 0 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7249 : }
7250 :
7251 2 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
7252 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
7253 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
7254 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7255 : } else {
7256 : // Algorithm Type: VRF model based on system curve
7257 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
7258 : state, VRFTUNum, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
7259 : }
7260 :
7261 : // if zone temp will overshoot, pass the LoadToHeatingSP as the load to meet
7262 2 : if (TempOutput < LoadToHeatingSP) {
7263 2 : QZnReq = LoadToHeatingSP;
7264 2 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7265 2 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7266 : }
7267 : } else {
7268 : // last mode was heating, zone temp will overshoot heating setpoint, reset QznReq to LoadtoHeatingSP
7269 3 : QZnReq = LoadToHeatingSP;
7270 3 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7271 3 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7272 : }
7273 : }
7274 : }
7275 : // test that the system is active if constant fan logic enables system when thermostat control logic did not
7276 4721 : if (!state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && !state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
7277 85 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) &&
7278 85 : OutsideDryBulbTemp >= state.dataHVACVarRefFlow->VRF(VRFCond).MinOATCooling &&
7279 0 : OutsideDryBulbTemp <= state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATCooling) {
7280 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
7281 85 : } else if (state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) &&
7282 86 : OutsideDryBulbTemp >= state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeating &&
7283 1 : OutsideDryBulbTemp <= state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeating) {
7284 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
7285 : }
7286 : }
7287 : } // IF(VRFTU(VRFTUNum)%fanOp == HVAC::FanOp::Continuous)THEN
7288 :
7289 7115 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed) {
7290 2 : if (OutsideDryBulbTemp < state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeatRecovery ||
7291 1 : OutsideDryBulbTemp > state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeatRecovery) {
7292 2 : if ((any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest) && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) ||
7293 1 : (any(state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest) && state.dataHVACVarRefFlow->CoolingLoad(VRFCond))) {
7294 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HRMaxTempLimitIndex == 0) {
7295 0 : ShowWarningMessage(state,
7296 0 : format("{} \"{}\".",
7297 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
7298 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name));
7299 0 : ShowContinueError(state,
7300 : "...InitVRF: VRF Heat Pump Min/Max Outdoor Temperature in Heat Recovery Mode Limits have been exceeded and "
7301 : "VRF heat recovery is disabled.");
7302 0 : ShowContinueError(state, format("... Outdoor Dry-Bulb Temperature = {:.3T}", OutsideDryBulbTemp));
7303 0 : ShowContinueError(state,
7304 0 : format("... Heat Recovery Minimum Outdoor Dry-Bulb Temperature = {:.3T}",
7305 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeatRecovery));
7306 0 : ShowContinueError(state,
7307 0 : format("... Heat Recovery Maximum Outdoor Dry-Bulb Temperature = {:.3T}",
7308 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeatRecovery));
7309 0 : ShowContinueErrorTimeStamp(state, "... Check VRF Heat Pump Min/Max Outdoor Temperature in Heat Recovery Mode limits.");
7310 0 : ShowContinueError(state, "...the system will operate in heat pump mode when applicable.");
7311 : }
7312 0 : ShowRecurringWarningErrorAtEnd(state,
7313 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)) + " \"" +
7314 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name +
7315 : "\" -- Exceeded VRF Heat Recovery min/max outdoor temperature limit error continues...",
7316 0 : state.dataHVACVarRefFlow->VRF(VRFCond).HRMaxTempLimitIndex,
7317 : OutsideDryBulbTemp,
7318 : OutsideDryBulbTemp);
7319 : }
7320 : // Allow heat pump mode to operate if within limits
7321 2 : if (OutsideDryBulbTemp < state.dataHVACVarRefFlow->VRF(VRFCond).MinOATCooling ||
7322 1 : OutsideDryBulbTemp > state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATCooling) {
7323 : // Disable cooling mode only, heating model will still be allowed
7324 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7325 : }
7326 2 : if (OutsideDryBulbTemp < state.dataHVACVarRefFlow->VRF(VRFCond).MinOATHeating ||
7327 1 : OutsideDryBulbTemp > state.dataHVACVarRefFlow->VRF(VRFCond).MaxOATHeating) {
7328 : // Disable heating mode only, cooling model will still be allowed
7329 1 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7330 : }
7331 : }
7332 : } else {
7333 7114 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest = false;
7334 7114 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest = false;
7335 : }
7336 :
7337 : // Override operating mode when using EMS
7338 : // this logic seems suspect, uses a "just run it on" mentality. Nee to test using EMS.
7339 7115 : if (state.dataHVACVarRefFlow->VRF(VRFCond).EMSOverrideHPOperatingMode) {
7340 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).EMSValueForHPOperatingMode == 0.0) { // Off
7341 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
7342 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
7343 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7344 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7345 0 : } else if (state.dataHVACVarRefFlow->VRF(VRFCond).EMSValueForHPOperatingMode == 1.0) { // Cooling
7346 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
7347 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
7348 0 : QZnReq = LoadToCoolingSP;
7349 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed) {
7350 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = false;
7351 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = true;
7352 : }
7353 0 : } else if (state.dataHVACVarRefFlow->VRF(VRFCond).EMSValueForHPOperatingMode == 2.0) { // Heating
7354 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
7355 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
7356 0 : QZnReq = LoadToHeatingSP;
7357 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed) {
7358 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList) = true;
7359 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList) = false;
7360 : }
7361 : } else {
7362 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HPOperatingModeErrorIndex == 0) {
7363 0 : ShowWarningMessage(state,
7364 0 : format("{} \"{}\".",
7365 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
7366 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name));
7367 0 : ShowContinueError(
7368 : state,
7369 0 : format("...InitVRF: Illegal HP operating mode = {:.0T}", state.dataHVACVarRefFlow->VRF(VRFCond).EMSValueForHPOperatingMode));
7370 0 : ShowContinueError(state, "...InitVRF: VRF HP operating mode will not be controlled by EMS.");
7371 : }
7372 0 : ShowRecurringWarningErrorAtEnd(state,
7373 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)) + " \"" +
7374 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name + "\" -- Illegal HP operating mode error continues...",
7375 0 : state.dataHVACVarRefFlow->VRF(VRFCond).HPOperatingModeErrorIndex,
7376 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EMSValueForHPOperatingMode,
7377 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EMSValueForHPOperatingMode);
7378 : }
7379 : }
7380 :
7381 : // set the TU flow rate. Check for heat recovery operation first, these will be FALSE if HR is not used.
7382 7115 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList)) {
7383 1 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7384 1 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7385 1 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7386 1 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7387 1 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7388 1 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7389 7114 : } else if (state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList)) {
7390 0 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7391 0 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7392 0 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7393 0 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7394 0 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio;
7395 0 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7396 7114 : } else if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && QZnReq != 0.0) {
7397 3487 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7398 3487 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7399 3487 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7400 3487 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7401 3487 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7402 3487 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7403 3627 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && QZnReq != 0.0) {
7404 3491 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7405 3491 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7406 3491 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7407 3491 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7408 3491 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio;
7409 3491 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7410 : } else {
7411 136 : if (state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
7412 40 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7413 40 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7414 40 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7415 40 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7416 40 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7417 : }
7418 136 : if (state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
7419 96 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7420 96 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7421 96 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7422 96 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7423 96 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7424 : }
7425 136 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7426 : }
7427 :
7428 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Cycling) {
7429 2387 : state.dataHVACVarRefFlow->CompOffMassFlow = 0.0;
7430 2387 : state.dataHVACVarRefFlow->OACompOffMassFlow = 0.0;
7431 2387 : state.dataHVACVarRefFlow->CompOffFlowRatio = 0.0;
7432 : }
7433 :
7434 7115 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating > 0 || state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling > 0) {
7435 4712 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SpeedNum = 0;
7436 4712 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SpeedRatio = 0.0;
7437 4712 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CycRatio = 0.0;
7438 : }
7439 :
7440 7115 : SetAverageAirFlow(state, VRFTUNum, 0.0, OnOffAirFlowRatio);
7441 :
7442 7115 : if (ErrorsFound) {
7443 0 : ShowFatalError(state,
7444 0 : format("{}: Errors found in getting ZoneHVAC:TerminalUnit:VariableRefrigerantFlow system input. Preceding condition(s) "
7445 : "causes termination.",
7446 : RoutineName));
7447 : }
7448 7115 : }
7449 :
7450 9435 : void SetCompFlowRate(EnergyPlusData &state, int const VRFTUNum, int const VRFCond, bool const UseCurrentMode)
7451 : {
7452 :
7453 : // SUBROUTINE INFORMATION:
7454 : // AUTHOR Richard Raustad, FSEC
7455 : // DATE WRITTEN June 2011
7456 : // MODIFIED na
7457 : // RE-ENGINEERED na
7458 :
7459 : // PURPOSE OF THIS SUBROUTINE:
7460 : // This subroutine is for calling VRF terminal units during Init to initialize flow rate
7461 : // while looping through all terminal units connected to a specific condenser.
7462 : // This allows polling of capacities for all terminal units.
7463 : // Since the heat pump can only heat or cool, a single operating mode is chosen for each condenser.
7464 :
7465 : // METHODOLOGY EMPLOYED:
7466 : // Initializes flow rates for a specific terminal unit.
7467 :
7468 : int IndexToTUInTUList; // - index to TU in specific list for this VRF system
7469 : int TUListIndex; // index to TU list for this VRF system
7470 :
7471 9435 : IndexToTUInTUList = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).IndexToTUInTUList;
7472 9435 : TUListIndex = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex;
7473 :
7474 : // uses current operating mode to set flow rate (after mode is set)
7475 9435 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList)) {
7476 2303 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7477 2303 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7478 2303 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7479 2303 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7480 2303 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7481 2303 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7482 7132 : } else if (state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList)) {
7483 2323 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7484 2323 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7485 2323 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7486 2323 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7487 2323 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio;
7488 2323 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7489 4809 : } else if (UseCurrentMode) { // uses current operating mode to set flow rate (after mode is set)
7490 95 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
7491 6 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7492 6 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7493 6 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7494 6 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7495 6 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7496 6 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7497 89 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
7498 4 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7499 4 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7500 4 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7501 4 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7502 4 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio;
7503 4 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7504 85 : } else if (state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) { // if NOT cooling or heating then use last mode
7505 36 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7506 36 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7507 36 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7508 36 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7509 36 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7510 36 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7511 49 : } else if (state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) { // if NOT cooling or heating then use last mode
7512 49 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7513 49 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7514 49 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7515 49 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7516 49 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio;
7517 49 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7518 : } else { // should not happen so just set to cooling flow rate
7519 0 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7520 0 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7521 0 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7522 0 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7523 0 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7524 0 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7525 : }
7526 : } else { // uses previous operating mode to set flow rate (used for looping through each TU in Init before mode is set)
7527 4714 : if (state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
7528 2342 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7529 2342 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7530 2342 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7531 2342 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7532 2342 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7533 2342 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7534 2372 : } else if (state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
7535 2372 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirMassFlow;
7536 2372 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirMassFlow;
7537 2372 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirMassFlow;
7538 2372 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7539 2372 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingSpeedRatio;
7540 2372 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoHeatingSpeedRatio;
7541 : } else { // should not happen so just set to cooling flow rate
7542 0 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirMassFlow;
7543 0 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirMassFlow;
7544 0 : state.dataHVACVarRefFlow->OACompOnMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirMassFlow;
7545 0 : state.dataHVACVarRefFlow->OACompOffMassFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirMassFlow;
7546 0 : state.dataHVACVarRefFlow->CompOnFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingSpeedRatio;
7547 0 : state.dataHVACVarRefFlow->CompOffFlowRatio = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolingSpeedRatio;
7548 : }
7549 : }
7550 :
7551 9435 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Cycling) {
7552 0 : state.dataHVACVarRefFlow->CompOffMassFlow = 0.0;
7553 0 : state.dataHVACVarRefFlow->OACompOffMassFlow = 0.0;
7554 0 : state.dataHVACVarRefFlow->CompOffFlowRatio = 0.0;
7555 : }
7556 9435 : }
7557 :
7558 13 : void SizeVRF(EnergyPlusData &state, int const VRFTUNum)
7559 : {
7560 :
7561 : // SUBROUTINE INFORMATION:
7562 : // AUTHOR Richard Raustad, FSEC
7563 : // DATE WRITTEN August 2010
7564 : // MODIFIED August 2013 Daeho Kang, add component sizing table entries
7565 : // B Nigusse, FSEC, added scalable sizing
7566 : // RE-ENGINEERED na
7567 :
7568 : // PURPOSE OF THIS SUBROUTINE:
7569 : // This subroutine is for sizing VRF Components for which inputs have not been
7570 : // specified in the input.
7571 :
7572 : // METHODOLOGY EMPLOYED:
7573 : // Obtains flow rates from the zone or system sizing arrays.
7574 :
7575 : using namespace DataSizing;
7576 : using Curve::CurveValue;
7577 : using HVAC::CoolingAirflowSizing;
7578 : using HVAC::CoolingCapacitySizing;
7579 : using HVAC::HeatingAirflowSizing;
7580 : using HVAC::HeatingCapacitySizing;
7581 :
7582 : using PlantUtilities::RegisterPlantCompDesignFlow;
7583 :
7584 : static constexpr std::string_view RoutineName("SizeVRF: "); // include trailing blank space
7585 :
7586 13 : auto &CheckVRFCombinationRatio = state.dataHVACVarRefFlow->CheckVRFCombinationRatio;
7587 : Real64 TUCoolingCapacity; // total terminal unit cooling capacity
7588 : Real64 TUHeatingCapacity; // total terminal unit heating capacity
7589 : int VRFCond; // index to VRF condenser
7590 : Real64 OnOffAirFlowRat; // temporary variable used when sizing coils
7591 : Real64 DXCoilCap; // capacity of DX cooling coil (W)
7592 : bool IsAutoSize; // Indicator to autosize
7593 : Real64 MaxCoolAirVolFlowDes; // Autosized supply air during cooling for reporting
7594 : Real64 MaxCoolAirVolFlowUser; // Hardsized supply air during cooling for reporting
7595 : Real64 MaxHeatAirVolFlowDes; // Autosized supply air during heating for reporting
7596 : Real64 MaxHeatAirVolFlowUser; // Hardsized supply air during heating for reporting
7597 : Real64 MaxNoCoolAirVolFlowDes; // Autosized supply air flow when no cooling is needed for reporting
7598 : Real64 MaxNoCoolAirVolFlowUser; // Hardsized supply air flow when no cooling is needed for reporting
7599 : Real64 MaxNoHeatAirVolFlowDes; // Autosized supply air flow when no heating is needed for reporting
7600 : Real64 MaxNoHeatAirVolFlowUser; // Hardsized supply air flow when no heating is needed for reporting
7601 : Real64 CoolOutAirVolFlowDes; // Autosized outdoor air flow during cooling for reporting
7602 : Real64 CoolOutAirVolFlowUser; // Hardsized outdoor air flow during cooling for reporting
7603 : Real64 HeatOutAirVolFlowDes; // Autosized outdoor air flow during heating for reporting
7604 : Real64 HeatOutAirVolFlowUser; // Hardsized outdoor air flow during heating for reporting
7605 : Real64 NoCoolHeatOutAirVolFlowDes; // Autosized outdoor air when unconditioned for reporting
7606 : Real64 NoCoolHeatOutAirVolFlowUser; // Hardsized outdoor air when unconditioned for reporting
7607 : Real64 CoolingCapacityDes; // Autosized cooling capacity for reporting
7608 : Real64 CoolingCapacityUser; // Hardsized cooling capacity for reporting
7609 : Real64 HeatingCapacityDes; // Autosized heating capacity for reporting
7610 : Real64 HeatingCapacityUser; // Hardsized heating capacity for reporting
7611 : Real64 DefrostCapacityDes; // Autosized defrost heater capacity for reporting
7612 : Real64 DefrostCapacityUser; // Hardsized defrost heater capacity for reporting
7613 : Real64 EvapCondAirVolFlowRateDes; // Autosized evaporative condenser flow for reporting
7614 : Real64 EvapCondAirVolFlowRateUser; // Hardsized evaporative condenser flow for reporting
7615 : Real64 EvapCondPumpPowerDes; // Autosized evaporative condenser pump power for reporting
7616 : Real64 EvapCondPumpPowerUser; // Hardsized evaporative condenser pump power for reporting
7617 :
7618 13 : std::string CompName; // component name
7619 13 : std::string CompType; // component type
7620 13 : std::string SizingString; // input field sizing description (e.g., Nominal Capacity)
7621 : Real64 TempSize; // autosized value of coil input field
7622 13 : int FieldNum = 2; // IDD numeric field number where input field description is found
7623 13 : bool PrintFlag = true; // TRUE when sizing information is reported in the eio file
7624 :
7625 13 : auto &ZoneEqSizing = state.dataSize->ZoneEqSizing;
7626 :
7627 13 : DataSizing::ZoneEqSizingData *select_EqSizing(nullptr);
7628 :
7629 : // sweep specific data into one pointer to avoid if statements throughout this subroutine
7630 13 : if (state.dataSize->CurOASysNum > 0) {
7631 0 : select_EqSizing = &state.dataSize->OASysEqSizing(state.dataSize->CurOASysNum);
7632 13 : } else if (state.dataSize->CurSysNum > 0) {
7633 1 : select_EqSizing = &state.dataSize->UnitarySysEqSizing(state.dataSize->CurSysNum);
7634 12 : } else if (state.dataSize->CurZoneEqNum > 0) {
7635 12 : select_EqSizing = &ZoneEqSizing(state.dataSize->CurZoneEqNum);
7636 12 : state.dataSize->ZoneEqUnitarySys = true;
7637 : } else {
7638 0 : assert(false);
7639 : }
7640 : // Object Data, points to specific array
7641 13 : DataSizing::ZoneEqSizingData &EqSizing(*select_EqSizing);
7642 :
7643 : // can't hurt to initialize these going in, probably redundant
7644 13 : EqSizing.AirFlow = false;
7645 13 : EqSizing.CoolingAirFlow = false;
7646 13 : EqSizing.HeatingAirFlow = false;
7647 13 : EqSizing.AirVolFlow = 0.0;
7648 13 : EqSizing.CoolingAirVolFlow = 0.0;
7649 13 : EqSizing.HeatingAirVolFlow = 0.0;
7650 13 : EqSizing.Capacity = false;
7651 13 : EqSizing.CoolingCapacity = false;
7652 13 : EqSizing.HeatingCapacity = false;
7653 13 : EqSizing.DesCoolingLoad = 0.0;
7654 13 : EqSizing.DesHeatingLoad = 0.0;
7655 13 : EqSizing.OAVolFlow = 0.0;
7656 :
7657 13 : VRFCond = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum;
7658 13 : MaxCoolAirVolFlowDes = 0.0;
7659 13 : MaxCoolAirVolFlowUser = 0.0;
7660 13 : MaxHeatAirVolFlowDes = 0.0;
7661 13 : MaxHeatAirVolFlowUser = 0.0;
7662 13 : MaxNoCoolAirVolFlowDes = 0.0;
7663 13 : MaxNoCoolAirVolFlowUser = 0.0;
7664 13 : MaxNoHeatAirVolFlowDes = 0.0;
7665 13 : MaxNoHeatAirVolFlowUser = 0.0;
7666 13 : CoolOutAirVolFlowDes = 0.0;
7667 13 : CoolOutAirVolFlowUser = 0.0;
7668 13 : HeatOutAirVolFlowDes = 0.0;
7669 13 : HeatOutAirVolFlowUser = 0.0;
7670 13 : NoCoolHeatOutAirVolFlowDes = 0.0;
7671 13 : NoCoolHeatOutAirVolFlowUser = 0.0;
7672 13 : CoolingCapacityDes = 0.0;
7673 13 : CoolingCapacityUser = 0.0;
7674 13 : HeatingCapacityDes = 0.0;
7675 13 : HeatingCapacityUser = 0.0;
7676 13 : DefrostCapacityDes = 0.0;
7677 13 : DefrostCapacityUser = 0.0;
7678 13 : EvapCondAirVolFlowRateDes = 0.0;
7679 13 : EvapCondAirVolFlowRateUser = 0.0;
7680 13 : EvapCondPumpPowerDes = 0.0;
7681 13 : EvapCondPumpPowerUser = 0.0;
7682 :
7683 13 : state.dataSize->DataScalableSizingON = false;
7684 13 : state.dataSize->DataScalableCapSizingON = false;
7685 13 : state.dataSize->DataFracOfAutosizedCoolingAirflow = 1.0;
7686 13 : state.dataSize->DataFracOfAutosizedHeatingAirflow = 1.0;
7687 13 : state.dataSize->DataFracOfAutosizedCoolingCapacity = 1.0;
7688 13 : state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
7689 13 : state.dataSize->SuppHeatCap = 0.0;
7690 :
7691 13 : if (state.dataHVACVarRefFlow->MyOneTimeSizeFlag) {
7692 : // initialize the environment and sizing flags
7693 11 : CheckVRFCombinationRatio.dimension(state.dataHVACVarRefFlow->NumVRFCond, true);
7694 11 : state.dataHVACVarRefFlow->MyOneTimeSizeFlag = false;
7695 : }
7696 :
7697 13 : CompType = tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type];
7698 13 : CompName = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name;
7699 13 : state.dataSize->DataZoneNumber = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum;
7700 :
7701 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex > 0) {
7702 12 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone) {
7703 12 : state.dataSize->DataFanType = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType;
7704 12 : state.dataSize->DataFanIndex = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex;
7705 12 : state.dataSize->DataFanPlacement = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanPlace;
7706 0 : } else if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInAirLoop) {
7707 0 : state.dataAirSystemsData->PrimaryAirSystems(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).airLoopNum).supFanType =
7708 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType;
7709 0 : state.dataAirSystemsData->PrimaryAirSystems(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).airLoopNum).supFanNum =
7710 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex;
7711 0 : state.dataAirSystemsData->PrimaryAirSystems(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).airLoopNum).supFanPlace =
7712 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanPlace;
7713 : }
7714 : }
7715 :
7716 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HVACSizingIndex > 0) {
7717 : // initialize OA flow for sizing other inputs (e.g., capacity)
7718 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow == AutoSize) {
7719 0 : EqSizing.OAVolFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
7720 : } else {
7721 0 : EqSizing.OAVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow;
7722 : }
7723 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow != AutoSize) {
7724 0 : EqSizing.OAVolFlow = max(EqSizing.OAVolFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow);
7725 : }
7726 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists &&
7727 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone) { // set up ATMixer conditions for scalable capacity sizing
7728 0 : EqSizing.OAVolFlow = 0.0; // Equipment OA flow should always be 0 when ATMixer is used
7729 0 : SingleDuct::setATMixerSizingProperties(state,
7730 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerIndex,
7731 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum,
7732 0 : state.dataSize->CurZoneEqNum);
7733 : }
7734 :
7735 0 : int zoneHVACIndex = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HVACSizingIndex;
7736 :
7737 : // Integer representation of sizing method name (e.g., CoolingAirflowSizing, HeatingAirflowSizing, CoolingCapacitySizing,
7738 : // HeatingCapacitySizing, etc.)
7739 0 : int SizingMethod = CoolingAirflowSizing;
7740 0 : PrintFlag = true;
7741 0 : bool errorsFound = false;
7742 : // supply air flow rate sizing method (SupplyAirFlowRate, FlowPerFloorArea, FractionOfAutosizedCoolingAirflow,
7743 : // FractionOfAutosizedHeatingAirflow ...)
7744 0 : int SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingSAFMethod;
7745 0 : EqSizing.SizingMethod(SizingMethod) = SAFMethod;
7746 0 : if (SAFMethod == SupplyAirFlowRate || SAFMethod == FlowPerFloorArea || SAFMethod == FractionOfAutosizedCoolingAirflow) {
7747 0 : if (SAFMethod == SupplyAirFlowRate) {
7748 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow > 0.0) {
7749 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
7750 0 : EqSizing.SystemAirFlow = true;
7751 : }
7752 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
7753 0 : } else if (SAFMethod == FlowPerFloorArea) {
7754 0 : EqSizing.SystemAirFlow = true;
7755 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow *
7756 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
7757 0 : TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow;
7758 0 : state.dataSize->DataScalableSizingON = true;
7759 0 : } else if (SAFMethod == FractionOfAutosizedCoolingAirflow) {
7760 0 : state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
7761 0 : TempSize = AutoSize;
7762 0 : state.dataSize->DataScalableSizingON = true;
7763 : } else {
7764 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
7765 : }
7766 :
7767 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
7768 0 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
7769 0 : if (state.dataGlobal->isEpJSON) {
7770 0 : stringOverride = "cooling_supply_air_flow_rate [m3/s]";
7771 : }
7772 0 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
7773 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7774 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7775 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7776 :
7777 0 : } else if (SAFMethod == FlowPerCoolingCapacity) {
7778 0 : SizingMethod = CoolingCapacitySizing; // either this isn't needed or needs to be assigned to EqSizing
7779 0 : TempSize = AutoSize;
7780 0 : PrintFlag = false;
7781 0 : state.dataSize->DataScalableSizingON = true;
7782 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow;
7783 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingCapMethod == FractionOfAutosizedCoolingCapacity) {
7784 0 : state.dataSize->DataFracOfAutosizedCoolingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
7785 : }
7786 0 : CoolingCapacitySizer sizerCoolingCapacity;
7787 0 : sizerCoolingCapacity.overrideSizingString(SizingString);
7788 0 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7789 0 : state.dataSize->DataAutosizedCoolingCapacity = sizerCoolingCapacity.size(state, TempSize, errorsFound);
7790 0 : state.dataSize->DataFlowPerCoolingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
7791 0 : PrintFlag = true;
7792 0 : TempSize = AutoSize;
7793 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
7794 0 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
7795 0 : if (state.dataGlobal->isEpJSON) {
7796 0 : stringOverride = "cooling_supply_air_flow_rate [m3/s]";
7797 : }
7798 0 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
7799 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7800 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7801 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7802 0 : }
7803 : // Multispeed Fan cooling flow sizing
7804 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling > 0) {
7805 0 : Real64 AirFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow;
7806 0 : for (int i = 1; i <= state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling; ++i) {
7807 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex > -1) {
7808 0 : if (state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
7809 0 : .coolingVolFlowRatio[i] == DataSizing::AutoSize) {
7810 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] =
7811 0 : double(i) / double(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling) * AirFlowRate;
7812 : } else {
7813 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] =
7814 0 : state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
7815 0 : .coolingVolFlowRatio[i] *
7816 : AirFlowRate;
7817 : }
7818 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] =
7819 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
7820 : } else {
7821 0 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex));
7822 0 : assert(fanSystem != nullptr);
7823 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] == 0.0 && !fanSystem->massFlowAtSpeed.empty()) {
7824 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] = fanSystem->massFlowAtSpeed[i - 1];
7825 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] =
7826 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] / state.dataEnvrn->StdRhoAir;
7827 : }
7828 : }
7829 : }
7830 : }
7831 :
7832 0 : SizingMethod = HeatingAirflowSizing;
7833 0 : FieldNum = 3; // N3, \field Supply Air Flow Rate During Heating Operation
7834 0 : PrintFlag = true;
7835 0 : SizingString = state.dataHVACVarRefFlow->VRFTUNumericFields(VRFTUNum).FieldNames(FieldNum) + " [m3/s]";
7836 0 : SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingSAFMethod;
7837 0 : EqSizing.SizingMethod(SizingMethod) = SAFMethod;
7838 0 : if (SAFMethod == SupplyAirFlowRate || SAFMethod == FlowPerFloorArea || SAFMethod == FractionOfAutosizedHeatingAirflow) {
7839 0 : if (SAFMethod == SupplyAirFlowRate) {
7840 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow > 0.0) {
7841 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
7842 0 : EqSizing.SystemAirFlow = true;
7843 : }
7844 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
7845 0 : } else if (SAFMethod == FlowPerFloorArea) {
7846 0 : EqSizing.SystemAirFlow = true;
7847 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow *
7848 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
7849 0 : TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow;
7850 0 : state.dataSize->DataScalableSizingON = true;
7851 0 : } else if (SAFMethod == FractionOfAutosizedHeatingAirflow) {
7852 0 : state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
7853 0 : TempSize = AutoSize;
7854 0 : state.dataSize->DataScalableSizingON = true;
7855 : } else {
7856 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
7857 : }
7858 0 : errorsFound = false;
7859 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
7860 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
7861 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7862 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7863 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
7864 0 : } else if (SAFMethod == FlowPerHeatingCapacity) {
7865 0 : SizingMethod = HeatingCapacitySizing; // either this isn't needed or needs to be assigned to EqSizing
7866 0 : TempSize = AutoSize;
7867 0 : PrintFlag = false;
7868 0 : state.dataSize->DataScalableSizingON = true;
7869 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatVolFlow;
7870 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod == FractionOfAutosizedHeatingCapacity) {
7871 0 : state.dataSize->DataFracOfAutosizedHeatingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
7872 : }
7873 0 : errorsFound = false;
7874 0 : HeatingCapacitySizer sizerHeatingCapacity;
7875 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
7876 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7877 0 : state.dataSize->DataAutosizedHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
7878 0 : state.dataSize->DataFlowPerHeatingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
7879 0 : SizingMethod = HeatingAirflowSizing; // either this isn't needed or needs to be assigned to EqSizing
7880 0 : PrintFlag = true;
7881 0 : TempSize = AutoSize;
7882 0 : errorsFound = false;
7883 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
7884 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
7885 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7886 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7887 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
7888 0 : }
7889 : // Multispeed Fan heating flow sizing
7890 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating > 0) {
7891 0 : Real64 AirFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow;
7892 0 : for (int i = 1; i <= state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating; ++i) {
7893 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex > -1) {
7894 0 : if (state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
7895 0 : .heatingVolFlowRatio[i] == DataSizing::AutoSize) {
7896 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] =
7897 0 : double(i) / double(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating) * AirFlowRate;
7898 : } else {
7899 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] =
7900 0 : state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
7901 0 : .heatingVolFlowRatio[i] *
7902 : AirFlowRate;
7903 : }
7904 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] =
7905 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
7906 : } else {
7907 0 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex));
7908 0 : assert(fanSystem != nullptr);
7909 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] == 0.0 && !fanSystem->massFlowAtSpeed.empty()) {
7910 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] = fanSystem->massFlowAtSpeed[i - 1];
7911 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] =
7912 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] / state.dataEnvrn->StdRhoAir;
7913 : }
7914 : }
7915 : }
7916 : }
7917 :
7918 0 : PrintFlag = true;
7919 0 : SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).NoCoolHeatSAFMethod;
7920 0 : EqSizing.SizingMethod(SizingMethod) = SAFMethod;
7921 0 : if ((SAFMethod == SupplyAirFlowRate) || (SAFMethod == FlowPerFloorArea) || (SAFMethod == FractionOfAutosizedHeatingAirflow) ||
7922 : (SAFMethod == FractionOfAutosizedCoolingAirflow)) {
7923 0 : if (SAFMethod == SupplyAirFlowRate) {
7924 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow > 0.0) {
7925 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7926 0 : EqSizing.SystemAirFlow = true;
7927 : }
7928 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7929 0 : } else if (SAFMethod == FlowPerFloorArea) {
7930 0 : EqSizing.SystemAirFlow = true;
7931 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow *
7932 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
7933 0 : TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow;
7934 0 : state.dataSize->DataScalableSizingON = true;
7935 0 : } else if (SAFMethod == FractionOfAutosizedCoolingAirflow) {
7936 0 : state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7937 0 : state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7938 0 : TempSize = AutoSize;
7939 0 : state.dataSize->DataScalableSizingON = true;
7940 0 : } else if (SAFMethod == FractionOfAutosizedHeatingAirflow) {
7941 0 : state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7942 0 : state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7943 0 : TempSize = AutoSize;
7944 0 : state.dataSize->DataScalableSizingON = true;
7945 : } else {
7946 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7947 : }
7948 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
7949 0 : std::string stringOverride = "No Cooling Supply Air Flow Rate [m3/s]";
7950 0 : if (state.dataGlobal->isEpJSON) {
7951 0 : stringOverride = "no_cooling_supply_air_flow_rate [m3/s]";
7952 : }
7953 0 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
7954 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7955 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7956 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling > 0) {
7957 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[1];
7958 0 : sizingCoolingAirFlow.reportSizerOutput(state,
7959 : sizingCoolingAirFlow.compType,
7960 : sizingCoolingAirFlow.compName,
7961 0 : "Design Size " + stringOverride,
7962 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow);
7963 : } else {
7964 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7965 : }
7966 0 : }
7967 :
7968 0 : SizingMethod = HeatingAirflowSizing;
7969 0 : FieldNum = 4; // N4, \field Supply Air Flow Rate When No Heating is Needed
7970 0 : PrintFlag = true;
7971 0 : SizingString = state.dataHVACVarRefFlow->VRFTUNumericFields(VRFTUNum).FieldNames(FieldNum) + " [m3/s]";
7972 0 : SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).NoCoolHeatSAFMethod;
7973 0 : EqSizing.SizingMethod(SizingMethod) = SAFMethod;
7974 0 : if ((SAFMethod == SupplyAirFlowRate) || (SAFMethod == FlowPerFloorArea) || (SAFMethod == FractionOfAutosizedHeatingAirflow) ||
7975 : (SAFMethod == FractionOfAutosizedCoolingAirflow)) {
7976 0 : if (SAFMethod == SupplyAirFlowRate) {
7977 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow > 0.0) {
7978 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7979 0 : EqSizing.SystemAirFlow = true;
7980 : }
7981 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7982 0 : } else if (SAFMethod == FlowPerFloorArea) {
7983 0 : EqSizing.SystemAirFlow = true;
7984 0 : EqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow *
7985 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
7986 0 : TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow;
7987 0 : state.dataSize->DataScalableSizingON = true;
7988 0 : } else if (SAFMethod == FractionOfAutosizedHeatingAirflow) {
7989 0 : state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7990 0 : state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7991 0 : TempSize = AutoSize;
7992 0 : state.dataSize->DataScalableSizingON = true;
7993 0 : } else if (SAFMethod == FractionOfAutosizedCoolingAirflow) {
7994 0 : state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7995 0 : state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
7996 0 : TempSize = AutoSize;
7997 0 : state.dataSize->DataScalableSizingON = true;
7998 : } else {
7999 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxNoCoolHeatAirVolFlow;
8000 : }
8001 0 : errorsFound = false;
8002 0 : HeatingAirFlowSizer sizingNoHeatingAirFlow;
8003 0 : sizingNoHeatingAirFlow.overrideSizingString(SizingString);
8004 : // sizingNoHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8005 0 : sizingNoHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8006 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating > 0) {
8007 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[1];
8008 0 : sizingNoHeatingAirFlow.reportSizerOutput(state,
8009 : sizingNoHeatingAirFlow.compType,
8010 : sizingNoHeatingAirFlow.compName,
8011 0 : "Design Size " + SizingString,
8012 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow);
8013 : } else {
8014 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow = sizingNoHeatingAirFlow.size(state, TempSize, errorsFound);
8015 : }
8016 0 : }
8017 :
8018 : // initialize capacity sizing variables: cooling
8019 0 : initCapSizingVars(state,
8020 : CoolingCapacitySizing,
8021 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingCapMethod,
8022 : EqSizing.SizingMethod(SizingMethod),
8023 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity,
8024 0 : EqSizing.CoolingCapacity,
8025 0 : EqSizing.DesCoolingLoad,
8026 0 : state.dataSize->DataScalableCapSizingON,
8027 0 : state.dataSize->DataFracOfAutosizedCoolingCapacity);
8028 :
8029 : // initialize capacity sizing variables: heating
8030 0 : initCapSizingVars(state,
8031 : HeatingCapacitySizing,
8032 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod,
8033 : EqSizing.SizingMethod(SizingMethod),
8034 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity,
8035 0 : EqSizing.HeatingCapacity,
8036 0 : EqSizing.DesHeatingLoad,
8037 0 : state.dataSize->DataScalableCapSizingON,
8038 0 : state.dataSize->DataFracOfAutosizedHeatingCapacity);
8039 :
8040 : } else {
8041 : // no scalable sizing method has been specified. Sizing proceeds using the method
8042 : // specified in the zoneHVAC object
8043 :
8044 13 : PrintFlag = true;
8045 :
8046 13 : TempSize = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow;
8047 13 : bool errorsFound = false;
8048 13 : CoolingAirFlowSizer sizingCoolingAirFlow;
8049 13 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
8050 13 : if (state.dataGlobal->isEpJSON) {
8051 0 : stringOverride = "cooling_supply_air_flow_rate [m3/s]";
8052 : }
8053 13 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
8054 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8055 13 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8056 13 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
8057 : // Multispeed Fan cooling flow sizing
8058 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling > 0) {
8059 2 : Real64 AirFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow;
8060 6 : for (int i = 1; i <= state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling; ++i) {
8061 4 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex > -1) {
8062 0 : if (state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
8063 0 : .coolingVolFlowRatio[i] == DataSizing::AutoSize) {
8064 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] =
8065 0 : double(i) / double(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling) * AirFlowRate;
8066 : } else {
8067 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] =
8068 0 : state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
8069 0 : .coolingVolFlowRatio[i] *
8070 : AirFlowRate;
8071 : }
8072 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] =
8073 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
8074 : } else {
8075 4 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex));
8076 4 : assert(fanSystem != nullptr);
8077 4 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] == 0.0 && !fanSystem->massFlowAtSpeed.empty()) {
8078 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] = fanSystem->massFlowAtSpeed[i - 1];
8079 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[i] =
8080 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolMassFlowRate[i] / state.dataEnvrn->StdRhoAir;
8081 : }
8082 : }
8083 : }
8084 : }
8085 :
8086 13 : FieldNum = 3; // N3, \field Supply Air Flow Rate During Heating Operation
8087 13 : SizingString = state.dataHVACVarRefFlow->VRFTUNumericFields(VRFTUNum).FieldNames(FieldNum) + " [m3/s]";
8088 13 : TempSize = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow;
8089 13 : errorsFound = false;
8090 13 : HeatingAirFlowSizer sizingHeatingAirFlow;
8091 13 : sizingHeatingAirFlow.overrideSizingString(SizingString);
8092 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8093 13 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8094 13 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
8095 : // Multispeed Fan heating flow sizing
8096 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating > 0) {
8097 2 : Real64 AirFlowRate = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow;
8098 6 : for (int i = 1; i <= state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating; ++i) {
8099 4 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex > -1) {
8100 0 : if (state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
8101 0 : .heatingVolFlowRatio[i] == DataSizing::AutoSize) {
8102 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] =
8103 0 : double(i) / double(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating) * AirFlowRate;
8104 : } else {
8105 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] =
8106 0 : state.dataUnitarySystems->designSpecMSHP[state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex]
8107 0 : .heatingVolFlowRatio[i] *
8108 : AirFlowRate;
8109 : }
8110 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] =
8111 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
8112 : } else {
8113 4 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex));
8114 4 : assert(fanSystem != nullptr);
8115 4 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] == 0.0 && !fanSystem->massFlowAtSpeed.empty()) {
8116 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] = fanSystem->massFlowAtSpeed[i - 1];
8117 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[i] =
8118 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatMassFlowRate[i] / state.dataEnvrn->StdRhoAir;
8119 : }
8120 : }
8121 : }
8122 : }
8123 :
8124 13 : errorsFound = false;
8125 13 : SystemAirFlowSizer sizerSystemAirFlow;
8126 13 : std::string sizingString = "No Cooling Supply Air Flow Rate [m3/s]";
8127 13 : sizerSystemAirFlow.overrideSizingString(sizingString);
8128 13 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8129 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling > 0) {
8130 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[1];
8131 6 : sizerSystemAirFlow.reportSizerOutput(state,
8132 : sizerSystemAirFlow.compType,
8133 : sizerSystemAirFlow.compName,
8134 2 : "Design Size " + sizingString,
8135 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow);
8136 : } else {
8137 11 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow =
8138 11 : sizerSystemAirFlow.size(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoCoolAirVolFlow, errorsFound);
8139 : }
8140 :
8141 13 : SystemAirFlowSizer sizerSystemAirFlow2;
8142 13 : sizingString = "No Heating Supply Air Flow Rate [m3/s]";
8143 13 : sizerSystemAirFlow2.overrideSizingString(sizingString);
8144 13 : sizerSystemAirFlow2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8145 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating > 0) {
8146 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[1];
8147 6 : sizerSystemAirFlow.reportSizerOutput(state,
8148 : sizerSystemAirFlow.compType,
8149 : sizerSystemAirFlow.compName,
8150 2 : "Design Size " + sizingString,
8151 2 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow);
8152 : } else {
8153 11 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow =
8154 11 : sizerSystemAirFlow2.size(state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxNoHeatAirVolFlow, errorsFound);
8155 : }
8156 13 : }
8157 13 : IsAutoSize = false;
8158 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow == AutoSize) {
8159 5 : IsAutoSize = true;
8160 : }
8161 13 : if (state.dataSize->CurZoneEqNum > 0) {
8162 12 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // Simulation continue
8163 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow > 0.0) {
8164 0 : BaseSizer::reportSizerOutput(state,
8165 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8166 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8167 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
8168 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow);
8169 : }
8170 : } else {
8171 12 : CheckZoneSizing(state, tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type], state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name);
8172 12 : CoolOutAirVolFlowDes =
8173 12 : min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow);
8174 12 : if (CoolOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
8175 9 : CoolOutAirVolFlowDes = 0.0;
8176 : }
8177 :
8178 12 : if (IsAutoSize) {
8179 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow = CoolOutAirVolFlowDes;
8180 8 : BaseSizer::reportSizerOutput(state,
8181 4 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8182 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8183 : "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]",
8184 : CoolOutAirVolFlowDes);
8185 : } else {
8186 8 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow > 0.0 && CoolOutAirVolFlowDes > 0.0) {
8187 1 : CoolOutAirVolFlowUser = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow;
8188 2 : BaseSizer::reportSizerOutput(state,
8189 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8190 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8191 : "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]",
8192 : CoolOutAirVolFlowDes,
8193 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
8194 : CoolOutAirVolFlowUser);
8195 1 : if (state.dataGlobal->DisplayExtraWarnings) {
8196 0 : if ((std::abs(CoolOutAirVolFlowDes - CoolOutAirVolFlowUser) / CoolOutAirVolFlowUser) >
8197 0 : state.dataSize->AutoVsHardSizingThreshold) {
8198 0 : ShowMessage(state,
8199 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8200 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8201 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
8202 0 : ShowContinueError(
8203 : state,
8204 0 : format("User-Specified Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]", CoolOutAirVolFlowUser));
8205 0 : ShowContinueError(state,
8206 0 : format("differs from Design Size Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]",
8207 : CoolOutAirVolFlowDes));
8208 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8209 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8210 : }
8211 : }
8212 : }
8213 : }
8214 : }
8215 : } else {
8216 1 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow == DataSizing::AutoSize) {
8217 1 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).OASysExists) {
8218 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow = 0.0;
8219 : } else {
8220 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow =
8221 0 : min(state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesOutAirVolFlow,
8222 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow);
8223 : }
8224 2 : BaseSizer::reportSizerOutput(state,
8225 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8226 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8227 : "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]",
8228 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow);
8229 : }
8230 : }
8231 :
8232 13 : IsAutoSize = false;
8233 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow == AutoSize) {
8234 5 : IsAutoSize = true;
8235 : }
8236 13 : if (state.dataSize->CurZoneEqNum > 0) {
8237 12 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // Simulation continue
8238 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow > 0.0) {
8239 0 : BaseSizer::reportSizerOutput(state,
8240 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8241 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8242 : "Outdoor Air Flow Rate During Heating Operation [m3/s]",
8243 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow);
8244 : }
8245 : } else {
8246 12 : CheckZoneSizing(state, tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type], state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name);
8247 12 : HeatOutAirVolFlowDes =
8248 12 : min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow);
8249 12 : if (HeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
8250 9 : HeatOutAirVolFlowDes = 0.0;
8251 : }
8252 :
8253 12 : if (IsAutoSize) {
8254 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow = HeatOutAirVolFlowDes;
8255 8 : BaseSizer::reportSizerOutput(state,
8256 4 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8257 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8258 : "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]",
8259 : HeatOutAirVolFlowDes);
8260 : } else {
8261 8 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow > 0.0 && HeatOutAirVolFlowDes > 0.0) {
8262 1 : HeatOutAirVolFlowUser = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow;
8263 2 : BaseSizer::reportSizerOutput(state,
8264 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8265 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8266 : "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]",
8267 : HeatOutAirVolFlowDes,
8268 : "User-Specified Outdoor Air Flow Rate During Heating Operation [m3/s]",
8269 : HeatOutAirVolFlowUser);
8270 1 : if (state.dataGlobal->DisplayExtraWarnings) {
8271 0 : if ((std::abs(HeatOutAirVolFlowDes - HeatOutAirVolFlowUser) / HeatOutAirVolFlowUser) >
8272 0 : state.dataSize->AutoVsHardSizingThreshold) {
8273 0 : ShowMessage(state,
8274 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8275 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8276 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
8277 0 : ShowContinueError(
8278 : state,
8279 0 : format("User-Specified Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]", HeatOutAirVolFlowUser));
8280 0 : ShowContinueError(state,
8281 0 : format("differs from Design Size Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]",
8282 : HeatOutAirVolFlowDes));
8283 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8284 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8285 : }
8286 : }
8287 : }
8288 : }
8289 : }
8290 : } else {
8291 1 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow == DataSizing::AutoSize) {
8292 1 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).OASysExists) {
8293 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow = 0.0;
8294 : } else {
8295 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow =
8296 0 : min(state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesOutAirVolFlow,
8297 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow);
8298 : }
8299 2 : BaseSizer::reportSizerOutput(state,
8300 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8301 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8302 : "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]",
8303 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow);
8304 : }
8305 : }
8306 13 : EqSizing.OAVolFlow =
8307 13 : max(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow);
8308 :
8309 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists &&
8310 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone) { // set up ATMixer conditions for use in component sizing
8311 0 : EqSizing.OAVolFlow = 0.0; // Equipment OA flow should always be 0 when ATMixer is used
8312 0 : SingleDuct::setATMixerSizingProperties(state,
8313 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerIndex,
8314 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum,
8315 0 : state.dataSize->CurZoneEqNum);
8316 : }
8317 :
8318 13 : IsAutoSize = false;
8319 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow == AutoSize) {
8320 4 : IsAutoSize = true;
8321 : }
8322 13 : if (state.dataSize->CurZoneEqNum > 0) {
8323 12 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // Simulation continue
8324 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow > 0.0) {
8325 0 : BaseSizer::reportSizerOutput(state,
8326 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8327 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8328 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
8329 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow);
8330 : }
8331 : } else {
8332 12 : CheckZoneSizing(state, tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type], state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name);
8333 12 : NoCoolHeatOutAirVolFlowDes = min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA,
8334 12 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow,
8335 12 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow);
8336 12 : if (NoCoolHeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
8337 9 : NoCoolHeatOutAirVolFlowDes = 0.0;
8338 : }
8339 :
8340 12 : if (IsAutoSize) {
8341 3 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow = NoCoolHeatOutAirVolFlowDes;
8342 6 : BaseSizer::reportSizerOutput(state,
8343 3 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8344 3 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8345 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
8346 : NoCoolHeatOutAirVolFlowDes);
8347 : } else {
8348 9 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow > 0.0 && NoCoolHeatOutAirVolFlowDes > 0.0) {
8349 1 : NoCoolHeatOutAirVolFlowUser = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow;
8350 2 : BaseSizer::reportSizerOutput(state,
8351 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8352 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8353 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
8354 : NoCoolHeatOutAirVolFlowDes,
8355 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
8356 : NoCoolHeatOutAirVolFlowUser);
8357 1 : if (state.dataGlobal->DisplayExtraWarnings) {
8358 0 : if ((std::abs(NoCoolHeatOutAirVolFlowDes - NoCoolHeatOutAirVolFlowUser) / NoCoolHeatOutAirVolFlowUser) >
8359 0 : state.dataSize->AutoVsHardSizingThreshold) {
8360 0 : ShowMessage(state,
8361 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8362 0 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8363 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name));
8364 0 : ShowContinueError(state,
8365 0 : format("User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
8366 : NoCoolHeatOutAirVolFlowUser));
8367 0 : ShowContinueError(
8368 : state,
8369 0 : format("differs from Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
8370 : NoCoolHeatOutAirVolFlowDes));
8371 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8372 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8373 : }
8374 : }
8375 : }
8376 : }
8377 : }
8378 : } else {
8379 1 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow == DataSizing::AutoSize) {
8380 1 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).OASysExists) {
8381 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow = 0.0;
8382 : } else {
8383 0 : if (!(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedCooling > 0 &&
8384 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NumOfSpeedHeating > 0)) {
8385 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow =
8386 0 : min(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow);
8387 : } else {
8388 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSpecMSHPIndex > -1) {
8389 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow =
8390 0 : min(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatVolumeFlowRate[1],
8391 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolVolumeFlowRate[1]);
8392 : }
8393 : }
8394 : }
8395 2 : BaseSizer::reportSizerOutput(state,
8396 1 : tuTypeNames[(int)state.dataHVACVarRefFlow->VRFTU(VRFTUNum).type],
8397 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name,
8398 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating Heating is Needed [m3/s]",
8399 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).NoCoolHeatOutAirVolFlow);
8400 : }
8401 : }
8402 :
8403 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatingCoilPresent) {
8404 4 : bool ErrorsFound = false;
8405 4 : TempSize = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxSATFromSuppHeatCoil;
8406 4 : MaxHeaterOutletTempSizer sizerMaxHeaterOutTemp;
8407 4 : std::string stringOverride = "Maximum Supply Air Temperature from Supplemental Heater [C]";
8408 4 : if (state.dataGlobal->isEpJSON) {
8409 0 : stringOverride = "maximum_supply_air_temperature_from_supplemental_heater [C]";
8410 : }
8411 4 : sizerMaxHeaterOutTemp.overrideSizingString(stringOverride);
8412 4 : sizerMaxHeaterOutTemp.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8413 4 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxSATFromSuppHeatCoil = sizerMaxHeaterOutTemp.size(state, TempSize, ErrorsFound);
8414 4 : }
8415 :
8416 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
8417 0 : bool ErrorsFound = false;
8418 0 : WaterCoils::SetCoilDesFlow(state,
8419 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType,
8420 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
8421 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow,
8422 : ErrorsFound);
8423 : }
8424 :
8425 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatingCoilPresent) {
8426 4 : CompType = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType;
8427 4 : CompName = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName;
8428 4 : PrintFlag = false; // why isn't this being reported?
8429 4 : TempSize = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSuppHeatingCapacity;
8430 4 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
8431 : // sizing result should always be reported
8432 0 : if (TempSize == DataSizing::AutoSize) {
8433 0 : WaterHeatingCapacitySizer sizerWaterHeatingCapacity;
8434 0 : bool ErrorsFound = false;
8435 0 : std::string stringOverride = "Supplemental Heating Coil Nominal Capacity [W]";
8436 0 : if (state.dataGlobal->isEpJSON) {
8437 0 : stringOverride = "supplemental_heating_coil_nominal_capacity [W]";
8438 : }
8439 0 : sizerWaterHeatingCapacity.overrideSizingString(stringOverride);
8440 0 : sizerWaterHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8441 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSuppHeatingCapacity = sizerWaterHeatingCapacity.size(state, TempSize, ErrorsFound);
8442 0 : }
8443 : } else {
8444 4 : SizingString = "Supplemental Heating Coil Nominal Capacity [W]";
8445 4 : if (TempSize == DataSizing::AutoSize) {
8446 0 : bool errorsFound = false;
8447 0 : HeatingCapacitySizer sizerHeatingCapacity;
8448 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
8449 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8450 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).DesignSuppHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
8451 0 : }
8452 : }
8453 : }
8454 :
8455 13 : EqSizing.CoolingAirFlow = true;
8456 13 : EqSizing.CoolingAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxCoolAirVolFlow;
8457 13 : EqSizing.HeatingAirFlow = true;
8458 13 : EqSizing.HeatingAirVolFlow = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).MaxHeatAirVolFlow;
8459 :
8460 13 : if (CheckVRFCombinationRatio(VRFCond)) {
8461 13 : OnOffAirFlowRat = 1.0;
8462 : // set up the outside air data for sizing the DX coils
8463 13 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInZone) {
8464 12 : state.dataSize->ZoneEqDXCoil = true;
8465 : }
8466 13 : if (state.dataSize->CurZoneEqNum > 0) {
8467 21 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow > 0.0 ||
8468 9 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow > 0.0) {
8469 3 : EqSizing.OAVolFlow =
8470 3 : max(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolOutAirVolFlow, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatOutAirVolFlow);
8471 : } else {
8472 9 : EqSizing.OAVolFlow = 0.0;
8473 : }
8474 : } else {
8475 1 : EqSizing.OAVolFlow = 0.0;
8476 : }
8477 :
8478 13 : Real64 SuppHeatCoilLoad = 0.0;
8479 : // simulate the TU to size the coils
8480 13 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
8481 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
8482 6 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
8483 : state, VRFTUNum, true, 0.0, TUCoolingCapacity, OnOffAirFlowRat, SuppHeatCoilLoad);
8484 : } else {
8485 : // Algorithm Type: VRF model based on system curve
8486 7 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(state, VRFTUNum, true, 0.0, TUCoolingCapacity, OnOffAirFlowRat, SuppHeatCoilLoad);
8487 : }
8488 :
8489 : // ZoneEqDXCoil = .FALSE.
8490 13 : TUCoolingCapacity = 0.0;
8491 13 : TUHeatingCapacity = 0.0;
8492 13 : bool FoundAll = true;
8493 : bool errFlag; // temporary variable used for error checking
8494 13 : int TUListNum = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TUListIndex;
8495 28 : for (int NumTU = 1; NumTU <= state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList; ++NumTU) {
8496 17 : int TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
8497 17 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex > 0) {
8498 51 : DXCoilCap = DXCoils::GetCoilCapacityByIndexType(state,
8499 17 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex,
8500 17 : state.dataHVACVarRefFlow->VRFTU(TUIndex).DXCoolCoilType_Num,
8501 : errFlag);
8502 17 : TUCoolingCapacity += DXCoilCap;
8503 17 : if (DXCoilCap == AutoSize) {
8504 2 : FoundAll = false;
8505 2 : break;
8506 : }
8507 : }
8508 15 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex > 0) {
8509 45 : DXCoilCap = DXCoils::GetCoilCapacityByIndexType(state,
8510 15 : state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex,
8511 15 : state.dataHVACVarRefFlow->VRFTU(TUIndex).DXHeatCoilType_Num,
8512 : errFlag);
8513 15 : TUHeatingCapacity += DXCoilCap;
8514 15 : if (DXCoilCap == AutoSize) {
8515 0 : FoundAll = false;
8516 0 : break;
8517 : }
8518 : }
8519 : }
8520 :
8521 13 : if (FoundAll && (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::SysCurve)) {
8522 : // Size VRF rated cooling/heating capacity (VRF-SysCurve Model)
8523 :
8524 : // Size VRF( VRFCond ).CoolingCapacity
8525 7 : IsAutoSize = false;
8526 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity == AutoSize) {
8527 5 : IsAutoSize = true;
8528 : }
8529 7 : CoolingCapacityDes = TUCoolingCapacity;
8530 7 : if (IsAutoSize) {
8531 5 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity = CoolingCapacityDes;
8532 15 : BaseSizer::reportSizerOutput(state,
8533 15 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8534 5 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8535 : "Design Size Rated Total Cooling Capacity (gross) [W]",
8536 : CoolingCapacityDes);
8537 : } else {
8538 2 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity > 0.0 && CoolingCapacityDes > 0.0) {
8539 2 : CoolingCapacityUser = state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity;
8540 6 : BaseSizer::reportSizerOutput(state,
8541 6 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8542 2 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8543 : "Design Size Rated Total Cooling Capacity (gross) [W]",
8544 : CoolingCapacityDes,
8545 : "User-Specified Rated Total Cooling Capacity (gross) [W]",
8546 : CoolingCapacityUser);
8547 2 : if (state.dataGlobal->DisplayExtraWarnings) {
8548 0 : if ((std::abs(CoolingCapacityDes - CoolingCapacityUser) / CoolingCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8549 0 : ShowMessage(state,
8550 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8551 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8552 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8553 0 : ShowContinueError(state,
8554 0 : format("User-Specified Rated Total Cooling Capacity (gross) of {:.2R} [W]", CoolingCapacityUser));
8555 0 : ShowContinueError(
8556 0 : state, format("differs from Design Size Rated Total Cooling Capacity (gross) of {:.2R} [W]", CoolingCapacityDes));
8557 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8558 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8559 : }
8560 : }
8561 : }
8562 : }
8563 :
8564 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity > 0.0) {
8565 7 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCombinationRatio =
8566 7 : TUCoolingCapacity / state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity;
8567 : }
8568 :
8569 : // Size VRF( VRFCond ).HeatingCapacity
8570 7 : IsAutoSize = false;
8571 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity == AutoSize) {
8572 5 : IsAutoSize = true;
8573 : }
8574 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).LockHeatingCapacity) {
8575 0 : HeatingCapacityDes =
8576 0 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity * state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacitySizeRatio;
8577 : } else {
8578 7 : HeatingCapacityDes = TUHeatingCapacity;
8579 : }
8580 7 : if (IsAutoSize) {
8581 5 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity = HeatingCapacityDes;
8582 15 : BaseSizer::reportSizerOutput(state,
8583 15 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8584 5 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8585 : "Design Size Rated Total Heating Capacity [W]",
8586 : HeatingCapacityDes);
8587 : } else {
8588 2 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity > 0.0 && HeatingCapacityDes > 0.0) {
8589 2 : HeatingCapacityUser = state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity;
8590 6 : BaseSizer::reportSizerOutput(state,
8591 6 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8592 2 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8593 : "Design Size Rated Total Heating Capacity [W]",
8594 : HeatingCapacityDes,
8595 : "User-Specified Rated Total Heating Capacity [W]",
8596 : HeatingCapacityUser);
8597 2 : if (state.dataGlobal->DisplayExtraWarnings) {
8598 0 : if ((std::abs(HeatingCapacityDes - HeatingCapacityUser) / HeatingCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8599 0 : ShowMessage(state,
8600 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8601 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8602 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8603 0 : ShowContinueError(state, format("User-Specified Rated Total Heating Capacity of {:.2R} [W]", HeatingCapacityUser));
8604 0 : ShowContinueError(state,
8605 0 : format("differs from Design Size Rated Total Heating Capacity of {:.2R} [W]", HeatingCapacityDes));
8606 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8607 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8608 : }
8609 : }
8610 : }
8611 : }
8612 :
8613 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity > 0.0) {
8614 7 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCombinationRatio =
8615 7 : TUHeatingCapacity / state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity;
8616 : }
8617 :
8618 : // calculate the piping correction factors only once
8619 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthCoolPtr > 0) {
8620 : {
8621 6 : if (state.dataCurveManager->curves(state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthCoolPtr)->numDims == 2) {
8622 6 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionCooling =
8623 6 : min(1.0,
8624 : max(0.5,
8625 24 : CurveValue(state,
8626 6 : state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthCoolPtr,
8627 6 : state.dataHVACVarRefFlow->VRF(VRFCond).EquivPipeLngthCool,
8628 6 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCombinationRatio) +
8629 6 : state.dataHVACVarRefFlow->VRF(VRFCond).VertPipeLngth * state.dataHVACVarRefFlow->VRF(VRFCond).PCFHeightCool));
8630 : } else {
8631 0 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionCooling =
8632 0 : min(1.0,
8633 : max(0.5,
8634 0 : CurveValue(state,
8635 0 : state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthCoolPtr,
8636 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EquivPipeLngthCool) +
8637 0 : state.dataHVACVarRefFlow->VRF(VRFCond).VertPipeLngth * state.dataHVACVarRefFlow->VRF(VRFCond).PCFHeightCool));
8638 : }
8639 : }
8640 : } else {
8641 1 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionCooling = min(
8642 : 1.0,
8643 1 : max(0.5, (1.0 + state.dataHVACVarRefFlow->VRF(VRFCond).VertPipeLngth * state.dataHVACVarRefFlow->VRF(VRFCond).PCFHeightCool)));
8644 : }
8645 :
8646 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthHeatPtr > 0) {
8647 : {
8648 0 : if (state.dataCurveManager->curves(state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthHeatPtr)->numDims == 2) {
8649 0 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionHeating =
8650 0 : min(1.0,
8651 : max(0.5,
8652 0 : CurveValue(state,
8653 0 : state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthHeatPtr,
8654 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EquivPipeLngthHeat,
8655 0 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCombinationRatio) +
8656 0 : state.dataHVACVarRefFlow->VRF(VRFCond).VertPipeLngth * state.dataHVACVarRefFlow->VRF(VRFCond).PCFHeightHeat));
8657 : } else {
8658 0 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionHeating =
8659 0 : min(1.0,
8660 : max(0.5,
8661 0 : CurveValue(state,
8662 0 : state.dataHVACVarRefFlow->VRF(VRFCond).PCFLengthHeatPtr,
8663 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EquivPipeLngthHeat) +
8664 0 : state.dataHVACVarRefFlow->VRF(VRFCond).VertPipeLngth * state.dataHVACVarRefFlow->VRF(VRFCond).PCFHeightHeat));
8665 : }
8666 : }
8667 : } else {
8668 7 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionHeating = min(
8669 : 1.0,
8670 7 : max(0.5, (1.0 + state.dataHVACVarRefFlow->VRF(VRFCond).VertPipeLngth * state.dataHVACVarRefFlow->VRF(VRFCond).PCFHeightHeat)));
8671 : }
8672 :
8673 7 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedCoolingPower =
8674 7 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity / state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCOP;
8675 7 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedHeatingPower =
8676 7 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity / state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCOP;
8677 :
8678 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).CoolCombRatioPTR > 0) {
8679 6 : state.dataHVACVarRefFlow->CoolCombinationRatio(VRFCond) = CurveValue(
8680 6 : state, state.dataHVACVarRefFlow->VRF(VRFCond).CoolCombRatioPTR, state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCombinationRatio);
8681 : } else {
8682 1 : state.dataHVACVarRefFlow->CoolCombinationRatio(VRFCond) = 1.0;
8683 : }
8684 :
8685 7 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatCombRatioPTR > 0) {
8686 6 : state.dataHVACVarRefFlow->HeatCombinationRatio(VRFCond) = CurveValue(
8687 6 : state, state.dataHVACVarRefFlow->VRF(VRFCond).HeatCombRatioPTR, state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCombinationRatio);
8688 : } else {
8689 1 : state.dataHVACVarRefFlow->HeatCombinationRatio(VRFCond) = 1.0;
8690 : }
8691 : }
8692 :
8693 13 : if (FoundAll && (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl)) {
8694 : // Size VRF rated evaporative capacity (VRF-FluidTCtrl Model)
8695 : // Set piping correction factors to 1.0 here for reporting to eio output - recalculated every time step in
8696 : // VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl
8697 4 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionCooling = 1.0;
8698 4 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionHeating = 1.0;
8699 :
8700 : // Size VRF( VRFCond ).RatedEvapCapacity
8701 4 : IsAutoSize = false;
8702 4 : if (state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity == AutoSize) {
8703 2 : IsAutoSize = true;
8704 : }
8705 :
8706 4 : CoolingCapacityDes = TUCoolingCapacity;
8707 4 : HeatingCapacityDes = TUHeatingCapacity;
8708 :
8709 4 : if (IsAutoSize) {
8710 : // RatedEvapCapacity
8711 2 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity =
8712 2 : max(CoolingCapacityDes, HeatingCapacityDes / (1 + state.dataHVACVarRefFlow->VRF(VRFCond).RatedCompPowerPerCapcity));
8713 :
8714 : // Other parameters dependent on RatedEvapCapacity
8715 2 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedCompPower =
8716 2 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedCompPowerPerCapcity * state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity;
8717 2 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedOUFanPower =
8718 2 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedOUFanPowerPerCapcity * state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity;
8719 2 : state.dataHVACVarRefFlow->VRF(VRFCond).OUAirFlowRate =
8720 2 : state.dataHVACVarRefFlow->VRF(VRFCond).OUAirFlowRatePerCapcity * state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity;
8721 :
8722 2 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity = state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity;
8723 2 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity =
8724 2 : state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity * (1 + state.dataHVACVarRefFlow->VRF(VRFCond).RatedCompPowerPerCapcity);
8725 :
8726 6 : BaseSizer::reportSizerOutput(state,
8727 6 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8728 2 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8729 : "Design Size Rated Total Heating Capacity [W]",
8730 2 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCapacity);
8731 6 : BaseSizer::reportSizerOutput(state,
8732 6 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8733 2 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8734 : "Design Size Rated Total Cooling Capacity (gross) [W]",
8735 2 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity);
8736 : } else {
8737 2 : CoolingCapacityUser = state.dataHVACVarRefFlow->VRF(VRFCond).RatedEvapCapacity;
8738 2 : HeatingCapacityUser = state.dataHVACVarRefFlow->VRF(VRFCond).RatedHeatCapacity;
8739 :
8740 6 : BaseSizer::reportSizerOutput(state,
8741 6 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8742 2 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8743 : "Design Size Rated Total Cooling Capacity (gross) [W]",
8744 : CoolingCapacityDes,
8745 : "User-Specified Rated Total Cooling Capacity (gross) [W]",
8746 : CoolingCapacityUser);
8747 6 : BaseSizer::reportSizerOutput(state,
8748 6 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8749 2 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8750 : "Design Size Rated Total Heating Capacity [W]",
8751 : HeatingCapacityDes,
8752 : "User-Specified Rated Total Heating Capacity [W]",
8753 : HeatingCapacityUser);
8754 :
8755 2 : if (state.dataGlobal->DisplayExtraWarnings) {
8756 0 : if ((std::abs(CoolingCapacityDes - CoolingCapacityUser) / CoolingCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8757 0 : ShowMessage(state,
8758 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8759 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8760 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8761 0 : ShowContinueError(state, format("User-Specified Rated Total Cooling Capacity (gross) of {:.2R} [W]", CoolingCapacityUser));
8762 0 : ShowContinueError(state,
8763 0 : format("differs from Design Size Rated Total Cooling Capacity (gross) of {:.2R} [W]", CoolingCapacityDes));
8764 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8765 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8766 : }
8767 :
8768 0 : if ((std::abs(HeatingCapacityDes - HeatingCapacityUser) / HeatingCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8769 0 : ShowMessage(state,
8770 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8771 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8772 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8773 0 : ShowContinueError(state, format("User-Specified Rated Total Heating Capacity of {:.2R} [W]", HeatingCapacityUser));
8774 0 : ShowContinueError(state, format("differs from Design Size Rated Total Heating Capacity of {:.2R} [W]", HeatingCapacityDes));
8775 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8776 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8777 : }
8778 : }
8779 : }
8780 : }
8781 :
8782 13 : if (FoundAll) {
8783 : // autosize resistive defrost heater capacity
8784 11 : IsAutoSize = false;
8785 11 : if (state.dataHVACVarRefFlow->VRF(VRFCond).DefrostCapacity == AutoSize) {
8786 5 : IsAutoSize = true;
8787 : }
8788 11 : if (state.dataHVACVarRefFlow->VRF(VRFCond).DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
8789 2 : DefrostCapacityDes = state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity;
8790 : } else {
8791 9 : DefrostCapacityDes = 0.0;
8792 : }
8793 11 : if (IsAutoSize) {
8794 5 : state.dataHVACVarRefFlow->VRF(VRFCond).DefrostCapacity = DefrostCapacityDes;
8795 15 : BaseSizer::reportSizerOutput(state,
8796 15 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8797 5 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8798 : "Design Size Resistive Defrost Heater Capacity [W]",
8799 : DefrostCapacityDes);
8800 : } else {
8801 6 : if (state.dataHVACVarRefFlow->VRF(VRFCond).DefrostCapacity > 0.0 && DefrostCapacityDes > 0.0) {
8802 0 : DefrostCapacityUser = state.dataHVACVarRefFlow->VRF(VRFCond).DefrostCapacity;
8803 0 : BaseSizer::reportSizerOutput(state,
8804 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8805 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8806 : "Design Size Resistive Defrost Heater Capacity [W]",
8807 : DefrostCapacityDes,
8808 : "User-Specified Resistive Defrost Heater Capacity",
8809 : DefrostCapacityUser);
8810 0 : if (state.dataGlobal->DisplayExtraWarnings) {
8811 0 : if ((std::abs(DefrostCapacityDes - DefrostCapacityUser) / DefrostCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8812 0 : ShowMessage(state,
8813 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8814 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8815 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8816 0 : ShowContinueError(state, format("User-Specified Resistive Defrost Heater Capacity of {:.2R} [W]", DefrostCapacityUser));
8817 0 : ShowContinueError(state,
8818 0 : format("differs from Design Size Resistive Defrost Heater Capacity of {:.2R} [W]", DefrostCapacityDes));
8819 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8820 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8821 : }
8822 : }
8823 : }
8824 : }
8825 :
8826 11 : IsAutoSize = false;
8827 11 : if (state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondAirVolFlowRate == AutoSize) {
8828 0 : IsAutoSize = true;
8829 : }
8830 : // Auto-size condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
8831 11 : EvapCondAirVolFlowRateDes = state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity * 0.000114;
8832 11 : if (IsAutoSize) {
8833 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondAirVolFlowRate = EvapCondAirVolFlowRateDes;
8834 0 : BaseSizer::reportSizerOutput(state,
8835 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8836 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8837 : "Design Size Evaporative Condenser Air Flow Rate [m3/s]",
8838 : EvapCondAirVolFlowRateDes);
8839 : } else {
8840 11 : if (state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondAirVolFlowRate > 0.0 && EvapCondAirVolFlowRateDes > 0.0) {
8841 0 : EvapCondAirVolFlowRateUser = state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondAirVolFlowRate;
8842 0 : BaseSizer::reportSizerOutput(state,
8843 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8844 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8845 : "Design Size Evaporative Condenser Air Flow Rate [m3/s]",
8846 : EvapCondAirVolFlowRateDes,
8847 : "User-Specified Evaporative Condenser Air Flow Rate [m3/s]",
8848 : EvapCondAirVolFlowRateUser);
8849 0 : if (state.dataGlobal->DisplayExtraWarnings) {
8850 0 : if ((std::abs(EvapCondAirVolFlowRateDes - EvapCondAirVolFlowRateUser) / EvapCondAirVolFlowRateUser) >
8851 0 : state.dataSize->AutoVsHardSizingThreshold) {
8852 0 : ShowMessage(state,
8853 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8854 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8855 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8856 0 : ShowContinueError(
8857 0 : state, format("User-Specified Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", EvapCondAirVolFlowRateUser));
8858 0 : ShowContinueError(
8859 : state,
8860 0 : format("differs from Design Size Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", EvapCondAirVolFlowRateDes));
8861 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8862 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8863 : }
8864 : }
8865 : }
8866 : }
8867 :
8868 11 : IsAutoSize = false;
8869 11 : if (state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondPumpPower == AutoSize) {
8870 0 : IsAutoSize = true;
8871 : }
8872 : // Auto-size evap condenser pump power to Total Capacity * 0.004266 w/w (15 w/ton)
8873 11 : EvapCondPumpPowerDes = state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCapacity * 0.004266;
8874 11 : if (IsAutoSize) {
8875 0 : state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondPumpPower = EvapCondPumpPowerDes;
8876 0 : BaseSizer::reportSizerOutput(state,
8877 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8878 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8879 : "Design Size Evaporative Condenser Pump Rated Power Consumption [W]",
8880 : EvapCondPumpPowerDes);
8881 :
8882 : } else {
8883 11 : if (state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondPumpPower > 0.0 && EvapCondPumpPowerDes > 0.0) {
8884 0 : EvapCondPumpPowerUser = state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondPumpPower;
8885 0 : BaseSizer::reportSizerOutput(state,
8886 0 : std::string(cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum)),
8887 0 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8888 : "Design Size Evaporative Condenser Pump Rated Power Consumption [W]",
8889 : EvapCondPumpPowerDes,
8890 : "User-Specified Evaporative Condenser Pump Rated Power Consumption [W]",
8891 : EvapCondPumpPowerUser);
8892 0 : if (state.dataGlobal->DisplayExtraWarnings) {
8893 0 : if ((std::abs(EvapCondPumpPowerDes - EvapCondPumpPowerUser) / EvapCondPumpPowerUser) >
8894 0 : state.dataSize->AutoVsHardSizingThreshold) {
8895 0 : ShowMessage(state,
8896 0 : format("SizeVRF: Potential issue with equipment sizing for {} {}",
8897 0 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8898 0 : state.dataHVACVarRefFlow->VRFTU(VRFCond).Name));
8899 0 : ShowContinueError(
8900 : state,
8901 0 : format("User-Specified Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]", EvapCondPumpPowerUser));
8902 0 : ShowContinueError(state,
8903 0 : format("differs from Design Size Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]",
8904 : EvapCondPumpPowerDes));
8905 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8906 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8907 : }
8908 : }
8909 : }
8910 : }
8911 :
8912 : // Report to eio other information not related to autosizing
8913 11 : if (state.dataHVACVarRefFlow->MyOneTimeEIOFlag) {
8914 : static constexpr std::string_view Format_990(
8915 : "! <VRF System Information>, VRF System Type, VRF System Name, VRF System Cooling Combination Ratio, VRF "
8916 : "System Heating Combination Ratio, VRF System Cooling Piping Correction Factor, VRF System Heating Piping "
8917 : "Correction Factor\n");
8918 11 : print(state.files.eio, Format_990);
8919 11 : state.dataHVACVarRefFlow->MyOneTimeEIOFlag = false;
8920 : }
8921 : static constexpr std::string_view Format_991(" VRF System Information, {}, {}, {:.5R}, {:.5R}, {:.5R}, {:.5R}\n");
8922 11 : print(state.files.eio,
8923 : Format_991,
8924 11 : cVRFTypes(state.dataHVACVarRefFlow->VRF(VRFCond).VRFSystemTypeNum),
8925 11 : state.dataHVACVarRefFlow->VRF(VRFCond).Name,
8926 11 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCombinationRatio,
8927 11 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCombinationRatio,
8928 11 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionCooling,
8929 11 : state.dataHVACVarRefFlow->VRF(VRFCond).PipingCorrectionHeating);
8930 :
8931 11 : CheckVRFCombinationRatio(VRFCond) = false;
8932 : }
8933 : }
8934 :
8935 13 : state.dataSize->DataScalableCapSizingON = false;
8936 13 : }
8937 :
8938 6 : void initCapSizingVars(EnergyPlusData &state,
8939 : int sizingMethod,
8940 : int capSizingMethod,
8941 : int &eqSizingMethod,
8942 : Real64 scaledCapacity,
8943 : bool &modeCapacity,
8944 : Real64 &designLoad,
8945 : bool &scalableCapSizingOn,
8946 : Real64 &fracOfAutosizedCapacity)
8947 : {
8948 : using namespace DataSizing;
8949 : using HVAC::CoolingCapacitySizing;
8950 : using HVAC::HeatingCapacitySizing;
8951 :
8952 6 : eqSizingMethod = capSizingMethod;
8953 6 : if (capSizingMethod == CoolingDesignCapacity || capSizingMethod == HeatingDesignCapacity || capSizingMethod == CapacityPerFloorArea ||
8954 2 : capSizingMethod == FractionOfAutosizedCoolingCapacity || capSizingMethod == FractionOfAutosizedHeatingCapacity) {
8955 5 : if ((capSizingMethod == CoolingDesignCapacity && sizingMethod == CoolingCapacitySizing) ||
8956 1 : (capSizingMethod == HeatingDesignCapacity && sizingMethod == HeatingCapacitySizing)) {
8957 2 : if (scaledCapacity > 0.0) {
8958 2 : modeCapacity = true;
8959 2 : designLoad = scaledCapacity;
8960 : }
8961 3 : } else if (capSizingMethod == CapacityPerFloorArea) {
8962 1 : modeCapacity = true;
8963 1 : designLoad = scaledCapacity * state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
8964 1 : scalableCapSizingOn = true;
8965 2 : } else if ((capSizingMethod == FractionOfAutosizedCoolingCapacity && sizingMethod == CoolingCapacitySizing) ||
8966 1 : (capSizingMethod == FractionOfAutosizedHeatingCapacity && sizingMethod == HeatingCapacitySizing)) {
8967 2 : fracOfAutosizedCapacity = scaledCapacity;
8968 2 : scalableCapSizingOn = true;
8969 : }
8970 : }
8971 6 : }
8972 :
8973 1 : void VRFCondenserEquipment::SizeVRFCondenser(EnergyPlusData &state)
8974 : {
8975 :
8976 : // SUBROUTINE INFORMATION:
8977 : // AUTHOR Richard Raustad, FSEC
8978 : // DATE WRITTEN August 2012
8979 : // MODIFIED na
8980 : // RE-ENGINEERED na
8981 :
8982 : // PURPOSE OF THIS SUBROUTINE:
8983 : // This subroutine is for sizing VRF Condenser.
8984 :
8985 : // METHODOLOGY EMPLOYED:
8986 : // Set water-cooled plant flow rates.
8987 :
8988 : static constexpr std::string_view RoutineName("SizeVRFCondenser");
8989 :
8990 : Real64 rho; // local fluid density [kg/m3]
8991 : Real64 Cp; // local fluid specific heat [J/kg-k]
8992 : Real64 tmpCondVolFlowRate; // local condenser design volume flow rate [m3/s]
8993 :
8994 : // save the design water flow rate for use by the water loop sizing algorithms
8995 1 : if (this->CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
8996 :
8997 1 : bool ErrorsFound = false;
8998 1 : if (this->WaterCondVolFlowRate == DataSizing::AutoSize) {
8999 1 : int PltSizCondNum = 0;
9000 1 : if (this->SourcePlantLoc.loopNum > 0) {
9001 1 : PltSizCondNum = state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).PlantSizNum;
9002 : }
9003 1 : if (PltSizCondNum > 0) {
9004 1 : rho = state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum)
9005 1 : .glycol->getDensity(state, state.dataSize->PlantSizData(PltSizCondNum).ExitTemp, RoutineName);
9006 :
9007 1 : Cp = state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum)
9008 1 : .glycol->getSpecificHeat(state, state.dataSize->PlantSizData(PltSizCondNum).ExitTemp, RoutineName);
9009 1 : tmpCondVolFlowRate =
9010 1 : max(this->CoolingCapacity, this->HeatingCapacity) / (state.dataSize->PlantSizData(PltSizCondNum).DeltaT * Cp * rho);
9011 1 : if (this->HeatingCapacity != DataSizing::AutoSize && this->CoolingCapacity != DataSizing::AutoSize) {
9012 1 : this->WaterCondVolFlowRate = tmpCondVolFlowRate;
9013 1 : BaseSizer::reportSizerOutput(state,
9014 : "AirConditioner:VariableRefrigerantFlow",
9015 : this->Name,
9016 : "Design Condenser Water Flow Rate [m3/s]",
9017 : this->WaterCondVolFlowRate);
9018 : }
9019 :
9020 1 : rho = state.dataPlnt->PlantLoop(this->SourcePlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
9021 1 : this->WaterCondenserDesignMassFlow = this->WaterCondVolFlowRate * rho;
9022 1 : PlantUtilities::InitComponentNodes(
9023 : state, 0.0, this->WaterCondenserDesignMassFlow, this->CondenserNodeNum, this->CondenserOutletNodeNum);
9024 :
9025 : } else {
9026 0 : ShowSevereError(state, "Autosizing of condenser water flow rate requires a condenser loop Sizing:Plant object");
9027 0 : ShowContinueError(state, format("... occurs in AirConditioner:VariableRefrigerantFlow object={}", this->Name));
9028 0 : ShowContinueError(state, "... plant loop name must be referenced in Sizing:Plant object");
9029 0 : ErrorsFound = true;
9030 : }
9031 : }
9032 :
9033 1 : if (ErrorsFound) {
9034 0 : ShowFatalError(state, "Preceding sizing errors cause program termination");
9035 : }
9036 :
9037 1 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->CondenserNodeNum, this->WaterCondVolFlowRate);
9038 : }
9039 1 : }
9040 :
9041 7118 : void SimVRF(EnergyPlusData &state,
9042 : int const VRFTUNum,
9043 : bool const FirstHVACIteration,
9044 : Real64 &OnOffAirFlowRatio,
9045 : Real64 &SysOutputProvided,
9046 : Real64 &LatOutputProvided,
9047 : Real64 const QZnReq)
9048 : {
9049 :
9050 : // SUBROUTINE INFORMATION:
9051 : // AUTHOR Richard Raustad, FSEC
9052 : // DATE WRITTEN August 2010
9053 : // MODIFIED na
9054 : // RE-ENGINEERED na
9055 :
9056 : // PURPOSE OF THIS SUBROUTINE:
9057 : // This subroutine simulates the VRF TU's.
9058 :
9059 : // METHODOLOGY EMPLOYED:
9060 : // Simulate terminal unit to meet zone load.
9061 :
9062 7118 : Real64 PartLoadRatio(1.0);
9063 7118 : Real64 SuppHeatCoilLoad(0.0); // supplemental heating coil load (W)
9064 :
9065 7118 : if (state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
9066 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9067 2378 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ControlVRF_FluidTCtrl(
9068 : state, VRFTUNum, QZnReq, FirstHVACIteration, PartLoadRatio, OnOffAirFlowRatio, SuppHeatCoilLoad);
9069 2378 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
9070 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, SysOutputProvided, OnOffAirFlowRatio, SuppHeatCoilLoad, LatOutputProvided);
9071 2378 : if (PartLoadRatio ==
9072 : 0.0) { // set coil inlet conditions when coil does not operate. Inlet conditions are set in ControlVRF_FluidTCtrl when PLR=1
9073 44 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingCoilPresent) {
9074 44 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coilInNodeT =
9075 44 : state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolCoilIndex).AirInNode).Temp;
9076 44 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coilInNodeW =
9077 44 : state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolCoilIndex).AirInNode).HumRat;
9078 : } else {
9079 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coilInNodeT =
9080 0 : state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatCoilIndex).AirInNode).Temp;
9081 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coilInNodeW =
9082 0 : state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatCoilIndex).AirInNode).HumRat;
9083 : }
9084 : }
9085 : // CalcVRF( VRFTUNum, FirstHVACIteration, PartLoadRatio, SysOutputProvided, OnOffAirFlowRatio, LatOutputProvided );
9086 : } else {
9087 : // Algorithm Type: VRF model based on system curve
9088 4740 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ControlVRF(
9089 : state, VRFTUNum, QZnReq, FirstHVACIteration, PartLoadRatio, OnOffAirFlowRatio, SuppHeatCoilLoad);
9090 4740 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
9091 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, SysOutputProvided, OnOffAirFlowRatio, SuppHeatCoilLoad, LatOutputProvided);
9092 : }
9093 :
9094 7118 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TerminalUnitSensibleRate = SysOutputProvided;
9095 7118 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TerminalUnitLatentRate = LatOutputProvided;
9096 7118 : }
9097 :
9098 4740 : void VRFTerminalUnitEquipment::ControlVRF(EnergyPlusData &state,
9099 : int const VRFTUNum, // Index to VRF terminal unit
9100 : Real64 const QZnReq, // Index to zone number
9101 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
9102 : Real64 &PartLoadRatio, // unit part load ratio
9103 : Real64 &OnOffAirFlowRatio, // ratio of compressor ON airflow to AVERAGE airflow over timestep
9104 : Real64 &SuppHeatCoilLoad // supplemental heating coil load (W)
9105 : )
9106 : {
9107 :
9108 : // SUBROUTINE INFORMATION:
9109 : // AUTHOR Richard Raustad
9110 : // DATE WRITTEN July 2005
9111 :
9112 : // PURPOSE OF THIS SUBROUTINE:
9113 : // Determine the part load fraction of the heat pump for this time step.
9114 :
9115 : // METHODOLOGY EMPLOYED:
9116 : // Use RegulaFalsi technique to iterate on part-load ratio until convergence is achieved.
9117 :
9118 4740 : PartLoadRatio = 0.0;
9119 4740 : state.dataHVACVarRefFlow->LoopDXCoolCoilRTF = 0.0;
9120 4740 : state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = 0.0;
9121 4740 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatPartLoadRatio = 0.0;
9122 :
9123 : // The RETURNS here will jump back to SimVRF where the CalcVRF routine will simulate with latest PLR
9124 :
9125 : // do nothing else if TU is scheduled off
9126 4740 : if (this->availSched->getCurrentVal() == 0.0) {
9127 0 : return;
9128 : }
9129 :
9130 : // do nothing if TU has no load (TU will be modeled using PLR=0)
9131 4740 : if (QZnReq == 0.0) {
9132 81 : return;
9133 : }
9134 :
9135 : // Set EMS value for PLR and return
9136 4659 : if (this->EMSOverridePartLoadFrac) {
9137 0 : PartLoadRatio = this->EMSValueForPartLoadFrac;
9138 0 : return;
9139 : }
9140 :
9141 : // Get result when DX coil is operating at the minimum PLR (1E-20) if not otherwise specified
9142 4659 : PartLoadRatio = this->MinOperatingPLR;
9143 :
9144 4659 : this->ControlVRFToLoad(state, VRFTUNum, QZnReq, FirstHVACIteration, PartLoadRatio, OnOffAirFlowRatio, SuppHeatCoilLoad);
9145 : }
9146 :
9147 4659 : void VRFTerminalUnitEquipment::ControlVRFToLoad(EnergyPlusData &state,
9148 : int const VRFTUNum,
9149 : Real64 const QZnReq,
9150 : bool const FirstHVACIteration,
9151 : Real64 &PartLoadRatio,
9152 : Real64 &OnOffAirFlowRatio,
9153 : Real64 &SuppHeatCoilLoad)
9154 : {
9155 :
9156 4659 : int constexpr MaxIte(500); // maximum number of iterations
9157 4659 : Real64 constexpr MinPLF(0.0); // minimum part load factor allowed
9158 4659 : Real64 constexpr ErrorTol(0.001); // tolerance for RegulaFalsi iterations
9159 :
9160 4659 : int VRFCond = this->VRFSysNum;
9161 4659 : Real64 FullOutput = 0.0; // unit full output when compressor is operating [W]
9162 4659 : Real64 TempOutput = 0.0; // unit output when iteration limit exceeded [W]
9163 4659 : Real64 TempMinPLR = 0.0; // min PLR used in Regula Falsi call
9164 4659 : Real64 TempMaxPLR = 0.0; // max PLR used in Regula Falsi call
9165 4659 : Real64 NoCompOutput = 0.0; // output when no active compressor [W]
9166 4659 : bool VRFCoolingMode = state.dataHVACVarRefFlow->CoolingLoad(VRFCond);
9167 4659 : bool VRFHeatingMode = state.dataHVACVarRefFlow->HeatingLoad(VRFCond);
9168 4659 : int IndexToTUInTUList = this->IndexToTUInTUList;
9169 4659 : auto &thisVRFCond = state.dataHVACVarRefFlow->VRF(VRFCond);
9170 4659 : int TUListIndex = thisVRFCond.ZoneTUListPtr;
9171 4659 : bool HRCoolingMode = state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList);
9172 4659 : bool HRHeatingMode = state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList);
9173 4659 : auto &thisVRFTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
9174 :
9175 4659 : if (thisVRFCond.VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
9176 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9177 0 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, PartLoadRatio, NoCompOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9178 : } else {
9179 : // Algorithm Type: VRF model based on system curve
9180 4659 : this->CalcVRF(state, VRFTUNum, FirstHVACIteration, PartLoadRatio, NoCompOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9181 : }
9182 :
9183 4659 : bool DXCoolingCoilOprCtrl = true;
9184 :
9185 4659 : if (VRFCoolingMode && HRHeatingMode) {
9186 : // IF the system is in cooling mode, but the terminal unit requests heating (heat recovery)
9187 0 : if (NoCompOutput >= QZnReq) {
9188 0 : PartLoadRatio = 0.0;
9189 16 : return;
9190 : }
9191 4659 : } else if (VRFHeatingMode && HRCoolingMode) {
9192 : // IF the system is in heating mode, but the terminal unit requests cooling (heat recovery)
9193 0 : if (NoCompOutput <= QZnReq) {
9194 0 : PartLoadRatio = 0.0;
9195 0 : return;
9196 : }
9197 4659 : } else if (VRFCoolingMode || HRCoolingMode) {
9198 : // IF the system is in cooling mode and/or the terminal unit requests cooling
9199 2316 : if (NoCompOutput <= QZnReq) {
9200 0 : DXCoolingCoilOprCtrl = false;
9201 0 : if (!this->SuppHeatingCoilPresent || HRCoolingMode) {
9202 0 : PartLoadRatio = 0.0;
9203 0 : return;
9204 : }
9205 : }
9206 2343 : } else if (VRFHeatingMode || HRHeatingMode) {
9207 : // IF the system is in heating mode and/or the terminal unit requests heating
9208 2333 : if (NoCompOutput >= QZnReq) {
9209 1 : PartLoadRatio = 0.0;
9210 1 : return;
9211 : }
9212 : }
9213 :
9214 : // Otherwise the coil needs to turn on. Get full load result
9215 4658 : PartLoadRatio = 1.0;
9216 4658 : if (!DXCoolingCoilOprCtrl) {
9217 0 : PartLoadRatio = 0.0;
9218 : }
9219 4658 : if (thisVRFCond.VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
9220 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9221 0 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, PartLoadRatio, FullOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9222 : } else {
9223 : // Algorithm Type: VRF model based on system curve
9224 4658 : if (this->NumOfSpeedHeating > 0 && VRFHeatingMode) {
9225 2324 : this->SpeedNum = this->NumOfSpeedHeating;
9226 2324 : this->SpeedRatio = 1.0;
9227 2324 : this->CycRatio = 1.0;
9228 : }
9229 4658 : if (this->NumOfSpeedCooling > 0 && VRFCoolingMode) {
9230 2308 : this->SpeedNum = this->NumOfSpeedCooling;
9231 2308 : this->SpeedRatio = 1.0;
9232 2308 : this->CycRatio = 1.0;
9233 : }
9234 4658 : this->CalcVRF(state, VRFTUNum, FirstHVACIteration, PartLoadRatio, FullOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9235 : }
9236 :
9237 : // set supplemental heating coil calculation if the condition requires
9238 4658 : if (this->SuppHeatingCoilPresent) {
9239 0 : if (this->isSetPointControlled) {
9240 0 : auto const &thisSuppHeatCoilAirInletNode = state.dataLoopNodes->Node(this->SuppHeatCoilAirInletNode);
9241 0 : if (this->suppTempSetPoint > thisSuppHeatCoilAirInletNode.Temp) {
9242 0 : Real64 mDot = thisSuppHeatCoilAirInletNode.MassFlowRate;
9243 0 : Real64 Tin = thisSuppHeatCoilAirInletNode.Temp;
9244 0 : Real64 Win = thisSuppHeatCoilAirInletNode.HumRat;
9245 0 : Real64 CpAirIn = Psychrometrics::PsyCpAirFnW(Win);
9246 0 : SuppHeatCoilLoad = mDot * CpAirIn * (this->suppTempSetPoint - Tin);
9247 0 : this->SuppHeatingCoilLoad = SuppHeatCoilLoad;
9248 : } else {
9249 0 : SuppHeatCoilLoad = 0.0;
9250 : }
9251 : } else {
9252 : // not sure why FirstHVAC has anything to do with this but that was already here
9253 : // another branch should test removing FirstHVACIteration to get same answer each iteration
9254 0 : if (!FirstHVACIteration &&
9255 0 : ((QZnReq > HVAC::SmallLoad && QZnReq > FullOutput) || (((QZnReq - NoCompOutput) > HVAC::SmallLoad) && QZnReq <= 0.0))) {
9256 0 : Real64 ZoneLoad = 0.0;
9257 0 : Real64 LoadToHeatingSP = 0.0;
9258 0 : Real64 LoadToCoolingSP = 0.0;
9259 0 : getVRFTUZoneLoad(state, VRFTUNum, ZoneLoad, LoadToHeatingSP, LoadToCoolingSP, false);
9260 0 : if ((QZnReq - NoCompOutput) > HVAC::SmallLoad && QZnReq <= 0.0) {
9261 0 : if (LoadToHeatingSP < 0.0 && QZnReq == 0.0) {
9262 0 : SuppHeatCoilLoad = max(0.0, LoadToHeatingSP - FullOutput);
9263 : } else {
9264 0 : SuppHeatCoilLoad = max(0.0, QZnReq - FullOutput);
9265 : }
9266 0 : } else if (FullOutput < (LoadToHeatingSP - HVAC::SmallLoad) && LoadToHeatingSP > 0.0) {
9267 0 : if (QZnReq > 0.0 && (NoCompOutput - QZnReq) >= HVAC::SmallLoad) {
9268 0 : SuppHeatCoilLoad = 0.0;
9269 : } else {
9270 0 : SuppHeatCoilLoad = max(0.0, LoadToHeatingSP - FullOutput);
9271 : }
9272 : } else {
9273 0 : SuppHeatCoilLoad = 0.0;
9274 : }
9275 0 : } else {
9276 0 : SuppHeatCoilLoad = 0.0;
9277 : }
9278 : }
9279 0 : if (this->DesignSuppHeatingCapacity > 0.0) {
9280 0 : this->SuppHeatPartLoadRatio = min(1.0, SuppHeatCoilLoad / this->DesignSuppHeatingCapacity);
9281 : }
9282 : } else { // does it matter what these are if there is no supp heater?
9283 4658 : SuppHeatCoilLoad = 0.0;
9284 4658 : this->SuppHeatPartLoadRatio = 0.0;
9285 : }
9286 :
9287 4658 : if ((VRFCoolingMode && !thisVRFCond.HeatRecoveryUsed) || (thisVRFCond.HeatRecoveryUsed && HRCoolingMode)) {
9288 : // Since we are cooling, we expect FullOutput < NoCompOutput
9289 : // If the QZnReq <= FullOutput the unit needs to run full out
9290 2316 : if (QZnReq <= FullOutput) {
9291 : // if no coil present in terminal unit, no need to reset PLR?
9292 2 : if (thisVRFTU.CoolingCoilPresent && DXCoolingCoilOprCtrl) {
9293 2 : PartLoadRatio = 1.0;
9294 : // the zone set point could be exceeded if set point control is used so protect against that
9295 2 : if (this->isSetPointControlled) {
9296 0 : if (state.dataLoopNodes->Node(this->coolCoilAirOutNode).Temp > this->coilTempSetPoint) {
9297 0 : return;
9298 : }
9299 : } else {
9300 2 : return;
9301 : }
9302 : } else {
9303 0 : PartLoadRatio = 0.0;
9304 0 : return;
9305 : }
9306 : }
9307 2342 : } else if ((VRFHeatingMode && !thisVRFCond.HeatRecoveryUsed) || (thisVRFCond.HeatRecoveryUsed && HRHeatingMode)) {
9308 : // Since we are heating, we expect FullOutput > NoCompOutput
9309 : // If the QZnReq >= FullOutput the unit needs to run full out
9310 2332 : if (QZnReq >= FullOutput) {
9311 : // if no coil present in terminal unit, no need reset PLR?
9312 3 : if (this->HeatingCoilPresent) {
9313 3 : PartLoadRatio = 1.0;
9314 : // the zone set point could be exceeded if set point control is used so protect against that
9315 3 : if (this->isSetPointControlled) {
9316 0 : if (state.dataLoopNodes->Node(this->heatCoilAirOutNode).Temp < this->coilTempSetPoint) {
9317 0 : return;
9318 : }
9319 : } else {
9320 3 : return;
9321 : }
9322 : } else {
9323 0 : PartLoadRatio = 0.0;
9324 0 : return;
9325 : }
9326 : }
9327 : } else {
9328 : // VRF terminal unit is off
9329 : // shouldn't actually get here
9330 10 : PartLoadRatio = 0.0;
9331 10 : return;
9332 : }
9333 :
9334 : // The coil will not operate at PLR=0 or PLR=1, calculate the operating part-load ratio
9335 :
9336 4643 : if ((VRFHeatingMode || HRHeatingMode) || ((VRFCoolingMode && DXCoolingCoilOprCtrl) || HRCoolingMode)) {
9337 :
9338 4643 : int NumOfSpeed = 1;
9339 4643 : if (this->NumOfSpeedHeating > 1 && ((VRFHeatingMode || HRHeatingMode))) {
9340 2324 : NumOfSpeed = this->NumOfSpeedHeating;
9341 : }
9342 4643 : if (this->NumOfSpeedCooling > 1 && ((VRFCoolingMode || HRCoolingMode))) {
9343 2306 : NumOfSpeed = this->NumOfSpeedCooling;
9344 : }
9345 :
9346 5827 : for (int SpeedNum = 1; SpeedNum <= NumOfSpeed; ++SpeedNum) {
9347 :
9348 5817 : if (NumOfSpeed > 1) {
9349 5804 : this->SpeedNum = SpeedNum;
9350 5804 : this->CalcVRF(state, VRFTUNum, FirstHVACIteration, 1.0, FullOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9351 5804 : if ((VRFHeatingMode || HRHeatingMode) && QZnReq >= FullOutput) {
9352 1164 : continue;
9353 : }
9354 5802 : if ((VRFCoolingMode || HRCoolingMode) && QZnReq <= FullOutput) {
9355 1162 : continue;
9356 : }
9357 : }
9358 :
9359 4653 : if (SpeedNum == 1) {
9360 3479 : this->SpeedRatio = 0.0;
9361 : }
9362 4653 : int SolFla = 0; // Flag of RegulaFalsi solver
9363 24832 : auto f = [&state, VRFTUNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio](Real64 const PartLoadRatio) {
9364 20179 : Real64 QZnReqTemp = QZnReq; // denominator representing zone load (W)
9365 : Real64 ActualOutput; // delivered capacity of VRF terminal unit
9366 20179 : Real64 SuppHeatCoilLoad = 0.0;
9367 20179 : bool setPointControlled = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isSetPointControlled;
9368 20179 : Real64 nonConstOnOffAirFlowRatio = OnOffAirFlowRatio;
9369 :
9370 20179 : if (state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum).VRFAlgorithmType ==
9371 : AlgorithmType::FluidTCtrl) {
9372 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9373 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
9374 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, ActualOutput, nonConstOnOffAirFlowRatio, SuppHeatCoilLoad);
9375 : } else {
9376 : // Algorithm Type: VRF model based on system curve
9377 20179 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
9378 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, ActualOutput, nonConstOnOffAirFlowRatio, SuppHeatCoilLoad);
9379 : }
9380 :
9381 20179 : if (setPointControlled) {
9382 10 : Real64 outletNodeT = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum).Temp;
9383 10 : return (outletNodeT - state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coilTempSetPoint);
9384 : } else {
9385 20169 : if (std::abs(QZnReq) < 100.0) {
9386 100 : QZnReqTemp = sign(100.0, QZnReq);
9387 : }
9388 20169 : return (ActualOutput - QZnReq) / QZnReqTemp;
9389 : }
9390 4653 : };
9391 4653 : General::SolveRoot(state, ErrorTol, MaxIte, SolFla, PartLoadRatio, f, 0.0, 1.0);
9392 4653 : if (SpeedNum == 1) {
9393 3479 : if (this->NumOfSpeedCooling > 1 || this->NumOfSpeedHeating > 1) {
9394 3466 : this->CycRatio = PartLoadRatio;
9395 : }
9396 3479 : this->SpeedRatio = 0.0;
9397 3479 : if (SolFla > 0 && PartLoadRatio <= 1.0) {
9398 4633 : break;
9399 : }
9400 : } else {
9401 1174 : this->CycRatio = 1.0;
9402 1174 : this->SpeedRatio = PartLoadRatio;
9403 1174 : if (SolFla > 0 && PartLoadRatio <= 1.0) {
9404 1164 : break;
9405 : }
9406 : }
9407 :
9408 20 : if (SolFla == -1) {
9409 : // Very low loads may not converge quickly. Tighten PLR boundary and try again.
9410 0 : TempMaxPLR = -0.1;
9411 0 : bool ContinueIter = true;
9412 0 : while (ContinueIter && TempMaxPLR < 1.0) {
9413 0 : TempMaxPLR += 0.1;
9414 :
9415 0 : if (thisVRFCond.VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
9416 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9417 0 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, TempMaxPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9418 : } else {
9419 : // Algorithm Type: VRF model based on system curve
9420 0 : this->CalcVRF(state, VRFTUNum, FirstHVACIteration, TempMaxPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9421 : }
9422 :
9423 0 : if (VRFHeatingMode && TempOutput > QZnReq) {
9424 0 : ContinueIter = false;
9425 : }
9426 0 : if (VRFCoolingMode && TempOutput < QZnReq) {
9427 0 : ContinueIter = false;
9428 : }
9429 : }
9430 0 : TempMinPLR = TempMaxPLR;
9431 0 : ContinueIter = true;
9432 0 : while (ContinueIter && TempMinPLR > 0.0) {
9433 0 : TempMaxPLR = TempMinPLR;
9434 0 : TempMinPLR -= 0.01;
9435 :
9436 0 : if (thisVRFCond.VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
9437 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9438 0 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, TempMinPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9439 : } else {
9440 : // Algorithm Type: VRF model based on system curve
9441 0 : this->CalcVRF(state, VRFTUNum, FirstHVACIteration, TempMinPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9442 : }
9443 :
9444 0 : if (VRFHeatingMode && TempOutput < QZnReq) {
9445 0 : ContinueIter = false;
9446 : }
9447 0 : if (VRFCoolingMode && TempOutput > QZnReq) {
9448 0 : ContinueIter = false;
9449 : }
9450 : }
9451 0 : General::SolveRoot(state, ErrorTol, MaxIte, SolFla, PartLoadRatio, f, TempMinPLR, TempMaxPLR);
9452 0 : if (SolFla == -1) {
9453 0 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
9454 0 : if (this->IterLimitExceeded == 0) {
9455 0 : ShowWarningMessage(state, format("{} \"{}\"", tuTypeNames[(int)this->type], this->Name));
9456 0 : ShowContinueError(
9457 : state,
9458 0 : format(" Iteration limit exceeded calculating terminal unit part-load ratio, maximum iterations = {}", MaxIte));
9459 0 : ShowContinueErrorTimeStamp(state, format(" Part-load ratio returned = {:.3R}", PartLoadRatio));
9460 :
9461 0 : if (thisVRFCond.VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
9462 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
9463 0 : this->CalcVRF_FluidTCtrl(
9464 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9465 : } else {
9466 : // Algorithm Type: VRF model based on system curve
9467 0 : this->CalcVRF(state, VRFTUNum, FirstHVACIteration, PartLoadRatio, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
9468 : }
9469 :
9470 0 : ShowContinueError(state, format(" Load requested = {:.5T}, Load delivered = {:.5T}", QZnReq, TempOutput));
9471 0 : ShowRecurringWarningErrorAtEnd(state,
9472 0 : format("{} \"{}\" -- Terminal unit Iteration limit exceeded error continues...",
9473 0 : tuTypeNames[(int)this->type],
9474 0 : this->Name),
9475 0 : this->IterLimitExceeded);
9476 : } else {
9477 0 : ShowRecurringWarningErrorAtEnd(state,
9478 0 : format("{} \"{}\" -- Terminal unit Iteration limit exceeded error continues...",
9479 0 : tuTypeNames[(int)this->type],
9480 0 : this->Name),
9481 0 : this->IterLimitExceeded);
9482 : }
9483 : }
9484 0 : } else if (SolFla == -2) {
9485 0 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
9486 0 : if (thisVRFTU.FirstIterfailed == 0) {
9487 0 : ShowWarningMessage(state, format("{} \"{}\"", tuTypeNames[(int)this->type], this->Name));
9488 0 : ShowContinueError(state, "Terminal unit part-load ratio calculation failed: PLR limits of 0 to 1 exceeded");
9489 0 : ShowContinueError(state, "Please fill out a bug report and forward to the EnergyPlus support group.");
9490 0 : ShowContinueErrorTimeStamp(state, "");
9491 0 : ShowRecurringWarningErrorAtEnd(
9492 : state,
9493 0 : format("{} \"{}\" -- Terminal unit part-load ratio limits of 0 to 1 exceeded error continues...",
9494 0 : tuTypeNames[(int)this->type],
9495 0 : this->Name),
9496 0 : this->FirstIterfailed);
9497 : } else {
9498 0 : ShowRecurringWarningErrorAtEnd(
9499 : state,
9500 0 : format("{} \"{}\" -- Terminal unit part-load ratio limits of 0 to 1 exceeded error continues...",
9501 0 : tuTypeNames[(int)this->type],
9502 0 : this->Name),
9503 0 : thisVRFTU.FirstIterfailed);
9504 : }
9505 : }
9506 0 : PartLoadRatio = max(MinPLF, std::abs(QZnReq - NoCompOutput) / std::abs(FullOutput - NoCompOutput));
9507 : }
9508 20 : } else if (SolFla == -2) {
9509 20 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
9510 0 : if (thisVRFTU.FirstIterfailed == 0) {
9511 0 : ShowWarningMessage(state, format("{} \"{}\"", tuTypeNames[(int)this->type], this->Name));
9512 :
9513 0 : ShowContinueError(state, "Terminal unit part-load ratio calculation failed: PLR limits of 0 to 1 exceeded");
9514 0 : ShowContinueError(state, "Please fill out a bug report and forward to the EnergyPlus support group.");
9515 0 : ShowContinueErrorTimeStamp(state, "");
9516 0 : ShowRecurringWarningErrorAtEnd(
9517 : state,
9518 0 : format("{} \"{}\" -- Terminal unit part-load ratio limits of 0 to 1 exceeded error continues...",
9519 0 : tuTypeNames[(int)this->type],
9520 0 : " \"" + this->Name),
9521 0 : this->FirstIterfailed);
9522 : } else {
9523 0 : ShowRecurringWarningErrorAtEnd(
9524 : state,
9525 0 : format("{} \"{}\" -- Terminal unit part-load ratio limits of 0 to 1 exceeded error continues...",
9526 0 : tuTypeNames[(int)this->type],
9527 0 : this->Name),
9528 0 : this->FirstIterfailed);
9529 : }
9530 : }
9531 20 : if (FullOutput - NoCompOutput == 0.0) {
9532 0 : PartLoadRatio = 0.0;
9533 : } else {
9534 20 : PartLoadRatio = min(1.0, max(MinPLF, std::abs(QZnReq - NoCompOutput) / std::abs(FullOutput - NoCompOutput)));
9535 : }
9536 : }
9537 : }
9538 : }
9539 : }
9540 :
9541 49492 : void VRFTerminalUnitEquipment::CalcVRF(EnergyPlusData &state,
9542 : int const VRFTUNum, // Unit index in VRF terminal unit array
9543 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
9544 : Real64 const PartLoadRatio, // compressor part load fraction
9545 : Real64 &LoadMet, // load met by unit (W)
9546 : Real64 &OnOffAirFlowRatio, // ratio of ON air flow to average air flow
9547 : Real64 &SuppHeatCoilLoad, // supplemental heating coil load (W)
9548 : ObjexxFCL::Optional<Real64> LatOutputProvided // delivered latent capacity (kgWater/s)
9549 : )
9550 : {
9551 :
9552 : // SUBROUTINE INFORMATION:
9553 : // AUTHOR Richard Raustad
9554 : // DATE WRITTEN July 2005
9555 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
9556 : // RE-ENGINEERED na
9557 :
9558 : // PURPOSE OF THIS SUBROUTINE:
9559 : // Simulate the components making up the VRF terminal unit.
9560 :
9561 : // METHODOLOGY EMPLOYED:
9562 : // Simulates the unit components sequentially in the air flow direction.
9563 :
9564 : using DXCoils::SimDXCoil;
9565 : using SingleDuct::SimATMixer;
9566 : using SteamCoils::SimulateSteamCoilComponents;
9567 : using WaterCoils::SimulateWaterCoilComponents;
9568 :
9569 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9570 : int VRFTUOutletNodeNum; // TU air outlet node
9571 : int VRFTUInletNodeNum; // TU air inlet node
9572 : Real64 AirMassFlow; // total supply air mass flow [m3/s]
9573 : HVAC::FanOp fanOp; // fan operating mode, HVAC::FanOp::Cycling or HVAC::FanOp::Continuous
9574 : int VRFCond; // index to VRF condenser
9575 49492 : Real64 SpecHumOut(0.0); // specific humidity ratio at outlet node
9576 49492 : Real64 SpecHumIn(0.0); // specific humidity ratio at inlet node
9577 : int TUListIndex; // index to TU list for this VRF system
9578 : int IndexToTUInTUList; // index to TU in specific list for the VRF system
9579 : int ZoneNode; // Zone node of VRFTU is serving
9580 :
9581 49492 : VRFCond = this->VRFSysNum;
9582 49492 : TUListIndex = state.dataHVACVarRefFlow->VRF(VRFCond).ZoneTUListPtr;
9583 49492 : IndexToTUInTUList = this->IndexToTUInTUList;
9584 49492 : VRFTUOutletNodeNum = this->VRFTUOutletNodeNum;
9585 49492 : VRFTUInletNodeNum = this->VRFTUInletNodeNum;
9586 49492 : fanOp = this->fanOp;
9587 49492 : ZoneNode = this->ZoneAirNode;
9588 :
9589 : // Set inlet air mass flow rate based on PLR and compressor on/off air flow rates
9590 49492 : SetAverageAirFlow(state, VRFTUNum, PartLoadRatio, OnOffAirFlowRatio);
9591 :
9592 49492 : AirMassFlow = state.dataLoopNodes->Node(VRFTUInletNodeNum).MassFlowRate;
9593 49492 : if (this->ATMixerExists) {
9594 : // There is an air terminal mixer
9595 16 : state.dataHVACVarRefFlow->ATMixOutNode = this->ATMixerOutNode;
9596 16 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
9597 : // set the primary air inlet mass flow rate
9598 8 : state.dataLoopNodes->Node(this->ATMixerPriNode).MassFlowRate =
9599 8 : min(state.dataLoopNodes->Node(this->ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(VRFTUInletNodeNum).MassFlowRate);
9600 : // now calculate the the mixer outlet air conditions (and the secondary air inlet flow rate). The mixer outlet flow rate has already
9601 : // been set above (it is the "inlet" node flow rate)
9602 8 : SimATMixer(state, this->ATMixerName, FirstHVACIteration, this->ATMixerIndex);
9603 : }
9604 : } else {
9605 : // ATMixOutNode = 0;
9606 49476 : if (this->OAMixerUsed) {
9607 49476 : MixedAir::SimOAMixer(state, this->OAMixerName, this->OAMixerIndex);
9608 : }
9609 : }
9610 : // if blow through, simulate fan then coils
9611 49492 : if (this->fanPlace == HVAC::FanPlace::BlowThru) {
9612 2 : if (this->fanType == HVAC::FanType::SystemModel) {
9613 0 : if (OnOffAirFlowRatio > 0.0) {
9614 0 : state.dataFans->fans(this->FanIndex)->simulate(state, FirstHVACIteration, _, _);
9615 : } else {
9616 0 : state.dataFans->fans(this->FanIndex)->simulate(state, FirstHVACIteration, _, _, PartLoadRatio);
9617 : }
9618 : } else {
9619 2 : state.dataFans->fans(this->FanIndex)->simulate(state, FirstHVACIteration, state.dataHVACVarRefFlow->FanSpeedRatio);
9620 : }
9621 : }
9622 :
9623 49492 : if (this->CoolingCoilPresent) {
9624 : // above condition for heat pump mode, below condition for heat recovery mode
9625 73068 : if ((!state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed && state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) ||
9626 23576 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
9627 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList))) {
9628 51832 : SimDXCoil(state,
9629 : "",
9630 : HVAC::CompressorOp::On,
9631 : FirstHVACIteration,
9632 25916 : this->CoolCoilIndex,
9633 : fanOp,
9634 : PartLoadRatio,
9635 : OnOffAirFlowRatio,
9636 : _,
9637 25916 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond),
9638 25916 : state.dataHVACVarRefFlow->VRF(this->VRFSysNum).VRFCondCyclingRatio);
9639 : } else { // cooling coil is off
9640 23576 : SimDXCoil(state, "", HVAC::CompressorOp::Off, FirstHVACIteration, this->CoolCoilIndex, fanOp, 0.0, OnOffAirFlowRatio);
9641 : }
9642 49492 : state.dataHVACVarRefFlow->LoopDXCoolCoilRTF = state.dataAirLoop->LoopDXCoilRTF;
9643 : } else {
9644 0 : state.dataHVACVarRefFlow->LoopDXCoolCoilRTF = 0.0;
9645 : }
9646 :
9647 49492 : if (this->HeatingCoilPresent) {
9648 : // above condition for heat pump mode, below condition for heat recovery mode
9649 80320 : if ((!state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) ||
9650 30828 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
9651 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList))) {
9652 55992 : SimDXCoil(state,
9653 : "",
9654 : HVAC::CompressorOp::Off,
9655 : FirstHVACIteration,
9656 18664 : this->HeatCoilIndex,
9657 : fanOp,
9658 : PartLoadRatio,
9659 : OnOffAirFlowRatio,
9660 : _,
9661 18664 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
9662 : } else {
9663 30828 : SimDXCoil(state, "", HVAC::CompressorOp::Off, FirstHVACIteration, this->HeatCoilIndex, fanOp, 0.0, OnOffAirFlowRatio, _);
9664 : }
9665 49492 : state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = state.dataAirLoop->LoopDXCoilRTF;
9666 : } else {
9667 0 : state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = 0.0;
9668 : }
9669 :
9670 : // if draw through, simulate coils then fan
9671 49492 : if (this->fanPlace == HVAC::FanPlace::DrawThru) {
9672 49430 : if (this->fanType == HVAC::FanType::SystemModel) {
9673 49310 : if (OnOffAirFlowRatio > 0.0) {
9674 44656 : state.dataFans->fans(this->FanIndex)->simulate(state, FirstHVACIteration, _, _);
9675 : } else {
9676 4654 : state.dataFans->fans(this->FanIndex)->simulate(state, FirstHVACIteration, _, _, PartLoadRatio);
9677 : }
9678 :
9679 : } else {
9680 120 : state.dataFans->fans(this->FanIndex)->simulate(state, FirstHVACIteration, state.dataHVACVarRefFlow->FanSpeedRatio);
9681 : }
9682 : }
9683 :
9684 : // track fan power per terminal unit for calculating COP
9685 49492 : this->FanPower = (this->FanIndex == 0) ? 0.0 : state.dataFans->fans(this->FanIndex)->totalPower;
9686 :
9687 : // run supplemental heating coil
9688 49492 : if (this->SuppHeatingCoilPresent) {
9689 0 : Real64 SuppPLR = this->SuppHeatPartLoadRatio;
9690 0 : this->CalcVRFSuppHeatingCoil(state, VRFTUNum, FirstHVACIteration, SuppPLR, SuppHeatCoilLoad);
9691 0 : if ((state.dataLoopNodes->Node(this->SuppHeatCoilAirOutletNode).Temp > this->MaxSATFromSuppHeatCoil) && SuppPLR > 0.0) {
9692 : // adjust the heating load to maximum allowed
9693 0 : Real64 MaxHeatCoilLoad = this->HeatingCoilCapacityLimit(state, this->SuppHeatCoilAirInletNode, this->MaxSATFromSuppHeatCoil);
9694 0 : this->CalcVRFSuppHeatingCoil(state, VRFTUNum, FirstHVACIteration, SuppPLR, MaxHeatCoilLoad);
9695 0 : SuppHeatCoilLoad = MaxHeatCoilLoad;
9696 : }
9697 : }
9698 :
9699 49492 : Real64 LatentLoadMet = 0.0; // latent load delivered [kgWater/s]
9700 49492 : Real64 TempOut = 0.0;
9701 49492 : Real64 TempIn = 0.0;
9702 49492 : if (this->ATMixerExists) {
9703 16 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
9704 : // Air terminal supply side mixer, calculate supply side mixer output
9705 8 : SimATMixer(state, this->ATMixerName, FirstHVACIteration, this->ATMixerIndex);
9706 8 : TempOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->ATMixOutNode).Temp;
9707 8 : SpecHumOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->ATMixOutNode).HumRat;
9708 8 : AirMassFlow = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->ATMixOutNode).MassFlowRate;
9709 : } else {
9710 : // Air terminal inlet side mixer
9711 8 : TempOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).Temp;
9712 8 : SpecHumOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).HumRat;
9713 : }
9714 16 : TempIn = state.dataLoopNodes->Node(ZoneNode).Temp;
9715 16 : SpecHumIn = state.dataLoopNodes->Node(ZoneNode).HumRat;
9716 : } else {
9717 49476 : TempOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).Temp;
9718 49476 : SpecHumOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).HumRat;
9719 49476 : if (ZoneNode > 0) {
9720 49446 : TempIn = state.dataLoopNodes->Node(ZoneNode).Temp;
9721 49446 : SpecHumIn = state.dataLoopNodes->Node(ZoneNode).HumRat;
9722 : } else {
9723 30 : TempIn = state.dataLoopNodes->Node(VRFTUInletNodeNum).Temp;
9724 30 : SpecHumIn = state.dataLoopNodes->Node(VRFTUInletNodeNum).HumRat;
9725 : }
9726 : }
9727 : // calculate sensible load met using delta enthalpy
9728 49492 : Real64 TotalOutput = AirMassFlow * (Psychrometrics::PsyHFnTdbW(TempOut, SpecHumOut) -
9729 49492 : Psychrometrics::PsyHFnTdbW(TempIn, SpecHumIn)); // total addition/removal rate, {W};
9730 49492 : LoadMet = AirMassFlow * PsyDeltaHSenFnTdb2W2Tdb1W1(TempOut, SpecHumOut, TempIn, SpecHumIn); // sensible {W}
9731 49492 : LatentLoadMet = TotalOutput - LoadMet;
9732 49492 : if (present(LatOutputProvided)) {
9733 : // CR9155 Remove specific humidity calculations
9734 4740 : LatOutputProvided = LatentLoadMet;
9735 : }
9736 49492 : }
9737 :
9738 7091 : void ReportVRFTerminalUnit(EnergyPlusData &state, int const VRFTUNum) // index to VRF terminal unit
9739 : {
9740 :
9741 : // SUBROUTINE INFORMATION:
9742 : // AUTHOR Richard Raustad, FSEC
9743 : // DATE WRITTEN August 2010
9744 : // MODIFIED na
9745 : // RE-ENGINEERED na
9746 :
9747 : // PURPOSE OF THIS SUBROUTINE:
9748 : // This subroutine updates the report variables for the VRF Terminal Units.
9749 :
9750 : using namespace DataSizing;
9751 :
9752 : Real64 TotalConditioning; // - sum of sensible and latent rates
9753 : Real64 SensibleConditioning; // - sensible rate
9754 : Real64 LatentConditioning; // - latent rate
9755 : Real64 ReportingConstant; // - used to convert watts to joules
9756 : int VRFCond; // - index to VRF condenser
9757 : int TUListIndex; // - index to terminal unit list
9758 : int IndexToTUInTUList; // - index to the TU in the list
9759 : bool HRHeatRequestFlag; // - indicates TU could be in heat mode
9760 : bool HRCoolRequestFlag; // - indicates TU could be in cool mode
9761 :
9762 7091 : VRFCond = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum;
9763 7091 : TUListIndex = state.dataHVACVarRefFlow->VRF(VRFCond).ZoneTUListPtr;
9764 7091 : IndexToTUInTUList = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).IndexToTUInTUList;
9765 7091 : HRHeatRequestFlag = state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList);
9766 7091 : HRCoolRequestFlag = state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList);
9767 7091 : ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
9768 :
9769 : // account for terminal unit parasitic On/Off power use
9770 : // account for heat recovery first since these flags will be FALSE otherwise, each TU may have different operating mode
9771 :
9772 7091 : if (HRCoolRequestFlag) {
9773 1 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingCoilPresent) {
9774 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower =
9775 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElec * state.dataHVACVarRefFlow->LoopDXCoolCoilRTF +
9776 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec * (1.0 - state.dataHVACVarRefFlow->LoopDXCoolCoilRTF);
9777 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption =
9778 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower * ReportingConstant;
9779 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower = 0.0;
9780 1 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption = 0.0;
9781 : } else {
9782 : // cooling parasitic power report variable is not even available when there is no cooling coil, report for heating
9783 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec;
9784 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption =
9785 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower * ReportingConstant;
9786 : }
9787 7090 : } else if (HRHeatRequestFlag) {
9788 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingCoilPresent) {
9789 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower = 0.0;
9790 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption = 0.0;
9791 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower =
9792 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElec * state.dataHVACVarRefFlow->LoopDXHeatCoilRTF +
9793 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec * (1.0 - state.dataHVACVarRefFlow->LoopDXHeatCoilRTF);
9794 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption =
9795 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower * ReportingConstant;
9796 : } else {
9797 : // heating parasitic power report variable is not even available when there is no heating coil, report for cooling
9798 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec;
9799 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption =
9800 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower * ReportingConstant;
9801 : }
9802 10700 : } else if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) ||
9803 3610 : (!state.dataHVACVarRefFlow->HeatingLoad(VRFCond) &&
9804 125 : state.dataHVACVarRefFlow->LastModeCooling(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum))) {
9805 3516 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingCoilPresent) {
9806 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower =
9807 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElec * state.dataHVACVarRefFlow->LoopDXCoolCoilRTF +
9808 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec * (1.0 - state.dataHVACVarRefFlow->LoopDXCoolCoilRTF);
9809 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption =
9810 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower * ReportingConstant;
9811 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower = 0.0;
9812 3516 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption = 0.0;
9813 : } else {
9814 : // cooling parasitic power report variable is not even available when there is no cooling coil, report for heating
9815 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec;
9816 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption =
9817 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower * ReportingConstant;
9818 : }
9819 3663 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) ||
9820 89 : (!state.dataHVACVarRefFlow->CoolingLoad(VRFCond) &&
9821 89 : state.dataHVACVarRefFlow->LastModeHeating(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum))) {
9822 3574 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingCoilPresent) {
9823 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower = 0.0;
9824 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption = 0.0;
9825 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower =
9826 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElec * state.dataHVACVarRefFlow->LoopDXHeatCoilRTF +
9827 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec * (1.0 - state.dataHVACVarRefFlow->LoopDXHeatCoilRTF);
9828 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption =
9829 3574 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower * ReportingConstant;
9830 : } else {
9831 : // heating parasitic power report variable is not even available when there is no heating coil, report for cooling
9832 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec;
9833 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption =
9834 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower * ReportingConstant;
9835 : }
9836 : } else {
9837 : // happens when there is no cooling or heating load
9838 0 : if (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CoolingCoilPresent) {
9839 : // report all for heating
9840 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec;
9841 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption =
9842 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower * ReportingConstant;
9843 0 : } else if (!state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HeatingCoilPresent) {
9844 : // report all for cooling
9845 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec;
9846 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption =
9847 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower * ReportingConstant;
9848 : } else {
9849 : // split parasitic between both reporting variables
9850 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec / 2.0;
9851 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecCoolConsumption =
9852 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticCoolElecPower * ReportingConstant;
9853 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticOffElec / 2.0;
9854 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticElecHeatConsumption =
9855 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ParasiticHeatElecPower * ReportingConstant;
9856 : }
9857 : }
9858 :
9859 7091 : SensibleConditioning = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TerminalUnitSensibleRate;
9860 7091 : LatentConditioning = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TerminalUnitLatentRate;
9861 7091 : Real64 TempOut = 0.0;
9862 7091 : Real64 TempIn = 0.0;
9863 7091 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerExists) {
9864 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerType == HVAC::MixerType::SupplySide) {
9865 : // Air terminal supply side mixer
9866 0 : TempOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ATMixerOutNode).Temp;
9867 0 : TempIn = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneAirNode).Temp;
9868 : } else {
9869 : // Air terminal inlet side mixer
9870 0 : TempOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum).Temp;
9871 0 : TempIn = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneAirNode).Temp;
9872 : }
9873 : } else {
9874 7091 : TempOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum).Temp;
9875 7091 : TempIn = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum).Temp;
9876 : }
9877 7091 : TotalConditioning = SensibleConditioning + LatentConditioning;
9878 :
9879 7091 : if (TotalConditioning <= 0.0) {
9880 3567 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalCoolingRate = std::abs(TotalConditioning);
9881 3567 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalHeatingRate = 0.0;
9882 : } else {
9883 3524 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalCoolingRate = 0.0;
9884 3524 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalHeatingRate = TotalConditioning;
9885 : }
9886 7091 : if (SensibleConditioning <= 0.0) {
9887 3568 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleCoolingRate = std::abs(SensibleConditioning);
9888 3568 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleHeatingRate = 0.0;
9889 : } else {
9890 3523 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleCoolingRate = 0.0;
9891 3523 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleHeatingRate = SensibleConditioning;
9892 : }
9893 7091 : if (LatentConditioning <= 0.0) {
9894 4426 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentCoolingRate = std::abs(LatentConditioning);
9895 4426 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentHeatingRate = 0.0;
9896 : } else {
9897 2665 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentCoolingRate = 0.0;
9898 2665 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentHeatingRate = LatentConditioning;
9899 : }
9900 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalCoolingEnergy = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalCoolingRate * ReportingConstant;
9901 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleCoolingEnergy =
9902 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleCoolingRate * ReportingConstant;
9903 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentCoolingEnergy = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentCoolingRate * ReportingConstant;
9904 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalHeatingEnergy = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalHeatingRate * ReportingConstant;
9905 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleHeatingEnergy =
9906 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SensibleHeatingRate * ReportingConstant;
9907 7091 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentHeatingEnergy = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).LatentHeatingRate * ReportingConstant;
9908 :
9909 7091 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).firstPass) {
9910 15 : if (!state.dataHVACVarRefFlow->MySizeFlag(VRFTUNum)) {
9911 12 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, 0, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).firstPass);
9912 : }
9913 : }
9914 :
9915 : // reset to 1 in case blow through fan configuration (fan resets to 1, but for blow thru fans coil sets back down < 1)
9916 7091 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
9917 7091 : }
9918 :
9919 7087 : void ReportVRFCondenser(EnergyPlusData &state, int const VRFCond) // index to VRF condensing unit
9920 : {
9921 :
9922 : // SUBROUTINE INFORMATION:
9923 : // AUTHOR Richard Raustad, FSEC
9924 : // DATE WRITTEN August 2010
9925 : // MODIFIED na
9926 : // RE-ENGINEERED na
9927 :
9928 : // PURPOSE OF THIS SUBROUTINE:
9929 : // This subroutine updates the report variables for the VRF Condenser.
9930 :
9931 : Real64 ReportingConstant; // - conversion constant for energy
9932 :
9933 7087 : ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
9934 :
9935 : // calculate VRF condenser power/energy use
9936 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).CoolElecConsumption = state.dataHVACVarRefFlow->VRF(VRFCond).ElecCoolingPower * ReportingConstant;
9937 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).HeatElecConsumption = state.dataHVACVarRefFlow->VRF(VRFCond).ElecHeatingPower * ReportingConstant;
9938 :
9939 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).DefrostConsumption = state.dataHVACVarRefFlow->VRF(VRFCond).DefrostPower * ReportingConstant;
9940 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).BasinHeaterConsumption = state.dataHVACVarRefFlow->VRF(VRFCond).BasinHeaterPower * ReportingConstant;
9941 :
9942 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondPumpElecConsumption =
9943 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).EvapCondPumpElecPower * ReportingConstant;
9944 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).CrankCaseHeaterElecConsumption =
9945 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).CrankCaseHeaterPower * ReportingConstant;
9946 :
9947 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).QCondEnergy = state.dataHVACVarRefFlow->VRF(VRFCond).QCondenser * ReportingConstant;
9948 7087 : state.dataHVACVarRefFlow->VRF(VRFCond).VRFHeatEnergyRec = state.dataHVACVarRefFlow->VRF(VRFCond).VRFHeatRec * ReportingConstant;
9949 7087 : }
9950 :
9951 5 : void UpdateVRFCondenser(EnergyPlusData &state, int const VRFCond) // index to VRF condensing unit
9952 : {
9953 :
9954 : // SUBROUTINE INFORMATION:
9955 : // AUTHOR Richard Raustad, FSEC
9956 : // DATE WRITTEN May 2012
9957 : // MODIFIED na
9958 : // RE-ENGINEERED na
9959 :
9960 : // PURPOSE OF THIS SUBROUTINE:
9961 : // This subroutine updates the node data for the VRF Condenser.
9962 :
9963 : int CondenserOutletNode; // - outlet node for VRF water-cooled condenser
9964 :
9965 5 : CondenserOutletNode = state.dataHVACVarRefFlow->VRF(VRFCond).CondenserOutletNodeNum;
9966 :
9967 5 : state.dataLoopNodes->Node(CondenserOutletNode).Temp = state.dataHVACVarRefFlow->VRF(VRFCond).CondenserSideOutletTemp;
9968 :
9969 5 : state.dataLoopNodes->Node(CondenserOutletNode).MassFlowRate = state.dataHVACVarRefFlow->CondenserWaterMassFlowRate;
9970 5 : state.dataLoopNodes->Node(CondenserOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(CondenserOutletNode).MassFlowRateMaxAvail;
9971 5 : state.dataLoopNodes->Node(CondenserOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(CondenserOutletNode).MassFlowRateMinAvail;
9972 5 : }
9973 :
9974 0 : void isVRFCoilPresent(EnergyPlusData &state, std::string_view VRFTUName, bool &CoolCoilPresent, bool &HeatCoilPresent)
9975 : {
9976 :
9977 0 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
9978 0 : GetVRFInput(state);
9979 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
9980 : }
9981 :
9982 : int WhichVRFTU =
9983 0 : Util::FindItemInList(VRFTUName, state.dataHVACVarRefFlow->VRFTU, &VRFTerminalUnitEquipment::Name, state.dataHVACVarRefFlow->NumVRFTU);
9984 0 : if (WhichVRFTU != 0) {
9985 0 : CoolCoilPresent = state.dataHVACVarRefFlow->VRFTU(WhichVRFTU).CoolingCoilPresent;
9986 0 : HeatCoilPresent = state.dataHVACVarRefFlow->VRFTU(WhichVRFTU).HeatingCoilPresent;
9987 : } else {
9988 0 : ShowSevereError(state, format("isVRFCoilPresent: Could not find VRF TU = \"{}\"", VRFTUName));
9989 : }
9990 0 : }
9991 :
9992 : // End of Reporting subroutines for the Module
9993 : // *****************************************************************************
9994 :
9995 : // Utility subroutines for the Module
9996 :
9997 151813 : void SetAverageAirFlow(EnergyPlusData &state,
9998 : int const VRFTUNum, // Unit index
9999 : Real64 const PartLoadRatio, // unit part load ratio
10000 : Real64 &OnOffAirFlowRatio // ratio of compressor ON airflow to average airflow over timestep
10001 : )
10002 : {
10003 :
10004 : // SUBROUTINE INFORMATION:
10005 : // AUTHOR Richard Raustad
10006 : // DATE WRITTEN August 2010
10007 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
10008 : // RE-ENGINEERED na
10009 :
10010 : // PURPOSE OF THIS SUBROUTINE:
10011 : // Set the average air mass flow rates using the part load fraction of the heat pump for this time step
10012 : // Set OnOffAirFlowRatio to be used by DX coils
10013 151813 : auto &s_vrf = state.dataHVACVarRefFlow;
10014 151813 : auto &vrfTu = s_vrf->VRFTU(VRFTUNum);
10015 :
10016 : int InletNode; // inlet node number
10017 : int OutsideAirNode; // outside air node number
10018 : int AirRelNode; // relief air node number
10019 151813 : Real64 AverageUnitMassFlow(0.0); // average supply air mass flow rate over time step
10020 151813 : Real64 AverageOAMassFlow(0.0); // average outdoor air mass flow rate over time step
10021 :
10022 151813 : InletNode = vrfTu.VRFTUInletNodeNum;
10023 151813 : OutsideAirNode = vrfTu.VRFTUOAMixerOANodeNum;
10024 151813 : AirRelNode = vrfTu.VRFTUOAMixerRelNodeNum;
10025 :
10026 151813 : if (vrfTu.fanOp == HVAC::FanOp::Cycling && vrfTu.SpeedNum == 0) {
10027 97646 : Real64 partLoadRat = PartLoadRatio;
10028 97646 : if (partLoadRat == 0.0 && vrfTu.SuppHeatPartLoadRatio > 0.0) {
10029 2 : partLoadRat = vrfTu.SuppHeatPartLoadRatio;
10030 : }
10031 97646 : AverageUnitMassFlow = (partLoadRat * s_vrf->CompOnMassFlow) + ((1 - partLoadRat) * s_vrf->CompOffMassFlow);
10032 97646 : AverageOAMassFlow = (partLoadRat * s_vrf->OACompOnMassFlow) + ((1 - partLoadRat) * s_vrf->OACompOffMassFlow);
10033 151813 : } else if (vrfTu.SpeedNum == 0) {
10034 9747 : if (PartLoadRatio == 0.0) {
10035 : // set the average OA air flow to off compressor values if the compressor PartLoadRatio is zero
10036 5024 : AverageUnitMassFlow = s_vrf->CompOffMassFlow;
10037 5024 : AverageOAMassFlow = s_vrf->OACompOffMassFlow;
10038 : } else {
10039 4723 : AverageUnitMassFlow = s_vrf->CompOnMassFlow;
10040 4723 : AverageOAMassFlow = s_vrf->OACompOnMassFlow;
10041 : }
10042 44420 : } else if (vrfTu.SpeedNum == 1) {
10043 29256 : if (s_vrf->CoolingLoad(vrfTu.VRFSysNum)) {
10044 11880 : AverageUnitMassFlow = vrfTu.CoolMassFlowRate[vrfTu.SpeedNum] * PartLoadRatio + (1.0 - PartLoadRatio) * s_vrf->CompOffMassFlow;
10045 17376 : } else if (s_vrf->HeatingLoad(vrfTu.VRFSysNum)) {
10046 13916 : AverageUnitMassFlow = vrfTu.HeatMassFlowRate[vrfTu.SpeedNum] * PartLoadRatio + (1.0 - PartLoadRatio) * s_vrf->CompOffMassFlow;
10047 : }
10048 15164 : } else if (s_vrf->CoolingLoad(vrfTu.VRFSysNum)) {
10049 11626 : AverageUnitMassFlow =
10050 11626 : vrfTu.CoolMassFlowRate[vrfTu.SpeedNum] * PartLoadRatio + (1.0 - PartLoadRatio) * vrfTu.CoolMassFlowRate[vrfTu.SpeedNum - 1];
10051 3538 : } else if (s_vrf->HeatingLoad(vrfTu.VRFSysNum)) {
10052 2354 : AverageUnitMassFlow =
10053 2354 : vrfTu.HeatMassFlowRate[vrfTu.SpeedNum] * PartLoadRatio + (1.0 - PartLoadRatio) * vrfTu.HeatMassFlowRate[vrfTu.SpeedNum - 1];
10054 : }
10055 :
10056 151813 : if (vrfTu.SpeedNum == 0) {
10057 107393 : if (s_vrf->CompOffFlowRatio > 0.0) {
10058 9637 : s_vrf->FanSpeedRatio = (PartLoadRatio * s_vrf->CompOnFlowRatio) + ((1 - PartLoadRatio) * s_vrf->CompOffFlowRatio);
10059 : } else {
10060 97756 : s_vrf->FanSpeedRatio = s_vrf->CompOnFlowRatio;
10061 : }
10062 : }
10063 :
10064 : // if the terminal unit and fan are scheduled on then set flow rate
10065 303625 : if (vrfTu.availSched->getCurrentVal() > 0.0 && (vrfTu.fanAvailSched->getCurrentVal() > 0.0 || state.dataHVACGlobal->TurnFansOn) &&
10066 151812 : !state.dataHVACGlobal->TurnFansOff) {
10067 :
10068 : // so for sure OA system TUs should use inlet node flow rate, don't overwrite inlet node flow rate
10069 : // could there be a reason for air loops to use inlet node flow? Possibly when VAV TUs used?
10070 151811 : if (!vrfTu.isInOASys) {
10071 151811 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
10072 : }
10073 151811 : if (!vrfTu.isInOASys) {
10074 151811 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AverageUnitMassFlow;
10075 : }
10076 151811 : if (OutsideAirNode > 0) {
10077 151675 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = AverageOAMassFlow;
10078 151675 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = AverageOAMassFlow;
10079 151675 : state.dataLoopNodes->Node(AirRelNode).MassFlowRate = AverageOAMassFlow;
10080 151675 : state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = AverageOAMassFlow;
10081 : }
10082 151811 : if (AverageUnitMassFlow > 0.0) {
10083 139957 : OnOffAirFlowRatio = s_vrf->CompOnMassFlow / AverageUnitMassFlow;
10084 : } else {
10085 11854 : OnOffAirFlowRatio = 0.0;
10086 : }
10087 :
10088 : } else { // terminal unit and/or fan is off
10089 2 : if (!vrfTu.isInOASys) {
10090 2 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
10091 2 : OnOffAirFlowRatio = 0.0;
10092 : }
10093 2 : if (OutsideAirNode > 0) {
10094 2 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = 0.0;
10095 2 : state.dataLoopNodes->Node(AirRelNode).MassFlowRate = 0.0;
10096 : }
10097 : }
10098 151813 : }
10099 :
10100 7115 : void InitializeOperatingMode(EnergyPlusData &state,
10101 : bool const FirstHVACIteration, // flag for first time through HVAC systems
10102 : int const VRFCond, // Condenser Unit index
10103 : int const TUListNum, // Condenser Unit terminal unit list
10104 : Real64 &OnOffAirFlowRatio // ratio of on to off flow rate
10105 : )
10106 : {
10107 :
10108 : // SUBROUTINE INFORMATION:
10109 : // AUTHOR Richard Raustad
10110 : // DATE WRITTEN July 2012 (Moved from InitVRF)
10111 : // MODIFIED na
10112 : // RE-ENGINEERED na
10113 :
10114 : // PURPOSE OF THIS SUBROUTINE:
10115 : // Scans each zone coil and determines the load based on control
10116 : // Moved from Init to clean up and localize code segments
10117 :
10118 : Real64 ZoneDeltaT; // zone temperature difference from setpoint
10119 : Real64 SPTempHi; // thermostat setpoint high
10120 : Real64 SPTempLo; // thermostat setpoint low
10121 : int NumTU; // loop counter, number of TU's in list
10122 : Real64 ZoneLoad; // current zone load (W)
10123 : Real64 LoadToCoolingSP; // thermostat load to cooling setpoint (W)
10124 : Real64 LoadToHeatingSP; // thermostat load to heating setpoint (W)
10125 : Real64 TempOutput; // terminal unit output [W]
10126 : Real64 SuppHeatCoilLoad; // supplemental heating coil load
10127 :
10128 7115 : state.dataHVACVarRefFlow->MaxDeltaT = 0.0;
10129 7115 : state.dataHVACVarRefFlow->MinDeltaT = 0.0;
10130 7115 : state.dataHVACVarRefFlow->NumCoolingLoads = 0;
10131 7115 : state.dataHVACVarRefFlow->SumCoolingLoads = 0.0;
10132 7115 : state.dataHVACVarRefFlow->NumHeatingLoads = 0;
10133 7115 : state.dataHVACVarRefFlow->SumHeatingLoads = 0.0;
10134 7115 : SuppHeatCoilLoad = 0.0;
10135 :
10136 7115 : state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond) = 0;
10137 7115 : state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond) = 0;
10138 7115 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) = 0.0;
10139 7115 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) = 0.0;
10140 7115 : state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = 0.0;
10141 7115 : state.dataHVACVarRefFlow->MinDeltaT(VRFCond) = 0.0;
10142 7115 : ZoneDeltaT = 0.0;
10143 7115 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10144 7115 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10145 7115 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).CoolingCoilAvailable = false;
10146 7115 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HeatingCoilAvailable = false;
10147 : // loop through all TU's to find operating mode. Be careful not to mix loop counters with current TU/Cond index
10148 14225 : for (NumTU = 1; NumTU <= state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList; ++NumTU) {
10149 : // make sure TU's have been sized before looping through each one of them to determine operating mode
10150 7117 : if (any(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TerminalUnitNotSizedYet)) {
10151 7 : break;
10152 : }
10153 7110 : int TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
10154 :
10155 : // check to see if coil is present
10156 7110 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).CoolingCoilPresent(NumTU)) {
10157 : // now check to see if coil is scheduled off
10158 7110 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).coolingCoilAvailScheds(NumTU)->getCurrentVal() > 0.0) {
10159 7110 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).CoolingCoilAvailable(NumTU) = true;
10160 : }
10161 : }
10162 :
10163 : // check to see if coil is present
10164 7110 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HeatingCoilPresent(NumTU)) {
10165 : // now check to see if coil is scheduled off
10166 7110 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).heatingCoilAvailScheds(NumTU)->getCurrentVal() > 0.0) {
10167 7110 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HeatingCoilAvailable(NumTU) = true;
10168 : }
10169 : }
10170 :
10171 7110 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).isSetPointControlled) {
10172 : // set point temperature may only reside at the TU outlet node
10173 7 : Real64 coolCoilTempSetPoint = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOutletNodeNum).TempSetPoint;
10174 7 : state.dataHVACVarRefFlow->VRFTU(TUIndex).suppTempSetPoint = coolCoilTempSetPoint;
10175 7 : Real64 heatCoilTempSetPoint = coolCoilTempSetPoint;
10176 : // adjust coil control for fan heat when set point is at outlet node
10177 7 : Real64 coolfanDeltaT = 0.0;
10178 7 : Real64 heatfanDeltaT = 0.0;
10179 7 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanPlace == HVAC::FanPlace::DrawThru) {
10180 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanOutletNode > 0) {
10181 0 : coolfanDeltaT = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).fanOutletNode).Temp -
10182 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).fanInletNode).Temp;
10183 : }
10184 : }
10185 7 : heatfanDeltaT = coolfanDeltaT;
10186 : // or the set point could be placed at either or both coils, update both if necessary
10187 7 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolingCoilPresent) {
10188 7 : if (state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirOutNode).TempSetPoint !=
10189 : DataLoopNode::SensedNodeFlagValue) {
10190 0 : coolCoilTempSetPoint = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirOutNode).TempSetPoint;
10191 : //// should we adjust for fan heat or not? What if it's a mixed air SP that already adjusts for fan heat?
10192 : // coolfanDeltaT = 0.0;
10193 : }
10194 : }
10195 7 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatingCoilPresent) {
10196 7 : if (state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirOutNode).TempSetPoint !=
10197 : DataLoopNode::SensedNodeFlagValue) {
10198 7 : heatCoilTempSetPoint = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirOutNode).TempSetPoint;
10199 : //// should we adjust for fan heat or not? What if it's a mixed air SP that already adjusts for fan heat?
10200 : // heatfanDeltaT = 0.0;
10201 : }
10202 : }
10203 : // set a flow rate and simulate ATMixer/OASystem if needed
10204 7 : if (FirstHVACIteration) {
10205 7 : SetAverageAirFlow(state, TUIndex, 1.0, OnOffAirFlowRatio);
10206 7 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).ATMixerExists) {
10207 : // There is an air terminal mixer
10208 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).ATMixerType ==
10209 : HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
10210 : // set the primary air inlet mass flow rate
10211 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).ATMixerPriNode).MassFlowRate =
10212 0 : min(state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).ATMixerPriNode).MassFlowRateMaxAvail,
10213 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum).MassFlowRate);
10214 : // now calculate the the mixer outlet air conditions (and the secondary air inlet flow rate). The mixer outlet flow rate
10215 : // has already been set above (it is the "inlet" node flow rate)
10216 0 : SingleDuct::SimATMixer(state,
10217 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ATMixerName,
10218 : FirstHVACIteration,
10219 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).ATMixerIndex);
10220 : }
10221 : } else {
10222 : // simulate OA Mixer
10223 7 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerUsed) {
10224 7 : MixedAir::SimOAMixer(
10225 7 : state, state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerName, state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerIndex);
10226 : }
10227 : }
10228 : }
10229 : // identify a coil inlet temperature
10230 7 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolingCoilPresent) {
10231 7 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coilInNodeT =
10232 7 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirInNode).Temp;
10233 7 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coilInNodeW =
10234 7 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).coolCoilAirInNode).HumRat;
10235 : } else {
10236 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coilInNodeT =
10237 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirInNode).Temp;
10238 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coilInNodeW =
10239 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).heatCoilAirInNode).HumRat;
10240 : }
10241 7 : Real64 coilInletTemp = state.dataHVACVarRefFlow->VRFTU(TUIndex).coilInNodeT;
10242 7 : Real64 coilInletHumRat = state.dataHVACVarRefFlow->VRFTU(TUIndex).coilInNodeW;
10243 7 : Real64 coilInletMassFlow = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum).MassFlowRate;
10244 7 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coolSPActive = false;
10245 7 : state.dataHVACVarRefFlow->VRFTU(TUIndex).heatSPActive = false;
10246 :
10247 7 : if ((heatCoilTempSetPoint - coilInletTemp - heatfanDeltaT) > HVAC::SmallTempDiff) { // heating
10248 3 : Real64 CpAirIn = Psychrometrics::PsyCpAirFnW(coilInletHumRat);
10249 3 : ZoneLoad = coilInletMassFlow * CpAirIn * (heatCoilTempSetPoint - coilInletTemp - heatfanDeltaT);
10250 3 : state.dataHVACVarRefFlow->VRFTU(TUIndex).heatSPActive = true;
10251 3 : state.dataHVACVarRefFlow->VRFTU(TUIndex).heatLoadToSP = ZoneLoad;
10252 3 : ++state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond);
10253 3 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) += ZoneLoad;
10254 3 : state.dataHVACVarRefFlow->MinDeltaT(VRFCond) = min(state.dataHVACVarRefFlow->MinDeltaT(VRFCond), -1.0);
10255 3 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coilTempSetPoint = heatCoilTempSetPoint - heatfanDeltaT;
10256 4 : } else if ((coilInletTemp - coolCoilTempSetPoint - coolfanDeltaT) > HVAC::SmallTempDiff) { // cooling
10257 4 : Real64 CpAirIn = Psychrometrics::PsyCpAirFnW(coilInletHumRat);
10258 4 : ZoneLoad = coilInletMassFlow * CpAirIn * (coolCoilTempSetPoint - coilInletTemp - coolfanDeltaT);
10259 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coolSPActive = true;
10260 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coolLoadToSP = ZoneLoad;
10261 4 : ++state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond);
10262 4 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) += ZoneLoad;
10263 4 : state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = max(state.dataHVACVarRefFlow->MaxDeltaT(VRFCond), 1.0);
10264 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).coilTempSetPoint = coolCoilTempSetPoint - coolfanDeltaT;
10265 : }
10266 : } else { // else is not set point controlled
10267 : // Constant fan systems are tested for ventilation load to determine if load to be met changes.
10268 : // more logic may be needed here, what is the OA flow rate, was last mode heating or cooling, what control is used, etc...
10269 :
10270 7103 : int ThisZoneNum = state.dataHVACVarRefFlow->VRFTU(TUIndex).ZoneNum;
10271 7103 : getVRFTUZoneLoad(state, TUIndex, ZoneLoad, LoadToHeatingSP, LoadToCoolingSP, true);
10272 :
10273 7103 : if (state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority == ThermostatCtrlType::ThermostatOffsetPriority) {
10274 : // for TSTATPriority, just check difference between zone temp and thermostat setpoint
10275 5 : if (ThisZoneNum > 0) {
10276 5 : auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ThisZoneNum);
10277 5 : auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ThisZoneNum);
10278 5 : SPTempHi = zoneTstatSetpt.setptHi;
10279 5 : SPTempLo = zoneTstatSetpt.setptLo;
10280 :
10281 5 : switch (state.dataHeatBalFanSys->TempControlType(ThisZoneNum)) {
10282 0 : case HVAC::SetptType::Uncontrolled:
10283 : // MaxDeltaT denotes cooling, MinDeltaT denotes heating
10284 0 : break;
10285 0 : case HVAC::SetptType::SingleHeat:
10286 : // if heating load, ZoneDeltaT will be negative
10287 0 : ZoneDeltaT = min(0.0, thisZoneHB.ZT - SPTempLo);
10288 0 : state.dataHVACVarRefFlow->MinDeltaT(VRFCond) = min(state.dataHVACVarRefFlow->MinDeltaT(VRFCond), ZoneDeltaT);
10289 0 : break;
10290 0 : case HVAC::SetptType::SingleCool:
10291 : // if cooling load, ZoneDeltaT will be positive
10292 0 : ZoneDeltaT = max(0.0, thisZoneHB.ZT - SPTempHi);
10293 0 : state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = max(state.dataHVACVarRefFlow->MaxDeltaT(VRFCond), ZoneDeltaT);
10294 0 : break;
10295 0 : case HVAC::SetptType::SingleHeatCool:
10296 0 : ZoneDeltaT = thisZoneHB.ZT - SPTempHi; //- SPTempHi and SPTempLo are same value
10297 0 : if (ZoneDeltaT > 0.0) {
10298 0 : state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = max(state.dataHVACVarRefFlow->MaxDeltaT(VRFCond), ZoneDeltaT);
10299 : } else {
10300 0 : state.dataHVACVarRefFlow->MinDeltaT(VRFCond) = min(state.dataHVACVarRefFlow->MinDeltaT(VRFCond), ZoneDeltaT);
10301 : }
10302 0 : break;
10303 5 : case HVAC::SetptType::DualHeatCool:
10304 5 : if (thisZoneHB.ZT - SPTempHi > 0.0) {
10305 1 : ZoneDeltaT = max(0.0, thisZoneHB.ZT - SPTempHi);
10306 1 : state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = max(state.dataHVACVarRefFlow->MaxDeltaT(VRFCond), ZoneDeltaT);
10307 4 : } else if (SPTempLo - thisZoneHB.ZT > 0.0) {
10308 4 : ZoneDeltaT = min(0.0, thisZoneHB.ZT - SPTempLo);
10309 4 : state.dataHVACVarRefFlow->MinDeltaT(VRFCond) = min(state.dataHVACVarRefFlow->MinDeltaT(VRFCond), ZoneDeltaT);
10310 : }
10311 5 : break;
10312 0 : default:
10313 0 : break;
10314 : }
10315 : }
10316 7098 : } else if (state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority == ThermostatCtrlType::LoadPriority ||
10317 0 : state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority == ThermostatCtrlType::ZonePriority) {
10318 7098 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).fanOp == HVAC::FanOp::Continuous) {
10319 4714 : SetCompFlowRate(state, TUIndex, VRFCond);
10320 :
10321 4714 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
10322 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
10323 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CalcVRF_FluidTCtrl(
10324 : state, TUIndex, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
10325 : } else {
10326 : // Algorithm Type: VRF model based on system curve
10327 4714 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CalcVRF(
10328 : state, TUIndex, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
10329 : }
10330 :
10331 : // If the Terminal Unit has a net cooling capacity (NoCompOutput < 0) and
10332 : // the zone temp is above the Tstat heating setpoint (QToHeatSetPt < 0)
10333 4714 : if (TempOutput < 0.0 && LoadToHeatingSP < 0.0) {
10334 : // If the net cooling capacity overshoots the heating setpoint count as heating load
10335 41 : if (TempOutput < LoadToHeatingSP) {
10336 : // Don't count as heating load unless mode is allowed. Also check for floating zone.
10337 8 : if (state.dataHeatBalFanSys->TempControlType(ThisZoneNum) != HVAC::SetptType::SingleCool &&
10338 4 : state.dataHeatBalFanSys->TempControlType(ThisZoneNum) != HVAC::SetptType::Uncontrolled) {
10339 4 : if (!state.dataHVACVarRefFlow->LastModeHeating(VRFCond)) {
10340 : // if last mode was cooling, make sure heating flow rate is used
10341 0 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerUsed) {
10342 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOAMixerRetNodeNum).MassFlowRate =
10343 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).MaxHeatAirMassFlow;
10344 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOAMixerOANodeNum).MassFlowRate =
10345 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatOutAirMassFlow;
10346 0 : MixedAir::SimOAMixer(state,
10347 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerName,
10348 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerIndex);
10349 : } else {
10350 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum).MassFlowRate =
10351 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).MaxHeatAirMassFlow;
10352 : }
10353 :
10354 : // recalculate using correct flow rate
10355 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
10356 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
10357 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CalcVRF_FluidTCtrl(
10358 : state, TUIndex, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
10359 : } else {
10360 : // Algorithm Type: VRF model based on system curve
10361 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CalcVRF(
10362 : state, TUIndex, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
10363 : }
10364 :
10365 0 : if (TempOutput < LoadToHeatingSP) {
10366 0 : ++state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond);
10367 : // sum heating load on condenser, not total zone heating load
10368 0 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) += (LoadToHeatingSP - TempOutput);
10369 : }
10370 : } else {
10371 4 : ++state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond);
10372 : // sum heating load on condenser, not total zone heating load
10373 4 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) += (LoadToHeatingSP - TempOutput);
10374 : }
10375 : }
10376 37 : } else if (TempOutput < ZoneLoad) {
10377 : // If the net cooling capacity meets the zone cooling load but does not overshoot heating setpoint, turn
10378 : // off coil do nothing, the zone will float
10379 1 : } else if (ZoneLoad < 0.0) {
10380 : // still a cooling load
10381 1 : ++state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond);
10382 : // sum cooling load on condenser, not total zone cooling load
10383 1 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) += (LoadToCoolingSP - TempOutput);
10384 : }
10385 :
10386 : // If the terminal unit has a net heating capacity and the zone temp is below the Tstat cooling setpoint
10387 4673 : } else if (TempOutput > 0.0 && LoadToCoolingSP > 0.0) {
10388 : // If the net heating capacity overshoots the cooling setpoint count as cooling load
10389 34 : if (TempOutput > LoadToCoolingSP) {
10390 : // Don't count as cooling load unless mode is allowed. Also check for floating zone.
10391 12 : if (state.dataHeatBalFanSys->TempControlType(ThisZoneNum) != HVAC::SetptType::SingleHeat &&
10392 6 : state.dataHeatBalFanSys->TempControlType(ThisZoneNum) != HVAC::SetptType::Uncontrolled) {
10393 6 : if (!state.dataHVACVarRefFlow->LastModeCooling(VRFCond)) {
10394 4 : if (state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerUsed) {
10395 4 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOAMixerRetNodeNum).MassFlowRate =
10396 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).MaxCoolAirMassFlow;
10397 4 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUOAMixerOANodeNum).MassFlowRate =
10398 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolOutAirMassFlow;
10399 4 : MixedAir::SimOAMixer(state,
10400 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerName,
10401 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).OAMixerIndex);
10402 : } else {
10403 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(TUIndex).VRFTUInletNodeNum).MassFlowRate =
10404 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).MaxCoolAirMassFlow;
10405 : }
10406 :
10407 4 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
10408 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
10409 0 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CalcVRF_FluidTCtrl(
10410 : state, TUIndex, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
10411 : } else {
10412 : // Algorithm Type: VRF model based on system curve
10413 4 : state.dataHVACVarRefFlow->VRFTU(TUIndex).CalcVRF(
10414 : state, TUIndex, FirstHVACIteration, 0.0, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
10415 : }
10416 :
10417 4 : if (TempOutput > LoadToCoolingSP) {
10418 4 : ++state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond);
10419 4 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) += (LoadToCoolingSP - TempOutput);
10420 : }
10421 : } else {
10422 2 : ++state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond);
10423 2 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) += (LoadToCoolingSP - TempOutput);
10424 : }
10425 : }
10426 28 : } else if (TempOutput > ZoneLoad) {
10427 : // do nothing, zone will float
10428 0 : } else if (ZoneLoad > 0.0) {
10429 0 : ++state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond);
10430 0 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) += ZoneLoad;
10431 : }
10432 : // ELSE there is no overshoot and the zone has a valid cooling load
10433 4639 : } else if (ZoneLoad < 0.0) {
10434 2302 : ++state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond);
10435 2302 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) += ZoneLoad;
10436 : // ELSE there is no overshoot and the zone has a valid heating load
10437 2337 : } else if (ZoneLoad > 0.0) {
10438 2322 : ++state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond);
10439 2322 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) += ZoneLoad;
10440 : }
10441 : } else { // is cycling fan
10442 2384 : if (ZoneLoad > 0.0) {
10443 1166 : ++state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond);
10444 1166 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) += ZoneLoad;
10445 1218 : } else if (ZoneLoad < 0.0) {
10446 1177 : ++state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond);
10447 1177 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) += ZoneLoad;
10448 : }
10449 : }
10450 : }
10451 : }
10452 : }
10453 :
10454 : // Determine operating mode based on VRF type and thermostat control selection
10455 7115 : switch (state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority) {
10456 5 : case ThermostatCtrlType::ThermostatOffsetPriority: {
10457 6 : if (state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) > std::abs(state.dataHVACVarRefFlow->MinDeltaT(VRFCond)) &&
10458 1 : state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) > 0.0) {
10459 1 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10460 1 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
10461 8 : } else if (state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) < std::abs(state.dataHVACVarRefFlow->MinDeltaT(VRFCond)) &&
10462 4 : state.dataHVACVarRefFlow->MinDeltaT(VRFCond) < 0.0) {
10463 4 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
10464 4 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10465 : } else {
10466 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10467 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10468 : }
10469 5 : } break;
10470 7110 : case ThermostatCtrlType::LoadPriority: {
10471 10603 : if (state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) > std::abs(state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond)) &&
10472 3493 : state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) > 0.0) {
10473 3493 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
10474 3493 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10475 7234 : } else if (state.dataHVACVarRefFlow->SumHeatingLoads(VRFCond) <= std::abs(state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond)) &&
10476 3617 : state.dataHVACVarRefFlow->SumCoolingLoads(VRFCond) < 0.0) {
10477 3489 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10478 3489 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
10479 : } else {
10480 128 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10481 128 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10482 : }
10483 7110 : } break;
10484 0 : case ThermostatCtrlType::ZonePriority: {
10485 0 : if (state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond) > state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond) &&
10486 0 : state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond) > 0) {
10487 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
10488 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10489 0 : } else if (state.dataHVACVarRefFlow->NumHeatingLoads(VRFCond) <= state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond) &&
10490 0 : state.dataHVACVarRefFlow->NumCoolingLoads(VRFCond) > 0) {
10491 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10492 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
10493 : } else {
10494 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10495 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10496 : }
10497 0 : } break;
10498 0 : case ThermostatCtrlType::ScheduledPriority: {
10499 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).prioritySched->getCurrentVal() == 0) {
10500 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
10501 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10502 0 : } else if (state.dataHVACVarRefFlow->VRF(VRFCond).prioritySched->getCurrentVal() == 1) {
10503 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10504 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
10505 : } else {
10506 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10507 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10508 : }
10509 0 : } break;
10510 0 : case ThermostatCtrlType::MasterThermostatPriority: {
10511 0 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZonePtr).RemainingOutputRequired /
10512 0 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex).controlZoneMassFlowFrac;
10513 0 : if (state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex).fanOp == HVAC::FanOp::Continuous) {
10514 0 : SetCompFlowRate(state, state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex, VRFCond);
10515 :
10516 0 : if (state.dataHVACVarRefFlow->VRF(VRFCond).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
10517 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
10518 0 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex)
10519 0 : .CalcVRF_FluidTCtrl(state,
10520 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex,
10521 : FirstHVACIteration,
10522 : 0.0,
10523 : TempOutput,
10524 : OnOffAirFlowRatio,
10525 : SuppHeatCoilLoad);
10526 : } else {
10527 : // Algorithm Type: VRF model based on system curve
10528 0 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex)
10529 0 : .CalcVRF(state,
10530 0 : state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex,
10531 : FirstHVACIteration,
10532 : 0.0,
10533 : TempOutput,
10534 : OnOffAirFlowRatio,
10535 : SuppHeatCoilLoad);
10536 : }
10537 :
10538 0 : LoadToCoolingSP =
10539 0 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZonePtr).OutputRequiredToCoolingSP /
10540 0 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex).controlZoneMassFlowFrac;
10541 0 : LoadToHeatingSP =
10542 0 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZonePtr).OutputRequiredToHeatingSP /
10543 0 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->VRF(VRFCond).MasterZoneTUIndex).controlZoneMassFlowFrac;
10544 0 : if (TempOutput < LoadToHeatingSP) {
10545 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10546 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
10547 0 : } else if (TempOutput > LoadToCoolingSP) {
10548 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
10549 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10550 : } else {
10551 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10552 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10553 : }
10554 0 : } else if (ZoneLoad > 0.0) {
10555 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = true;
10556 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10557 0 : } else if (ZoneLoad < 0.0) {
10558 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10559 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = true;
10560 : } else {
10561 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10562 0 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
10563 : }
10564 0 : } break;
10565 0 : case ThermostatCtrlType::FirstOnPriority: {
10566 : // na
10567 0 : } break;
10568 0 : default:
10569 0 : break;
10570 : }
10571 :
10572 : // limit to one possible mode
10573 7115 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
10574 0 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
10575 : }
10576 7115 : }
10577 :
10578 1 : void LimitTUCapacity(EnergyPlusData &state,
10579 : int const VRFCond, // Condenser Unit index
10580 : int const NumTUInList, // Number of terminal units in list
10581 : Real64 const StartingCapacity, // temporary variable holding condenser capacity [W]
10582 : const Array1D<Real64> &CapArray, // Array of coil capacities in either cooling or heating mode [W]
10583 : Real64 &MaxLimit, // Maximum terminal unit capacity for coils in same operating mode [W]
10584 : Real64 const AltCapacity, // temporary variable holding heat recovery capacity [W]
10585 : const Array1D<Real64> &AltArray, // Array of coil capacities of heat recovery [W]
10586 : Real64 &AltLimit // Maximum terminal unit capacity of heat recovery coils [W]
10587 : )
10588 : {
10589 :
10590 : // SUBROUTINE INFORMATION:
10591 : // AUTHOR Richard Raustad
10592 : // DATE WRITTEN July 2012 (Moved from InitVRF)
10593 : // MODIFIED na
10594 : // RE-ENGINEERED na
10595 :
10596 : // PURPOSE OF THIS SUBROUTINE:
10597 : // Calculate the maximum allowed terminal unit capacity. Total terminal unit capacity must not
10598 : // exceed the available condenser capacity. This variable, MaxCapacity (passed out to MaxCoolingCapacity
10599 : // or MaxHeatingCapacity), is used to limit the terminal units providing more capacity than allowed.
10600 : // Example: TU loads are 1-ton, 2-ton, 3-ton, and 4-ton connected to a condenser having only 9-tons available.
10601 : // This variable is will be set to 3-tons and the 4-ton terminal unit will be limited to 3-tons
10602 : // (see InitVRF where this variable is reset and CalcVRF where the call to the DX coils passes this argument).
10603 :
10604 : // METHODOLOGY EMPLOYED:
10605 : // The coils are simulated and summed. This value is compared to the available capacity. If the summed
10606 : // TU capacity is greater than the available capacity, limit the TU's with the highest capacity so that
10607 : // the TU capacity equals the available capacity. The report variable Variable Refrigerant Flow Heat Pump
10608 : // Maximum Terminal Unit Cool/Heating Capacity holds the value for maximum TU capacity. This value may not
10609 : // match the maximum individual coil capacity exactly since the available capacity uses a load weighted
10610 : // average WB temperature to calculate available capacity. When the TU's are limited, this weighting changes.
10611 : // The extra iterations required for these values to converge is considered excessive.
10612 : // If the global flag SimZoneEquipment could be set for 1 additional iteration, these variables would
10613 : // converge more closely (setting this global flag is not yet implemented).
10614 :
10615 : Real64 RemainingCapacity; // decrement capacity counter to find limiting TU capacity [W]
10616 :
10617 : // limit TU coil capacity to be equal to the condenser capacity (piping losses already accounted for)
10618 1 : LimitCoilCapacity(NumTUInList, StartingCapacity, CapArray, MaxLimit);
10619 :
10620 : // ** add in logic to limit coils operating opposite to mode when heat recovery is used
10621 : // ** this is a hard one since we are here because the system is overloaded. That means
10622 : // ** that we do not know at this point the actual operating capacity or compressor power.
10623 1 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed) {
10624 0 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
10625 0 : RemainingCapacity = StartingCapacity * (1 + 1 / state.dataHVACVarRefFlow->VRF(VRFCond).CoolingCOP);
10626 0 : if (AltCapacity > RemainingCapacity) {
10627 0 : LimitCoilCapacity(NumTUInList, RemainingCapacity, AltArray, AltLimit);
10628 : }
10629 : }
10630 0 : if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
10631 0 : RemainingCapacity = StartingCapacity / (1 + 1 / state.dataHVACVarRefFlow->VRF(VRFCond).HeatingCOP);
10632 0 : if (AltCapacity > RemainingCapacity) {
10633 0 : LimitCoilCapacity(NumTUInList, RemainingCapacity, AltArray, AltLimit);
10634 : }
10635 : }
10636 : }
10637 1 : }
10638 :
10639 1 : void LimitCoilCapacity(int const NumTUInList, // Number of terminal units in list
10640 : Real64 const TotalCapacity, // temporary variable holding condenser capacity [W]
10641 : const Array1D<Real64> &CapArray, // Array of coil capacities in either cooling or heating mode [W]
10642 : Real64 &MaxLimit // Maximum terminal unit capacity for coils in same operating mode [W]
10643 : )
10644 : {
10645 :
10646 : // SUBROUTINE INFORMATION:
10647 : // AUTHOR Richard Raustad
10648 : // DATE WRITTEN July 2012 (Moved from InitVRF)
10649 : // MODIFIED na
10650 : // RE-ENGINEERED na
10651 :
10652 : // PURPOSE OF THIS SUBROUTINE:
10653 : // Calculate the maximum allowed terminal unit capacity. Total terminal unit capacity must not
10654 : // exceed the available condenser capacity. This variable, MaxCapacity (passed out to MaxCoolingCapacity
10655 : // or MaxHeatingCapacity), is used to limit the terminal units providing more capacity than allowed.
10656 : // Example: TU loads are 1-ton, 2-ton, 3-ton, and 4-ton connected to a condenser having only 9-tons available.
10657 : // This variable is will be set to 3-tons and the 4-ton terminal unit will be limited to 3-tons
10658 : // (see InitVRF where this variable is reset and CalcVRF where the call to the DX coils passes this argument).
10659 :
10660 : // METHODOLOGY EMPLOYED:
10661 : // The coils are simulated and summed. This value is compared to the available capacity. If the summed
10662 : // TU capacity is greater than the available capacity, limit the TU's with the highest capacity so that
10663 : // the TU capacity equals the available capacity. The report variable Variable Refrigerant Flow Heat Pump
10664 : // Maximum Terminal Unit Cool/Heating Capacity holds the value for maximum TU capacity. This value may not
10665 : // match the maximum individual coil capacity exactly since the available capacity uses a load weighted
10666 : // average WB temperature to calculate available capacity. When the TU's are limited, this weighting changes.
10667 : // The extra iterations required for these values to converge is considered excessive.
10668 : // If the global flag SimZoneEquipment could be set for 1 additional iteration, these variables would
10669 : // converge more closely (setting this global flag is not yet implemented).
10670 :
10671 : int NumTU; // loop counter
10672 : int TempTUIndex; // temp variable used to find max terminal unit limit
10673 : int MinOutputIndex; // index to TU with lowest load
10674 : Real64 MinOutput; // used when finding TU "max" capacity limit
10675 : Real64 RemainingCapacity; // decrement capacity counter to find limiting TU capacity [W]
10676 1 : Array1D<Real64> Temp(NumTUInList, CapArray); // temporary array for processing terminal units
10677 1 : Array1D<Real64> Temp2(NumTUInList, Temp); // temporary array for processing terminal units
10678 :
10679 1 : RemainingCapacity = TotalCapacity;
10680 :
10681 : // sort TU capacity from lowest to highest
10682 2 : for (TempTUIndex = 1; TempTUIndex <= NumTUInList; ++TempTUIndex) {
10683 1 : MinOutput = Constant::MaxCap;
10684 2 : for (NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
10685 1 : if (Temp2(NumTU) < MinOutput) {
10686 1 : MinOutput = Temp2(NumTU);
10687 1 : Temp(TempTUIndex) = MinOutput;
10688 1 : MinOutputIndex = NumTU;
10689 : }
10690 : }
10691 1 : Temp2(MinOutputIndex) = Constant::MaxCap;
10692 : }
10693 :
10694 : // find limit of "terminal unit" capacity so that sum of all TU's does not exceed condenser capacity
10695 : // if the terminal unit capacity multiplied by number of remaining TU's does not exceed remaining available, subtract and cycle
10696 1 : for (TempTUIndex = 1; TempTUIndex <= NumTUInList; ++TempTUIndex) {
10697 1 : if ((Temp(TempTUIndex) * (NumTUInList - TempTUIndex + 1)) < RemainingCapacity) {
10698 0 : RemainingCapacity -= Temp(TempTUIndex);
10699 0 : continue;
10700 : } else {
10701 : // if it does exceed, limit is found
10702 1 : MaxLimit = RemainingCapacity / (NumTUInList - TempTUIndex + 1);
10703 1 : break;
10704 : }
10705 : }
10706 1 : }
10707 :
10708 865 : int GetVRFTUOutAirNode(EnergyPlusData &state, int const VRFTUNum)
10709 : {
10710 :
10711 : // FUNCTION INFORMATION:
10712 : // AUTHOR R. Raustad (copy of B Griffith routine)
10713 : // DATE WRITTEN Jan 2015
10714 : // MODIFIED na
10715 : // RE-ENGINEERED na
10716 :
10717 : // PURPOSE OF THIS FUNCTION:
10718 : // lookup function for VRF terminal unit OA inlet node
10719 :
10720 865 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10721 0 : GetVRFInput(state);
10722 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10723 : }
10724 :
10725 865 : if (VRFTUNum > 0 && VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU) {
10726 865 : return state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum;
10727 : } else {
10728 0 : return 0;
10729 : }
10730 : }
10731 :
10732 872 : int GetVRFTUZoneInletAirNode(EnergyPlusData &state, int const VRFTUNum)
10733 : {
10734 :
10735 : // FUNCTION INFORMATION:
10736 : // AUTHOR R. Raustad (copy of B Griffith routine)
10737 : // DATE WRITTEN Jan 2015
10738 : // MODIFIED na
10739 : // RE-ENGINEERED na
10740 :
10741 : // PURPOSE OF THIS FUNCTION:
10742 : // lookup function for VRF terminal unit zone inlet node
10743 :
10744 872 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10745 5 : GetVRFInput(state);
10746 5 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10747 : }
10748 :
10749 872 : if (VRFTUNum > 0 && VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU) {
10750 872 : return state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum;
10751 : } else {
10752 0 : return 0;
10753 : }
10754 : }
10755 :
10756 0 : int GetVRFTUOutAirNodeFromName(EnergyPlusData &state, std::string const &VRFTUName, bool &errorsFound)
10757 : {
10758 : int NodeNum; // return value of node number
10759 :
10760 0 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10761 0 : GetVRFInput(state);
10762 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10763 : }
10764 :
10765 : int WhichVRFTU =
10766 0 : Util::FindItemInList(VRFTUName, state.dataHVACVarRefFlow->VRFTU, &VRFTerminalUnitEquipment::Name, state.dataHVACVarRefFlow->NumVRFTU);
10767 0 : if (WhichVRFTU != 0) {
10768 0 : NodeNum = state.dataHVACVarRefFlow->VRFTU(WhichVRFTU).VRFTUOutletNodeNum;
10769 : } else {
10770 0 : ShowSevereError(state, format("GetVRFTUOutAirNodeFromName: Could not find VRF TU = \"{}\"", VRFTUName));
10771 0 : errorsFound = true;
10772 0 : NodeNum = 0;
10773 : }
10774 :
10775 0 : return NodeNum;
10776 : }
10777 :
10778 0 : int GetVRFTUInAirNodeFromName(EnergyPlusData &state, std::string const &VRFTUName, bool &errorsFound)
10779 : {
10780 : int NodeNum; // return value of node number
10781 :
10782 0 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10783 0 : GetVRFInput(state);
10784 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10785 : }
10786 :
10787 : int WhichVRFTU =
10788 0 : Util::FindItemInList(VRFTUName, state.dataHVACVarRefFlow->VRFTU, &VRFTerminalUnitEquipment::Name, state.dataHVACVarRefFlow->NumVRFTU);
10789 0 : if (WhichVRFTU != 0) {
10790 0 : NodeNum = state.dataHVACVarRefFlow->VRFTU(WhichVRFTU).VRFTUInletNodeNum;
10791 : } else {
10792 0 : ShowSevereError(state, format("GetVRFTUInAirNodeFromName: Could not find VRF TU = \"{}\"", VRFTUName));
10793 0 : errorsFound = true;
10794 0 : NodeNum = 0;
10795 : }
10796 :
10797 0 : return NodeNum;
10798 : }
10799 :
10800 865 : int GetVRFTUMixedAirNode(EnergyPlusData &state, int const VRFTUNum)
10801 : {
10802 :
10803 : // FUNCTION INFORMATION:
10804 : // AUTHOR R. Raustad (copy of B Griffith routine)
10805 : // DATE WRITTEN Jan 2015
10806 : // MODIFIED na
10807 : // RE-ENGINEERED na
10808 :
10809 : // PURPOSE OF THIS FUNCTION:
10810 : // lookup function for VRF terminal unit mixed air node
10811 :
10812 865 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10813 0 : GetVRFInput(state);
10814 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10815 : }
10816 :
10817 865 : if (VRFTUNum > 0 && VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU) {
10818 865 : return state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum;
10819 : } else {
10820 0 : return 0;
10821 : }
10822 : }
10823 :
10824 865 : int GetVRFTUReturnAirNode(EnergyPlusData &state, int const VRFTUNum)
10825 : {
10826 :
10827 : // FUNCTION INFORMATION:
10828 : // AUTHOR R. Raustad (copy of B Griffith routine)
10829 : // DATE WRITTEN Jan 2015
10830 : // MODIFIED na
10831 : // RE-ENGINEERED na
10832 :
10833 : // PURPOSE OF THIS FUNCTION:
10834 : // lookup function for VRF terminal unit return air node
10835 :
10836 865 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10837 0 : GetVRFInput(state);
10838 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10839 : }
10840 :
10841 865 : if (VRFTUNum > 0 && VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU) {
10842 865 : return state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerRetNodeNum;
10843 : } else {
10844 0 : return 0;
10845 : }
10846 : }
10847 :
10848 1 : int getEqIndex(EnergyPlusData &state, std::string_view VRFTUName)
10849 : {
10850 1 : if (state.dataHVACVarRefFlow->GetVRFInputFlag) {
10851 0 : GetVRFInput(state);
10852 0 : state.dataHVACVarRefFlow->GetVRFInputFlag = false;
10853 : }
10854 :
10855 1 : for (int VRFTUNum = 1; VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU; VRFTUNum++) {
10856 1 : if (Util::SameString(VRFTUName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).Name)) {
10857 1 : return VRFTUNum;
10858 : }
10859 : }
10860 0 : return 0;
10861 : }
10862 :
10863 14230 : void getVRFTUZoneLoad(
10864 : EnergyPlusData &state, int const VRFTUNum, Real64 &zoneLoad, Real64 &LoadToHeatingSP, Real64 &LoadToCoolingSP, bool const InitFlag)
10865 : {
10866 :
10867 14230 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).zoneSequenceCoolingNum > 0 &&
10868 14230 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).zoneSequenceHeatingNum > 0 && state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isInAirLoop) {
10869 : // air loop equipment uses sequenced variables
10870 0 : LoadToCoolingSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum)
10871 0 : .SequencedOutputRequiredToCoolingSP(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).zoneSequenceCoolingNum) /
10872 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10873 0 : LoadToHeatingSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum)
10874 0 : .SequencedOutputRequiredToHeatingSP(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).zoneSequenceHeatingNum) /
10875 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10876 0 : if (LoadToHeatingSP > 0.0 && LoadToCoolingSP > 0.0 &&
10877 0 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleCool) {
10878 0 : zoneLoad = LoadToHeatingSP;
10879 0 : } else if (LoadToHeatingSP > 0.0 && LoadToCoolingSP > 0.0 &&
10880 0 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) == HVAC::SetptType::SingleCool) {
10881 0 : zoneLoad = 0.0;
10882 0 : } else if (LoadToHeatingSP < 0.0 && LoadToCoolingSP < 0.0 &&
10883 0 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) != HVAC::SetptType::SingleHeat) {
10884 0 : zoneLoad = LoadToCoolingSP;
10885 0 : } else if (LoadToHeatingSP < 0.0 && LoadToCoolingSP < 0.0 &&
10886 0 : state.dataHeatBalFanSys->TempControlType(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum) == HVAC::SetptType::SingleHeat) {
10887 0 : zoneLoad = 0.0;
10888 0 : } else if (LoadToHeatingSP <= 0.0 && LoadToCoolingSP >= 0.0) {
10889 0 : zoneLoad = 0.0;
10890 : }
10891 14230 : } else if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum > 0) {
10892 : // zone equipment uses Remaining* variables
10893 14223 : if (InitFlag) {
10894 : // this will need more investigation. Using Remaining* variable during the initial load calculation seems wrong.
10895 : // This may also have implications when VRF TUs are in the air loop or if SP control is used
10896 : // another question is whether initialization of the operating mode should look at TotalOutputRequired or RemainingOutputRequired
10897 7103 : zoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum).RemainingOutputRequired /
10898 7103 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10899 7103 : LoadToCoolingSP =
10900 7103 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum).OutputRequiredToCoolingSP /
10901 7103 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10902 7103 : LoadToHeatingSP =
10903 7103 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum).OutputRequiredToHeatingSP /
10904 7103 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10905 : } else {
10906 7120 : zoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum).RemainingOutputRequired /
10907 7120 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10908 7120 : LoadToCoolingSP =
10909 7120 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum).RemainingOutputReqToCoolSP /
10910 7120 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10911 7120 : LoadToHeatingSP =
10912 7120 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneNum).RemainingOutputReqToHeatSP /
10913 7120 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).controlZoneMassFlowFrac;
10914 : }
10915 7 : } else if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isSetPointControlled) {
10916 7 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coolSPActive) {
10917 4 : LoadToCoolingSP = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coolLoadToSP;
10918 4 : zoneLoad = LoadToCoolingSP;
10919 4 : LoadToHeatingSP = 0.0;
10920 : }
10921 7 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).heatSPActive) {
10922 3 : LoadToHeatingSP = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).heatLoadToSP;
10923 3 : zoneLoad = LoadToHeatingSP;
10924 3 : LoadToCoolingSP = 0.0;
10925 : }
10926 : }
10927 14230 : }
10928 :
10929 42 : bool getVRFTUNodeNumber(EnergyPlusData &state, int const nodeNumber)
10930 : {
10931 43 : for (int vrfTUIndex = 1; vrfTUIndex <= state.dataHVACVarRefFlow->NumVRFTU; ++vrfTUIndex) {
10932 11 : auto const &vrfTU = state.dataHVACVarRefFlow->VRFTU(vrfTUIndex);
10933 :
10934 11 : bool noVrfTUOutdoorAir = false;
10935 11 : if (vrfTU.CoolOutAirVolFlow == 0 && vrfTU.HeatOutAirVolFlow == 0 && vrfTU.NoCoolHeatOutAirVolFlow == 0) {
10936 11 : noVrfTUOutdoorAir = true;
10937 : }
10938 :
10939 11 : if (noVrfTUOutdoorAir &&
10940 11 : (nodeNumber == vrfTU.VRFTUInletNodeNum || nodeNumber == vrfTU.VRFTUOutletNodeNum || nodeNumber == vrfTU.fanInletNode ||
10941 8 : nodeNumber == vrfTU.fanOutletNode || nodeNumber == vrfTU.heatCoilAirOutNode || nodeNumber == vrfTU.coolCoilAirOutNode ||
10942 5 : nodeNumber == vrfTU.VRFTUOAMixerOANodeNum || nodeNumber == vrfTU.VRFTUOAMixerRelNodeNum || nodeNumber == vrfTU.VRFTUOAMixerRetNodeNum ||
10943 2 : nodeNumber == vrfTU.VRFTUOAMixerMixedNodeNum || nodeNumber == vrfTU.SuppHeatCoilAirInletNode ||
10944 1 : nodeNumber == vrfTU.SuppHeatCoilAirOutletNode)) {
10945 10 : return true;
10946 : }
10947 : }
10948 32 : return false;
10949 : }
10950 :
10951 2374 : void VRFCondenserEquipment::CalcVRFIUTeTc_FluidTCtrl(EnergyPlusData &state)
10952 : {
10953 : // SUBROUTINE INFORMATION:
10954 : // AUTHOR RP Zhang (LBNL), XF Pang (LBNL), Y Yura (Daikin Inc)
10955 : // DATE WRITTEN June 2015
10956 : // MODIFIED na
10957 : // RE-ENGINEERED na
10958 :
10959 : // PURPOSE OF THIS SUBROUTINE:
10960 : // This subroutine is part of the new VRF model based on physics, applicable for Fluid Temperature Control.
10961 : // This subroutine determines the VRF evaporating temperature at cooling mode and the condensing temperature
10962 : // at heating mode. This is the indoor unit side analysis.
10963 :
10964 : // METHODOLOGY EMPLOYED:
10965 : // There are two options to calculate the IU Te/Tc: (1) HighSensible method analyzes the conditions of each IU
10966 : // and then decide and Te/Tc that can satisfy all the zones (2) TeTcConstant method uses fixed values provided
10967 : // by the user.
10968 :
10969 : // Followings for FluidTCtrl Only
10970 2374 : Array1D<Real64> EvapTemp;
10971 2374 : Array1D<Real64> CondTemp;
10972 : Real64 IUMinEvapTemp;
10973 : Real64 IUMaxCondTemp;
10974 :
10975 2374 : int TUListNum = this->ZoneTUListPtr;
10976 2374 : EvapTemp.allocate(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList);
10977 2374 : CondTemp.allocate(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList);
10978 2374 : IUMinEvapTemp = 100.0;
10979 2374 : IUMaxCondTemp = 0.0;
10980 :
10981 2374 : if (this->AlgorithmIUCtrl == 1) {
10982 : // 1. HighSensible: analyze the conditions of each IU
10983 :
10984 15 : for (int i = 1; i <= state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList; i++) {
10985 10 : int VRFTUNum = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(i);
10986 : // analyze the conditions of each IU
10987 10 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRFIUVariableTeTc(state, EvapTemp(i), CondTemp(i));
10988 :
10989 : // select the Te/Tc that can satisfy all the zones
10990 10 : IUMinEvapTemp = min(IUMinEvapTemp, EvapTemp(i), this->IUEvapTempHigh);
10991 10 : IUMaxCondTemp = max(IUMaxCondTemp, CondTemp(i), this->IUCondTempLow);
10992 : }
10993 :
10994 5 : this->IUEvaporatingTemp = max(IUMinEvapTemp, this->IUEvapTempLow);
10995 5 : this->IUCondensingTemp = min(IUMaxCondTemp, this->IUCondTempHigh);
10996 :
10997 : } else {
10998 : // 2. TeTcConstant: use fixed values provided by the user
10999 2369 : this->IUEvaporatingTemp = this->EvapTempFixed;
11000 2369 : this->IUCondensingTemp = this->CondTempFixed;
11001 : }
11002 2374 : }
11003 :
11004 10 : void VRFTerminalUnitEquipment::CalcVRFIUVariableTeTc(EnergyPlusData &state,
11005 : Real64 &EvapTemp, // evaporating temperature
11006 : Real64 &CondTemp // condensing temperature
11007 : )
11008 : {
11009 : // SUBROUTINE INFORMATION:
11010 : // AUTHOR Xiufeng Pang, LBNL
11011 : // DATE WRITTEN Feb 2014
11012 : // MODIFIED Jul 2015, RP Zhang, LBNL, Modify the bounds of the Te/Tc
11013 : // MODIFIED Nov 2015, RP Zhang, LBNL, take into account OA in Te/Tc determination
11014 : // RE-ENGINEERED na
11015 :
11016 : // PURPOSE OF THIS SUBROUTINE:
11017 : // Calculate the VRF IU Te (cooling mode) and Tc (heating mode), given zonal loads.
11018 :
11019 : // METHODOLOGY EMPLOYED:
11020 : // A new physics based VRF model applicable for Fluid Temperature Control.
11021 :
11022 : using namespace DataZoneEnergyDemands;
11023 : using Psychrometrics::PsyHFnTdbW;
11024 : using SingleDuct::SimATMixer;
11025 :
11026 : int CoolCoilNum; // index to the VRF Cooling DX coil to be simulated
11027 : int HeatCoilNum; // index to the VRF Heating DX coil to be simulated
11028 : int IndexToTUInTUList; // index to TU in specific list for the VRF system
11029 : int TUListIndex; // index to TU list for this VRF system
11030 : int VRFNum; // index to VRF that the VRF Terminal Unit serves
11031 : int VRFInletNode; // VRF inlet node number
11032 : Real64 BFC; // Bypass factor at the cooling mode (-)
11033 : Real64 BFH; // Bypass factor at the heating mode (-)
11034 : Real64 C1Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
11035 : Real64 C2Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
11036 : Real64 C3Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
11037 : Real64 C1Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
11038 : Real64 C2Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
11039 : Real64 C3Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
11040 : Real64 CondTempMin; // Min condensing temperature (C)
11041 : Real64 CondTempMax; // Max condensing temperature, correspond to the maximum heating capacity (C)
11042 : Real64 DeltaT; // Difference between evaporating/condensing temperature and coil surface temperature (C)
11043 : Real64 EvapTempMax; // Max evaporating temperature (C)
11044 : Real64 EvapTempMin; // Min evaporating temperature, correspond to the maximum cooling capacity (C)
11045 : Real64 Garate; // Nominal air mass flow rate
11046 : Real64 H_coil_in; // Air enthalpy at the coil inlet (kJ/kg)
11047 : Real64 QZnReqSenCoolingLoad; // Zone required sensible cooling load (W)
11048 : Real64 QZnReqSenHeatingLoad; // Zone required sensible heating load (W)
11049 : Real64 RHsat; // Relative humidity of the air at saturated condition(-)
11050 : Real64 SH; // Super heating degrees (C)
11051 : Real64 SC; // Subcooling degrees (C)
11052 : Real64 T_coil_in; // Temperature of the air at the coil inlet, after absorbing the heat released by fan (C)
11053 : Real64 T_TU_in; // Air temperature at the indoor unit inlet (C)
11054 : Real64 Tout; // Air temperature at the indoor unit outlet (C)
11055 : Real64 Th2; // Air temperature at the coil surface (C)
11056 : Real64 W_coil_in; // coil inlet air humidity ratio [kg/kg]
11057 : Real64 W_TU_in; // Air humidity ratio at the indoor unit inlet[kg/kg]
11058 :
11059 : // Get the equipment/zone index corresponding to the VRFTU
11060 10 : CoolCoilNum = this->CoolCoilIndex;
11061 10 : HeatCoilNum = this->HeatCoilIndex;
11062 10 : VRFNum = this->VRFSysNum;
11063 10 : TUListIndex = state.dataHVACVarRefFlow->VRF(VRFNum).ZoneTUListPtr;
11064 10 : IndexToTUInTUList = this->IndexToTUInTUList;
11065 :
11066 : // Bounds of Te/Tc for VRF IU Control Algorithm: VariableTemp
11067 10 : EvapTempMin = state.dataHVACVarRefFlow->VRF(VRFNum).IUEvapTempLow;
11068 10 : EvapTempMax = state.dataHVACVarRefFlow->VRF(VRFNum).IUEvapTempHigh;
11069 10 : CondTempMin = state.dataHVACVarRefFlow->VRF(VRFNum).IUCondTempLow;
11070 10 : CondTempMax = state.dataHVACVarRefFlow->VRF(VRFNum).IUCondTempHigh;
11071 :
11072 : // Coefficients describing coil performance
11073 10 : SH = state.dataDXCoils->DXCoil(CoolCoilNum).SH;
11074 10 : SC = state.dataDXCoils->DXCoil(HeatCoilNum).SC;
11075 10 : C1Tevap = state.dataDXCoils->DXCoil(CoolCoilNum).C1Te;
11076 10 : C2Tevap = state.dataDXCoils->DXCoil(CoolCoilNum).C2Te;
11077 10 : C3Tevap = state.dataDXCoils->DXCoil(CoolCoilNum).C3Te;
11078 10 : C1Tcond = state.dataDXCoils->DXCoil(HeatCoilNum).C1Tc;
11079 10 : C2Tcond = state.dataDXCoils->DXCoil(HeatCoilNum).C2Tc;
11080 10 : C3Tcond = state.dataDXCoils->DXCoil(HeatCoilNum).C3Tc;
11081 :
11082 10 : VRFInletNode = this->VRFTUInletNodeNum;
11083 10 : T_TU_in = state.dataLoopNodes->Node(VRFInletNode).Temp;
11084 10 : W_TU_in = state.dataLoopNodes->Node(VRFInletNode).HumRat;
11085 10 : T_coil_in = this->coilInNodeT;
11086 10 : W_coil_in = this->coilInNodeW;
11087 :
11088 10 : Garate = state.dataHVACVarRefFlow->CompOnMassFlow;
11089 10 : H_coil_in = PsyHFnTdbW(T_coil_in, W_coil_in);
11090 10 : RHsat = 0.98;
11091 10 : BFC = 0.0592;
11092 10 : BFH = 0.136;
11093 10 : Real64 ZoneLoad = 0.0;
11094 10 : Real64 LoadToHeatingSP = 0.0;
11095 10 : Real64 LoadToCoolingSP = 0.0;
11096 :
11097 : // 1. COOLING Mode
11098 14 : if ((Garate > 0.0) && ((!state.dataHVACVarRefFlow->VRF(VRFNum).HeatRecoveryUsed && state.dataHVACVarRefFlow->CoolingLoad(VRFNum)) ||
11099 4 : (state.dataHVACVarRefFlow->VRF(VRFNum).HeatRecoveryUsed &&
11100 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList)))) {
11101 : // 1.1) Cooling coil is running
11102 4 : getVRFTUZoneLoad(state, IndexToTUInTUList, ZoneLoad, LoadToHeatingSP, LoadToCoolingSP, false);
11103 4 : QZnReqSenCoolingLoad = max(0.0, -1.0 * LoadToCoolingSP);
11104 4 : Tout = T_TU_in - QZnReqSenCoolingLoad * 1.2 / Garate / 1005;
11105 4 : Th2 = T_coil_in - (T_coil_in - Tout) / (1 - BFC);
11106 4 : DeltaT = C3Tevap * SH * SH + C2Tevap * SH + C1Tevap;
11107 4 : EvapTemp = max(min((Th2 - DeltaT), EvapTempMax), EvapTempMin);
11108 :
11109 : } else {
11110 : // 1.2) Cooling coil is not running
11111 6 : EvapTemp = T_coil_in;
11112 : }
11113 :
11114 : // 2. HEATING Mode
11115 14 : if ((Garate > 0.0) && ((!state.dataHVACVarRefFlow->VRF(VRFNum).HeatRecoveryUsed && state.dataHVACVarRefFlow->HeatingLoad(VRFNum)) ||
11116 4 : (state.dataHVACVarRefFlow->VRF(VRFNum).HeatRecoveryUsed &&
11117 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList)))) {
11118 : // 2.1) Heating coil is running
11119 4 : getVRFTUZoneLoad(state, IndexToTUInTUList, ZoneLoad, LoadToHeatingSP, LoadToCoolingSP, false);
11120 4 : QZnReqSenHeatingLoad = max(0.0, LoadToHeatingSP);
11121 4 : Tout = T_TU_in + QZnReqSenHeatingLoad / Garate / 1005;
11122 4 : Th2 = T_coil_in + (Tout - T_coil_in) / (1 - BFH);
11123 4 : DeltaT = C3Tcond * SC * SC + C2Tcond * SC + C1Tcond;
11124 4 : CondTemp = max(min((Th2 + DeltaT), CondTempMax), CondTempMin);
11125 : } else {
11126 : // 2.2) Heating coil is not running
11127 6 : CondTemp = T_coil_in;
11128 : }
11129 10 : }
11130 :
11131 2368 : void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state, const bool FirstHVACIteration)
11132 : {
11133 :
11134 : // SUBROUTINE INFORMATION:
11135 : // AUTHOR RP Zhang (LBNL), XF Pang (LBNL), Y Yura (Daikin Inc)
11136 : // DATE WRITTEN June 2015
11137 : // MODIFIED Feb 2016, RP Zhang, add the control logics for VRF-HR operations
11138 : // RE-ENGINEERED na
11139 :
11140 : // PURPOSE OF THIS SUBROUTINE:
11141 : // This subroutine is part of the new VRF model based on physics, applicable for Fluid Temperature Control.
11142 : // This is adapted from subroutine CalcVRFCondenser, which is part of the VRF model based on system curves.
11143 : // This subroutine models the interactions of VRF indoor units with the outdoor unit.
11144 : // The indoor terminal units are simulated first, and then the outdoor unit is simulated.
11145 :
11146 : // METHODOLOGY EMPLOYED:
11147 : // A new physics based VRF model applicable for Fluid Temperature Control.
11148 :
11149 : using Curve::CurveValue;
11150 : using General::SolveRoot;
11151 :
11152 : using PlantUtilities::SetComponentFlowRate;
11153 : using Psychrometrics::RhoH2O;
11154 :
11155 : static constexpr std::string_view RoutineName("CalcVRFCondenser_FluidTCtrl");
11156 :
11157 : int VRFCond; // index to VRF condenser
11158 : int TUListNum; // index to TU List
11159 : int NumTUInList; // number of terminal units is list
11160 : int NumTU; // index for loop on terminal units
11161 : int TUIndex; // Index to terminal unit
11162 : int CoolCoilIndex; // index to cooling coil in terminal unit
11163 : int HeatCoilIndex; // index to heating coil in terminal unit
11164 : int NumTUInCoolingMode; // number of terminal units actually cooling
11165 : int NumTUInHeatingMode; // number of terminal units actually heating
11166 :
11167 : Real64 TUParasiticPower; // total terminal unit parasitic power (W)
11168 : Real64 TUFanPower; // total terminal unit fan power (W)
11169 : Real64 InletAirWetBulbC; // coil inlet air wet-bulb temperature (C)
11170 : Real64 InletAirDryBulbC; // coil inlet air dry-bulb temperature (C)
11171 : Real64 CondInletTemp; // condenser inlet air temperature (C)
11172 : Real64 OutdoorDryBulb; // outdoor dry-bulb temperature (C)
11173 : Real64 OutdoorHumRat; // outdoor humidity ratio (kg/kg)
11174 : Real64 OutdoorPressure; // outdoor pressure (Pa)
11175 : Real64 OutdoorWetBulb; // outdoor wet-bulb temperature (C)
11176 : Real64 SumCoolInletWB; // sum of active TU's DX cooling coil inlet air wet-bulb temperature
11177 : Real64 SumHeatInletDB; // sum of active TU's DX heating coil inlet air dry-bulb temperature
11178 : Real64 SumHeatInletWB; // sum of active TU's DX heating coil inlet air wet-bulb temperature
11179 : Real64 TotalTUCoolingCapacity; // sum of TU's cooling capacity (W)
11180 : Real64 TotalTUHeatingCapacity; // sum of TU's heating capacity (W)
11181 : Real64 TotalCondCoolingCapacity; // total available condenser cooling capacity (W)
11182 : Real64 TotalCondHeatingCapacity; // total available condenser heating capacity (W)
11183 : Real64 CoolingPLR; // condenser cooling PLR
11184 : Real64 HeatingPLR; // condenser heating PLR
11185 : Real64 CyclingRatio; // cycling ratio of condenser's compressors
11186 : int Stage; // used for crankcase heater power calculation
11187 : Real64 UpperStageCompressorRatio; // used for crankcase heater power calculation
11188 : Real64 RhoAir; // Density of air [kg/m3]
11189 : Real64 PartLoadFraction; // Part load fraction from PLFFPLR curve
11190 : Real64 VRFRTF; // VRF runtime fraction when cycling below MINPLR
11191 : Real64 OutdoorCoilT; // Outdoor coil temperature (C)
11192 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
11193 : Real64 FractionalDefrostTime; // Fraction of time step system is in defrost
11194 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
11195 : Real64 InputPowerMultiplier; // Multiplier for power when system is in defrost
11196 : Real64 LoadDueToDefrost; // Additional load due to defrost
11197 : Real64 DefrostEIRTempModFac; // EIR modifier for defrost (function of entering drybulb, outside wetbulb)
11198 : Real64 HRInitialCapFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
11199 : Real64 HRCapTC; // Time constant used to recover from initial degradation in cooling heat recovery
11200 : Real64 HRInitialEIRFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
11201 : Real64 HREIRTC; // Time constant used to recover from initial degradation in cooling heat recovery
11202 : Real64 CurrentEndTime; // end time of current time step
11203 : Real64 SUMultiplier; // multiplier for simulating mode changes
11204 : Real64 CondPower; // condenser power [W]
11205 : Real64 CondCapacity; // condenser heat rejection [W]
11206 : Real64 TotPower; // total condenser power use [W]
11207 : bool HRHeatRequestFlag; // flag indicating VRF TU could operate in heating mode
11208 : bool HRCoolRequestFlag; // flag indicating VRF TU could operate in cooling mode
11209 :
11210 : // Followings for VRF FluidTCtrl Only
11211 : int Counter; // index for iterations [-]
11212 : int NumIteHIUIn; // index for HIU calculation iterations [-]
11213 : int NumOfCompSpdInput; // Number of compressor speed input by the user [-]
11214 : Real64 CompSpdActual; // Actual compressor running speed [rps]
11215 : Real64 C_cap_operation; // Compressor capacity modification algorithm_modified Cap [-]
11216 : Real64 CompEvaporatingCAPSpdMin; // evaporating capacity at the lowest compressor speed [W]
11217 : Real64 CompEvaporatingCAPSpdMax; // evaporating capacity at the highest compressor speed [W]
11218 : Real64 CompEvaporatingPWRSpdMin; // compressor power at the lowest compressor speed [W]
11219 : Real64 CompEvaporatingPWRSpdMax; // compressor power at the highest compressor speed [W]
11220 : Real64 CapMaxTe; // maximum Te during operation, for capacity calculations [C]
11221 : Real64 CapMinTe; // minimum Te during operation, for capacity calculations [C]
11222 : Real64 CapMinPe; // minimum Pe during operation, for capacity calculations [Pa]
11223 : Real64 CapMaxTc; // maximum Tc during operation, for capacity calculations [C]
11224 : Real64 CapMaxPc; // maximum Pc during operation, for capacity calculations [Pa]
11225 : Real64 CapMinTc; // minimum Tc during operation, for capacity calculations [C]
11226 : Real64 CapMinPc; // minimum Pc during operation, for capacity calculations [Pa]
11227 : Real64 h_IU_evap_in; // enthalpy of IU evaporator at inlet [kJ/kg]
11228 : Real64 h_IU_evap_in_new; // enthalpy of IU evaporator at inlet (new) [kJ/kg]
11229 : Real64 h_IU_evap_in_low; // enthalpy of IU evaporator at inlet (low) [kJ/kg]
11230 : Real64 h_IU_evap_in_up; // enthalpy of IU evaporator at inlet (up) [kJ/kg]
11231 : Real64 h_IU_evap_out; // enthalpy of IU evaporator at outlet [kJ/kg]
11232 : Real64 h_IU_evap_out_i; // enthalpy of IU evaporator at outlet (individual) [kJ/kg]
11233 : Real64 h_IU_cond_in; // enthalpy of IU condenser at inlet [kJ/kg]
11234 : Real64 h_IU_cond_in_low; // enthalpy of IU condenser at inlet (low) [kJ/kg]
11235 : Real64 h_IU_cond_in_up; // enthalpy of IU condenser at inlet (up) [kJ/kg]
11236 : Real64 h_IU_cond_out; // enthalpy of IU condenser at outlet [kJ/kg]
11237 : Real64 h_IU_cond_out_i; // enthalpy of IU condenser at outlet (individual) [kJ/kg]
11238 : Real64 h_IU_cond_out_ave; // average enthalpy of the refrigerant leaving IU condensers [kJ/kg]
11239 : Real64 h_IU_PLc_out; // enthalpy of refrigerant at the outlet of IU evaporator side main pipe, after piping loss (c) [kJ/kg]
11240 : Real64 h_comp_in; // enthalpy of refrigerant at compressor inlet, after piping loss (c) [kJ/kg]
11241 : Real64 h_comp_in_new; // enthalpy of refrigerant at compressor inlet (new) [kJ/kg]
11242 : Real64 h_comp_out; // enthalpy of refrigerant at compressor outlet [kJ/kg]
11243 : Real64 h_comp_out_new; // enthalpy of refrigerant at compressor outlet (new) [kJ/kg]
11244 : Real64 m_air; // OU coil air mass flow rate [kg/s]
11245 : Real64 m_ref_IU_cond; // mass flow rate of Refrigerant through IU condensers [kg/s]
11246 : Real64 m_ref_IU_cond_i; // mass flow rate of Refrigerant through an individual IU condenser [kg/s]
11247 : Real64 m_ref_IU_evap; // mass flow rate of Refrigerant through IU evaporators [kg/s]
11248 : Real64 m_ref_IU_evap_i; // mass flow rate of Refrigerant through an individual IU evaporator [kg/s]
11249 : Real64 m_ref_OU_evap; // mass flow rate of Refrigerant through OU evaporator [kg/s]
11250 : Real64 m_ref_OU_cond; // mass flow rate of Refrigerant through OU condenser [kg/s]
11251 : Real64 Ncomp; // compressor power [W]
11252 : Real64 Ncomp_new; // compressor power for temporary use in iterations [W]
11253 : Real64 P_comp_in; // pressure of refrigerant at IU condenser outlet [Pa]
11254 : Real64 Pcond; // VRF condensing pressure [Pa]
11255 : Real64 Pevap; // VRF evaporating pressure [Pa]
11256 : Real64 Pdischarge; // VRF compressor discharge pressure [Pa]
11257 : Real64 Psuction; // VRF compressor suction pressure [Pa]
11258 : Real64 Pipe_DeltP_c; // Piping Loss Algorithm Parameter: Pipe pressure drop (c) [Pa]
11259 : Real64 Pipe_DeltP_h; // Piping Loss Algorithm Parameter: Pipe pressure drop (h) [Pa]
11260 : Real64 Pipe_Q_c; // Piping Loss Algorithm Parameter: Heat loss (c) [W]
11261 : Real64 Pipe_Q_h; // Piping Loss Algorithm Parameter: Heat loss (h) [W]
11262 : Real64 Q_c_TU_PL; // Cooling load to be met at cooling mode, including the piping loss(W)
11263 : Real64 Q_h_TU_PL; // Heating load to be met at heating mode, including the piping loss (W)
11264 : Real64 Q_h_OU; // outdoor unit condenser heat release (cooling mode) [W]
11265 : Real64 Q_c_OU; // outdoor unit evaporator heat extract (heating mode) [W]
11266 : Real64 RefMaxPc; // maximum refrigerant condensing pressure [Pa]
11267 : Real64 RefMinTe; // Minimum refrigerant evaporating temperature [Pa]
11268 : Real64 RefMinPe; // Minimum refrigerant evaporating pressure [Pa]
11269 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
11270 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
11271 : Real64 RefTLow; // Low Temperature Value for Ps (max in tables) [C]
11272 : Real64 RefTHigh; // High Temperature Value for Ps (max in tables) [C]
11273 : Real64 RefTSat; // Saturated temperature of the refrigerant. Used to check whether the refrigerant is in the superheat area [C]
11274 : Real64 SC_IU_merged; // Piping Loss Algorithm Parameter: average subcooling degrees after the indoor units [C]
11275 : Real64 SH_IU_merged; // Piping Loss Algorithm Parameter: average super heating degrees after the indoor units [C]
11276 : Real64 SC_OU; // subcooling degrees at OU condenser [C]
11277 : Real64 SH_OU; // super heating degrees at OU evaporator [C]
11278 : Real64 SH_Comp; // Temperature difference between compressor inlet node and Tsuction [C]
11279 : Real64 T_comp_in; // temperature of refrigerant at compressor inlet, after piping loss (c) [C]
11280 : Real64 TU_HeatingLoad; // Heating load from terminal units, excluding heating loss [W]
11281 : Real64 TU_CoolingLoad; // Cooling load from terminal units, excluding heating loss [W]
11282 : Real64 Tdischarge; // VRF Compressor discharge refrigerant temperature [C]
11283 : Real64 Tsuction; // VRF compressor suction refrigerant temperature [C]
11284 : Real64 Tolerance; // Tolerance for condensing temperature calculation [C]
11285 : Real64 Tfs; // Temperature of the air at the coil surface [C]
11286 2368 : Array1D<Real64> CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W]
11287 2368 : Array1D<Real64> CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W]
11288 :
11289 : // variable initializations
11290 2368 : TUListNum = this->ZoneTUListPtr;
11291 2368 : NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
11292 2368 : VRFCond = state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(1)).VRFSysNum;
11293 2368 : TU_CoolingLoad = 0.0;
11294 2368 : TU_HeatingLoad = 0.0;
11295 2368 : TUParasiticPower = 0.0;
11296 2368 : TUFanPower = 0.0;
11297 2368 : CoolingPLR = 0.0;
11298 2368 : HeatingPLR = 0.0;
11299 2368 : CyclingRatio = 1.0;
11300 2368 : SumCoolInletWB = 0.0;
11301 2368 : SumHeatInletDB = 0.0;
11302 2368 : SumHeatInletWB = 0.0;
11303 2368 : TotalCondCoolingCapacity = 0.0;
11304 2368 : TotalCondHeatingCapacity = 0.0;
11305 2368 : TotalTUCoolingCapacity = 0.0;
11306 2368 : TotalTUHeatingCapacity = 0.0;
11307 2368 : NumTUInCoolingMode = 0;
11308 2368 : NumTUInHeatingMode = 0;
11309 2368 : Tolerance = 0.05;
11310 2368 : Counter = 1;
11311 2368 : NumIteHIUIn = 1;
11312 2368 : this->ElecCoolingPower = 0.0;
11313 2368 : this->ElecHeatingPower = 0.0;
11314 2368 : this->CrankCaseHeaterPower = 0.0;
11315 2368 : this->EvapCondPumpElecPower = 0.0; // for EvaporativelyCooled condenser
11316 2368 : this->EvapWaterConsumpRate = 0.0;
11317 2368 : this->DefrostPower = 0.0;
11318 2368 : this->OperatingCoolingCOP = 0.0;
11319 2368 : this->OperatingHeatingCOP = 0.0;
11320 2368 : this->OperatingCOP = 0.0;
11321 2368 : this->SCHE = 0.0;
11322 2368 : this->BasinHeaterPower = 0.0;
11323 2368 : this->CondensingTemp = 60.0; // OutDryBulbTemp;
11324 2368 : this->VRFHeatRec = 0.0;
11325 :
11326 : // Refrigerant data
11327 2368 : RefMinTe = -15;
11328 2368 : RefMaxPc = 4000000.0;
11329 2368 : RefMinPe = this->refrig->getSatPressure(state, RefMinTe, RoutineName);
11330 2368 : RefTLow = this->refrig->PsLowTempValue; // High Temperature Value for Ps (max in tables)
11331 2368 : RefTHigh = this->refrig->PsHighTempValue; // High Temperature Value for Ps (max in tables)
11332 2368 : RefPLow = this->refrig->PsLowPresValue; // Low Pressure Value for Ps (>0.0)
11333 2368 : RefPHigh = this->refrig->PsHighPresValue; // High Pressure Value for Ps (max in tables)
11334 :
11335 : // sum loads on TU coils
11336 4736 : for (NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
11337 2368 : TU_CoolingLoad += state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU);
11338 2368 : TU_HeatingLoad += state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU);
11339 2368 : TUParasiticPower +=
11340 2368 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU)).ParasiticCoolElecPower +
11341 2368 : state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU)).ParasiticHeatElecPower;
11342 2368 : TUFanPower += state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU)).FanPower;
11343 : }
11344 2368 : this->TUCoolingLoad = TU_CoolingLoad; // this is cooling coil load, not terminal unit load
11345 2368 : this->TUHeatingLoad = TU_HeatingLoad; // this is heating coil load, not terminal unit load
11346 :
11347 : // loop through TU's and calculate average inlet conditions for active coils
11348 4736 : for (NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
11349 2368 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
11350 2368 : CoolCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
11351 2368 : HeatCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex;
11352 :
11353 2368 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) > 0.0) {
11354 1171 : SumCoolInletWB += state.dataDXCoils->DXCoilCoolInletAirWBTemp(CoolCoilIndex) *
11355 1171 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) / TU_CoolingLoad;
11356 1171 : ++NumTUInCoolingMode;
11357 : }
11358 2368 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) > 0.0) {
11359 1158 : SumHeatInletDB += state.dataDXCoils->DXCoilHeatInletAirDBTemp(HeatCoilIndex) *
11360 1158 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) / TU_HeatingLoad;
11361 1158 : SumHeatInletWB += state.dataDXCoils->DXCoilHeatInletAirWBTemp(HeatCoilIndex) *
11362 1158 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) / TU_HeatingLoad;
11363 1158 : ++NumTUInHeatingMode;
11364 : }
11365 : }
11366 :
11367 : // set condenser entering air conditions (Outdoor air conditions)
11368 2368 : if (this->CondenserNodeNum != 0) {
11369 0 : OutdoorDryBulb = state.dataLoopNodes->Node(this->CondenserNodeNum).Temp;
11370 0 : if (this->CondenserType != DataHeatBalance::RefrigCondenserType::Water) {
11371 0 : OutdoorHumRat = state.dataLoopNodes->Node(this->CondenserNodeNum).HumRat;
11372 0 : OutdoorPressure = state.dataLoopNodes->Node(this->CondenserNodeNum).Press;
11373 0 : OutdoorWetBulb = state.dataLoopNodes->Node(this->CondenserNodeNum).OutAirWetBulb;
11374 : } else {
11375 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
11376 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11377 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
11378 : }
11379 : } else {
11380 2368 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
11381 2368 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
11382 2368 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11383 2368 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
11384 : }
11385 2368 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
11386 :
11387 2368 : CondInletTemp = OutdoorDryBulb; // this->CondenserType == AirCooled
11388 2368 : this->CondenserInletTemp = CondInletTemp;
11389 :
11390 : //*************
11391 : // VRF-HP MODES:
11392 : // 1. Cooling
11393 : // 2. Heating
11394 : // 3. No running
11395 : // VRF-HR MODES:
11396 : // 1. Cooling Only
11397 : // 2. Cooling Dominant w/o HR Loss
11398 : // 3. Cooling Dominant w/ HR Loss
11399 : // 4. Heating Dominant w/ HR Loss
11400 : // 5. Heating Dominant w/o HR Loss
11401 : // 6. Heating Only
11402 : // 7. No running
11403 :
11404 : // Flag for VRF-HR Operations
11405 2368 : if (TU_HeatingLoad > 0) {
11406 1158 : HRHeatRequestFlag = true;
11407 : } else {
11408 1210 : state.dataHVACVarRefFlow->HeatingLoad(VRFCond) = false;
11409 1210 : HRHeatRequestFlag = false;
11410 : }
11411 2368 : if (TU_CoolingLoad > 0) {
11412 1171 : HRCoolRequestFlag = true;
11413 : } else {
11414 1197 : state.dataHVACVarRefFlow->CoolingLoad(VRFCond) = false;
11415 1197 : HRCoolRequestFlag = false;
11416 : }
11417 :
11418 : // Initialization for Ncomp iterations
11419 2368 : NumOfCompSpdInput = this->CompressorSpeed.size();
11420 2368 : CompEvaporatingPWRSpd.dimension(NumOfCompSpdInput);
11421 2368 : CompEvaporatingCAPSpd.dimension(NumOfCompSpdInput);
11422 2368 : this->OperatingMode = 0; // report variable for heating or cooling mode
11423 :
11424 : // 1. VRF-HP Cooling Mode .OR. VRF-HR Mode_1
11425 3566 : if ((!this->HeatRecoveryUsed && state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) ||
11426 1198 : (this->HeatRecoveryUsed && !HRHeatRequestFlag && HRCoolRequestFlag)) {
11427 :
11428 1171 : this->OperatingMode = ModeCoolingOnly;
11429 1171 : this->VRFOperationSimPath = 10;
11430 :
11431 : // Initialization of VRF-FluidTCtrl Model
11432 1171 : Q_c_TU_PL = TU_CoolingLoad;
11433 :
11434 : // Evaporator (IU side) operational parameters
11435 1171 : Pevap = this->refrig->getSatPressure(state, this->IUEvaporatingTemp, RoutineName);
11436 1171 : Psuction = Pevap;
11437 1171 : this->EvaporatingTemp =
11438 1171 : this->IUEvaporatingTemp; // GetSatTemperatureRefrig(state, this->RefrigerantName, max( min( Pevap, RefPHigh ), RefPLow
11439 : // ), RefrigerantIndex, RoutineName );
11440 :
11441 : // Condenser (OU side) operation ranges
11442 1171 : CapMaxPc = min(Psuction + this->CompMaxDeltaP, RefMaxPc);
11443 1171 : CapMaxTc = this->refrig->getSatTemperature(state, max(min(CapMaxPc, RefPHigh), RefPLow), RoutineName);
11444 1171 : CapMinTc = OutdoorDryBulb + this->SC;
11445 1171 : CapMinPc = this->refrig->getSatPressure(state, CapMinTc, RoutineName);
11446 :
11447 : // Evaporator (IU side) operation ranges
11448 1171 : CapMinPe = max(CapMinPc - this->CompMaxDeltaP, RefMinPe);
11449 1171 : CapMinTe = this->refrig->getSatTemperature(state, max(min(CapMinPe, RefPHigh), RefPLow), RoutineName);
11450 :
11451 : // Evaporative capacity ranges
11452 1171 : CompEvaporatingCAPSpdMin = this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(1), CapMinTc, CapMinTe);
11453 1171 : CompEvaporatingPWRSpdMin = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(1), CapMinTc, CapMinTe);
11454 2342 : CompEvaporatingCAPSpdMax = this->CoffEvapCap * this->RatedEvapCapacity *
11455 1171 : CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), this->CondensingTemp, this->IUEvaporatingTemp);
11456 1171 : CompEvaporatingPWRSpdMax =
11457 1171 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(NumOfCompSpdInput), this->CondensingTemp, this->IUEvaporatingTemp);
11458 :
11459 : // Initialization for h_IU_evap_in iterations (Label12)
11460 1171 : h_IU_evap_in_low = this->refrig->getSatEnthalpy(state, OutdoorDryBulb - this->SC, 0.0, RoutineName); // Tc = Tamb
11461 1171 : h_IU_evap_in_up = this->refrig->getSatEnthalpy(state, CapMaxTc - this->SC, 0.0, RoutineName); // Tc = CapMaxTc
11462 1171 : h_IU_evap_in = this->refrig->getSatEnthalpy(state, OutdoorDryBulb + 10 - this->SC, 0.0, RoutineName); // Tc = Tamb+10
11463 :
11464 1171 : NumIteHIUIn = 1;
11465 : bool converged_12;
11466 : do {
11467 1555 : m_ref_IU_evap = 0;
11468 1555 : h_IU_evap_out = 0;
11469 1555 : h_IU_evap_out_i = 0;
11470 1555 : m_ref_IU_evap_i = 0;
11471 1555 : SH_IU_merged = 0;
11472 :
11473 : // Calculate total IU refrigerant flow rate and SH_IU_merged
11474 1555 : if (Q_c_TU_PL > CompEvaporatingCAPSpdMax) {
11475 : // Required load is beyond the max system capacity
11476 :
11477 236 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11478 472 : h_IU_evap_out = this->refrig->getSupHeatEnthalpy(
11479 236 : state, max(RefTSat, this->IUEvaporatingTemp + 3), max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11480 236 : SH_IU_merged = 3;
11481 236 : m_ref_IU_evap = TU_CoolingLoad / (h_IU_evap_out - h_IU_evap_in);
11482 :
11483 : } else {
11484 :
11485 2638 : for (NumTU = 1; NumTU <= NumTUInList; NumTU++) { // Calc total refrigerant flow rate
11486 1319 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) > 0) {
11487 1319 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
11488 1319 : CoolCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
11489 :
11490 1319 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11491 2638 : h_IU_evap_out_i = this->refrig->getSupHeatEnthalpy(
11492 : state,
11493 1319 : max(RefTSat, this->IUEvaporatingTemp + state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH),
11494 : max(min(Pevap, RefPHigh), RefPLow),
11495 : RoutineName);
11496 :
11497 1319 : if (h_IU_evap_out_i > h_IU_evap_in) {
11498 1319 : m_ref_IU_evap_i = (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) <= 0.0)
11499 1319 : ? 0.0
11500 1319 : : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) /
11501 1319 : (h_IU_evap_out_i - h_IU_evap_in)); // Ref Flow Rate in the IU( kg/s )
11502 1319 : m_ref_IU_evap = m_ref_IU_evap + m_ref_IU_evap_i;
11503 1319 : h_IU_evap_out = h_IU_evap_out + m_ref_IU_evap_i * h_IU_evap_out_i;
11504 1319 : SH_IU_merged = SH_IU_merged + m_ref_IU_evap_i * state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH;
11505 : }
11506 : }
11507 : }
11508 1319 : if (m_ref_IU_evap > 0) {
11509 1319 : h_IU_evap_out = h_IU_evap_out / m_ref_IU_evap;
11510 1319 : SH_IU_merged = SH_IU_merged / m_ref_IU_evap;
11511 : } else {
11512 0 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11513 0 : h_IU_evap_out = this->refrig->getSupHeatEnthalpy(
11514 0 : state, max(RefTSat, this->IUEvaporatingTemp + 3), max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11515 0 : SH_IU_merged = 3;
11516 0 : m_ref_IU_evap = TU_CoolingLoad / (h_IU_evap_out - h_IU_evap_in);
11517 : }
11518 : }
11519 :
11520 : // *Calculate piping loss
11521 1555 : this->VRFOU_PipeLossC(state,
11522 : m_ref_IU_evap,
11523 : max(min(Pevap, RefPHigh), RefPLow),
11524 : h_IU_evap_out,
11525 : SH_IU_merged,
11526 : OutdoorDryBulb,
11527 : Pipe_Q_c,
11528 : Pipe_DeltP_c,
11529 : h_comp_in);
11530 1555 : Tsuction = this->refrig->getSatTemperature(state, max(min(Pevap - Pipe_DeltP_c, RefPHigh), RefPLow), RoutineName);
11531 1555 : Psuction = Pevap - Pipe_DeltP_c; // This Psuction is used for rps > min; will be updated for rps = min
11532 :
11533 : // Perform iteration to calculate T_comp_in
11534 1555 : T_comp_in = this->refrig->getSupHeatTemp(
11535 : state, max(min(Pevap - Pipe_DeltP_c, RefPHigh), RefPLow), h_comp_in, Tsuction + 3, Tsuction + 30, RoutineName);
11536 1555 : SH_Comp = T_comp_in - Tsuction; // This is used for rps > min; will be updated for rps = min
11537 :
11538 1555 : Q_c_TU_PL = TU_CoolingLoad + Pipe_Q_c;
11539 1555 : Q_h_OU = Q_c_TU_PL + CompEvaporatingPWRSpdMin;
11540 :
11541 : // *Calculate capacity modification factor
11542 1555 : C_cap_operation = this->VRFOU_CapModFactor(
11543 : state, h_comp_in, h_IU_evap_in, max(min(Psuction, RefPHigh), RefPLow), Tsuction + SH_Comp, Tsuction + 8, CapMinTc - 5);
11544 :
11545 : // Iteration_Ncomp: Perform iterations to calculate Ncomp (Label10)
11546 1555 : Counter = 1;
11547 1555 : Ncomp = TU_CoolingLoad / this->CoolingCOP;
11548 1555 : Ncomp_new = Ncomp;
11549 : bool converged_10;
11550 : do {
11551 2834 : Q_h_OU = Q_c_TU_PL + Ncomp_new; // Ncomp_new may be updated during Iteration_Ncomp Label10
11552 :
11553 : // *VRF OU TeTc calculations
11554 2834 : m_air = this->OUAirFlowRate * RhoAir;
11555 2834 : SC_OU = this->SC;
11556 2834 : this->VRFOU_TeTc(
11557 2834 : state, HXOpMode::CondMode, Q_h_OU, SC_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->CondensingTemp);
11558 2834 : this->CondensingTemp = min(CapMaxTc, this->CondensingTemp);
11559 2834 : this->SC = SC_OU;
11560 :
11561 : // *VEF OU Compressor Simulation at cooling mode: Specify the compressor speed and power consumption
11562 2834 : this->VRFOU_CalcCompC(state,
11563 : TU_CoolingLoad,
11564 : Tsuction,
11565 : this->CondensingTemp,
11566 : Psuction,
11567 : T_comp_in,
11568 : h_comp_in,
11569 : h_IU_evap_in,
11570 : Pipe_Q_c,
11571 : CapMaxTc,
11572 : Q_h_OU,
11573 : CompSpdActual,
11574 : Ncomp,
11575 : CyclingRatio);
11576 :
11577 2834 : converged_10 = (std::abs(Ncomp - Ncomp_new) <= (Tolerance * Ncomp_new)) || (Counter >= 30);
11578 2834 : if (!converged_10) {
11579 1279 : Ncomp_new = Ncomp;
11580 : }
11581 2834 : } while (!converged_10);
11582 :
11583 : // Update h_IU_evap_in in iterations Label12
11584 1555 : h_IU_evap_in_new = this->refrig->getSatEnthalpy(state, this->CondensingTemp - this->SC, 0.0, RoutineName);
11585 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) &&
11586 384 : (h_IU_evap_in > h_IU_evap_in_low));
11587 1555 : h_IU_evap_in = h_IU_evap_in_new;
11588 1555 : NumIteHIUIn = NumIteHIUIn + 1;
11589 1555 : } while (!converged_12);
11590 1171 : if ((std::abs(h_IU_evap_in - h_IU_evap_in_new) > Tolerance * h_IU_evap_in)) {
11591 0 : h_IU_evap_in = 0.5 * (h_IU_evap_in_low + h_IU_evap_in_up);
11592 1171 : } else if (h_IU_evap_in > h_IU_evap_in_up) {
11593 0 : h_IU_evap_in = h_IU_evap_in_up;
11594 1171 : } else if (h_IU_evap_in < h_IU_evap_in_low) {
11595 0 : h_IU_evap_in = h_IU_evap_in_low;
11596 : } else {
11597 1171 : h_IU_evap_in = (h_IU_evap_in + h_IU_evap_in_new) / 2;
11598 : }
11599 :
11600 : // Key outputs of this subroutine
11601 1171 : Ncomp *= CyclingRatio;
11602 1171 : Q_h_OU *= CyclingRatio;
11603 1171 : this->CompActSpeed = max(CompSpdActual, 0.0);
11604 1171 : this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter; // 0.95 is the efficiency of the compressor inverter, can come from IDF //@minor
11605 1171 : this->OUFanPower = this->RatedOUFanPower * CyclingRatio; //@ * pow_3( CondFlowRatio )
11606 1171 : this->VRFCondCyclingRatio = CyclingRatio; // report variable for cycling rate
11607 :
11608 1171 : Tdischarge = this->CondensingTemp; // outdoor unit condensing temperature
11609 1171 : this->CoolingCapacity =
11610 2342 : this->CoffEvapCap * this->RatedEvapCapacity *
11611 2342 : CurveValue(
11612 1171 : state, this->OUCoolingCAPFT(NumOfCompSpdInput), Tdischarge, Tsuction); // Include the piping loss, at the highest compressor speed
11613 1171 : this->PipingCorrectionCooling = TU_CoolingLoad / (TU_CoolingLoad + Pipe_Q_c);
11614 1171 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond) = this->CoolingCapacity; // for report, maximum evaporating capacity of the system
11615 :
11616 1171 : this->HeatingCapacity = 0.0; // Include the piping loss
11617 1171 : this->PipingCorrectionHeating = 1.0; // 1 means no piping loss
11618 1171 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) = Constant::MaxCap;
11619 :
11620 1171 : this->OUCondHeatRate = Q_h_OU;
11621 1171 : this->OUEvapHeatRate = 0;
11622 1171 : this->IUCondHeatRate = 0;
11623 1171 : this->IUEvapHeatRate = TU_CoolingLoad;
11624 :
11625 : // 2. VRF-HP Heating Mode .OR. VRF-HR Mode_6
11626 1236 : } else if ((!this->HeatRecoveryUsed && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) ||
11627 39 : (this->HeatRecoveryUsed && !HRCoolRequestFlag && HRHeatRequestFlag)) {
11628 :
11629 1158 : this->OperatingMode = ModeHeatingOnly;
11630 1158 : this->VRFOperationSimPath = 60;
11631 :
11632 : // Initialization of VRF-FluidTCtrl Model
11633 1158 : Q_h_TU_PL = TU_HeatingLoad;
11634 1158 : Ncomp = TU_HeatingLoad / this->HeatingCOP;
11635 1158 : this->CondensingTemp = this->IUCondensingTemp;
11636 :
11637 : // Evaporative capacity ranges_Max
11638 1158 : CapMaxTe = OutdoorDryBulb - this->SH;
11639 2316 : CompEvaporatingCAPSpdMax = this->CoffEvapCap * this->RatedEvapCapacity *
11640 1158 : CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), this->IUCondensingTemp, CapMaxTe);
11641 1158 : CompEvaporatingPWRSpdMax =
11642 1158 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(NumOfCompSpdInput), this->IUCondensingTemp, CapMaxTe);
11643 :
11644 : // Initialization of h_comp_out iterations (Label23)
11645 1158 : Pcond = this->refrig->getSatPressure(state, 40.0, RoutineName);
11646 1158 : RefTSat = this->refrig->getSatTemperature(state, Pcond, RoutineName);
11647 1158 : h_IU_cond_in_up = this->refrig->getSupHeatEnthalpy(state, max(RefTSat, min(this->IUCondensingTemp + 50, RefTHigh)), Pcond, RoutineName);
11648 1158 : h_IU_cond_in_low = this->refrig->getSatEnthalpy(state, this->IUCondensingTemp, 1.0, RoutineName); // Quality=1
11649 1158 : h_IU_cond_in = h_IU_cond_in_low;
11650 :
11651 : bool converged_23;
11652 : do {
11653 2908 : m_ref_IU_cond = 0;
11654 2908 : h_IU_cond_out_ave = 0;
11655 2908 : SC_IU_merged = 0;
11656 :
11657 : // Calculate total refrigerant flow rate
11658 2908 : if (Q_h_TU_PL > CompEvaporatingCAPSpdMax + CompEvaporatingPWRSpdMax) {
11659 : // Required load is beyond the max system capacity
11660 :
11661 : h_IU_cond_out =
11662 0 : this->refrig->getSatEnthalpy(state,
11663 0 : this->refrig->getSatTemperature(state, max(min(Pcond, RefPHigh), RefPLow), RoutineName) - 5.0,
11664 : 0.0,
11665 : RoutineName); // Quality=0
11666 0 : h_IU_cond_out_ave = h_IU_cond_out;
11667 0 : SC_IU_merged = 5;
11668 0 : m_ref_IU_cond = TU_HeatingLoad / (h_IU_cond_in - h_IU_cond_out);
11669 :
11670 : } else {
11671 5816 : for (NumTU = 1; NumTU <= NumTUInList; NumTU++) {
11672 2908 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) > 0) {
11673 2908 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
11674 2908 : HeatCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex;
11675 : h_IU_cond_out_i =
11676 8724 : this->refrig->getSatEnthalpy(state,
11677 2908 : this->refrig->getSatTemperature(state, max(min(Pcond, RefPHigh), RefPLow), RoutineName) -
11678 2908 : state.dataDXCoils->DXCoil(HeatCoilIndex).ActualSC,
11679 : 0.0,
11680 : RoutineName); // Quality=0
11681 2908 : m_ref_IU_cond_i =
11682 2908 : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) <= 0.0)
11683 2908 : ? 0.0
11684 2908 : : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) / (h_IU_cond_in - h_IU_cond_out_i));
11685 2908 : m_ref_IU_cond = m_ref_IU_cond + m_ref_IU_cond_i;
11686 2908 : h_IU_cond_out_ave = h_IU_cond_out_ave + m_ref_IU_cond_i * h_IU_cond_out_i;
11687 2908 : SC_IU_merged = SC_IU_merged + m_ref_IU_cond_i * state.dataDXCoils->DXCoil(HeatCoilIndex).ActualSC;
11688 : }
11689 : }
11690 2908 : if (m_ref_IU_cond > 0) {
11691 2908 : h_IU_cond_out_ave = h_IU_cond_out_ave / m_ref_IU_cond; // h_merge
11692 2908 : SC_IU_merged = SC_IU_merged / m_ref_IU_cond;
11693 : } else {
11694 : h_IU_cond_out_ave =
11695 0 : this->refrig->getSatEnthalpy(state,
11696 0 : this->refrig->getSatTemperature(state, max(min(Pcond, RefPHigh), RefPLow), RoutineName) - 5.0,
11697 : 0.0,
11698 : RoutineName); // Quality=0
11699 0 : SC_IU_merged = 5;
11700 0 : m_ref_IU_cond = TU_HeatingLoad / (h_IU_cond_in - h_IU_cond_out_ave);
11701 : }
11702 : }
11703 :
11704 : // *Calculate piping loss
11705 2908 : this->VRFOU_PipeLossH(
11706 : state, m_ref_IU_cond, max(min(Pcond, RefPHigh), RefPLow), h_IU_cond_in, OutdoorDryBulb, Pipe_Q_h, Pipe_DeltP_h, h_comp_out);
11707 :
11708 2908 : Pdischarge = max(Pcond + Pipe_DeltP_h, Pcond); // affected by piping loss
11709 2908 : Tdischarge = this->refrig->getSatTemperature(state, max(min(Pdischarge, RefPHigh), RefPLow), RoutineName);
11710 :
11711 : // Evaporative capacity ranges_Min
11712 : // suction pressure lower bound need to be no less than both terms in the following
11713 2908 : CapMinPe = max(Pdischarge - this->CompMaxDeltaP, RefMinPe);
11714 2908 : CapMinTe = this->refrig->getSatTemperature(state, max(min(CapMinPe, RefPHigh), RefPLow), RoutineName);
11715 2908 : CompEvaporatingCAPSpdMin = this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(1), Tdischarge, CapMinTe);
11716 2908 : CompEvaporatingPWRSpdMin = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(1), Tdischarge, CapMinTe);
11717 :
11718 2908 : Q_h_TU_PL = TU_HeatingLoad + Pipe_Q_h;
11719 2908 : Q_c_OU = max(0.0, Q_h_TU_PL - CompEvaporatingPWRSpdMin);
11720 :
11721 : // *Calculate capacity modification factor
11722 2908 : RefTSat = this->refrig->getSatTemperature(state, max(min(CapMinPe, RefPHigh), RefPLow), RoutineName);
11723 2908 : h_comp_in =
11724 2908 : this->refrig->getSupHeatEnthalpy(state, max(RefTSat, CapMinTe + this->SH), max(min(CapMinPe, RefPHigh), RefPLow), RoutineName);
11725 2908 : C_cap_operation = this->VRFOU_CapModFactor(state,
11726 : h_comp_in,
11727 : h_IU_cond_out_ave,
11728 : max(min(CapMinPe, RefPHigh), RefPLow),
11729 2908 : CapMinTe + this->SH,
11730 : CapMinTe + 8,
11731 2908 : this->IUCondensingTemp - 5);
11732 :
11733 : Real64 CompEvaporatingCAPSpdMaxCurrentTsuc =
11734 5816 : this->CoffEvapCap * this->RatedEvapCapacity *
11735 2908 : CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), Tdischarge, this->EvaporatingTemp);
11736 : Real64 CompEvaporatingPWRSpdMaxCurrentTsuc =
11737 2908 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(NumOfCompSpdInput), Tdischarge, this->EvaporatingTemp);
11738 2908 : if (CompEvaporatingCAPSpdMin > CompEvaporatingCAPSpdMaxCurrentTsuc) {
11739 0 : if (this->CondenserCapErrIdx == 0) {
11740 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), this->Name));
11741 0 : ShowContinueErrorTimeStamp(state,
11742 0 : format(" Evaporative Capacity at max speed is smaller than evaporative capacity at min speed, "
11743 : "{:.3T} < {:.3T}",
11744 : CompEvaporatingCAPSpdMaxCurrentTsuc,
11745 : CompEvaporatingCAPSpdMin));
11746 : }
11747 0 : ShowRecurringSevereErrorAtEnd(
11748 : state,
11749 0 : format("\"{}\" - Evaporative Capacity at max speed is smaller than evaporative capacity at min speed ", this->Name),
11750 0 : this->CondenserCapErrIdx,
11751 0 : CompEvaporatingCAPSpdMaxCurrentTsuc - CompEvaporatingCAPSpdMin,
11752 0 : CompEvaporatingCAPSpdMaxCurrentTsuc - CompEvaporatingCAPSpdMin);
11753 : }
11754 2908 : if ((Q_c_OU * C_cap_operation) > CompEvaporatingCAPSpdMaxCurrentTsuc) {
11755 : // this branch resolves the issue of supplemental heating coil turning on when compressor speed is not at the highest
11756 0 : Q_c_OU = CompEvaporatingCAPSpdMaxCurrentTsuc;
11757 0 : CompSpdActual = this->CompressorSpeed(NumOfCompSpdInput);
11758 0 : Ncomp = CompEvaporatingPWRSpdMaxCurrentTsuc;
11759 0 : m_air = this->OUAirFlowRate * RhoAir;
11760 0 : SH_OU = this->SH;
11761 0 : this->VRFOU_TeTc(
11762 0 : state, HXOpMode::EvapMode, Q_c_OU, SH_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->EvaporatingTemp);
11763 1158 : break;
11764 : } else {
11765 : // CompEvaporatingCAPSpdMin < (Q_c_OU * C_cap_operation) <= CompEvaporatingCAPSpdMaxCurrentTsuc + CompEvaporatingPWRSpdMaxCurrentTsuc
11766 : // Required heating load is greater than or equal to the min heating capacity
11767 :
11768 : // Iteration_Ncomp: Perform iterations to calculate Ncomp (Label20)
11769 2908 : Counter = 1;
11770 : bool converged_20;
11771 : do {
11772 5269 : Ncomp_new = Ncomp;
11773 5269 : Q_c_OU = max(0.0, Q_h_TU_PL - Ncomp);
11774 :
11775 : // *VRF OU Te calculations
11776 5269 : m_air = this->OUAirFlowRate * RhoAir;
11777 5269 : SH_OU = this->SH;
11778 5269 : this->VRFOU_TeTc(
11779 5269 : state, HXOpMode::EvapMode, Q_c_OU, SH_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->EvaporatingTemp);
11780 5269 : this->SH = SH_OU;
11781 :
11782 : // *VRF OU Compressor Simulation at heating mode: Specify the compressor speed and power consumption
11783 5269 : this->VRFOU_CalcCompH(state,
11784 : TU_HeatingLoad,
11785 : this->EvaporatingTemp,
11786 : Tdischarge,
11787 : h_IU_cond_out_ave,
11788 : this->IUCondensingTemp,
11789 : CapMinTe,
11790 : Tfs,
11791 : Pipe_Q_h,
11792 : Q_c_OU,
11793 : CompSpdActual,
11794 : Ncomp_new,
11795 : CyclingRatio);
11796 :
11797 5269 : converged_20 = (std::abs(Ncomp_new - Ncomp) <= (Tolerance * Ncomp)) || (Counter >= 30);
11798 5269 : Counter = Counter + 1;
11799 5269 : if (!converged_20) {
11800 2361 : Ncomp = Ncomp_new;
11801 : }
11802 5269 : } while (!converged_20);
11803 :
11804 : // Update h_comp_out in iteration Label23
11805 2908 : P_comp_in = this->refrig->getSatPressure(state, this->EvaporatingTemp, RoutineName);
11806 2908 : RefTSat = this->refrig->getSatTemperature(state, max(min(P_comp_in, RefPHigh), RefPLow), RoutineName);
11807 5816 : h_comp_in_new = this->refrig->getSupHeatEnthalpy(
11808 2908 : state, max(RefTSat, this->SH + this->EvaporatingTemp), max(min(P_comp_in, RefPHigh), RefPLow), RoutineName);
11809 2908 : h_comp_out_new = Ncomp_new / m_ref_IU_cond + h_comp_in_new;
11810 :
11811 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));
11812 2908 : if (!converged_23) {
11813 1750 : h_IU_cond_in = h_IU_cond_in + 0.1 * (h_IU_cond_in_up - h_IU_cond_in_low);
11814 : } else {
11815 1158 : if (h_IU_cond_in > h_IU_cond_in_up) {
11816 0 : h_IU_cond_in = 0.5 * (h_IU_cond_in_up + h_IU_cond_in_low);
11817 : }
11818 1158 : Ncomp = Ncomp_new;
11819 1158 : break;
11820 : }
11821 : }
11822 1750 : } while (!converged_23);
11823 :
11824 : // Key outputs of this subroutine
11825 1158 : Q_c_OU *= CyclingRatio;
11826 1158 : this->CompActSpeed = max(CompSpdActual, 0.0);
11827 1158 : this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter;
11828 1158 : this->OUFanPower = this->RatedOUFanPower * CyclingRatio;
11829 1158 : this->VRFCondCyclingRatio = CyclingRatio;
11830 :
11831 1158 : Tsuction = this->EvaporatingTemp; // Outdoor unit evaporating temperature
11832 1158 : this->HeatingCapacity =
11833 1158 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), Tdischarge, Tsuction) +
11834 3474 : this->RatedCompPower * CurveValue(state,
11835 1158 : this->OUCoolingPWRFT(NumOfCompSpdInput),
11836 : Tdischarge,
11837 : Tsuction); // Include the piping loss, at the highest compressor speed
11838 1158 : this->PipingCorrectionHeating = TU_HeatingLoad / (TU_HeatingLoad + Pipe_Q_h);
11839 1158 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) =
11840 1158 : this->HeatingCapacity; // for report, maximum condensing capacity the system can provide
11841 :
11842 1158 : this->CoolingCapacity = 0.0; // Include the piping loss
11843 1158 : this->PipingCorrectionCooling = 1.0;
11844 1158 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond) = Constant::MaxCap; // for report
11845 :
11846 1158 : this->OUCondHeatRate = 0;
11847 1158 : this->OUEvapHeatRate = Q_c_OU;
11848 1158 : this->IUCondHeatRate = TU_HeatingLoad;
11849 1158 : this->IUEvapHeatRate = 0;
11850 :
11851 : // 3. VRF-HR Mode_2-5, Simultaneous Heating and Cooling
11852 39 : } else if (this->HeatRecoveryUsed && HRCoolRequestFlag && HRHeatRequestFlag) {
11853 :
11854 0 : this->OperatingMode = ModeCoolingAndHeating;
11855 :
11856 : // Initialization of VRF-FluidTCtrl Model
11857 0 : Q_c_TU_PL = TU_CoolingLoad;
11858 0 : Q_h_TU_PL = TU_HeatingLoad;
11859 :
11860 : // Evaporator (IU side) operational parameters
11861 0 : Pevap = this->refrig->getSatPressure(state, this->IUEvaporatingTemp, RoutineName);
11862 0 : Psuction = Pevap;
11863 0 : this->EvaporatingTemp = this->IUEvaporatingTemp;
11864 :
11865 : // Condenser (OU side) operation ranges
11866 0 : CapMaxPc = min(Psuction + this->CompMaxDeltaP, RefMaxPc);
11867 0 : CapMaxTc = this->refrig->getSatTemperature(state, max(min(CapMaxPc, RefPHigh), RefPLow), RoutineName);
11868 0 : CapMinTc = OutdoorDryBulb + this->SC;
11869 0 : CapMinPc = this->refrig->getSatPressure(state, CapMinTc, RoutineName);
11870 :
11871 : // Evaporator (IU side) operation ranges
11872 0 : CapMinPe = max(CapMinPc - this->CompMaxDeltaP, RefMinPe);
11873 0 : CapMinTe = this->refrig->getSatTemperature(state, max(min(CapMinPe, RefPHigh), RefPLow), RoutineName);
11874 :
11875 : //===**h_comp_out Iteration Starts
11876 :
11877 : // Initialization of h_comp_out iterations (Label230)
11878 : {
11879 0 : Pcond = this->refrig->getSatPressure(state, this->IUCondensingTemp, RoutineName);
11880 0 : Real64 Pcond_temp = this->refrig->getSatPressure(state, 40.0, RoutineName);
11881 0 : RefTSat = this->refrig->getSatTemperature(state, Pcond_temp, RoutineName);
11882 : h_IU_cond_in_up =
11883 0 : this->refrig->getSupHeatEnthalpy(state, max(RefTSat, min(this->IUCondensingTemp + 50, RefTHigh)), Pcond_temp, RoutineName);
11884 0 : h_IU_cond_in_low = this->refrig->getSatEnthalpy(state, this->IUCondensingTemp, 1.0, RoutineName); // Quality=1
11885 0 : h_IU_cond_in = h_IU_cond_in_low;
11886 : }
11887 :
11888 : bool converged_230;
11889 : do {
11890 : // *PL-h: Calculate total refrigerant flow rate
11891 0 : m_ref_IU_cond = 0;
11892 0 : h_IU_cond_out_ave = 0;
11893 0 : SC_IU_merged = 0;
11894 0 : for (NumTU = 1; NumTU <= NumTUInList; NumTU++) {
11895 0 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) > 0) {
11896 0 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
11897 0 : HeatCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex;
11898 : h_IU_cond_out_i =
11899 0 : this->refrig->getSatEnthalpy(state,
11900 0 : this->refrig->getSatTemperature(state, max(min(Pcond, RefPHigh), RefPLow), RoutineName) -
11901 0 : state.dataDXCoils->DXCoil(HeatCoilIndex).ActualSC,
11902 : 0.0,
11903 : RoutineName); // Quality=0
11904 0 : m_ref_IU_cond_i =
11905 0 : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) <= 0.0)
11906 0 : ? 0.0
11907 0 : : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad(NumTU) / (h_IU_cond_in - h_IU_cond_out_i));
11908 0 : m_ref_IU_cond = m_ref_IU_cond + m_ref_IU_cond_i;
11909 0 : h_IU_cond_out_ave = h_IU_cond_out_ave + m_ref_IU_cond_i * h_IU_cond_out_i;
11910 0 : SC_IU_merged = SC_IU_merged + m_ref_IU_cond_i * state.dataDXCoils->DXCoil(HeatCoilIndex).ActualSC;
11911 : }
11912 : }
11913 0 : if (m_ref_IU_cond > 0) {
11914 0 : h_IU_cond_out_ave = h_IU_cond_out_ave / m_ref_IU_cond;
11915 0 : SC_IU_merged = SC_IU_merged / m_ref_IU_cond;
11916 : } else {
11917 : h_IU_cond_out_ave =
11918 0 : this->refrig->getSatEnthalpy(state,
11919 0 : this->refrig->getSatTemperature(state, max(min(Pcond, RefPHigh), RefPLow), RoutineName) - 5.0,
11920 : 0.0,
11921 : RoutineName); // Quality=0
11922 0 : SC_IU_merged = 5;
11923 0 : m_ref_IU_cond = TU_HeatingLoad / (h_IU_cond_in - h_IU_cond_out_ave);
11924 : }
11925 :
11926 : // *PL-h: Calculate piping loss
11927 0 : this->VRFOU_PipeLossH(
11928 : state, m_ref_IU_cond, max(min(Pcond, RefPHigh), RefPLow), h_IU_cond_in, OutdoorDryBulb, Pipe_Q_h, Pipe_DeltP_h, h_comp_out);
11929 0 : Pdischarge = max(Pcond + Pipe_DeltP_h, Pcond); // affected by piping loss
11930 0 : Tdischarge = this->refrig->getSatTemperature(state, max(min(Pdischarge, RefPHigh), RefPLow), RoutineName);
11931 0 : Q_h_TU_PL = TU_HeatingLoad + Pipe_Q_h;
11932 :
11933 : // *PL-c: Calculate total IU refrigerant flow rate and SH_IU_merged
11934 0 : h_IU_evap_in = h_IU_cond_out_ave;
11935 0 : m_ref_IU_evap = 0;
11936 0 : h_IU_evap_out = 0;
11937 0 : SH_IU_merged = 0;
11938 0 : for (NumTU = 1; NumTU <= NumTUInList; NumTU++) { // Calc total refrigerant flow rate
11939 0 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) > 0) {
11940 0 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
11941 0 : CoolCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
11942 :
11943 0 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11944 : h_IU_evap_out_i =
11945 0 : this->refrig->getSupHeatEnthalpy(state,
11946 0 : max(RefTSat, this->IUEvaporatingTemp + state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH),
11947 : max(min(Pevap, RefPHigh), RefPLow),
11948 : RoutineName);
11949 :
11950 0 : if (h_IU_evap_out_i > h_IU_evap_in) {
11951 0 : m_ref_IU_evap_i = (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) <= 0.0)
11952 0 : ? 0.0
11953 0 : : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) /
11954 0 : (h_IU_evap_out_i - h_IU_evap_in)); // Ref Flow Rate in the IU( kg/s )
11955 0 : m_ref_IU_evap = m_ref_IU_evap + m_ref_IU_evap_i;
11956 0 : h_IU_evap_out = h_IU_evap_out + m_ref_IU_evap_i * h_IU_evap_out_i;
11957 0 : SH_IU_merged = SH_IU_merged + m_ref_IU_evap_i * state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH;
11958 : }
11959 : }
11960 : }
11961 0 : if (m_ref_IU_evap > 0) {
11962 0 : h_IU_evap_out = h_IU_evap_out / m_ref_IU_evap;
11963 0 : SH_IU_merged = SH_IU_merged / m_ref_IU_evap;
11964 : } else {
11965 0 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11966 0 : h_IU_evap_out = this->refrig->getSupHeatEnthalpy(
11967 0 : state, max(RefTSat, this->IUEvaporatingTemp + 3), max(min(Pevap, RefPHigh), RefPLow), RoutineName);
11968 0 : SH_IU_merged = 3;
11969 0 : m_ref_IU_evap = TU_CoolingLoad / (h_IU_evap_out - h_IU_evap_in);
11970 : }
11971 :
11972 : // *PL-c: Calculate piping loss
11973 0 : this->VRFOU_PipeLossC(state,
11974 : m_ref_IU_evap,
11975 : max(min(Pevap, RefPHigh), RefPLow),
11976 : h_IU_evap_out,
11977 : SH_IU_merged,
11978 : OutdoorDryBulb,
11979 : Pipe_Q_c,
11980 : Pipe_DeltP_c,
11981 : h_IU_PLc_out);
11982 0 : Psuction = min(Pevap - Pipe_DeltP_c, Pevap); // This Psuction is used for rps > min; will be updated for rps = min
11983 0 : Tsuction = this->refrig->getSatTemperature(state, max(min(Psuction, RefPHigh), RefPLow), RoutineName);
11984 0 : h_comp_in = h_IU_PLc_out;
11985 0 : Q_c_TU_PL = TU_CoolingLoad + Pipe_Q_c;
11986 :
11987 : //**OU operations: Determine VRF-HR OU system operational mode
11988 : // Determine the operational mode of the VRF-HR system, given the terminal unit side load conditions.
11989 : // A number of OU side operational parameters are also calculated here, including:
11990 : // (1) OU evaporator load Q_c_OU, (2) OU condenser load Q_h_OU,
11991 : // (3) m_ref_OU_evap, (4) m_ref_OU_cond
11992 : // Note that Te and Te' may be updated here, and thus IU evaporator side piping loss recalculations.
11993 : // Then a number of operational parameters need to be updated, including:
11994 : // (1) IU evaporating temperature Te (2) OU evaporating temperature Te' etc (3) m_ref_IU_evap
11995 : // (4) Pipe_Q_c (5) h_IU_PLc_out (6) h_comp_in
11996 : //*VRF OU Compressor Simulation at HR mode: Specify the compressor speed and power consumption
11997 : {
11998 0 : Real64 Pipe_Q_c_new = Pipe_Q_c;
11999 0 : Real64 Tsuction_new = Tsuction;
12000 0 : Real64 Te_new = this->IUEvaporatingTemp;
12001 : Real64 N_fan_OU;
12002 :
12003 0 : this->VRFHR_OU_HR_Mode(state,
12004 : h_IU_evap_in,
12005 : h_comp_out,
12006 : Q_c_TU_PL,
12007 : Q_h_TU_PL,
12008 : Tdischarge,
12009 : Tsuction_new,
12010 : Te_new,
12011 : h_comp_in,
12012 : h_IU_PLc_out,
12013 : Pipe_Q_c_new,
12014 : Q_c_OU,
12015 : Q_h_OU,
12016 : m_ref_IU_evap,
12017 : m_ref_OU_evap,
12018 : m_ref_OU_cond,
12019 : N_fan_OU,
12020 : CompSpdActual,
12021 : Ncomp);
12022 :
12023 : // parameter update
12024 0 : Tsuction = Tsuction_new;
12025 0 : Pipe_Q_c = Pipe_Q_c_new;
12026 0 : this->OUFanPower = N_fan_OU;
12027 0 : this->IUEvaporatingTemp = Te_new;
12028 : }
12029 :
12030 : //* Update h_comp_out in iteration (Label230)
12031 0 : h_comp_out_new = Ncomp / (m_ref_IU_evap + m_ref_OU_evap) + h_comp_in;
12032 :
12033 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));
12034 0 : h_IU_cond_in = h_IU_cond_in + 0.1 * (h_IU_cond_in_up - h_IU_cond_in_low);
12035 0 : } while (!converged_230);
12036 0 : if (h_IU_cond_in > h_IU_cond_in_up) {
12037 0 : h_IU_cond_in = 0.5 * (h_IU_cond_in_up + h_IU_cond_in_low);
12038 : }
12039 :
12040 : //===**h_comp_out Iteration Ends (Label230)
12041 :
12042 : // Key outputs of this subroutine
12043 0 : this->CompActSpeed = max(CompSpdActual, 0.0);
12044 0 : this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter;
12045 0 : this->VRFCondCyclingRatio = 1.0;
12046 :
12047 0 : this->HeatingCapacity =
12048 0 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), Tdischarge, Tsuction) +
12049 0 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(NumOfCompSpdInput), Tdischarge, Tsuction); // Include the piping loss
12050 0 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) =
12051 0 : this->HeatingCapacity; // for report, maximum heating capacity of the system, at the highest compressor speed
12052 0 : this->PipingCorrectionHeating = TU_HeatingLoad / Q_h_TU_PL;
12053 :
12054 0 : this->CoolingCapacity =
12055 0 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), Tdischarge, Tsuction);
12056 0 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond) =
12057 0 : this->CoolingCapacity; // for report, maximum evaporating capacity of the system, at the highest compressor speed
12058 0 : this->PipingCorrectionCooling = TU_CoolingLoad / Q_c_TU_PL;
12059 :
12060 0 : this->CondensingTemp = Tdischarge; // OU condensing temperature
12061 0 : this->EvaporatingTemp = Tsuction; // OU evaporating temperature
12062 :
12063 0 : this->OUCondHeatRate = Q_h_OU;
12064 0 : this->OUEvapHeatRate = Q_c_OU;
12065 0 : this->IUCondHeatRate = TU_HeatingLoad;
12066 0 : this->IUEvapHeatRate = TU_CoolingLoad;
12067 :
12068 : // 4. Stop running
12069 0 : } else {
12070 :
12071 39 : this->OperatingMode = 0;
12072 39 : this->VRFOperationSimPath = 0;
12073 :
12074 39 : this->Ncomp = 0.0;
12075 39 : this->CompActSpeed = 0.0;
12076 39 : this->OUFanPower = 0.0;
12077 39 : this->VRFCondCyclingRatio = 0.0;
12078 :
12079 39 : this->HeatingCapacity = 0.0; // Include the piping loss
12080 39 : this->PipingCorrectionHeating = 1.0; // 1 means no piping loss
12081 39 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) = Constant::MaxCap; // yujie: default value is MaxCap = 1e+20, not 0
12082 :
12083 39 : this->CoolingCapacity = 0.0; // Include the piping loss
12084 39 : this->PipingCorrectionCooling = 1.0;
12085 39 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond) = Constant::MaxCap; // for report
12086 :
12087 39 : this->CondensingTemp = state.dataEnvrn->OutDryBulbTemp;
12088 39 : this->EvaporatingTemp = state.dataEnvrn->OutDryBulbTemp;
12089 :
12090 39 : this->OUCondHeatRate = 0.0;
12091 39 : this->OUEvapHeatRate = 0.0;
12092 39 : this->IUCondHeatRate = 0.0;
12093 39 : this->IUEvapHeatRate = 0.0;
12094 : }
12095 :
12096 : // calculate capacities and energy use
12097 3539 : if (((!this->HeatRecoveryUsed && state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) || (this->HeatRecoveryUsed && HRCoolRequestFlag)) &&
12098 1171 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).CoolingCoilPresent(NumTUInList)) {
12099 1171 : InletAirWetBulbC = SumCoolInletWB;
12100 :
12101 : // From the VRF_FluidTCtrl model
12102 1171 : TotalCondCoolingCapacity = this->CoolingCapacity;
12103 1171 : TotalTUCoolingCapacity = TotalCondCoolingCapacity * this->PipingCorrectionCooling;
12104 :
12105 1171 : if (TotalCondCoolingCapacity > 0.0) {
12106 1171 : CoolingPLR = min(1.0, (this->TUCoolingLoad / this->PipingCorrectionCooling) / TotalCondCoolingCapacity);
12107 : } else {
12108 0 : CoolingPLR = 0.0;
12109 : }
12110 : }
12111 3526 : if (((!this->HeatRecoveryUsed && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) || (this->HeatRecoveryUsed && HRHeatRequestFlag)) &&
12112 1158 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).HeatingCoilPresent(NumTUInList)) {
12113 1158 : InletAirDryBulbC = SumHeatInletDB;
12114 1158 : InletAirWetBulbC = SumHeatInletWB;
12115 :
12116 : // Initializing defrost adjustment factors
12117 1158 : LoadDueToDefrost = 0.0;
12118 1158 : HeatingCapacityMultiplier = 1.0;
12119 1158 : FractionalDefrostTime = 0.0;
12120 1158 : InputPowerMultiplier = 1.0;
12121 :
12122 : // Check outdoor temperature to determine of defrost is active
12123 1158 : if (OutdoorDryBulb <= this->MaxOATDefrost && this->CondenserType != DataHeatBalance::RefrigCondenserType::Water) {
12124 :
12125 : // Calculating adjustment factors for defrost
12126 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
12127 0 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
12128 0 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
12129 :
12130 : // Calculate defrost adjustment factors depending on defrost control type
12131 0 : if (this->DefrostControl == StandardRatings::HPdefrostControl::Timed) {
12132 0 : FractionalDefrostTime = this->DefrostFraction;
12133 0 : if (FractionalDefrostTime > 0.0) {
12134 0 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
12135 0 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
12136 : }
12137 : } else { // else defrost control is on-demand
12138 0 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
12139 0 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
12140 0 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
12141 : }
12142 :
12143 0 : if (FractionalDefrostTime > 0.0) {
12144 : // Calculate defrost adjustment factors depending on defrost control strategy
12145 0 : if (this->DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle &&
12146 0 : this->DefrostControl == StandardRatings::HPdefrostControl::OnDemand) {
12147 0 : LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (this->HeatingCapacity / 1.01667);
12148 0 : DefrostEIRTempModFac = CurveValue(state, this->DefrostEIRPtr, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
12149 :
12150 : // Warn user if curve output goes negative
12151 0 : if (DefrostEIRTempModFac < 0.0) {
12152 0 : if (!state.dataGlobal->WarmupFlag) {
12153 0 : if (this->DefrostHeatErrorIndex == 0) {
12154 0 : ShowSevereMessage(state, format("{} \"{}\":", cVRFTypes(VRF_HeatPump), this->Name));
12155 0 : ShowContinueError(
12156 : state,
12157 0 : format(" Defrost Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).",
12158 : DefrostEIRTempModFac));
12159 0 : ShowContinueError(state,
12160 0 : format(" Negative value occurs using an outdoor air dry-bulb temperature of {:.1T} C and an "
12161 : "average indoor air wet-bulb temperature of {:.1T} C.",
12162 : OutdoorDryBulb,
12163 : InletAirWetBulbC));
12164 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
12165 : }
12166 0 : ShowRecurringWarningErrorAtEnd(state,
12167 0 : format("{} \"{}\": Defrost Energy Input Ratio Modifier curve (function of temperature) "
12168 : "output is negative warning continues...",
12169 0 : PlantEquipTypeNames[static_cast<int>(PlantEquipmentType::HeatPumpVRF)],
12170 0 : this->Name),
12171 0 : this->DefrostHeatErrorIndex,
12172 : DefrostEIRTempModFac,
12173 : DefrostEIRTempModFac);
12174 0 : DefrostEIRTempModFac = 0.0;
12175 : }
12176 : }
12177 :
12178 0 : this->DefrostPower = DefrostEIRTempModFac * (this->HeatingCapacity / 1.01667) * FractionalDefrostTime;
12179 :
12180 : } else { // Defrost strategy is resistive
12181 0 : this->DefrostPower = this->DefrostCapacity * FractionalDefrostTime;
12182 : }
12183 : } else { // Defrost is not active because FractionalDefrostTime = 0.0
12184 0 : this->DefrostPower = 0.0;
12185 : }
12186 : }
12187 :
12188 : // From the VRF_FluidTCtrl model
12189 1158 : TotalCondHeatingCapacity = this->HeatingCapacity;
12190 1158 : TotalTUHeatingCapacity = TotalCondHeatingCapacity * this->PipingCorrectionHeating;
12191 :
12192 1158 : if (TotalCondHeatingCapacity > 0.0) {
12193 1158 : HeatingPLR = min(1.0, (this->TUHeatingLoad / this->PipingCorrectionHeating) / TotalCondHeatingCapacity);
12194 1158 : HeatingPLR += (LoadDueToDefrost * HeatingPLR) / TotalCondHeatingCapacity;
12195 : } else {
12196 0 : HeatingPLR = 0.0;
12197 : }
12198 : }
12199 :
12200 2368 : this->VRFCondPLR = max(CoolingPLR, HeatingPLR);
12201 :
12202 : // For VRF-HR Operations
12203 2368 : HRInitialCapFrac = 1.0;
12204 2368 : HRInitialEIRFrac = 1.0;
12205 2368 : HRCapTC = 0.0;
12206 2368 : HREIRTC = 0.0;
12207 2368 : if (!state.dataGlobal->DoingSizing && !state.dataGlobal->WarmupFlag) {
12208 577 : if (HRHeatRequestFlag && HRCoolRequestFlag) { // Simultaneous Heating and Cooling operations for HR system
12209 : // determine operating mode change: (1) ModeChange (2) HRCoolingActive (3) HRHeatingActive
12210 0 : if (!this->HRCoolingActive && !this->HRHeatingActive) {
12211 0 : this->ModeChange = true;
12212 : }
12213 0 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) {
12214 0 : if (this->HRHeatingActive && !this->HRCoolingActive) {
12215 0 : this->HRModeChange = true;
12216 : }
12217 0 : this->HRCoolingActive = true;
12218 0 : this->HRHeatingActive = false;
12219 :
12220 0 : HRInitialCapFrac = this->HRInitialCoolCapFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
12221 0 : HRCapTC = this->HRCoolCapTC; // Time constant used to recover from initial degradation in cooling heat recovery
12222 :
12223 0 : HRInitialEIRFrac = this->HRInitialCoolEIRFrac; // Fractional cooling degradation at the start of heat recovery from cooling mode
12224 0 : HREIRTC = this->HRCoolEIRTC; // Time constant used to recover from initial degradation in cooling heat recovery
12225 :
12226 0 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) {
12227 0 : if (!this->HRHeatingActive && this->HRCoolingActive) {
12228 0 : this->HRModeChange = true;
12229 : }
12230 0 : this->HRCoolingActive = false;
12231 0 : this->HRHeatingActive = true;
12232 :
12233 0 : HRInitialCapFrac = this->HRInitialHeatCapFrac; // Fractional heating degradation at the start of heat recovery from cooling mode
12234 0 : HRCapTC = this->HRHeatCapTC; // Time constant used to recover from initial degradation in heating heat recovery
12235 :
12236 0 : HRInitialEIRFrac = this->HRInitialHeatEIRFrac; // Fractional heating degradation at the start of heat recovery from heating mode
12237 0 : HREIRTC = this->HRHeatEIRTC; // Time constant used to recover from initial degradation in heating heat recovery
12238 :
12239 : } else {
12240 : // zone thermostats satisfied, condenser is off. Set values anyway
12241 : // HRCAPFTConst = 1.0;
12242 0 : HRInitialCapFrac = 1.0;
12243 0 : HRCapTC = 1.0;
12244 : // HREIRFTConst = 1.0;
12245 0 : HRInitialEIRFrac = 1.0;
12246 0 : HREIRTC = 1.0;
12247 0 : if (this->HRHeatingActive || this->HRCoolingActive) {
12248 0 : this->HRModeChange = true;
12249 : }
12250 0 : this->HRCoolingActive = false;
12251 0 : this->HRHeatingActive = false;
12252 : }
12253 :
12254 : } else { // IF(HRHeatRequestFlag .AND. HRCoolRequestFlag)THEN -- Heat recovery turned off
12255 577 : HRInitialCapFrac = 1.0;
12256 577 : HRCapTC = 0.0;
12257 577 : HRInitialEIRFrac = 1.0;
12258 577 : HREIRTC = 0.0;
12259 577 : this->HRModeChange = false;
12260 577 : this->HRCoolingActive = false;
12261 577 : this->HRHeatingActive = false;
12262 : }
12263 :
12264 : // Calculate the capacity modification factor (SUMultiplier) for the HR mode transition period
12265 : {
12266 577 : CurrentEndTime = double((state.dataGlobal->DayOfSim - 1) * 24) + state.dataGlobal->CurrentTime - state.dataGlobal->TimeStepZone +
12267 577 : state.dataHVACGlobal->SysTimeElapsed;
12268 :
12269 577 : if (this->ModeChange || this->HRModeChange) {
12270 0 : if (this->HRCoolingActive && this->HRTimer == 0.0) {
12271 0 : this->HRTimer = state.dataHVACVarRefFlow->CurrentEndTimeLast;
12272 0 : } else if (this->HRHeatingActive && this->HRTimer == 0.0) {
12273 0 : this->HRTimer = state.dataHVACVarRefFlow->CurrentEndTimeLast;
12274 0 : } else if (!this->HRCoolingActive && !this->HRHeatingActive) {
12275 0 : this->HRTimer = 0.0;
12276 : }
12277 : }
12278 :
12279 577 : this->HRTime = max(0.0, CurrentEndTime - this->HRTimer);
12280 577 : if (this->HRTime < (HRCapTC * 5.0)) {
12281 0 : if (HRCapTC > 0.0) {
12282 0 : SUMultiplier = min(1.0, 1.0 - std::exp(-this->HRTime / HRCapTC));
12283 : } else {
12284 0 : SUMultiplier = 1.0;
12285 : }
12286 : } else {
12287 577 : SUMultiplier = 1.0;
12288 577 : this->ModeChange = false;
12289 577 : this->HRModeChange = false;
12290 : }
12291 577 : this->SUMultiplier = SUMultiplier;
12292 :
12293 577 : state.dataHVACVarRefFlow->CurrentEndTimeLast = CurrentEndTime;
12294 : }
12295 :
12296 : // Modify HR capacity for the transition period
12297 : {
12298 577 : if (this->HeatRecoveryUsed && this->HRCoolingActive) {
12299 0 : TotalCondCoolingCapacity =
12300 0 : HRInitialCapFrac * TotalCondCoolingCapacity + (1.0 - HRInitialCapFrac) * TotalCondCoolingCapacity * SUMultiplier;
12301 0 : TotalTUCoolingCapacity = TotalCondCoolingCapacity * this->PipingCorrectionCooling;
12302 0 : if (TotalCondCoolingCapacity > 0.0) {
12303 0 : CoolingPLR = min(1.0, (this->TUCoolingLoad / this->PipingCorrectionCooling) / TotalCondCoolingCapacity);
12304 : } else {
12305 0 : CoolingPLR = 0.0;
12306 : }
12307 0 : this->VRFHeatRec = this->TUHeatingLoad;
12308 577 : } else if (this->HeatRecoveryUsed && this->HRHeatingActive) {
12309 0 : TotalCondHeatingCapacity =
12310 0 : HRInitialCapFrac * TotalCondHeatingCapacity + (1.0 - HRInitialCapFrac) * TotalCondHeatingCapacity * SUMultiplier;
12311 0 : TotalTUHeatingCapacity = TotalCondHeatingCapacity * this->PipingCorrectionHeating;
12312 0 : if (TotalCondHeatingCapacity > 0.0) {
12313 0 : HeatingPLR = min(1.0, (this->TUHeatingLoad / this->PipingCorrectionHeating) / TotalCondHeatingCapacity);
12314 : } else {
12315 0 : HeatingPLR = 0.0;
12316 : }
12317 0 : this->VRFHeatRec = this->TUCoolingLoad;
12318 : }
12319 :
12320 577 : this->VRFCondPLR = max(CoolingPLR, HeatingPLR);
12321 : }
12322 : }
12323 :
12324 2368 : this->TotalCoolingCapacity = TotalCondCoolingCapacity * CoolingPLR;
12325 2368 : this->TotalHeatingCapacity = TotalCondHeatingCapacity * HeatingPLR;
12326 :
12327 2368 : if (this->MinPLR > 0.0) {
12328 0 : bool const plrTooLow = this->VRFCondPLR < this->MinPLR;
12329 0 : bool const plrGreaterThanZero = this->VRFCondPLR > 0.0;
12330 0 : if (plrTooLow && plrGreaterThanZero) {
12331 0 : this->VRFCondPLR = this->MinPLR;
12332 : }
12333 : }
12334 :
12335 2368 : VRFRTF = 0.0;
12336 : // VRF Cooling and Heating Electric Power (output variables)
12337 2368 : if (this->OperatingMode == ModeCoolingOnly) {
12338 1171 : PartLoadFraction = 1.0;
12339 1171 : VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));
12340 :
12341 1171 : this->ElecCoolingPower = state.dataHVACVarRefFlow->VRF(VRFCond).Ncomp + this->OUFanPower;
12342 1171 : this->ElecHeatingPower = 0;
12343 :
12344 1197 : } else if (this->OperatingMode == ModeHeatingOnly) {
12345 1158 : PartLoadFraction = 1.0;
12346 1158 : VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));
12347 :
12348 1158 : this->ElecCoolingPower = 0;
12349 1158 : this->ElecHeatingPower = this->Ncomp + this->OUFanPower;
12350 :
12351 39 : } else if (this->OperatingMode == ModeCoolingAndHeating) {
12352 0 : PartLoadFraction = 1.0;
12353 0 : VRFRTF = min(1.0, (CyclingRatio / PartLoadFraction));
12354 :
12355 0 : this->ElecCoolingPower = (this->Ncomp + this->OUFanPower) * this->IUEvapHeatRate / (this->IUCondHeatRate + this->IUEvapHeatRate);
12356 0 : this->ElecHeatingPower = (this->Ncomp + this->OUFanPower) * this->IUCondHeatRate / (this->IUCondHeatRate + this->IUEvapHeatRate);
12357 :
12358 : } else {
12359 39 : this->ElecCoolingPower = 0;
12360 39 : this->ElecHeatingPower = 0;
12361 : }
12362 2368 : this->VRFCondRTF = VRFRTF;
12363 2368 : this->DefrostPower *= VRFRTF;
12364 :
12365 : // Calculate CrankCaseHeaterPower: VRF Heat Pump Crankcase Heater Electric Power [W]
12366 2368 : if (this->MaxOATCCHeater > OutdoorDryBulb) {
12367 : // calculate crankcase heater power
12368 0 : this->CrankCaseHeaterPower = this->CCHeaterPower * (1.0 - VRFRTF);
12369 0 : if (this->NumCompressors > 1) {
12370 0 : UpperStageCompressorRatio = (1.0 - this->CompressorSizeRatio) / (this->NumCompressors - 1);
12371 0 : for (Stage = 1; Stage <= this->NumCompressors - 2; ++Stage) {
12372 0 : if (this->VRFCondPLR < (this->CompressorSizeRatio + Stage * UpperStageCompressorRatio)) {
12373 0 : this->CrankCaseHeaterPower += this->CCHeaterPower;
12374 : }
12375 : }
12376 : }
12377 : } else {
12378 2368 : this->CrankCaseHeaterPower = 0.0;
12379 : }
12380 :
12381 : // Calculate QCondenser: VRF Heat Pump Condenser Heat Transfer Rate [W]
12382 2368 : CondCapacity = max(this->TotalCoolingCapacity, this->TotalHeatingCapacity) * VRFRTF;
12383 2368 : CondPower = max(this->ElecCoolingPower, this->ElecHeatingPower);
12384 2368 : if (this->ElecHeatingPower > 0.0) {
12385 1158 : this->QCondenser = CondCapacity + CondPower - this->TUHeatingLoad / this->PipingCorrectionHeating;
12386 1210 : } else if (this->ElecCoolingPower > 0.0) {
12387 1171 : this->QCondenser = -CondCapacity + CondPower + this->TUCoolingLoad / this->PipingCorrectionCooling;
12388 : } else {
12389 39 : this->QCondenser = 0.0;
12390 : }
12391 : // if ( this->CondenserType == HVAC::EvapCooled )
12392 :
12393 : // Calculate OperatingHeatingCOP & OperatingCoolingCOP: VRF Heat Pump Operating COP []
12394 2368 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && CoolingPLR > 0.0) {
12395 1171 : if (this->ElecCoolingPower != 0.0) {
12396 : // this calc should use delivered capacity, not condenser capacity, use VRF(VRFCond).TUCoolingLoad
12397 1171 : this->OperatingCoolingCOP = (this->TotalCoolingCapacity) /
12398 1171 : (this->ElecCoolingPower + this->CrankCaseHeaterPower + this->EvapCondPumpElecPower + this->DefrostPower);
12399 : } else {
12400 0 : this->OperatingCoolingCOP = 0.0;
12401 : }
12402 : }
12403 2368 : if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && HeatingPLR > 0.0) {
12404 : // this calc should use delivered capacity, not condenser capacity, use VRF(VRFCond).TUHeatingLoad
12405 1158 : if (this->ElecHeatingPower != 0.0) {
12406 1158 : this->OperatingHeatingCOP = (this->TotalHeatingCapacity) /
12407 1158 : (this->ElecHeatingPower + this->CrankCaseHeaterPower + this->EvapCondPumpElecPower + this->DefrostPower);
12408 : } else {
12409 0 : this->OperatingHeatingCOP = 0.0;
12410 : }
12411 : }
12412 :
12413 2368 : TotPower = TUParasiticPower + TUFanPower + this->ElecHeatingPower + this->ElecCoolingPower + this->CrankCaseHeaterPower +
12414 2368 : this->EvapCondPumpElecPower + this->DefrostPower;
12415 2368 : if (TotPower > 0.0) {
12416 2368 : this->OperatingCOP = (this->TUCoolingLoad + this->TUHeatingLoad) / TotPower;
12417 2368 : this->SCHE = this->OperatingCOP * 3.412141633; // see StandardRatings::ConvFromSIToIP
12418 : }
12419 :
12420 : // limit the TU capacity when the condenser is maxed out on capacity
12421 : // I think this next line will make the max cap report variable match the coil objects, will probably change the answer though
12422 : // IF(CoolingLoad(VRFCond) .AND. NumTUInCoolingMode .GT. 0 .AND. MaxCoolingCapacity(VRFCond) == MaxCap)THEN
12423 2368 : if (state.dataHVACVarRefFlow->CoolingLoad(VRFCond) && NumTUInCoolingMode > 0) {
12424 :
12425 : // IF TU capacity is greater than condenser capacity find maximum allowed TU capacity (i.e., conserve energy)
12426 1171 : if (TU_CoolingLoad > TotalTUCoolingCapacity) {
12427 0 : LimitTUCapacity(state,
12428 : VRFCond,
12429 : NumTUInList,
12430 : TotalTUCoolingCapacity,
12431 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad,
12432 0 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond),
12433 : TotalTUHeatingCapacity,
12434 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad,
12435 0 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
12436 : }
12437 1197 : } else if (state.dataHVACVarRefFlow->HeatingLoad(VRFCond) && NumTUInHeatingMode > 0) {
12438 : // IF TU capacity is greater than condenser capacity
12439 1158 : if (TU_HeatingLoad > TotalTUHeatingCapacity) {
12440 0 : LimitTUCapacity(state,
12441 : VRFCond,
12442 : NumTUInList,
12443 : TotalTUHeatingCapacity,
12444 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalHeatLoad,
12445 0 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond),
12446 : TotalTUCoolingCapacity,
12447 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad,
12448 0 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond));
12449 : }
12450 : } else {
12451 : }
12452 :
12453 : // Calculate the IU Te/Tc for the next time step
12454 2368 : this->CalcVRFIUTeTc_FluidTCtrl(state);
12455 : // update coil and IU evaporating temperature, also keep coil RTF updated with the condenser side cycling ratio, for the FluidTCtrl model
12456 4736 : for (int VRFTUNum = 1; VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU; ++VRFTUNum) {
12457 2368 : auto const &thisTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
12458 2368 : auto &coolingCoil = state.dataDXCoils->DXCoil(thisTU.CoolCoilIndex);
12459 2368 : if (this->adjustedTe && (!FirstHVACIteration)) {
12460 65 : coolingCoil.EvaporatingTemp = this->EvaporatingTemp;
12461 65 : this->IUEvaporatingTemp = this->EvaporatingTemp;
12462 : }
12463 :
12464 : int PLF;
12465 2368 : if (coolingCoil.PLFFPLR(1) > 0 && this->VRFCondCyclingRatio < 1.0) {
12466 0 : PLF = Curve::CurveValue(state, coolingCoil.PLFFPLR(1), this->VRFCondCyclingRatio); // Calculate part-load factor
12467 : } else {
12468 2368 : PLF = 1.0;
12469 : }
12470 2368 : if (coolingCoil.TotalCoolingEnergyRate > 0.0) {
12471 1171 : coolingCoil.CoolingCoilRuntimeFraction = this->VRFCondCyclingRatio / PLF;
12472 : }
12473 : }
12474 2368 : }
12475 :
12476 2378 : void VRFTerminalUnitEquipment::ControlVRF_FluidTCtrl(EnergyPlusData &state,
12477 : int const VRFTUNum, // Index to VRF terminal unit
12478 : Real64 const QZnReq, // Index to zone number
12479 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
12480 : Real64 &PartLoadRatio, // unit part load ratio
12481 : Real64 &OnOffAirFlowRatio, // ratio of compressor ON airflow to AVERAGE airflow over timestep
12482 : Real64 &SuppHeatCoilLoad // supplemental heating coil load (W)
12483 : )
12484 : {
12485 :
12486 : // SUBROUTINE INFORMATION:
12487 : // AUTHOR Rongpeng Zhang
12488 : // DATE WRITTEN Nov 2015
12489 : // MODIFIED na
12490 : // RE-ENGINEERED na
12491 :
12492 : // PURPOSE OF THIS SUBROUTINE:
12493 : // Determine the coil load and part load ratio, given the zone load
12494 : // Determine the air mass flow rate corresponding to the coil load of the heat pump for this time step
12495 :
12496 : // METHODOLOGY EMPLOYED:
12497 : // Use RegulaFalsi technique to iterate on part-load ratio until convergence is achieved.
12498 :
12499 : using General::SolveRoot;
12500 :
12501 2378 : int constexpr MaxIte(500); // maximum number of iterations
12502 2378 : Real64 constexpr MinPLF(0.0); // minimum part load factor allowed
12503 2378 : Real64 constexpr ErrorTol(0.001); // tolerance for RegulaFalsi iterations
12504 :
12505 : Real64 FullOutput; // unit full output when compressor is operating [W]
12506 : Real64 TempOutput; // unit output when iteration limit exceeded [W]
12507 : Real64 NoCompOutput; // output when no active compressor [W]
12508 : Real64 TempMinPLR; // min PLR used in Regula Falsi call
12509 : Real64 TempMaxPLR; // max PLR used in Regula Falsi call
12510 : int VRFCond; // index to VRF condenser
12511 : int IndexToTUInTUList; // index to TU in specific list for the VRF system
12512 : int TUListIndex; // index to TU list for this VRF system
12513 : bool VRFCoolingMode;
12514 : bool VRFHeatingMode;
12515 : bool HRCoolingMode;
12516 : bool HRHeatingMode;
12517 :
12518 2378 : PartLoadRatio = 0.0;
12519 2378 : state.dataHVACVarRefFlow->LoopDXCoolCoilRTF = 0.0;
12520 2378 : state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = 0.0;
12521 2378 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatPartLoadRatio = 0.0;
12522 2378 : VRFCond = this->VRFSysNum;
12523 2378 : IndexToTUInTUList = this->IndexToTUInTUList;
12524 2378 : auto &thisVRFCond = state.dataHVACVarRefFlow->VRF(VRFCond);
12525 2378 : TUListIndex = thisVRFCond.ZoneTUListPtr;
12526 2378 : VRFCoolingMode = state.dataHVACVarRefFlow->CoolingLoad(VRFCond);
12527 2378 : VRFHeatingMode = state.dataHVACVarRefFlow->HeatingLoad(VRFCond);
12528 2378 : HRCoolingMode = state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList);
12529 2378 : HRHeatingMode = state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList);
12530 2378 : auto &thisVRFTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum);
12531 :
12532 : // The RETURNS here will jump back to SimVRF where the CalcVRF routine will simulate with latest PLR
12533 :
12534 : // do nothing else if TU is scheduled off
12535 2378 : if (this->availSched->getCurrentVal() == 0.0) {
12536 41 : return;
12537 : }
12538 :
12539 : // Block the following statement: QZnReq==0 doesn't mean QCoilReq==0 due to possible OA mixer operation. zrp_201511
12540 : // do nothing if TU has no load (TU will be modeled using PLR=0)
12541 : // if ( QZnReq == 0.0 ) return;
12542 :
12543 : // Set EMS value for PLR and return
12544 2378 : if (this->EMSOverridePartLoadFrac) {
12545 0 : PartLoadRatio = this->EMSValueForPartLoadFrac;
12546 0 : return;
12547 : }
12548 :
12549 : // Get result when DX coil is off
12550 2378 : PartLoadRatio = 0.0;
12551 2378 : bool DXCoolingCoilOprCtrl = true;
12552 :
12553 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
12554 2378 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, 0.0, NoCompOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
12555 :
12556 2378 : if (VRFCoolingMode && HRHeatingMode) {
12557 : // IF the system is in cooling mode, but the terminal unit requests heating (heat recovery)
12558 0 : if (NoCompOutput >= QZnReq) {
12559 0 : return;
12560 : }
12561 2378 : } else if (VRFHeatingMode && HRCoolingMode) {
12562 : // IF the system is in heating mode, but the terminal unit requests cooling (heat recovery)
12563 0 : if (NoCompOutput <= QZnReq) {
12564 0 : return;
12565 : }
12566 2378 : } else if (VRFCoolingMode || HRCoolingMode) {
12567 : // IF the system is in cooling mode and/or the terminal unit requests cooling
12568 1180 : if (NoCompOutput <= QZnReq && ((QZnReq <= 0.0) || (QZnReq >= HVAC::SmallLoad && !HRCoolingMode))) {
12569 4 : DXCoolingCoilOprCtrl = false;
12570 4 : if (!this->SuppHeatingCoilPresent) {
12571 0 : return;
12572 : }
12573 : }
12574 1198 : } else if (VRFHeatingMode || HRHeatingMode) {
12575 : // IF the system is in heating mode and/or the terminal unit requests heating
12576 1158 : if (NoCompOutput >= QZnReq) {
12577 0 : return;
12578 : }
12579 : }
12580 :
12581 : // Otherwise the coil needs to turn on. Get full load result
12582 2378 : PartLoadRatio = 1.0;
12583 2378 : if (!DXCoolingCoilOprCtrl) {
12584 4 : PartLoadRatio = 0.0;
12585 : }
12586 2378 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, PartLoadRatio, FullOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
12587 2378 : if (this->CoolingCoilPresent) {
12588 2378 : auto const &thisAirInNode = state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(this->CoolCoilIndex).AirInNode);
12589 2378 : this->coilInNodeT = thisAirInNode.Temp;
12590 2378 : this->coilInNodeW = thisAirInNode.HumRat;
12591 : } else {
12592 0 : auto const &thisAirInNode = state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(this->HeatCoilIndex).AirInNode);
12593 0 : this->coilInNodeT = thisAirInNode.Temp;
12594 0 : this->coilInNodeW = thisAirInNode.HumRat;
12595 : }
12596 :
12597 : // set supplemental heating coil calculation if the condition requires
12598 2378 : if (this->SuppHeatingCoilPresent) {
12599 6 : auto const &thisSuppHeatCoilAirInletNode = state.dataLoopNodes->Node(this->SuppHeatCoilAirInletNode);
12600 6 : if (((QZnReq > HVAC::SmallLoad && QZnReq > FullOutput) || (((QZnReq - NoCompOutput) > HVAC::SmallLoad) && QZnReq <= 0.0)) ||
12601 2 : (this->isSetPointControlled && this->suppTempSetPoint > thisSuppHeatCoilAirInletNode.Temp)) {
12602 4 : Real64 ZoneLoad = 0.0;
12603 4 : Real64 LoadToHeatingSP = 0.0;
12604 4 : Real64 LoadToCoolingSP = 0.0;
12605 4 : if (this->isSetPointControlled) {
12606 0 : Real64 mDot = thisSuppHeatCoilAirInletNode.MassFlowRate;
12607 0 : Real64 Tin = thisSuppHeatCoilAirInletNode.Temp;
12608 0 : Real64 Win = thisSuppHeatCoilAirInletNode.HumRat;
12609 0 : Real64 CpAirIn = Psychrometrics::PsyCpAirFnW(Win);
12610 0 : SuppHeatCoilLoad = mDot * CpAirIn * (this->suppTempSetPoint - Tin);
12611 0 : this->SuppHeatingCoilLoad = SuppHeatCoilLoad;
12612 0 : if (this->DesignSuppHeatingCapacity > 0.0) {
12613 0 : this->SuppHeatPartLoadRatio = min(1.0, SuppHeatCoilLoad / this->DesignSuppHeatingCapacity);
12614 : }
12615 : } else {
12616 4 : getVRFTUZoneLoad(state, VRFTUNum, ZoneLoad, LoadToHeatingSP, LoadToCoolingSP, false);
12617 4 : if (((FullOutput < (LoadToHeatingSP - HVAC::SmallLoad) || ((QZnReq - NoCompOutput) > HVAC::SmallLoad && QZnReq <= 0.0))) &&
12618 4 : !FirstHVACIteration) {
12619 2 : if ((QZnReq - NoCompOutput) > HVAC::SmallLoad && QZnReq <= 0.0) {
12620 0 : if (LoadToHeatingSP < 0.0 && QZnReq == 0.0) {
12621 0 : SuppHeatCoilLoad = max(0.0, LoadToHeatingSP - FullOutput);
12622 : } else {
12623 0 : SuppHeatCoilLoad = max(0.0, QZnReq - FullOutput);
12624 : }
12625 : } else {
12626 2 : if (QZnReq > 0.0 && (NoCompOutput - QZnReq) >= HVAC::SmallLoad) {
12627 0 : SuppHeatCoilLoad = 0.0;
12628 : } else {
12629 2 : SuppHeatCoilLoad = max(0.0, LoadToHeatingSP - FullOutput);
12630 : }
12631 : }
12632 2 : this->SuppHeatingCoilLoad = SuppHeatCoilLoad;
12633 2 : if (this->DesignSuppHeatingCapacity > 0.0) {
12634 2 : this->SuppHeatPartLoadRatio = min(1.0, SuppHeatCoilLoad / this->DesignSuppHeatingCapacity);
12635 : }
12636 : } else {
12637 2 : SuppHeatCoilLoad = 0.0;
12638 2 : this->SuppHeatPartLoadRatio = 0.0;
12639 : }
12640 : }
12641 4 : } else {
12642 2 : SuppHeatCoilLoad = 0.0;
12643 2 : this->SuppHeatPartLoadRatio = 0.0;
12644 : }
12645 : } else {
12646 2372 : SuppHeatCoilLoad = 0.0;
12647 2372 : this->SuppHeatPartLoadRatio = 0.0;
12648 : }
12649 :
12650 2378 : if ((VRFCoolingMode && !thisVRFCond.HeatRecoveryUsed) || (thisVRFCond.HeatRecoveryUsed && HRCoolingMode)) {
12651 : // Since we are cooling, we expect FullOutput < NoCompOutput
12652 : // If the QZnReq <= FullOutput the unit needs to run full out
12653 1180 : if (QZnReq <= FullOutput) {
12654 : // if no coil present in terminal unit, no need to reset PLR?
12655 1 : if (thisVRFTU.CoolingCoilPresent) {
12656 1 : PartLoadRatio = 1.0;
12657 : // the zone set point could be exceeded if set point control is used so protect against that
12658 1 : if (this->isSetPointControlled) {
12659 0 : if (state.dataLoopNodes->Node(this->coolCoilAirOutNode).Temp > this->coilTempSetPoint) {
12660 0 : return;
12661 : }
12662 : } else {
12663 1 : if (QZnReq >= 0.0 && FullOutput >= 0.0) {
12664 0 : PartLoadRatio = 0.0;
12665 : }
12666 1 : return;
12667 : }
12668 : } else {
12669 0 : PartLoadRatio = 0.0;
12670 0 : return;
12671 : }
12672 : } else {
12673 1179 : if (QZnReq == 0.0 && (FullOutput < 0.0 && NoCompOutput < FullOutput)) {
12674 0 : PartLoadRatio = 0.0;
12675 0 : return;
12676 : }
12677 : }
12678 1198 : } else if ((VRFHeatingMode && !thisVRFCond.HeatRecoveryUsed) || (thisVRFCond.HeatRecoveryUsed && HRHeatingMode)) {
12679 : // Since we are heating, we expect FullOutput > NoCompOutput
12680 : // If the QZnReq >= FullOutput the unit needs to run full out
12681 1158 : if (QZnReq >= FullOutput) {
12682 : // if no coil present in terminal unit, no need reset PLR?
12683 0 : if (this->HeatingCoilPresent) {
12684 0 : PartLoadRatio = 1.0;
12685 : // the zone set point could be exceeded if set point control is used so protect against that
12686 0 : if (this->isSetPointControlled) {
12687 0 : if (state.dataLoopNodes->Node(this->heatCoilAirOutNode).Temp < this->coilTempSetPoint) {
12688 0 : return;
12689 : }
12690 : } else {
12691 0 : return;
12692 : }
12693 : } else {
12694 0 : PartLoadRatio = 0.0;
12695 0 : return;
12696 : }
12697 : }
12698 : } else {
12699 : // VRF terminal unit is off
12700 : // shouldn't actually get here
12701 40 : PartLoadRatio = 0.0;
12702 40 : return;
12703 : }
12704 :
12705 : // The coil will not operate at PLR=0 or PLR=1, calculate the operating part-load ratio
12706 :
12707 2337 : if ((VRFHeatingMode || HRHeatingMode) || ((VRFCoolingMode && DXCoolingCoilOprCtrl) || HRCoolingMode)) {
12708 : int SolFla; // Flag of RegulaFalsi solver
12709 18771 : auto f = [&state, VRFTUNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio](Real64 const PartLoadRatio) {
12710 16438 : Real64 QZnReqTemp = QZnReq; // denominator representing zone load (W)
12711 : Real64 ActualOutput; // delivered capacity of VRF terminal unit
12712 16438 : Real64 SuppHeatCoilLoad = 0.0; // supplemental heating coil load (W)
12713 16438 : bool setPointControlled = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).isSetPointControlled;
12714 16438 : Real64 nonConstOnOffAirFlowRatio = OnOffAirFlowRatio;
12715 :
12716 16438 : if (state.dataHVACVarRefFlow->VRF(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum).VRFAlgorithmType == AlgorithmType::FluidTCtrl) {
12717 : // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control
12718 16438 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF_FluidTCtrl(
12719 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, ActualOutput, nonConstOnOffAirFlowRatio, SuppHeatCoilLoad);
12720 : } else {
12721 : // Algorithm Type: VRF model based on system curve
12722 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).CalcVRF(
12723 : state, VRFTUNum, FirstHVACIteration, PartLoadRatio, ActualOutput, nonConstOnOffAirFlowRatio, SuppHeatCoilLoad);
12724 : }
12725 :
12726 16438 : if (setPointControlled) {
12727 0 : Real64 outletNodeT = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOutletNodeNum).Temp;
12728 0 : return (outletNodeT - state.dataHVACVarRefFlow->VRFTU(VRFTUNum).coilTempSetPoint);
12729 : } else {
12730 16438 : if (std::abs(QZnReq) < 100.0) {
12731 157 : QZnReqTemp = sign(100.0, QZnReq);
12732 : }
12733 16438 : return (ActualOutput - QZnReq) / QZnReqTemp;
12734 : }
12735 2333 : };
12736 2333 : SolveRoot(state, ErrorTol, MaxIte, SolFla, PartLoadRatio, f, 0.0, 1.0);
12737 2333 : if (SolFla == -1) {
12738 : // Very low loads may not converge quickly. Tighten PLR boundary and try again.
12739 8 : TempMaxPLR = -0.1;
12740 8 : bool ContinueIter = true;
12741 42 : while (ContinueIter && TempMaxPLR < 1.0) {
12742 34 : TempMaxPLR += 0.1;
12743 :
12744 34 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, TempMaxPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
12745 :
12746 34 : if (VRFHeatingMode && TempOutput > QZnReq) {
12747 1 : ContinueIter = false;
12748 : }
12749 34 : if (VRFCoolingMode && TempOutput < QZnReq) {
12750 7 : ContinueIter = false;
12751 : }
12752 : }
12753 8 : TempMinPLR = TempMaxPLR;
12754 8 : ContinueIter = true;
12755 49 : while (ContinueIter && TempMinPLR > 0.0) {
12756 41 : TempMaxPLR = TempMinPLR;
12757 41 : TempMinPLR -= 0.01;
12758 :
12759 41 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, TempMaxPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
12760 :
12761 41 : if (VRFHeatingMode && TempOutput < QZnReq) {
12762 1 : ContinueIter = false;
12763 : }
12764 41 : if (VRFCoolingMode && TempOutput > QZnReq) {
12765 7 : ContinueIter = false;
12766 : }
12767 : }
12768 :
12769 8 : SolveRoot(state, ErrorTol, MaxIte, SolFla, PartLoadRatio, f, TempMinPLR, TempMaxPLR);
12770 8 : if (SolFla == -1) {
12771 0 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
12772 0 : if (this->IterLimitExceeded == 0) {
12773 0 : ShowWarningMessage(state, format("{} \"{}\"", tuTypeNames[(int)this->type], this->Name));
12774 0 : ShowContinueError(
12775 0 : state, format(" Iteration limit exceeded calculating terminal unit part-load ratio, maximum iterations = {}", MaxIte));
12776 0 : ShowContinueErrorTimeStamp(state, format(" Part-load ratio returned = {:.3R}", PartLoadRatio));
12777 :
12778 0 : this->CalcVRF_FluidTCtrl(state, VRFTUNum, FirstHVACIteration, TempMinPLR, TempOutput, OnOffAirFlowRatio, SuppHeatCoilLoad);
12779 :
12780 0 : ShowContinueError(state, format(" Load requested = {:.5T}, Load delivered = {:.5T}", QZnReq, TempOutput));
12781 0 : ShowRecurringWarningErrorAtEnd(state,
12782 0 : format("{} \"{}\" -- Terminal unit Iteration limit exceeded error continues...",
12783 0 : tuTypeNames[(int)this->type],
12784 0 : this->Name),
12785 0 : this->IterLimitExceeded);
12786 : } else {
12787 0 : ShowRecurringWarningErrorAtEnd(state,
12788 0 : format("{} \"{}\" -- Terminal unit Iteration limit exceeded error continues...",
12789 0 : tuTypeNames[(int)this->type],
12790 0 : this->Name),
12791 0 : this->IterLimitExceeded);
12792 : }
12793 : }
12794 8 : } else if (SolFla == -2) {
12795 8 : PartLoadRatio = max(MinPLF, std::abs(QZnReq - NoCompOutput) / std::abs(FullOutput - NoCompOutput));
12796 : }
12797 2325 : } else if (SolFla == -2) {
12798 0 : if (FullOutput - NoCompOutput == 0.0) {
12799 0 : PartLoadRatio = 0.0;
12800 : } else {
12801 0 : PartLoadRatio = min(1.0, max(MinPLF, std::abs(QZnReq - NoCompOutput) / std::abs(FullOutput - NoCompOutput)));
12802 : }
12803 : }
12804 : }
12805 : }
12806 :
12807 23653 : void VRFTerminalUnitEquipment::CalcVRF_FluidTCtrl(EnergyPlusData &state,
12808 : int const VRFTUNum, // Index to VRF terminal unit
12809 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
12810 : Real64 const PartLoadRatio, // compressor part load fraction
12811 : Real64 &LoadMet, // load met by unit (W)
12812 : Real64 &OnOffAirFlowRatio, // ratio of ON air flow to average air flow
12813 : Real64 &SuppHeatCoilLoad, // supplemental heating coil load (W)
12814 : ObjexxFCL::Optional<Real64> LatOutputProvided // delivered latent capacity (W)
12815 : )
12816 : {
12817 :
12818 : // SUBROUTINE INFORMATION:
12819 : // AUTHOR RP Zhang (LBNL), XF Pang (LBNL), Y Yura (Daikin Inc)
12820 : // DATE WRITTEN June 2015
12821 : // MODIFIED na
12822 : // RE-ENGINEERED na
12823 :
12824 : // PURPOSE OF THIS SUBROUTINE:
12825 : // This subroutine is part of the new VRF model based on physics, applicable for Fluid Temperature Control.
12826 : // This is adapted from subroutine CalcVRF, which is part of the VRF model based on system curves.
12827 : // This subroutine simulates the components making up the VRF indoor terminal unit.
12828 :
12829 : // METHODOLOGY EMPLOYED:
12830 : // A new physics based VRF model applicable for Fluid Temperature Control.
12831 : using DXCoils::SimDXCoil;
12832 : using SingleDuct::SimATMixer;
12833 : using SteamCoils::SimulateSteamCoilComponents;
12834 : using WaterCoils::SimulateWaterCoilComponents;
12835 :
12836 : int VRFTUOutletNodeNum; // TU air outlet node
12837 : int VRFTUInletNodeNum; // TU air inlet node
12838 : Real64 AirMassFlow; // total supply air mass flow [m3/s]
12839 : HVAC::FanOp fanOp; // fan operating mode, HVAC::FanOp::Cycling or HVAC::FanOp::Continuous
12840 : int VRFCond; // index to VRF condenser
12841 : Real64 SpecHumOut; // specific humidity ratio at outlet node
12842 : Real64 SpecHumIn; // specific humidity ratio at inlet node
12843 : int TUListIndex; // index to TU list for this VRF system
12844 : int IndexToTUInTUList; // index to TU in specific list for the VRF system
12845 : Real64 EvapTemp; // evaporating temperature
12846 : Real64 CondTemp; // condensing temperature
12847 : int ZoneNode; // Zone node of VRFTU is serving
12848 :
12849 23653 : VRFCond = this->VRFSysNum;
12850 23653 : TUListIndex = state.dataHVACVarRefFlow->VRF(VRFCond).ZoneTUListPtr;
12851 23653 : IndexToTUInTUList = this->IndexToTUInTUList;
12852 23653 : VRFTUOutletNodeNum = this->VRFTUOutletNodeNum;
12853 23653 : VRFTUInletNodeNum = this->VRFTUInletNodeNum;
12854 23653 : fanOp = this->fanOp;
12855 23653 : EvapTemp = state.dataHVACVarRefFlow->VRF(VRFCond).IUEvaporatingTemp;
12856 23653 : CondTemp = state.dataHVACVarRefFlow->VRF(VRFCond).IUCondensingTemp;
12857 23653 : ZoneNode = this->ZoneAirNode;
12858 :
12859 : // Set inlet air mass flow rate based on PLR and compressor on/off air flow rates
12860 23653 : if (PartLoadRatio == 0) {
12861 : // only provide required OA when coil is off
12862 4773 : state.dataHVACVarRefFlow->CompOnMassFlow = state.dataHVACVarRefFlow->OACompOnMassFlow;
12863 4773 : state.dataHVACVarRefFlow->CompOffMassFlow = state.dataHVACVarRefFlow->OACompOffMassFlow;
12864 : } else {
12865 : // identify the air flow rate corresponding to the coil load
12866 18880 : if (this->HeatingCoilPresent && state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) < Constant::MaxCap) {
12867 : // Only fix heating only mode for now
12868 4300 : state.dataHVACVarRefFlow->CompOnMassFlow = CalVRFTUAirFlowRate_FluidTCtrl(
12869 4300 : state, VRFTUNum, PartLoadRatio, FirstHVACIteration, state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
12870 : } else {
12871 14580 : state.dataHVACVarRefFlow->CompOnMassFlow = CalVRFTUAirFlowRate_FluidTCtrl(state, VRFTUNum, PartLoadRatio, FirstHVACIteration, _);
12872 : }
12873 : }
12874 23653 : SetAverageAirFlow(state, VRFTUNum, PartLoadRatio, OnOffAirFlowRatio);
12875 23653 : AirMassFlow = state.dataLoopNodes->Node(VRFTUInletNodeNum).MassFlowRate;
12876 :
12877 23653 : if (this->ATMixerExists) {
12878 : // There is an air terminal mixer
12879 18 : state.dataHVACVarRefFlow->ATMixOutNode2 = this->ATMixerOutNode;
12880 18 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
12881 : // set the primary air inlet mass flow rate
12882 10 : state.dataLoopNodes->Node(this->ATMixerPriNode).MassFlowRate =
12883 10 : min(state.dataLoopNodes->Node(this->ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(VRFTUInletNodeNum).MassFlowRate);
12884 : // now calculate the the mixer outlet air conditions (and the secondary air inlet flow rate). The mixer outlet flow rate has already
12885 : // been set above (it is the "inlet" node flow rate)
12886 10 : SimATMixer(state, this->ATMixerName, FirstHVACIteration, this->ATMixerIndex);
12887 : // inlet side ATMixer can change the VRF TU inlet condition and therefore the operating air flow rate
12888 10 : if (this->fanOp == HVAC::FanOp::Cycling && PartLoadRatio > 0) {
12889 8 : if (this->HeatingCoilPresent && state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) < Constant::MaxCap) {
12890 : // Only fix heating only mode for now
12891 0 : state.dataHVACVarRefFlow->CompOnMassFlow = CalVRFTUAirFlowRate_FluidTCtrl(
12892 0 : state, VRFTUNum, PartLoadRatio, FirstHVACIteration, state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
12893 : } else {
12894 8 : state.dataHVACVarRefFlow->CompOnMassFlow = CalVRFTUAirFlowRate_FluidTCtrl(state, VRFTUNum, PartLoadRatio, FirstHVACIteration, _);
12895 : }
12896 8 : if (std::abs(state.dataHVACVarRefFlow->CompOnMassFlow - AirMassFlow) > HVAC::SmallMassFlow) {
12897 8 : SetAverageAirFlow(state, VRFTUNum, PartLoadRatio, OnOffAirFlowRatio);
12898 8 : AirMassFlow = state.dataLoopNodes->Node(VRFTUInletNodeNum).MassFlowRate;
12899 : // set the primary air inlet mass flow rate
12900 8 : state.dataLoopNodes->Node(this->ATMixerPriNode).MassFlowRate =
12901 8 : min(state.dataLoopNodes->Node(this->ATMixerPriNode).MassFlowRateMaxAvail,
12902 8 : state.dataLoopNodes->Node(VRFTUInletNodeNum).MassFlowRate);
12903 8 : SimATMixer(state, this->ATMixerName, FirstHVACIteration, this->ATMixerIndex);
12904 : }
12905 : }
12906 : }
12907 : } else {
12908 23635 : state.dataHVACVarRefFlow->ATMixOutNode2 = 0;
12909 : // simulate OA Mixer
12910 23635 : if (this->OAMixerUsed) {
12911 23626 : MixedAir::SimOAMixer(state, this->OAMixerName, this->OAMixerIndex);
12912 : }
12913 : }
12914 : // if blow through, simulate fan then coils
12915 23653 : if (this->fanPlace == HVAC::FanPlace::BlowThru) {
12916 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::SystemModel) {
12917 0 : if (OnOffAirFlowRatio > 0.0) {
12918 0 : state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex)->simulate(state, FirstHVACIteration, _, _);
12919 : } else {
12920 0 : state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex)->simulate(state, FirstHVACIteration, _, _, PartLoadRatio);
12921 : }
12922 : } else {
12923 0 : state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex)
12924 0 : ->simulate(state, FirstHVACIteration, state.dataHVACVarRefFlow->FanSpeedRatio);
12925 : }
12926 : }
12927 23653 : if (this->CoolingCoilPresent) {
12928 : // above condition for heat pump mode, below condition for heat recovery mode
12929 34647 : if ((!state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed && state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) ||
12930 10994 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
12931 9 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList))) {
12932 25334 : SimDXCoil(state,
12933 : "",
12934 : HVAC::CompressorOp::On,
12935 : FirstHVACIteration,
12936 12667 : this->CoolCoilIndex,
12937 : fanOp,
12938 : PartLoadRatio,
12939 : _,
12940 : _,
12941 12667 : state.dataHVACVarRefFlow->MaxCoolingCapacity(VRFCond),
12942 12667 : state.dataHVACVarRefFlow->VRF(this->VRFSysNum).VRFCondCyclingRatio);
12943 : } else { // cooling coil is off
12944 10986 : SimDXCoil(state, "", HVAC::CompressorOp::Off, FirstHVACIteration, this->CoolCoilIndex, fanOp, 0.0, _);
12945 : }
12946 23653 : state.dataHVACVarRefFlow->LoopDXCoolCoilRTF = state.dataAirLoop->LoopDXCoilRTF;
12947 : } else {
12948 0 : state.dataHVACVarRefFlow->LoopDXCoolCoilRTF = 0.0;
12949 : }
12950 :
12951 23653 : if (this->HeatingCoilPresent) {
12952 : // above condition for heat pump mode, below condition for heat recovery mode
12953 36440 : if ((!state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) ||
12954 12787 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
12955 9 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList))) {
12956 32598 : SimDXCoil(state,
12957 : "",
12958 : HVAC::CompressorOp::On,
12959 : FirstHVACIteration,
12960 10866 : this->HeatCoilIndex,
12961 : fanOp,
12962 : PartLoadRatio,
12963 : _,
12964 : _,
12965 10866 : state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond));
12966 : } else {
12967 12787 : SimDXCoil(state, "", HVAC::CompressorOp::Off, FirstHVACIteration, this->HeatCoilIndex, fanOp, 0.0, _);
12968 : }
12969 23653 : state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = state.dataAirLoop->LoopDXCoilRTF;
12970 : } else {
12971 0 : state.dataHVACVarRefFlow->LoopDXHeatCoilRTF = 0.0;
12972 : }
12973 :
12974 23653 : Real64 OnOffFanPartLoadFraction = 1.0;
12975 23653 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp == HVAC::FanOp::Cycling) {
12976 23648 : OnOffFanPartLoadFraction = state.dataHVACGlobal->OnOffFanPartLoadFraction;
12977 : }
12978 : // if draw through, simulate coils then fan
12979 23653 : if (this->fanPlace == HVAC::FanPlace::DrawThru) {
12980 23653 : auto *fan = state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex);
12981 23653 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::SystemModel) {
12982 23653 : if (OnOffAirFlowRatio > 0.0) {
12983 18891 : fan->simulate(state, FirstHVACIteration, _, _, _, fan->inletAirMassFlowRate, OnOffFanPartLoadFraction, 0, 0, _);
12984 : } else {
12985 4762 : fan->simulate(state, FirstHVACIteration, _, _, PartLoadRatio);
12986 : }
12987 : } else {
12988 0 : fan->simulate(state, FirstHVACIteration, state.dataHVACVarRefFlow->FanSpeedRatio);
12989 : }
12990 : }
12991 :
12992 : // track fan power per terminal unit for calculating COP
12993 23653 : this->FanPower = state.dataFans->fans(this->FanIndex)->totalPower;
12994 :
12995 : // run supplemental heating coil
12996 23653 : if (this->SuppHeatingCoilPresent) {
12997 32 : Real64 SuppPLR = this->SuppHeatPartLoadRatio;
12998 32 : this->CalcVRFSuppHeatingCoil(state, VRFTUNum, FirstHVACIteration, SuppPLR, SuppHeatCoilLoad);
12999 32 : if ((state.dataLoopNodes->Node(this->SuppHeatCoilAirOutletNode).Temp > this->MaxSATFromSuppHeatCoil) && SuppPLR > 0.0) {
13000 : // adjust the heating load to maximum allowed
13001 0 : Real64 MaxHeatCoilLoad = this->HeatingCoilCapacityLimit(state, this->SuppHeatCoilAirInletNode, this->MaxSATFromSuppHeatCoil);
13002 0 : this->CalcVRFSuppHeatingCoil(state, VRFTUNum, FirstHVACIteration, SuppPLR, MaxHeatCoilLoad);
13003 0 : SuppHeatCoilLoad = MaxHeatCoilLoad;
13004 : }
13005 : }
13006 :
13007 23653 : Real64 LatentLoadMet = 0.0;
13008 23653 : Real64 TempOut = 0.0;
13009 23653 : Real64 TempIn = 0.0;
13010 23653 : if (this->ATMixerExists) {
13011 18 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
13012 : // Air terminal supply side mixer, calculate supply side mixer output
13013 8 : SimATMixer(state, this->ATMixerName, FirstHVACIteration, this->ATMixerIndex);
13014 8 : TempOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->ATMixOutNode2).Temp;
13015 8 : SpecHumOut = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->ATMixOutNode2).HumRat;
13016 8 : AirMassFlow = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->ATMixOutNode2).MassFlowRate;
13017 : } else {
13018 : // Air terminal inlet side mixer
13019 10 : TempOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).Temp;
13020 10 : SpecHumOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).HumRat;
13021 : }
13022 18 : TempIn = state.dataLoopNodes->Node(ZoneNode).Temp;
13023 18 : SpecHumIn = state.dataLoopNodes->Node(ZoneNode).HumRat;
13024 : } else {
13025 23635 : TempOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).Temp;
13026 23635 : SpecHumOut = state.dataLoopNodes->Node(VRFTUOutletNodeNum).HumRat;
13027 23635 : if (ZoneNode > 0) {
13028 23635 : TempIn = state.dataLoopNodes->Node(ZoneNode).Temp;
13029 23635 : SpecHumIn = state.dataLoopNodes->Node(ZoneNode).HumRat;
13030 : } else {
13031 0 : TempIn = state.dataLoopNodes->Node(VRFTUInletNodeNum).Temp;
13032 0 : SpecHumIn = state.dataLoopNodes->Node(VRFTUInletNodeNum).HumRat;
13033 : }
13034 : }
13035 : // calculate sensible load met using delta enthalpy
13036 23653 : Real64 TotalOutput = AirMassFlow * (Psychrometrics::PsyHFnTdbW(TempOut, SpecHumOut) -
13037 23653 : Psychrometrics::PsyHFnTdbW(TempIn, SpecHumIn)); // total addition/removal rate, {W};
13038 23653 : LoadMet = AirMassFlow * PsyDeltaHSenFnTdb2W2Tdb1W1(TempOut, SpecHumOut, TempIn, SpecHumIn); // sensible {W}
13039 23653 : LatentLoadMet = TotalOutput - LoadMet;
13040 23653 : if (present(LatOutputProvided)) {
13041 2378 : LatOutputProvided = LatentLoadMet;
13042 : }
13043 23653 : }
13044 :
13045 18888 : Real64 VRFTerminalUnitEquipment::CalVRFTUAirFlowRate_FluidTCtrl(EnergyPlusData &state,
13046 : int const VRFTUNum, // Index to VRF terminal unit
13047 : Real64 PartLoadRatio, // part load ratio of the coil
13048 : [[maybe_unused]] bool FirstHVACIteration, // FirstHVACIteration flag
13049 : ObjexxFCL::Optional<Real64 const> MaxHeatCap // maximum allowed heating capacity
13050 : )
13051 : {
13052 : // SUBROUTINE INFORMATION:
13053 : // AUTHOR Rongpeng Zhang, LBNL
13054 : // DATE WRITTEN Nov 2015
13055 : // MODIFIED na
13056 : // RE-ENGINEERED na
13057 :
13058 : // PURPOSE OF THIS FUNCTION:
13059 : // This function determines the TU airflow rate corresponding to the coil load.
13060 : // This is used to address the coupling between OA mixer simulation and VRF-FluidTCtrl coil simulation.
13061 :
13062 : // METHODOLOGY EMPLOYED:
13063 : // VRF-FluidTCtrl TU airflow rate is determined by the control logic of VRF-FluidTCtrl coil to match the
13064 : // coil load. This is affected by the coil inlet conditions. However, the airflow rate will affect the
13065 : // OA mixer simulation, which leads to different coil inlet conditions. So, there is a coupling issue here.
13066 :
13067 : using General::SolveRoot;
13068 :
13069 : Real64 AirMassFlowRate; // air mass flow rate of the coil (kg/s)
13070 :
13071 18888 : int constexpr Mode(1); // Performance mode for MultiMode DX coil. Always 1 for other coil types
13072 18888 : int constexpr MaxIte(500); // maximum number of iterations
13073 : int DXCoilNum; // index to DX Coil
13074 : int IndexToTUInTUList; // index to TU in specific list for the VRF system
13075 : int SolFla; // Flag of RegulaFalsi solver
13076 : int TUListIndex; // index to TU list for this VRF system
13077 : int VRFCond; // index to VRF condenser
13078 18888 : Real64 constexpr ErrorTol(0.01); // tolerance for RegulaFalsi iterations
13079 : Real64 FanSpdRatio; // ratio of required and rated air flow rate
13080 : Real64 FanSpdRatioMin; // min fan speed ratio
13081 : Real64 FanSpdRatioMax; // min fan speed ratio
13082 : Real64 QCoilReq; // required coil load (W)
13083 : Real64 QCoilAct; // actual coil load (W)
13084 : Real64 TeTc; // evaporating temperature or condensing temperature for VRF indoor unit(C)
13085 :
13086 18888 : VRFCond = this->VRFSysNum;
13087 18888 : TUListIndex = state.dataHVACVarRefFlow->VRF(VRFCond).ZoneTUListPtr;
13088 18888 : IndexToTUInTUList = this->IndexToTUInTUList;
13089 :
13090 27481 : if ((!state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed && state.dataHVACVarRefFlow->CoolingLoad(VRFCond)) ||
13091 8593 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
13092 6 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRCoolRequest(IndexToTUInTUList))) {
13093 : // VRF terminal unit is on cooling mode
13094 10301 : DXCoilNum = this->CoolCoilIndex;
13095 10301 : QCoilReq = -PartLoadRatio * state.dataDXCoils->DXCoil(DXCoilNum).RatedTotCap(Mode);
13096 10301 : TeTc = state.dataHVACVarRefFlow->VRF(VRFCond).IUEvaporatingTemp;
13097 :
13098 : // For HR operations, Te is lower than the outdoor air temperature because of outdoor evaporator operations
13099 : // The difference is usually 2-3C according to the engineering experience. 2 is used here for a slightly bigger fan flow rate.
13100 10301 : if (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed) {
13101 6 : TeTc = min(TeTc, state.dataEnvrn->OutDryBulbTemp - 2);
13102 : }
13103 :
13104 8627 : } else if ((!state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed && state.dataHVACVarRefFlow->HeatingLoad(VRFCond)) ||
13105 40 : (state.dataHVACVarRefFlow->VRF(VRFCond).HeatRecoveryUsed &&
13106 0 : state.dataHVACVarRefFlow->TerminalUnitList(TUListIndex).HRHeatRequest(IndexToTUInTUList))) {
13107 : // VRF terminal unit is on heating mode
13108 8547 : DXCoilNum = this->HeatCoilIndex;
13109 8547 : Real64 RatedCapacity = state.dataDXCoils->DXCoil(DXCoilNum).RatedTotCap(Mode);
13110 8547 : if (present(MaxHeatCap)) {
13111 4300 : RatedCapacity = min(MaxHeatCap, RatedCapacity);
13112 : }
13113 8547 : QCoilReq = PartLoadRatio * RatedCapacity;
13114 8547 : TeTc = state.dataHVACVarRefFlow->VRF(VRFCond).IUCondensingTemp;
13115 :
13116 : } else {
13117 : // VRF terminal unit is off
13118 40 : QCoilAct = 0.0;
13119 40 : AirMassFlowRate = max(state.dataHVACVarRefFlow->OACompOnMassFlow, 0.0);
13120 40 : return AirMassFlowRate;
13121 : }
13122 :
13123 : // minimum airflow rate
13124 18848 : if (state.dataDXCoils->DXCoil(DXCoilNum).RatedAirMassFlowRate(Mode) > 0.0) {
13125 18848 : FanSpdRatioMin = min(state.dataHVACVarRefFlow->OACompOnMassFlow / state.dataDXCoils->DXCoil(DXCoilNum).RatedAirMassFlowRate(Mode), 1.0);
13126 : } else {
13127 : // VRF terminal unit is off
13128 0 : QCoilAct = 0.0;
13129 0 : AirMassFlowRate = max(state.dataHVACVarRefFlow->OACompOnMassFlow, 0.0);
13130 0 : return AirMassFlowRate;
13131 : }
13132 :
13133 18848 : FanSpdRatioMax = 1.0;
13134 :
13135 71534 : auto f = [&state, VRFTUNum, DXCoilNum, QCoilReq, TeTc, PartLoadRatio](Real64 const FanSpdRatio) {
13136 : using DXCoils::ControlVRFIUCoil;
13137 : using Psychrometrics::PsyHFnTdbW;
13138 : using SingleDuct::SimATMixer;
13139 :
13140 71534 : int constexpr Mode(1); // Performance mode for MultiMode DX coil. Always 1 for other coil types
13141 : int VRFCond; // index to VRF condenser
13142 : int VRFInletNode; // VRF inlet node number
13143 : Real64 FanSpdRatioBase; // baseline FanSpdRatio for VRFTUAirFlowResidual
13144 : Real64 FanSpdRatioAct; // calculated FanSpdRatio for VRFTUAirFlowResidual
13145 : Real64 QCoilAct; // actual coil load [W]
13146 : Real64 temp; // for temporary use
13147 : Real64 Tin; // coil inlet air temperature [C]
13148 : Real64 Win; // coil inlet air humidity ratio [kg/kg]
13149 : Real64 Hin; // coil inlet air enthalpy
13150 : Real64 Wout; // coil outlet air humidity ratio
13151 : Real64 Tout; // coil outlet air temperature
13152 : Real64 Hout; // coil outlet air enthalpy
13153 : Real64 SHact; // coil actual SH
13154 : Real64 SCact; // coil actual SC
13155 :
13156 71534 : VRFCond = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFSysNum;
13157 71534 : VRFInletNode = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum;
13158 :
13159 71534 : if (std::abs(FanSpdRatio) < 0.01) {
13160 18 : FanSpdRatioBase = sign(0.01, FanSpdRatio);
13161 : } else {
13162 71516 : FanSpdRatioBase = FanSpdRatio;
13163 : }
13164 :
13165 : // Set inlet air mass flow rate based on PLR and compressor on/off air flow rates
13166 71534 : state.dataHVACVarRefFlow->CompOnMassFlow = FanSpdRatio * state.dataDXCoils->DXCoil(DXCoilNum).RatedAirMassFlowRate(Mode);
13167 71534 : SetAverageAirFlow(state, VRFTUNum, PartLoadRatio, temp);
13168 71534 : Tin = state.dataLoopNodes->Node(VRFInletNode).Temp;
13169 71534 : Win = state.dataLoopNodes->Node(VRFInletNode).HumRat;
13170 :
13171 : // Simulation the OAMixer if there is any
13172 71534 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerUsed) {
13173 71450 : MixedAir::SimOAMixer(
13174 71450 : state, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerName, state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex);
13175 71450 : int OAMixNode = state.dataMixedAir->OAMixer(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).OAMixerIndex).MixNode;
13176 71450 : Tin = state.dataLoopNodes->Node(OAMixNode).Temp;
13177 71450 : Win = state.dataLoopNodes->Node(OAMixNode).HumRat;
13178 : }
13179 : // Simulate the blow-through fan if there is any
13180 71534 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanPlace == HVAC::FanPlace::BlowThru) {
13181 0 : auto *fan = state.dataFans->fans(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).FanIndex);
13182 0 : if (state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanType == HVAC::FanType::SystemModel) {
13183 0 : if (temp > 0) {
13184 0 : fan->simulate(state, false, _, _);
13185 : } else {
13186 0 : fan->simulate(state, false, _, _, PartLoadRatio);
13187 : }
13188 : } else {
13189 0 : fan->simulate(state, false, state.dataHVACVarRefFlow->FanSpeedRatio);
13190 : }
13191 0 : Tin = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOutletNode).Temp;
13192 0 : Win = state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOutletNode).HumRat;
13193 : }
13194 :
13195 : // Call the coil control logic to determine the air flow rate to match the given coil load
13196 71534 : ControlVRFIUCoil(
13197 71534 : state, DXCoilNum, QCoilReq, Tin, Win, TeTc, state.dataHVACVarRefFlow->OACompOnMassFlow, FanSpdRatioAct, Wout, Tout, Hout, SHact, SCact);
13198 :
13199 71534 : Hin = PsyHFnTdbW(Tin, Win);
13200 71534 : QCoilAct = FanSpdRatioAct * state.dataDXCoils->DXCoil(DXCoilNum).RatedAirMassFlowRate(Mode) *
13201 71534 : (Hout - Hin); // positive for heating, negative for cooling
13202 :
13203 71534 : return (FanSpdRatioAct - FanSpdRatio);
13204 18848 : };
13205 :
13206 18848 : SolveRoot(state, ErrorTol, MaxIte, SolFla, FanSpdRatio, f, FanSpdRatioMin, FanSpdRatioMax);
13207 18848 : if (SolFla < 0) {
13208 0 : FanSpdRatio = FanSpdRatioMax; // over capacity
13209 : }
13210 :
13211 18848 : AirMassFlowRate = FanSpdRatio * state.dataDXCoils->DXCoil(DXCoilNum).RatedAirMassFlowRate(Mode);
13212 :
13213 18848 : return AirMassFlowRate;
13214 : }
13215 :
13216 26134 : Real64 CompResidual_FluidTCtrl(EnergyPlusData &state,
13217 : Real64 T_dis,
13218 : Real64 CondHeat,
13219 : int CAPFT,
13220 : Real64 const T_suc // Compressor suction temperature Te' [C]
13221 : )
13222 : {
13223 : // FUNCTION INFORMATION:
13224 : // AUTHOR Xiufeng Pang (XP)
13225 : // DATE WRITTEN Mar 2013
13226 : // MODIFIED Jul 2015, RP Zhang, LBNL
13227 : // RE-ENGINEERED
13228 : //
13229 : // PURPOSE OF THIS FUNCTION:
13230 : // Calculates residual function ((VRV terminal unit cooling output - Zone sensible cooling load)
13231 : //
13232 : using Curve::CurveValue;
13233 :
13234 : Real64 CAPSpd; // Evaporative capacity of the compressor at a given spd[W]
13235 : Real64 CompResidual;
13236 :
13237 26134 : CAPSpd = CurveValue(state, CAPFT, T_dis, T_suc);
13238 26134 : CompResidual = (CondHeat - CAPSpd) / CAPSpd;
13239 :
13240 26134 : return CompResidual;
13241 : }
13242 :
13243 15376 : void VRFCondenserEquipment::VRFOU_TeTc(EnergyPlusData &state,
13244 : HXOpMode const OperationMode, // Mode 0 for running as condenser, 1 for evaporator
13245 : Real64 const Q_coil, // // OU coil heat release at cooling mode or heat extract at heating mode [W]
13246 : Real64 const SHSC, // SC for OU condenser or SH for OU evaporator [C]
13247 : Real64 const m_air, // OU coil air mass flow rate [kg/s]
13248 : Real64 const T_coil_in, // Temperature of air at OU coil inlet [C]
13249 : Real64 const W_coil_in, // Humidity ratio of air at OU coil inlet [kg/kg]
13250 : Real64 const OutdoorPressure, // Outdoor air pressure [Pa]
13251 : Real64 &T_coil_surf, // Air temperature at coil surface [C]
13252 : Real64 &TeTc // VRF Tc at cooling mode, or Te at heating mode [C]
13253 : )
13254 : {
13255 :
13256 : // SUBROUTINE INFORMATION:
13257 : // AUTHOR Rongpeng Zhang, LBNL
13258 : // DATE WRITTEN Jan 2016
13259 : // MODIFIED na
13260 : //
13261 : // RE-ENGINEERED na
13262 : //
13263 : // PURPOSE OF THIS SUBROUTINE:
13264 : // Calculate the VRF OU refrigerant side temperature, i.e., condensing temperature
13265 : // at cooling mode, or evaporating temperature at heating mode, given the coil heat
13266 : // release/extract amount and air side parameters.
13267 : //
13268 : // METHODOLOGY EMPLOYED:
13269 : // This is part of the physics based VRF model applicable for Fluid Temperature Control.
13270 : //
13271 :
13272 : Real64 BF; // VRF OU bypass [-]
13273 : Real64 deltaT; // Difference between Te/Tc and air temperature at coil surface [C]
13274 : Real64 h_coil_in; // Enthalpy of air at OU coil inlet [C]
13275 : Real64 h_coil_out; // Enthalpy of air at OU coil outlet [C]
13276 : Real64 T_coil_out; // Air temperature at coil outlet [C]
13277 : Real64 T_coil_surf_sat; // Saturated air temperature at coil surface [C]
13278 : Real64 W_coil_surf_sat; // Humidity ratio of saturated air at coil surface [kg/kg]
13279 :
13280 15376 : if (OperationMode == HXOpMode::CondMode) {
13281 : // IU Cooling: OperationMode 0
13282 :
13283 10106 : if (m_air <= 0) {
13284 0 : TeTc = this->CondensingTemp;
13285 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit airflow rate ({:.3T} ) for \"{}\":", m_air, this->Name));
13286 0 : ShowContinueError(state, " This cannot be used to calculate outdoor unit refrigerant temperature.");
13287 0 : ShowContinueError(state, format(" Default condensing temperature is used: {:.3T}", TeTc));
13288 : }
13289 :
13290 10106 : BF = this->RateBFOUCond; // 0.219;
13291 10106 : T_coil_out = T_coil_in + Q_coil / 1005.0 / m_air;
13292 10106 : T_coil_surf = T_coil_in + (T_coil_out - T_coil_in) / (1 - BF);
13293 :
13294 10106 : deltaT = this->C3Tc * pow_2(SHSC) + this->C2Tc * SHSC + this->C1Tc;
13295 :
13296 10106 : TeTc = T_coil_surf + deltaT;
13297 :
13298 5270 : } else if (OperationMode == HXOpMode::EvapMode) {
13299 : // IU Heating: OperationMode 1
13300 :
13301 5270 : if (m_air <= 0) {
13302 0 : TeTc = this->EvaporatingTemp;
13303 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit airflow rate ({:.3T} ) for \"{}\":", m_air, this->Name));
13304 0 : ShowContinueError(state, " This cannot be used to calculate outdoor unit refrigerant temperature.");
13305 0 : ShowContinueError(state, format(" Default condensing temperature is used: {:.3T}", TeTc));
13306 : }
13307 :
13308 5270 : BF = this->RateBFOUEvap; // 0.45581;
13309 5270 : h_coil_in = PsyHFnTdbW(T_coil_in, W_coil_in);
13310 5270 : h_coil_out = h_coil_in - Q_coil / m_air / (1 - BF);
13311 5270 : h_coil_out = max(0.01, h_coil_out);
13312 :
13313 5270 : T_coil_surf_sat = PsyTsatFnHPb(state, h_coil_out, OutdoorPressure, "VRFOU_TeTc");
13314 5270 : W_coil_surf_sat = PsyWFnTdbH(state, T_coil_surf_sat, h_coil_out, "VRFOU_TeTc");
13315 :
13316 5270 : if (W_coil_surf_sat < W_coil_in) {
13317 : // There is dehumidification
13318 5269 : T_coil_surf = T_coil_surf_sat;
13319 : } else {
13320 : // No dehumidification
13321 1 : T_coil_surf = PsyTdbFnHW(h_coil_out, W_coil_in);
13322 : }
13323 :
13324 5270 : deltaT = this->C3Te * pow_2(SHSC) + this->C2Te * SHSC + this->C1Te;
13325 :
13326 5270 : TeTc = T_coil_surf - deltaT;
13327 : }
13328 15376 : }
13329 :
13330 2 : Real64 VRFCondenserEquipment::VRFOU_Cap(EnergyPlusData &state,
13331 : HXOpMode const OperationMode, // Mode 0 for running as condenser, 1 for evaporator
13332 : Real64 const TeTc, // VRF Tc at cooling mode, or Te at heating mode [C]
13333 : Real64 const SHSC, // SC for OU condenser or SH for OU evaporator [C]
13334 : Real64 const m_air, // OU coil air mass flow rate [kg/s]
13335 : Real64 const T_coil_in, // Temperature of air at OU coil inlet [C]
13336 : Real64 const W_coil_in // Humidity ratio of air at OU coil inlet [kg/kg]
13337 : )
13338 : {
13339 :
13340 : // SUBROUTINE INFORMATION:
13341 : // AUTHOR Rongpeng Zhang, LBNL
13342 : // DATE WRITTEN Jan 2016
13343 : // MODIFIED na
13344 : //
13345 : // RE-ENGINEERED na
13346 : //
13347 : // PURPOSE OF THIS SUBROUTINE:
13348 : // Calculate the VRF OU load, given refrigerant side temperature, i.e., condensing temperature
13349 : // and SC for condenser, or evaporating temperature and SH for evaporator.
13350 : //
13351 : // METHODOLOGY EMPLOYED:
13352 : // This is part of the physics based VRF model applicable for Fluid Temperature Control.
13353 :
13354 : Real64 BF; // VRF OU bypass [-]
13355 : Real64 deltaT; // Difference between Te/Tc and air temperature at coil surface [C]
13356 : Real64 h_coil_in; // Enthalpy of air at OU coil inlet [C]
13357 : Real64 h_coil_out; // Enthalpy of air at OU coil outlet [C]
13358 : Real64 Q_coil; // OU coil heat release at cooling mode or heat extract at heating mode [W]
13359 : Real64 T_coil_out; // Air temperature at coil outlet [C]
13360 : Real64 T_coil_surf; // Air temperature at coil surface [C]
13361 : Real64 W_coil_surf_sat; // Humidity ratio of saturated air at coil surface [kg/kg]
13362 :
13363 2 : Q_coil = 0.0;
13364 :
13365 2 : if (OperationMode == HXOpMode::CondMode) {
13366 : // IU Cooling: OperationMode 0
13367 1 : if (m_air <= 0) {
13368 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit airflow rate ({:.3T} ) for \"{}\":", m_air, this->Name));
13369 0 : ShowContinueError(state, " This cannot be used to calculate outdoor unit capacity.");
13370 : }
13371 :
13372 1 : BF = this->RateBFOUCond; // 0.219;
13373 1 : deltaT = this->C3Tc * pow_2(SHSC) + this->C2Tc * SHSC + this->C1Tc;
13374 1 : T_coil_surf = TeTc - deltaT;
13375 1 : T_coil_out = T_coil_in + (T_coil_surf - T_coil_in) * (1 - BF);
13376 1 : Q_coil = (T_coil_out - T_coil_in) * 1005.0 * m_air;
13377 :
13378 1 : } else if (OperationMode == HXOpMode::EvapMode) {
13379 : // IU Heating: OperationMode 1
13380 1 : if (m_air <= 0) {
13381 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit airflow rate ({:.3T} ) for \"{}\":", m_air, this->Name));
13382 0 : ShowContinueError(state, " This cannot be used to calculate outdoor unit capacity.");
13383 : }
13384 :
13385 1 : BF = this->RateBFOUEvap; // 0.45581;
13386 1 : deltaT = this->C3Te * pow_2(SHSC) + this->C2Te * SHSC + this->C1Te;
13387 1 : T_coil_surf = TeTc + deltaT;
13388 :
13389 : // saturated humidity ratio corresponding to T_coil_surf
13390 1 : W_coil_surf_sat = PsyWFnTdpPb(state, T_coil_surf, state.dataEnvrn->OutBaroPress);
13391 :
13392 1 : if (W_coil_surf_sat < W_coil_in) {
13393 : // There is dehumidification, W_coil_out = W_coil_surf_sat
13394 0 : h_coil_out = PsyHFnTdbW(T_coil_surf, W_coil_surf_sat);
13395 : } else {
13396 : // No dehumidification, W_coil_out = W_coil_in
13397 1 : h_coil_out = PsyHFnTdbW(T_coil_surf, W_coil_in);
13398 : }
13399 1 : h_coil_out = max(0.01, h_coil_out);
13400 1 : h_coil_in = PsyHFnTdbW(T_coil_in, W_coil_in);
13401 1 : Q_coil = (h_coil_in - h_coil_out) * m_air * (1 - BF); // bypass airflow should not be included here
13402 :
13403 : } else {
13404 : // Should not come here
13405 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit operational mode for \"{}\":", this->Name));
13406 0 : ShowContinueError(state, " The operational mode is not correctly set in the function VRFOU_Cap.");
13407 : }
13408 :
13409 2 : return Q_coil;
13410 : }
13411 :
13412 3 : Real64 VRFCondenserEquipment::VRFOU_FlowRate(EnergyPlusData &state,
13413 : HXOpMode const OperationMode, // Mode 0 for running as condenser, 1 for evaporator
13414 : Real64 const TeTc, // VRF Tc at cooling mode, or Te at heating mode [C]
13415 : Real64 const SHSC, // SC for OU condenser or SH for OU evaporator [C]
13416 : Real64 const Q_coil, // absolute value of OU coil heat release or heat extract [W]
13417 : Real64 const T_coil_in, // Temperature of air at OU coil inlet [C]
13418 : Real64 const W_coil_in // Humidity ratio of air at OU coil inlet [kg/kg]
13419 : ) const
13420 : {
13421 :
13422 : // SUBROUTINE INFORMATION:
13423 : // AUTHOR Rongpeng Zhang, LBNL
13424 : // DATE WRITTEN Mar 2016
13425 : // MODIFIED na
13426 : //
13427 : // RE-ENGINEERED na
13428 : //
13429 : // PURPOSE OF THIS SUBROUTINE:
13430 : // Calculate the outdoor unit fan flow rate, given VRF OU load and refrigerant side temperature, i.e.,
13431 : // condensing temperature and SC for condenser, or evaporating temperature and SH for evaporator.
13432 : //
13433 : // METHODOLOGY EMPLOYED:
13434 : // This is part of the physics based VRF model applicable for Fluid Temperature Control.
13435 :
13436 : Real64 BF; // VRF OU bypass [-]
13437 : Real64 deltaT; // Difference between Te/Tc and air temperature at coil surface [C]
13438 : Real64 h_coil_in; // Enthalpy of air at OU coil inlet [C]
13439 : Real64 h_coil_out; // Enthalpy of air at OU coil outlet [C]
13440 : Real64 m_air; // OU coil air mass flow rate [kg/s]
13441 : Real64 T_coil_out; // Air temperature at coil outlet [C]
13442 : Real64 T_coil_surf; // Air temperature at coil surface [C]
13443 : Real64 W_coil_surf_sat; // Humidity ratio of saturated air at coil surface [kg/kg]
13444 :
13445 3 : m_air = 0.0;
13446 :
13447 3 : if (OperationMode == HXOpMode::CondMode) {
13448 : // IU Cooling: OperationMode 0
13449 :
13450 1 : BF = this->RateBFOUCond; // 0.219;
13451 1 : deltaT = this->C3Tc * pow_2(SHSC) + this->C2Tc * SHSC + this->C1Tc;
13452 1 : T_coil_surf = TeTc - deltaT;
13453 1 : T_coil_out = T_coil_in + (T_coil_surf - T_coil_in) * (1 - BF);
13454 1 : m_air = Q_coil / (T_coil_out - T_coil_in) / 1005.0;
13455 :
13456 2 : } else if (OperationMode == HXOpMode::EvapMode) {
13457 : // IU Heating: OperationMode 1
13458 :
13459 2 : BF = this->RateBFOUEvap; // 0.45581;
13460 2 : deltaT = this->C3Te * pow_2(SHSC) + this->C2Te * SHSC + this->C1Te;
13461 2 : T_coil_surf = TeTc + deltaT;
13462 :
13463 : // saturated humidity ratio corresponding to T_coil_surf
13464 2 : W_coil_surf_sat = PsyWFnTdpPb(state, T_coil_surf, state.dataEnvrn->OutBaroPress);
13465 :
13466 2 : if (W_coil_surf_sat < W_coil_in) {
13467 : // There is dehumidification, W_coil_out = W_coil_surf_sat
13468 0 : h_coil_out = PsyHFnTdbW(T_coil_surf, W_coil_surf_sat);
13469 : } else {
13470 : // No dehumidification, W_coil_out = W_coil_in
13471 2 : h_coil_out = PsyHFnTdbW(T_coil_surf, W_coil_in);
13472 : }
13473 2 : h_coil_out = max(0.01, h_coil_out);
13474 2 : h_coil_in = PsyHFnTdbW(T_coil_in, W_coil_in);
13475 2 : m_air = Q_coil / (h_coil_in - h_coil_out) / (1 - BF);
13476 :
13477 : } else {
13478 : // Should not come here
13479 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit operational mode for \"{}\":", this->Name));
13480 0 : ShowContinueError(state, " The operational mode is not correctly set in the function VRFOU_Cap.");
13481 : }
13482 :
13483 3 : return m_air;
13484 : }
13485 :
13486 2 : Real64 VRFCondenserEquipment::VRFOU_SCSH(EnergyPlusData &state,
13487 : HXOpMode const OperationMode, // Mode 0 for running as condenser, 1 for evaporator
13488 : Real64 const Q_coil, // // OU coil heat release at cooling mode or heat extract at heating mode [W]
13489 : Real64 const TeTc, // VRF Tc at cooling mode, or Te at heating mode [C]
13490 : Real64 const m_air, // OU coil air mass flow rate [kg/s]
13491 : Real64 const T_coil_in, // Temperature of air at OU coil inlet [C]
13492 : Real64 const W_coil_in, // Humidity ratio of air at OU coil inlet [kg/kg]
13493 : Real64 const OutdoorPressure // Outdoor air pressure [Pa]
13494 : ) const
13495 : {
13496 :
13497 : // SUBROUTINE INFORMATION:
13498 : // AUTHOR Rongpeng Zhang, LBNL
13499 : // DATE WRITTEN Jan 2016
13500 : // MODIFIED na
13501 : //
13502 : // RE-ENGINEERED na
13503 : //
13504 : // PURPOSE OF THIS SUBROUTINE:
13505 : // Calculate the SC for OU condenser, or SH for OU evaporator, given
13506 : // VRF OU load and refrigerant side temperature, i.e., condensing temperature
13507 : // for condenser, or evaporating temperature for evaporator.
13508 : //
13509 : // METHODOLOGY EMPLOYED:
13510 : // This is part of the physics based VRF model applicable for Fluid Temperature Control.
13511 :
13512 : Real64 BF; // VRF OU bypass [-]
13513 : Real64 deltaT; // Difference between Te/Tc and air temperature at coil surface [C]
13514 : Real64 h_coil_in; // Enthalpy of air at OU coil inlet [C]
13515 : Real64 h_coil_out; // Enthalpy of air at OU coil outlet [C]
13516 : Real64 SHSC; // SC for OU condenser, or SH for OU evaporator
13517 : Real64 T_coil_out; // Air temperature at coil outlet [C]
13518 : Real64 T_coil_surf; // Air temperature at coil surface [C]
13519 : Real64 T_coil_surf_sat; // Saturated air temperature at coil surface [C]
13520 : Real64 W_coil_surf_sat; // Humidity ratio of saturated air at coil surface [kg/kg]
13521 :
13522 2 : SHSC = 0.0;
13523 :
13524 2 : if (OperationMode == HXOpMode::CondMode) {
13525 : // Cooling: OperationMode 0
13526 1 : if (m_air <= 0) {
13527 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit airflow rate ({:.3T} ) for \"{}\":", m_air, this->Name));
13528 0 : ShowContinueError(state, " This cannot be used to calculate outdoor unit subcooling.");
13529 : }
13530 :
13531 1 : BF = this->RateBFOUCond; // 0.219;
13532 1 : T_coil_out = T_coil_in + Q_coil / 1005.0 / m_air;
13533 1 : T_coil_surf = T_coil_in + (T_coil_out - T_coil_in) / (1 - BF);
13534 1 : deltaT = TeTc - T_coil_surf;
13535 :
13536 : // SC_OU
13537 1 : if (this->C3Tc == 0) {
13538 0 : SHSC = -(this->C1Tc - deltaT) / this->C2Tc;
13539 : } else {
13540 1 : SHSC = (-this->C2Tc + std::pow((pow_2(this->C2Tc) - 4 * (this->C1Tc - deltaT) * this->C3Tc), 0.5)) / (2 * this->C3Tc);
13541 : }
13542 :
13543 1 : } else if (OperationMode == HXOpMode::EvapMode) {
13544 : // Heating: OperationMode 1
13545 1 : if (m_air <= 0) {
13546 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit airflow rate ({:.3T} ) for \"{}\":", m_air, this->Name));
13547 0 : ShowContinueError(state, " This cannot be used to calculate outdoor unit super heating.");
13548 : }
13549 :
13550 1 : BF = this->RateBFOUEvap; // 0.45581;
13551 1 : h_coil_in = PsyHFnTdbW(T_coil_in, W_coil_in);
13552 1 : h_coil_out = h_coil_in - Q_coil / m_air / (1 - BF);
13553 1 : h_coil_out = max(0.01, h_coil_out);
13554 :
13555 1 : T_coil_surf_sat = PsyTsatFnHPb(state, h_coil_out, OutdoorPressure, "VRFOU_TeTc");
13556 1 : W_coil_surf_sat = PsyWFnTdbH(state, T_coil_surf_sat, h_coil_out, "VRFOU_TeTc");
13557 :
13558 1 : if (W_coil_surf_sat < W_coil_in) {
13559 : // There is dehumidification
13560 0 : T_coil_surf = T_coil_surf_sat;
13561 : } else {
13562 : // No dehumidification
13563 1 : T_coil_surf = PsyTdbFnHW(h_coil_out, W_coil_in);
13564 : }
13565 :
13566 1 : deltaT = T_coil_surf - TeTc;
13567 :
13568 : // SH_OU
13569 1 : if (this->C3Te == 0) {
13570 0 : SHSC = -(this->C1Te - deltaT) / this->C2Te;
13571 : } else {
13572 1 : SHSC = (-this->C2Te + std::pow((pow_2(this->C2Te) - 4 * (this->C1Te - deltaT) * this->C3Te), 0.5)) / (2 * this->C3Te);
13573 : }
13574 :
13575 : } else {
13576 : // Should not come here
13577 0 : ShowSevereMessage(state, format(" Unreasonable outdoor unit operational mode for \"{}\":", this->Name));
13578 0 : ShowContinueError(state, " The operational mode is not correctly set in the function VRFOU_Cap.");
13579 : }
13580 :
13581 2 : return SHSC;
13582 : }
13583 :
13584 21832 : Real64 VRFCondenserEquipment::VRFOU_CapModFactor(
13585 : EnergyPlusData &state,
13586 : Real64 const h_comp_in_real, // Enthalpy of refrigerant at the compressor inlet at real conditions [kJ/kg]
13587 : Real64 const h_evap_in_real, // Enthalpy of refrigerant at the evaporator inlet at real conditions [kJ/kg]
13588 : Real64 const P_evap_real, // Evaporative pressure at real conditions [Pa]
13589 : Real64 const T_comp_in_real, // Temperature of the refrigerant at the compressor inlet at real conditions [C]
13590 : Real64 const T_comp_in_rate, // Temperature of the refrigerant at the compressor inlet at rated conditions [C]
13591 : Real64 const T_cond_out_rate // Temperature of the refrigerant at the condenser outlet at rated conditions [C]
13592 : )
13593 : {
13594 :
13595 : // SUBROUTINE INFORMATION:
13596 : // AUTHOR Rongpeng Zhang
13597 : // DATE WRITTEN Nov 2015
13598 : // MODIFIED na
13599 : // RE-ENGINEERED na
13600 :
13601 : // PURPOSE OF THIS SUBROUTINE:
13602 : // Calculate capacity modification factor for the compressors at Outdoor Unit.
13603 : // This factor is used to modify the system evaporative capacity, by describing
13604 : // the difference between rated conditions and real conditions.
13605 :
13606 : // METHODOLOGY EMPLOYED:
13607 : // This is part of the VRF-FluidTCtrl Model.
13608 :
13609 : Real64 C_cap_density; // Compressor capacity modification algorithm_modified flow rate [-]
13610 : Real64 C_cap_enthalpy; // Compressor capacity modification algorithm_modified enthalpy difference [-]
13611 : Real64 C_cap_operation; // Compressor capacity modification algorithm_modified Cap [-]
13612 : Real64 RefTSat; // Saturated temperature of the refrigerant. Used to check whether the refrigerant is in the superheat area [C].
13613 : Real64 h_evap_out_rate; // enthalpy of refrigerant at the evaporator outlet at rated conditions [kJ/kg]
13614 : Real64 h_evap_in_rate; // enthalpy of refrigerant at the evaporator inlet at rated conditions [kJ/kg]
13615 : Real64 density_rate; // density of refrigerant at rated conditions [kg/m3]
13616 : Real64 density_real; // density of refrigerant at rated conditions [kg/m3]
13617 :
13618 : static constexpr std::string_view RoutineName("VRFOU_CapModFactor");
13619 :
13620 : // Saturated temperature at real evaporating pressure
13621 21832 : RefTSat = this->refrig->getSatTemperature(state, P_evap_real, RoutineName);
13622 :
13623 : // Enthalpy at rated conditions
13624 21832 : h_evap_out_rate = this->refrig->getSupHeatEnthalpy(state, max(RefTSat, T_comp_in_rate), P_evap_real, RoutineName);
13625 21832 : h_evap_in_rate = this->refrig->getSatEnthalpy(state, T_cond_out_rate, 0.0, RoutineName);
13626 :
13627 : // Density calculations
13628 21832 : density_rate = this->refrig->getSupHeatDensity(state, T_comp_in_rate, P_evap_real, RoutineName);
13629 21832 : density_real = this->refrig->getSupHeatDensity(state, T_comp_in_real, P_evap_real, RoutineName);
13630 :
13631 : // Modification factor calculations
13632 21832 : if (density_real > 0) {
13633 21832 : C_cap_density = density_rate / density_real;
13634 : } else {
13635 0 : C_cap_density = 1.0;
13636 : }
13637 :
13638 21832 : if ((h_comp_in_real - h_evap_in_real) > 0) {
13639 21832 : C_cap_enthalpy = std::abs(h_evap_out_rate - h_evap_in_rate) / std::abs(h_comp_in_real - h_evap_in_real);
13640 : } else {
13641 0 : C_cap_enthalpy = 1.0;
13642 : }
13643 :
13644 21832 : C_cap_operation = C_cap_density * C_cap_enthalpy;
13645 :
13646 21832 : return C_cap_operation;
13647 : }
13648 :
13649 0 : void VRFCondenserEquipment::VRFOU_TeModification(
13650 : EnergyPlusData &state,
13651 : Real64 const Te_up, // Upper bound of Te during iteration, i.e., Te before reduction [C]
13652 : Real64 const Te_low, // Lower bound of Te during iteration, i.e., the given suction temperature Te' [C]
13653 : Real64 const Pipe_h_IU_in, // Piping Loss Algorithm Parameter: enthalpy of IU at inlet [kJ/kg]
13654 : Real64 const OutdoorDryBulb, // outdoor dry-bulb temperature [C]
13655 : Real64 &Te_update, // Updated Te that can generate the required Tsuction [C]
13656 : Real64 &Pe_update, // Piping Loss Algorithm Parameter: evaporating pressure assumed for iterations [Pa]
13657 : Real64 &Pipe_m_ref, // Piping Loss Algorithm Parameter: Refrigerant mass flow rate [kg/s]
13658 : Real64 &Pipe_h_IU_out, // Piping Loss Algorithm Parameter: enthalpy of IU at outlet [kJ/kg]
13659 : Real64 &Pipe_SH_merged // Piping Loss Algorithm Parameter: Average SH after the indoor units [C]
13660 : )
13661 : {
13662 :
13663 : // SUBROUTINE INFORMATION:
13664 : // AUTHOR Rongpeng Zhang
13665 : // DATE WRITTEN Jan 2016
13666 : // MODIFIED na
13667 : // RE-ENGINEERED na
13668 :
13669 : // PURPOSE OF THIS SUBROUTINE:
13670 : // This is part of the low load modification algorithm for the VRF-FluidTCtrl model. It aims
13671 : // to find a new Te (Te_update) that can generate a new compressor suction temperature (Tsuction) equaling
13672 : // to the given compressor suction temperature (Te_low). This requires the re-calculate of piping loss.
13673 :
13674 : // METHODOLOGY EMPLOYED:
13675 : // This is part of the VRF-FluidTCtrl Model.
13676 :
13677 : int CoolCoilIndex; // index to cooling coil in terminal unit
13678 : int NumTUInList; // number of terminal units is list
13679 : int NumTeIte; // counter for Te calculation iterations [-]
13680 : int TUListNum; // index to TU List
13681 : int TUIndex; // Index to terminal unit
13682 : Real64 MaxNumTeIte; // Piping Loss Algorithm Parameter: max number of iterations for Te [-]
13683 : Real64 Pipe_h_comp_in; // Piping Loss Algorithm Parameter: Enthalpy after piping loss (compressor inlet) [kJ/kg]
13684 : Real64 Pipe_DeltP; // Piping Loss Algorithm Parameter: Pipe pressure drop [Pa]
13685 : Real64 Pipe_Q; // Piping Loss Algorithm Parameter: Heat loss [W]
13686 : Real64 Pipe_m_ref_i; // Piping Loss Algorithm Parameter: Refrigerant mass flow rate for a individual IU[kg/s]
13687 : Real64 Pipe_h_IU_out_i; // Piping Loss Algorithm Parameter: enthalpy of IU at outlet (individual) [kJ/kg]
13688 : Real64 RefTSat; // Saturated temperature of the refrigerant [C]
13689 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
13690 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
13691 : Real64 SH_IU_update; // Modified SH for VRF IU [C]
13692 : Real64 Te_ItePreci; // Precision of iterations for Te [C]he superheat area [C]
13693 : Real64 Tfs; // Temperature of the air at the coil surface [C]]
13694 : Real64 Tsuction; // VRF compressor suction refrigerant temperature [Pa]
13695 :
13696 : static constexpr std::string_view RoutineName("VRFOU_TeModification");
13697 :
13698 : // variable initializations
13699 0 : TUListNum = this->ZoneTUListPtr;
13700 0 : RefPLow = this->refrig->PsLowPresValue;
13701 0 : RefPHigh = this->refrig->PsHighPresValue;
13702 0 : NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
13703 :
13704 : // Initialization of Te iterations (Label11)
13705 0 : NumTeIte = 1;
13706 0 : Te_ItePreci = 0.1;
13707 0 : MaxNumTeIte = (Te_up - Te_low) / Te_ItePreci + 1; // upper bound and lower bound of Te iterations
13708 0 : Te_update = Te_up - Te_ItePreci;
13709 :
13710 : bool converged_11;
13711 : // The following is triggered in VariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf
13712 : do {
13713 0 : Pipe_m_ref = 0; // Total Ref Flow Rate( kg/s )
13714 0 : Pipe_h_IU_out = 0;
13715 0 : Pipe_h_IU_out_i = 0;
13716 0 : Pipe_m_ref_i = 0;
13717 0 : Pipe_SH_merged = 0;
13718 0 : Pe_update = this->refrig->getSatPressure(state, Te_update, RoutineName);
13719 :
13720 : // Re-calculate total refrigerant flow rate, with updated SH
13721 0 : for (int NumTU = 1; NumTU <= NumTUInList; NumTU++) {
13722 0 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) > 0) {
13723 0 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
13724 0 : CoolCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
13725 :
13726 : // The IU coil surface temperature should be the same.
13727 0 : Tfs = Te_up + (this->C3Te * pow_2(state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH) +
13728 0 : this->C2Te * state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH + this->C1Te);
13729 :
13730 : // SH_IU_update is the updated SH for a specific IU
13731 0 : if (this->C3Te == 0) {
13732 0 : SH_IU_update = -(this->C1Te - Tfs + Te_update) / this->C2Te;
13733 : } else {
13734 0 : SH_IU_update =
13735 0 : (-this->C2Te + std::pow((pow_2(this->C2Te) - 4 * (this->C1Te - Tfs + Te_update) * this->C3Te), 0.5)) / (2 * this->C3Te);
13736 : }
13737 :
13738 0 : RefTSat = this->refrig->getSatTemperature(state, Pe_update, RoutineName);
13739 0 : Pipe_h_IU_out_i = this->refrig->getSupHeatEnthalpy(state,
13740 0 : max(RefTSat, Te_update + SH_IU_update),
13741 : Pe_update,
13742 : RoutineName); // hB_i for the IU
13743 :
13744 0 : if (Pipe_h_IU_out_i > Pipe_h_IU_in) {
13745 0 : Pipe_m_ref_i =
13746 0 : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) <= 0.0)
13747 0 : ? 0.0
13748 0 : : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) / (Pipe_h_IU_out_i - Pipe_h_IU_in));
13749 0 : Pipe_m_ref = Pipe_m_ref + Pipe_m_ref_i;
13750 0 : Pipe_SH_merged = Pipe_SH_merged + Pipe_m_ref_i * SH_IU_update;
13751 0 : Pipe_h_IU_out = Pipe_h_IU_out + Pipe_m_ref_i * Pipe_h_IU_out_i;
13752 : }
13753 : }
13754 : }
13755 0 : if (Pipe_m_ref > 0) {
13756 0 : Pipe_h_IU_out = Pipe_h_IU_out / Pipe_m_ref;
13757 0 : Pipe_SH_merged = Pipe_SH_merged / Pipe_m_ref;
13758 : } else {
13759 0 : Pipe_SH_merged = this->SH;
13760 0 : RefTSat = this->refrig->getSatTemperature(state, Pe_update, RoutineName);
13761 0 : Pipe_h_IU_out = this->refrig->getSupHeatEnthalpy(state, max(RefTSat, Te_update + Pipe_SH_merged), Pe_update, RoutineName);
13762 : }
13763 :
13764 : // Re-calculate piping loss
13765 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);
13766 :
13767 0 : Tsuction = this->refrig->getSatTemperature(state, max(min(Pe_update - Pipe_DeltP, RefPHigh), RefPLow), RoutineName);
13768 0 : converged_11 = !((std::abs(Tsuction - Te_low) > 0.5) && (Te_update < Te_up) && (Te_update > Te_low) && (NumTeIte < MaxNumTeIte));
13769 0 : Te_update = Te_update - 0.1;
13770 0 : NumTeIte = NumTeIte + 1;
13771 0 : } while (!converged_11);
13772 :
13773 0 : if (std::abs(Tsuction - Te_low) > 0.5) {
13774 0 : NumTeIte = 999;
13775 0 : Tsuction = Te_low;
13776 0 : Pipe_SH_merged = 3.0;
13777 0 : Te_update = Te_low + 1;
13778 : }
13779 0 : }
13780 :
13781 4 : void VRFCondenserEquipment::VRFOU_CompSpd(
13782 : EnergyPlusData &state,
13783 : Real64 const Q_req, // Required capacity [W]
13784 : HXOpMode const Q_type, // Required capacity type: 0 for condenser, 1 for evaporator
13785 : Real64 const T_suction, // Compressor suction temperature Te' [C]
13786 : Real64 const T_discharge, // Compressor discharge temperature Tc' [C]
13787 : Real64 const h_IU_evap_in, // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg]
13788 : Real64 const h_comp_in, // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg]
13789 : Real64 &CompSpdActual // Actual compressor running speed [rps]
13790 : )
13791 : {
13792 :
13793 : // SUBROUTINE INFORMATION:
13794 : // AUTHOR Rongpeng Zhang, LBNL
13795 : // DATE WRITTEN Feb 2016
13796 : // MODIFIED na
13797 : // RE-ENGINEERED na
13798 :
13799 : // PURPOSE OF THIS SUBROUTINE:
13800 : // This subroutine specifies the compressor speed at given operational conditions to meet the evaporator or condenser capacity provided.
13801 :
13802 : // METHODOLOGY EMPLOYED:
13803 : // This is part of the VRF-FluidTCtrl Model.
13804 :
13805 : using Curve::CurveValue;
13806 :
13807 : // Locals
13808 : // SUBROUTINE ARGUMENT DEFINITIONS:
13809 :
13810 : // SUBROUTINE PARAMETER DEFINITIONS:
13811 : int CounterCompSpdTemp; // Index for the compressor speed level[-]
13812 : int CompSpdLB; // index for Compressor speed low bound [-]
13813 : int CompSpdUB; // index for Compressor speed up bound [-]
13814 : int NumOfCompSpdInput; // Number of compressor speed input by the user [-]
13815 : Real64 C_cap_operation; // Compressor capacity modification algorithm_modified Cap [-]
13816 : Real64 P_suction; // Compressor suction pressure Pe' [Pa]
13817 : Real64 Q_evap_req; // Required evaporative capacity [W]
13818 : Real64 Q_cond_req; // Required evaporative capacity [W]
13819 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
13820 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
13821 : Real64 SH_Comp; // Temperature between compressor inlet temperature and evaporative temperature Te' [C]
13822 : Real64 T_comp_in; // Refrigerant temperature at compressor inlet (after piping loss) [C]
13823 4 : Array1D<Real64> CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W]
13824 4 : Array1D<Real64> CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W]
13825 :
13826 : static constexpr std::string_view RoutineName("VRFOU_CompSpd");
13827 :
13828 : // variable initializations: component index
13829 4 : RefPLow = this->refrig->PsLowPresValue;
13830 4 : RefPHigh = this->refrig->PsHighPresValue;
13831 :
13832 : // variable initializations: compressor
13833 4 : NumOfCompSpdInput = this->CompressorSpeed.size();
13834 4 : CompEvaporatingPWRSpd.dimension(NumOfCompSpdInput);
13835 4 : CompEvaporatingCAPSpd.dimension(NumOfCompSpdInput);
13836 :
13837 : // variable initializations: system operational parameters
13838 4 : P_suction = this->refrig->getSatPressure(state, T_suction, RoutineName);
13839 4 : T_comp_in = this->refrig->getSupHeatTemp(state, max(min(P_suction, RefPHigh), RefPLow), h_comp_in, T_suction + 3, T_suction + 30, RoutineName);
13840 4 : SH_Comp = T_comp_in - T_suction;
13841 :
13842 : // Calculate capacity modification factor
13843 4 : C_cap_operation = this->VRFOU_CapModFactor(
13844 : state, h_comp_in, h_IU_evap_in, max(min(P_suction, RefPHigh), RefPLow), T_suction + SH_Comp, T_suction + 8, T_discharge - 5);
13845 :
13846 4 : if (Q_type == HXOpMode::EvapMode) {
13847 : // Capacity to meet is for evaporator
13848 :
13849 2 : Q_evap_req = Q_req;
13850 :
13851 2 : for (CounterCompSpdTemp = 1; CounterCompSpdTemp <= NumOfCompSpdInput; CounterCompSpdTemp++) {
13852 : // Iteration to find the VRF speed that can meet the required load, Iteration DoName1
13853 :
13854 4 : CompEvaporatingPWRSpd(CounterCompSpdTemp) =
13855 2 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
13856 4 : CompEvaporatingCAPSpd(CounterCompSpdTemp) =
13857 2 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction);
13858 :
13859 2 : if (Q_evap_req * C_cap_operation <= CompEvaporatingCAPSpd(CounterCompSpdTemp)) {
13860 : // Compressor speed stage CounterCompSpdTemp need not to be increased, finish Iteration DoName1
13861 :
13862 2 : if (CounterCompSpdTemp > 1) {
13863 :
13864 0 : CompSpdLB = CounterCompSpdTemp - 1;
13865 0 : CompSpdUB = CounterCompSpdTemp;
13866 :
13867 0 : CompSpdActual = this->CompressorSpeed(CompSpdLB) + (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB)) /
13868 0 : (CompEvaporatingCAPSpd(CompSpdUB) - CompEvaporatingCAPSpd(CompSpdLB)) *
13869 0 : (Q_evap_req * C_cap_operation - CompEvaporatingCAPSpd(CompSpdLB));
13870 :
13871 : } else {
13872 2 : CompSpdActual = this->CompressorSpeed(1) * (Q_evap_req * C_cap_operation) / CompEvaporatingCAPSpd(1);
13873 : }
13874 :
13875 2 : break; // EXIT DoName1
13876 : }
13877 : } // End: Iteration DoName1
13878 :
13879 2 : if (CounterCompSpdTemp > NumOfCompSpdInput) {
13880 0 : CompSpdActual = this->CompressorSpeed(NumOfCompSpdInput);
13881 : }
13882 :
13883 : } else {
13884 : // Capacity to meet is for condenser
13885 :
13886 : // derivation process
13887 : // let
13888 : // k be the speed level
13889 : // C be the short form for C_cap_operation
13890 : // PWR(.) be the short form of CompEvaporatingPWRSpd(.)
13891 : // CAP(.) be the short form of CompEvaporatingCAPSpd(.)
13892 : // spd(.) be the short form of this->CompressorSpeed(.)
13893 : // deltaPWR be PWR(k) - PWR(k - 1)
13894 : // deltaCAP be CAP(k) - CAP(k - 1)
13895 : //
13896 : // compressor heat = deltaPWR * r + PWR(k - 1)
13897 : // so
13898 : // Q_cond_req = Q_req = Q_evap_req + deltaPWR * r + PWR(k - 1) <---- eq 1
13899 : //
13900 : // we also know this from the CompSpdActual calculation equation that
13901 : // CompSpdActual = Spd(k - 1) + deltaSpd / deltaCAP * (Q_evap_req * C - CAP(k - 1))
13902 : // so we call the following r
13903 : // r = (Q_evap_req * C - CAP(k - 1)) / deltaCAP
13904 : // so
13905 : // CompSpdActual = Spd(k - 1) + deltaSpd * r
13906 : //
13907 : // arranging terms in eq 1
13908 : // Q_cond_req - deltaPWR * r - PWR(k - 1) = Q_evap_req
13909 : // (Q_cond_req - deltaPWR * r - PWR(k - 1)) * C - CAP(k - 1) = Q_evap_req * C - CAP(k - 1)
13910 : // ((Q_cond_req - deltaPWR * r - PWR(k - 1)) * C - CAP(k - 1)) / deltaCAP = (Q_evap_req * C - CAP(k - 1)) / deltaCAP
13911 : // ((Q_cond_req - deltaPWR * r - PWR(k - 1)) * C - CAP(k - 1)) / deltaCAP = r
13912 : // (Q_cond_req - deltaPWR * r - PWR(k - 1)) * C - CAP(k - 1) = deltaCAP * r
13913 : // (Q_cond_req - PWR(k - 1)) * C - CAP(k - 1) = deltaCAP * r + deltaPWR * r * C
13914 : // so
13915 : // r = ((Q_cond_req - PWR(k - 1)) * C - CAP(k - 1)) / (deltaCAP + deltaPWR * C)
13916 : // = ((Q_cond_req - PWR(k - 1)) - CAP(k - 1)/C) / (deltaCAP/C + deltaPWR)
13917 : //
13918 : // in the special case where k = 1, then k - 1, PWR(k - 1) and CAP(k - 1) will all be 0
13919 : // r = ((Q_cond_req) * C) / (CAP(1) - PWR(1) * C)
13920 : // = (Q_cond_req) / (CAP(1)/C - PWR(1))
13921 :
13922 2 : Q_cond_req = Q_req;
13923 :
13924 2 : CounterCompSpdTemp = 1;
13925 2 : CompEvaporatingPWRSpd(1) = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(1), T_discharge, T_suction);
13926 2 : CompEvaporatingCAPSpd(1) = this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(1), T_discharge, T_suction);
13927 2 : Real64 r = (Q_cond_req * C_cap_operation) / (CompEvaporatingCAPSpd(1) + CompEvaporatingPWRSpd(1) * C_cap_operation);
13928 2 : if (r < 1.0) {
13929 2 : CompSpdActual = this->CompressorSpeed(1) * r;
13930 2 : Q_evap_req = Q_cond_req - CompEvaporatingPWRSpd(1) * r;
13931 : } else {
13932 0 : for (CounterCompSpdTemp = 2; CounterCompSpdTemp <= NumOfCompSpdInput; CounterCompSpdTemp++) {
13933 0 : CompEvaporatingPWRSpd(CounterCompSpdTemp) =
13934 0 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
13935 0 : CompEvaporatingCAPSpd(CounterCompSpdTemp) =
13936 0 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction);
13937 0 : CompSpdLB = CounterCompSpdTemp - 1;
13938 0 : CompSpdUB = CounterCompSpdTemp;
13939 0 : Real64 deltaCAP = CompEvaporatingCAPSpd(CompSpdUB) - CompEvaporatingCAPSpd(CompSpdLB);
13940 0 : Real64 deltaPWR = CompEvaporatingPWRSpd(CompSpdUB) - CompEvaporatingPWRSpd(CompSpdLB);
13941 0 : Real64 r = ((Q_cond_req - CompEvaporatingPWRSpd(CompSpdLB)) * C_cap_operation - CompEvaporatingCAPSpd(CompSpdLB)) /
13942 0 : (deltaCAP + deltaPWR * C_cap_operation);
13943 0 : if (r < 1.0) {
13944 0 : CompSpdActual = this->CompressorSpeed(CompSpdLB) + (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB)) * r;
13945 0 : Q_evap_req = Q_cond_req - deltaPWR * r - CompEvaporatingPWRSpd(CompSpdLB);
13946 0 : break;
13947 : }
13948 : }
13949 : } // End: Iteration DoName1
13950 :
13951 2 : if (CounterCompSpdTemp > NumOfCompSpdInput) {
13952 0 : CompSpdActual = this->CompressorSpeed(NumOfCompSpdInput);
13953 : }
13954 : }
13955 4 : }
13956 :
13957 2 : void VRFCondenserEquipment::VRFOU_CompCap(
13958 : EnergyPlusData &state,
13959 : Real64 const CompSpdActual, // Given compressor speed
13960 : Real64 const T_suction, // Compressor suction temperature Te' [C]
13961 : Real64 const T_discharge, // Compressor discharge temperature Tc' [C]
13962 : Real64 const h_IU_evap_in, // Enthalpy of IU at inlet, for C_cap_operation calculation [kJ/kg]
13963 : Real64 const h_comp_in, // Enthalpy after piping loss (compressor inlet), for C_cap_operation calculation [kJ/kg]
13964 : Real64 &Q_c_tot, // Compressor evaporative capacity [W]
13965 : Real64 &Ncomp // Compressor power [W]
13966 : )
13967 : {
13968 :
13969 : // SUBROUTINE INFORMATION:
13970 : // AUTHOR Rongpeng Zhang, LBNL
13971 : // DATE WRITTEN Feb 2016
13972 : // MODIFIED na
13973 : // RE-ENGINEERED na
13974 :
13975 : // PURPOSE OF THIS SUBROUTINE:
13976 : // This subroutine specifies the compressor performance (power and capacity) at given compressor speed and operational conditions.
13977 :
13978 : // METHODOLOGY EMPLOYED:
13979 : // This is part of the VRF-FluidTCtrl Model.
13980 :
13981 : using Curve::CurveValue;
13982 : int CounterCompSpdTemp; // Index for the compressor speed level[-]
13983 : int CompSpdLB; // index for Compressor speed low bound [-]
13984 : int CompSpdUB; // index for Compressor speed up bound [-]
13985 : int NumOfCompSpdInput; // Number of compressor speed input by the user [-]
13986 : Real64 C_cap_operation; // Compressor capacity modification algorithm_modified Cap [-]
13987 : Real64 P_suction; // Compressor suction pressure Pe' [Pa]
13988 : Real64 Q_evap_sys; // evaporative capacity [W]
13989 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
13990 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
13991 : Real64 SH_Comp; // Temperature between compressor inlet temperature and evaporative temperature Te' [C]
13992 : Real64 T_comp_in; // Refrigerant temperature at compressor inlet (after piping loss) [C]
13993 2 : Array1D<Real64> CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W]
13994 2 : Array1D<Real64> CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W]
13995 :
13996 : static constexpr std::string_view RoutineName("VRFOU_CompCap");
13997 :
13998 : // variable initializations: component index
13999 2 : RefPLow = this->refrig->PsLowPresValue;
14000 2 : RefPHigh = this->refrig->PsHighPresValue;
14001 :
14002 : // variable initializations: compressor
14003 2 : NumOfCompSpdInput = this->CompressorSpeed.size();
14004 2 : CompEvaporatingPWRSpd.dimension(NumOfCompSpdInput);
14005 2 : CompEvaporatingCAPSpd.dimension(NumOfCompSpdInput);
14006 :
14007 2 : for (CounterCompSpdTemp = 1; CounterCompSpdTemp <= NumOfCompSpdInput; CounterCompSpdTemp++) {
14008 :
14009 4 : CompEvaporatingPWRSpd(CounterCompSpdTemp) =
14010 2 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
14011 4 : CompEvaporatingCAPSpd(CounterCompSpdTemp) =
14012 2 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction);
14013 :
14014 2 : if (CompSpdActual <= this->CompressorSpeed(CounterCompSpdTemp)) {
14015 : // Compressor speed stage CounterCompSpdTemp need not to be increased, finish Iteration DoName1
14016 :
14017 2 : if (CounterCompSpdTemp > 1) {
14018 :
14019 0 : CompSpdLB = CounterCompSpdTemp - 1;
14020 0 : CompSpdUB = CounterCompSpdTemp;
14021 :
14022 0 : Q_evap_sys = CompEvaporatingCAPSpd(CompSpdLB) + (CompEvaporatingCAPSpd(CompSpdUB) - CompEvaporatingCAPSpd(CompSpdLB)) *
14023 0 : (CompSpdActual - this->CompressorSpeed(CompSpdLB)) /
14024 0 : (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB));
14025 0 : Ncomp = CompEvaporatingPWRSpd(CompSpdLB) + (CompEvaporatingPWRSpd(CompSpdUB) - CompEvaporatingPWRSpd(CompSpdLB)) *
14026 0 : (CompSpdActual - this->CompressorSpeed(CompSpdLB)) /
14027 0 : (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB));
14028 :
14029 : } else {
14030 2 : Q_evap_sys = CompEvaporatingCAPSpd(1) * CompSpdActual / this->CompressorSpeed(1);
14031 2 : Ncomp = CompEvaporatingPWRSpd(1) * CompSpdActual / this->CompressorSpeed(1);
14032 : }
14033 :
14034 2 : break;
14035 : }
14036 : }
14037 :
14038 2 : if (CounterCompSpdTemp > NumOfCompSpdInput) {
14039 0 : Q_evap_sys = CompEvaporatingCAPSpd(NumOfCompSpdInput);
14040 0 : Ncomp = CompEvaporatingPWRSpd(NumOfCompSpdInput);
14041 : }
14042 :
14043 : // variable initializations: system operational parameters
14044 2 : P_suction = this->refrig->getSatPressure(state, T_suction, RoutineName);
14045 2 : T_comp_in = this->refrig->getSupHeatTemp(state, max(min(P_suction, RefPHigh), RefPLow), h_comp_in, T_suction + 3, T_suction + 30, RoutineName);
14046 2 : SH_Comp = T_comp_in - T_suction;
14047 :
14048 : // Calculate capacity modification factor
14049 2 : C_cap_operation = this->VRFOU_CapModFactor(
14050 : state, h_comp_in, h_IU_evap_in, max(min(P_suction, RefPHigh), RefPLow), T_suction + SH_Comp, T_suction + 8, T_discharge - 5);
14051 2 : C_cap_operation = min(1.5, max(0.5, C_cap_operation));
14052 2 : Q_c_tot = Q_evap_sys / C_cap_operation;
14053 2 : }
14054 :
14055 2835 : void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state,
14056 : Real64 TU_load, // Indoor unit cooling load [W]
14057 : Real64 T_suction, // Compressor suction temperature Te' [C]
14058 : Real64 T_discharge, // Compressor discharge temperature Tc' [C]
14059 : Real64 P_suction, // Compressor suction pressure Pe' [Pa]
14060 : Real64 Pipe_T_comp_in, // Refrigerant temperature at compressor inlet (after piping loss) [C]
14061 : Real64 Pipe_h_comp_in, // Enthalpy after piping loss (compressor inlet) [kJ/kg]
14062 : Real64 Pipe_h_IU_in, // Enthalpy of IU at inlet [kJ/kg]
14063 : Real64 Pipe_Q, // Piping Loss Algorithm Parameter: Heat loss [W]
14064 : Real64 MaxOutdoorUnitTc, // The maximum temperature that Tc can be at heating mode [C]
14065 : Real64 &OUCondHeatRelease, // Condenser heat release (cooling mode) [W]
14066 : Real64 &CompSpdActual, // Actual compressor running speed [rps]
14067 : Real64 &Ncomp, // Compressor power [W]
14068 : Real64 &CyclingRatio // Cycling Ratio [W]
14069 : )
14070 : {
14071 :
14072 : // SUBROUTINE INFORMATION:
14073 : // AUTHOR Xiufeng Pang
14074 : // DATE WRITTEN Feb 2014
14075 : // MODIFIED Rongpeng Zhang, Jan 2016
14076 : // MODIFIED Yujie Xu, Sep 2023
14077 : // RE-ENGINEERED na
14078 :
14079 : // PURPOSE OF THIS SUBROUTINE:
14080 : // This subroutine simulates the compressor performance at given operational conditions (cooling mode). More specifically, it specifies
14081 : // the compressor speed to provide sufficient evaporative capacity, and calculate the power of the compressor running at the specified
14082 : // speed. Note that it may be needed to manipulate the operational conditions to further adjust system capacity at low load conditions.
14083 : // The low load modification logics are different for cooling mode and heating mode.
14084 :
14085 : // METHODOLOGY EMPLOYED:
14086 : // This is part of the VRF-FluidTCtrl Model.
14087 :
14088 : using Curve::CurveValue;
14089 :
14090 : using General::SolveRoot;
14091 :
14092 : int CounterCompSpdTemp; // Index for the compressor speed level[-]
14093 : int CompSpdLB; // index for Compressor speed low bound [-]
14094 : int CompSpdUB; // index for Compressor speed up bound [-]
14095 : int CoolCoilIndex; // index to cooling coil in terminal unit
14096 2835 : int MaxIter(500); // max iteration number allowed [-]
14097 : int NumOfCompSpdInput; // Number of compressor speed input by the user [-]
14098 : int NumIteCcap; // counter for Ccap calculation iterations [-]
14099 : int NumIteTe; // counter for Te calculation iterations [-]
14100 : int NumTUInList; // number of terminal units is list
14101 : int SolFla; // Slove flag for SolveRoot [-]
14102 : int TUListNum; // index to TU List
14103 : int TUIndex; // Index to terminal unit
14104 : Real64 Cap_Eva0; // Evaporating capacity calculated based on physics model, used in the iterations [W]
14105 : Real64 Cap_Eva1; // Evaporating capacity calculated by curves, used in the iterations [W]
14106 : Real64 CapDiff; // Evaporating capacity difference used in the iterations [W]
14107 : Real64 C_cap_operation; // Compressor capacity modification algorithm_modified Cap [-]
14108 : Real64 C_cap_operation0; // Compressor capacity modification algorithm_modified Cap, for temporary use [-]
14109 : Real64 SmallLoadTe; // Updated suction temperature at small load conditions (Te') [C]
14110 : Real64 Modifi_SH; // Temperature between compressor inlet temperature and evaporative temperature Te' [C]
14111 : Real64 MaxNumIteTe; // Piping Loss Algorithm Parameter: max number of iterations for Te [-]
14112 : Real64 MinOutdoorUnitTe; // The minimum temperature that Te can be at cooling mode (only used for calculating Min capacity)
14113 : Real64 MinOutdoorUnitPe; // The minimum pressure that Pe can be at cooling mode (only used for calculating Min capacity)
14114 : Real64 MinRefriPe; // Minimum refrigerant evaporating pressure [Pa]
14115 : Real64 Modifi_SHin; // Compressor power modification algorithm_modified SH for IDU [C]
14116 : Real64 P_discharge; // VRF compressor discharge pressure [Pa]
14117 : Real64 Pipe_m_ref; // Piping Loss Algorithm Parameter: Refrigerant mass flow rate [kg/s]
14118 : Real64 Pipe_DeltP; // Piping Loss Algorithm Parameter: Pipe pressure drop [Pa]
14119 : Real64 Pipe_Q0; // Compressor capacity modification algorithm_modified Pipe_Q, for temporary use [W]
14120 : Real64 Pipe_m_ref_i; // Piping Loss Algorithm Parameter: Refrigerant mass flow rate for a individual IU[kg/s]
14121 : Real64 Pipe_h_IU_out; // Piping Loss Algorithm Parameter: enthalpy of IU at outlet [kJ/kg]
14122 : Real64 Pipe_h_IU_out_i; // Piping Loss Algorithm Parameter: enthalpy of IU at outlet (individual) [kJ/kg]
14123 : Real64 Pipe_Pe_assumed; // Piping Loss Algorithm Parameter: evaporating pressure assumed for iterations[Pa]
14124 : Real64 Pipe_SH_merged; // Piping Loss Algorithm Parameter: average super heating degrees after the indoor units [C]
14125 : Real64 Pipe_Te_assumed; // Piping Loss Algorithm Parameter: evaporating temperature assumed for iterations[C]
14126 : Real64 Q_evap_req; // Required evaporative capacity [W]
14127 : Real64 RefTSat; // Saturated temperature of the refrigerant [C]
14128 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
14129 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
14130 : Real64 T_discharge_new; // Condensing temperature, for temporary use in iterations [C]
14131 : Real64 Tfs; // Temperature of the air at the coil surface [C]]
14132 2835 : Real64 constexpr Tolerance(0.05); // Tolerance for condensing temperature calculation [C]
14133 2835 : Real64 constexpr TeTol(0.5); // Tolerance for the difference between Te and SmallLoadTe
14134 2835 : Array1D<Real64> CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W]
14135 2835 : Array1D<Real64> CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W]
14136 :
14137 : static constexpr std::string_view RoutineName("VRFOU_CalcCompC");
14138 :
14139 : // variable initializations
14140 2835 : NumOfCompSpdInput = this->CompressorSpeed.size();
14141 2835 : CompEvaporatingPWRSpd.dimension(NumOfCompSpdInput);
14142 2835 : CompEvaporatingCAPSpd.dimension(NumOfCompSpdInput);
14143 2835 : Q_evap_req = TU_load + Pipe_Q;
14144 :
14145 2835 : TUListNum = this->ZoneTUListPtr;
14146 2835 : RefPLow = this->refrig->PsLowPresValue;
14147 2835 : RefPHigh = this->refrig->PsHighPresValue;
14148 2835 : NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
14149 :
14150 2835 : Modifi_SH = Pipe_T_comp_in - T_suction;
14151 :
14152 : // set condenser entering air conditions (Outdoor air conditions)
14153 2835 : Real64 OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
14154 2835 : Real64 OutdoorHumRat = state.dataEnvrn->OutHumRat;
14155 2835 : Real64 OutdoorPressure = state.dataEnvrn->OutBaroPress;
14156 2835 : Real64 RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
14157 :
14158 : // Calculate capacity modification factor
14159 2835 : C_cap_operation = this->VRFOU_CapModFactor(
14160 : 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);
14161 :
14162 2835 : this->adjustedTe = false;
14163 6941 : for (CounterCompSpdTemp = 1; CounterCompSpdTemp <= NumOfCompSpdInput; CounterCompSpdTemp++) {
14164 : // Iteration to find the VRF speed that can meet the required load, Iteration DoName1
14165 :
14166 13882 : CompEvaporatingPWRSpd(CounterCompSpdTemp) =
14167 6941 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
14168 13882 : CompEvaporatingCAPSpd(CounterCompSpdTemp) =
14169 6941 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction);
14170 :
14171 6941 : if (Q_evap_req * C_cap_operation <= CompEvaporatingCAPSpd(CounterCompSpdTemp)) {
14172 : // Compressor speed stage CounterCompSpdTemp need not to be increased, finish Iteration DoName1
14173 :
14174 2835 : if (CounterCompSpdTemp > 1) { // Since: if( CounterCompSpdTemp <= 1 )
14175 : // Compressor speed > min
14176 :
14177 2582 : CompSpdLB = CounterCompSpdTemp - 1;
14178 2582 : CompSpdUB = CounterCompSpdTemp;
14179 :
14180 2582 : CompSpdActual = this->CompressorSpeed(CompSpdLB) + (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB)) /
14181 2582 : (CompEvaporatingCAPSpd(CompSpdUB) - CompEvaporatingCAPSpd(CompSpdLB)) *
14182 2582 : (Q_evap_req * C_cap_operation - CompEvaporatingCAPSpd(CompSpdLB));
14183 :
14184 2582 : Ncomp = CompEvaporatingPWRSpd(CompSpdLB) + (CompEvaporatingPWRSpd(CompSpdUB) - CompEvaporatingPWRSpd(CompSpdLB)) /
14185 2582 : (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB)) *
14186 2582 : (CompSpdActual - this->CompressorSpeed(CompSpdLB));
14187 2582 : break; // EXIT DoName1
14188 :
14189 : } else {
14190 : // Compressor runs at the min speed
14191 : // Low Load Modification Algorithm for cooling (IU side modification)
14192 :
14193 : // Initialization of NumIteCcap iterations (Label13)
14194 253 : Pipe_Q0 = Pipe_Q;
14195 253 : C_cap_operation0 = C_cap_operation;
14196 253 : T_discharge_new = T_discharge;
14197 253 : NumIteCcap = 1;
14198 :
14199 : // Update the C_cap_operation
14200 : bool converged_13;
14201 : do {
14202 7271 : Q_evap_req = TU_load + Pipe_Q0; // Pipe_Q0 is updated during the iteration
14203 7271 : Pipe_h_IU_in = this->refrig->getSatEnthalpy(state, T_discharge_new - this->SC, 0.0, RoutineName);
14204 7271 : CompSpdActual = this->CompressorSpeed(1);
14205 7271 : Real64 CondHeat = Q_evap_req * C_cap_operation0 / this->RatedEvapCapacity; // 150130 To be confirmed
14206 7271 : int CAPFT = this->OUCoolingCAPFT(CounterCompSpdTemp);
14207 :
14208 7271 : P_discharge = this->refrig->getSatPressure(state, T_discharge, RoutineName);
14209 7271 : MinRefriPe = this->refrig->getSatPressure(state, -15, RoutineName);
14210 7271 : MinOutdoorUnitPe = max(P_discharge - this->CompMaxDeltaP, MinRefriPe);
14211 7271 : MinOutdoorUnitTe = this->refrig->getSatTemperature(state, max(min(MinOutdoorUnitPe, RefPHigh), RefPLow), RoutineName);
14212 : // Te can't be smaller than user input lower bound
14213 7271 : MinOutdoorUnitTe = max(this->IUEvapTempLow, MinOutdoorUnitTe);
14214 :
14215 22011 : auto f = [&state, T_discharge_new, CondHeat, CAPFT](Real64 const T_suc) {
14216 22011 : return CompResidual_FluidTCtrl(state, T_discharge_new, CondHeat, CAPFT, T_suc);
14217 7271 : };
14218 :
14219 7271 : General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, SmallLoadTe, f, MinOutdoorUnitTe,
14220 : T_suction); // SmallLoadTe is the updated Te'
14221 7271 : if (SolFla == -1) {
14222 : // show error not converging
14223 0 : ShowWarningMessage(state, format("{}: low load Te adjustment failed for {}", RoutineName, this->Name));
14224 0 : ShowContinueErrorTimeStamp(state, "");
14225 0 : ShowContinueError(state, format(" Iteration limit [{}] exceeded in calculating OU evaporating temperature", MaxIter));
14226 7271 : } else if (SolFla == -2) {
14227 7269 : this->LowLoadTeError++;
14228 7269 : if (LowLoadTeError < 5) {
14229 24 : ShowWarningMessage(state,
14230 24 : format("{}: no Te solution was found for {} f({})={} and f({})={} are the same sign",
14231 : RoutineName,
14232 12 : this->Name,
14233 : MinOutdoorUnitTe,
14234 12 : f(MinOutdoorUnitTe),
14235 : T_suction,
14236 12 : f(T_suction)));
14237 36 : ShowContinueErrorTimeStamp(state, "");
14238 : }
14239 50883 : ShowRecurringWarningErrorAtEnd(state,
14240 : "Low load calculation Te solution not found as end points have the same sign",
14241 7269 : this->LowLoadTeErrorIndex,
14242 : SolFla,
14243 : SolFla);
14244 7269 : if (f(T_suction) < 0) {
14245 : // demand < capacity at both endpoints of the Te range, assuming f(x) is roughly monotonic than this is the low load case
14246 : // TeTol is added to prevent the final updated Te to go out of bounds
14247 7182 : SmallLoadTe = MinOutdoorUnitTe + TeTol; // MinOutdoorUnitTe; //SmallLoadTe( Te'_new ) is constant during iterations
14248 : } else {
14249 : // demand > capacity at both endpoints of the Te range, take the end point x where f(x) is closer to zero
14250 87 : if (f(MinOutdoorUnitTe) > f(T_suction)) { // f(T_suction > 0, not equal as SolFla will not be -2
14251 87 : SmallLoadTe = T_suction;
14252 : } else {
14253 0 : SmallLoadTe = MinOutdoorUnitTe;
14254 : }
14255 : }
14256 : }
14257 :
14258 : // Get an updated Te corresponding to the updated Te'
14259 : // VRFOU_TeModification( VRFCond, this->EvaporatingTemp, SmallLoadTe, Pipe_h_IU_in, OutdoorDryBulb, Pipe_Te_assumed,
14260 : // Pipe_Pe_assumed, Pipe_m_ref, Pipe_SH_merged );
14261 : {
14262 : // Initialization of Iteration_Te (Label11)
14263 : // i.e., find a new Te (Pipe_Te_assumed) that can generate a new T_suction equaling to SmallLoadTe.
14264 : // This requires the re-calculate of piping loss.
14265 7271 : NumIteTe = 1;
14266 7271 : MaxNumIteTe = (this->EvaporatingTemp - SmallLoadTe) / 0.1 + 1; // upper bound and lower bound of Te iterations
14267 7271 : Pipe_Te_assumed = this->EvaporatingTemp - 0.1;
14268 7271 : this->adjustedTe = true;
14269 :
14270 : bool converged_11_2;
14271 : do {
14272 7481 : Pipe_m_ref = 0; // Total Ref Flow Rate( kg/s )
14273 :
14274 : // Re-calculate Piping loss due to the Te and SH updates
14275 7481 : Pipe_h_IU_out = 0;
14276 7481 : Pipe_h_IU_out_i = 0;
14277 7481 : Pipe_m_ref_i = 0;
14278 7481 : Pipe_SH_merged = 0;
14279 7481 : Pipe_Pe_assumed = this->refrig->getSatPressure(state, Pipe_Te_assumed, RoutineName);
14280 :
14281 : // Re-calculate total refrigerant flow rate, with updated SH
14282 14962 : for (int NumTU = 1; NumTU <= NumTUInList; NumTU++) {
14283 7481 : if (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) > 0) {
14284 7451 : TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
14285 7451 : CoolCoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
14286 :
14287 7451 : Tfs = this->EvaporatingTemp + (this->C3Te * pow_2(state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH) +
14288 7451 : this->C2Te * state.dataDXCoils->DXCoil(CoolCoilIndex).ActualSH + this->C1Te);
14289 :
14290 : // Modifi_SH is the updated SH for a specific IU
14291 7451 : if (this->C3Te == 0) {
14292 0 : Modifi_SHin = -(this->C1Te - Tfs + Pipe_Te_assumed) / this->C2Te; // 150130 Modifi_SH>Modifi_SHin
14293 : } else {
14294 7451 : Modifi_SHin = (-this->C2Te +
14295 7451 : std::pow((pow_2(this->C2Te) - 4 * (this->C1Te - Tfs + Pipe_Te_assumed) * this->C3Te), 0.5)) /
14296 7451 : (2 * this->C3Te);
14297 : }
14298 :
14299 7451 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pipe_Pe_assumed, RefPHigh), RefPLow), RoutineName);
14300 7451 : Pipe_h_IU_out_i = this->refrig->getSupHeatEnthalpy(state,
14301 : max(RefTSat, Pipe_Te_assumed + Modifi_SHin),
14302 : max(min(Pipe_Pe_assumed, RefPHigh), RefPLow),
14303 : RoutineName);
14304 :
14305 7451 : if (Pipe_h_IU_out_i > Pipe_h_IU_in) {
14306 7451 : Real64 min_speed_capacity = this->CoffEvapCap * this->RatedEvapCapacity *
14307 7451 : CurveValue(state, this->OUCoolingCAPFT(1), T_discharge, T_suction);
14308 7451 : Pipe_m_ref_i = (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU) <= 0.0)
14309 7451 : ? 0.0
14310 : // refrigerant flow rate do not get smaller when the compressor needs to cycle.
14311 7451 : : max(min_speed_capacity,
14312 7451 : (state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).TotalCoolLoad(NumTU)) /
14313 7451 : (Pipe_h_IU_out_i - Pipe_h_IU_in));
14314 7451 : Pipe_m_ref = Pipe_m_ref + Pipe_m_ref_i;
14315 7451 : Pipe_SH_merged = Pipe_SH_merged + Pipe_m_ref_i * Modifi_SHin;
14316 7451 : Pipe_h_IU_out = Pipe_h_IU_out + Pipe_m_ref_i * Pipe_h_IU_out_i;
14317 : }
14318 : }
14319 : }
14320 7481 : if (Pipe_m_ref > 0) {
14321 7451 : Pipe_h_IU_out = Pipe_h_IU_out / Pipe_m_ref;
14322 7451 : Pipe_SH_merged = Pipe_SH_merged / Pipe_m_ref;
14323 : } else {
14324 30 : Pipe_SH_merged = this->SH;
14325 30 : RefTSat = this->refrig->getSatTemperature(state, max(min(Pipe_Pe_assumed, RefPHigh), RefPLow), RoutineName);
14326 30 : Pipe_h_IU_out = this->refrig->getSupHeatEnthalpy(
14327 : state, max(RefTSat, Pipe_Te_assumed + Pipe_SH_merged), max(min(Pipe_Pe_assumed, RefPHigh), RefPLow), RoutineName);
14328 : }
14329 :
14330 : // Re-calculate piping loss
14331 7481 : this->VRFOU_PipeLossC(state,
14332 : Pipe_m_ref,
14333 : max(min(Pipe_Pe_assumed, RefPHigh), RefPLow),
14334 : Pipe_h_IU_out,
14335 : Pipe_SH_merged,
14336 : OutdoorDryBulb,
14337 : Pipe_Q,
14338 : Pipe_DeltP,
14339 : Pipe_h_comp_in);
14340 :
14341 7481 : T_suction =
14342 7481 : this->refrig->getSatTemperature(state, max(min(Pipe_Pe_assumed - Pipe_DeltP, RefPHigh), RefPLow), RoutineName);
14343 :
14344 14962 : converged_11_2 = !((std::abs(T_suction - SmallLoadTe) > TeTol) && (Pipe_Te_assumed < this->EvaporatingTemp) &&
14345 7481 : (Pipe_Te_assumed > SmallLoadTe) && (NumIteTe < MaxNumIteTe));
14346 7481 : Pipe_Te_assumed = Pipe_Te_assumed - 0.1;
14347 7481 : NumIteTe = NumIteTe + 1;
14348 7481 : } while (!converged_11_2);
14349 :
14350 7271 : if (std::abs(T_suction - SmallLoadTe) > TeTol) {
14351 7271 : NumIteTe = 999;
14352 7271 : T_suction = SmallLoadTe;
14353 7271 : Pipe_SH_merged = 3.0;
14354 7271 : Pipe_Te_assumed = SmallLoadTe + 1;
14355 : }
14356 : // Iteration_Te End
14357 : }
14358 :
14359 : // Perform iteration to calculate Pipe_T_comp_in( Te'+SH' )
14360 7271 : Pipe_T_comp_in = this->refrig->getSupHeatTemp(
14361 : state, max(min(Pipe_Pe_assumed - Pipe_DeltP, RefPHigh), RefPLow), Pipe_h_comp_in, T_suction + 3, T_suction + 30, RoutineName);
14362 :
14363 7271 : Modifi_SH = Pipe_T_comp_in - T_suction;
14364 7271 : P_suction = Pipe_Pe_assumed - Pipe_DeltP;
14365 7271 : OUCondHeatRelease = TU_load + Pipe_Q + Ncomp; // Pipe_Q is changed when T_suction is changed -> Tc is also changed
14366 :
14367 : // *VRF OU Tc calculations
14368 7271 : this->VRFOU_TeTc(state,
14369 : HXOpMode::CondMode,
14370 : OUCondHeatRelease,
14371 : this->SC,
14372 7271 : this->OUAirFlowRate * RhoAir,
14373 : OutdoorDryBulb,
14374 : OutdoorHumRat,
14375 : OutdoorPressure,
14376 : Tfs,
14377 : T_discharge);
14378 7271 : T_discharge = min(MaxOutdoorUnitTc, T_discharge);
14379 :
14380 : // *Calculate capacity modification factor
14381 7271 : C_cap_operation = this->VRFOU_CapModFactor(state,
14382 : Pipe_h_comp_in,
14383 : Pipe_h_IU_in,
14384 : max(min(P_suction, RefPHigh), RefPLow),
14385 : T_suction + Modifi_SH,
14386 : T_suction + 8,
14387 : T_discharge - 5);
14388 :
14389 7271 : Cap_Eva0 = (TU_load + Pipe_Q) * C_cap_operation; // New Pipe_Q & C_cap_operation
14390 14542 : Cap_Eva1 = this->CoffEvapCap * this->RatedEvapCapacity *
14391 7271 : CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction); // New Tc
14392 7271 : CapDiff = std::abs(Cap_Eva1 - Cap_Eva0);
14393 7271 : converged_13 = !((CapDiff > (Tolerance * Cap_Eva0)) && (NumIteCcap < 30));
14394 7271 : NumIteCcap = NumIteCcap + 1;
14395 7271 : Pipe_Q0 = Pipe_Q;
14396 7271 : C_cap_operation0 = C_cap_operation;
14397 7271 : T_discharge_new = T_discharge;
14398 7271 : } while (!converged_13);
14399 :
14400 : // when it gets here, either NumIteCcap = 30 or CapDiff > (Tolerance * Cap_Eva0)
14401 253 : if (CapDiff > (Tolerance * Cap_Eva0) && (Cap_Eva1 - Cap_Eva0) >= 0.0) {
14402 239 : NumIteCcap = 999;
14403 239 : CyclingRatio = Cap_Eva0 / Cap_Eva1;
14404 : } else {
14405 14 : CyclingRatio = 1.0;
14406 : }
14407 :
14408 253 : Ncomp = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
14409 253 : OUCondHeatRelease = Ncomp + Cap_Eva1;
14410 :
14411 253 : this->CondensingTemp = T_discharge; // OU Tc' is updated due to OUCondHeatRelease updates, which is caused by IU Te' updates
14412 : // during low load conditions
14413 253 : this->EvaporatingTemp = T_suction;
14414 253 : this->IUEvaporatingTemp = T_suction;
14415 :
14416 253 : break; // EXIT DoName1
14417 :
14418 : } // End: if( CounterCompSpdTemp <= 1 ) Low load modification
14419 :
14420 : } // End: if( Q_evap_req <= CompEvaporatingCAPSpd( CounterCompSpdTemp ) )
14421 :
14422 : } // End: Iteration DoName1
14423 :
14424 2835 : if (CounterCompSpdTemp > NumOfCompSpdInput) {
14425 : // Required load is beyond the maximum system capacity
14426 0 : CompEvaporatingCAPSpd(NumOfCompSpdInput) =
14427 0 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), T_discharge, T_suction);
14428 0 : OUCondHeatRelease = Ncomp + CompEvaporatingCAPSpd(NumOfCompSpdInput);
14429 0 : CompSpdActual = this->CompressorSpeed(NumOfCompSpdInput);
14430 0 : Ncomp = CompEvaporatingPWRSpd(NumOfCompSpdInput);
14431 : }
14432 2835 : }
14433 :
14434 5271 : void VRFCondenserEquipment::VRFOU_CalcCompH(
14435 : EnergyPlusData &state,
14436 : Real64 TU_load, // Indoor unit heating load [W]
14437 : Real64 T_suction, // Compressor suction temperature Te' [C]
14438 : Real64 T_discharge, // Compressor discharge temperature Tc' [C]
14439 : Real64 Pipe_h_out_ave, // Average Enthalpy of the refrigerant leaving IUs [kJ/kg]
14440 : Real64 IUMaxCondTemp, // VRV IU condensing temperature, max among all indoor units [C]
14441 : Real64 MinOutdoorUnitTe, // The minimum temperature that OU Te can be at cooling mode (only used for calculating Min capacity)
14442 : Real64 Tfs, // Temperature of the air at the OU evaporator coil surface [C]]
14443 : Real64 Pipe_Q, // Piping Loss Algorithm Parameter: Heat loss [W]
14444 : Real64 &OUEvapHeatExtract, // Condenser heat release (cooling mode) [W]
14445 : Real64 &CompSpdActual, // Actual compressor running speed [rps]
14446 : Real64 &Ncomp, // Compressor power [W]
14447 : Real64 &CyclingRatio // Compressor cycling ratio
14448 : )
14449 : {
14450 :
14451 : // SUBROUTINE INFORMATION:
14452 : // AUTHOR Xiufeng Pang
14453 : // DATE WRITTEN Feb 2014
14454 : // MODIFIED Rongpeng Zhang, Jan 2016
14455 : // RE-ENGINEERED na
14456 :
14457 : // PURPOSE OF THIS SUBROUTINE:
14458 : // This subroutine simulates the compressor performance at given proportional conditions (heating mode). More specifically, it specifies
14459 : // the compressor speed to provide sufficient evaporative capacity, and calculate the power of the compressor running at the specified
14460 : // speed. Note that it may be needed to manipulate the operational conditions to further adjust system capacity at low load conditions.
14461 : // The low load modification logics are different for cooling mode and heating mode.
14462 :
14463 : // METHODOLOGY EMPLOYED:
14464 : // This is part of the VRF-FluidTCtrl Model.
14465 :
14466 : using Curve::CurveValue;
14467 : using General::SolveRoot;
14468 :
14469 : int CounterCompSpdTemp; // Index for the compressor speed level[-]
14470 : int CompSpdLB; // index for Compressor speed low bound [-]
14471 : int CompSpdUB; // index for Compressor speed up bound [-]
14472 5271 : int MaxIter(500); // max iteration number allowed [-]
14473 : int NumOfCompSpdInput; // Number of compressor speed input by the user [-]
14474 : int NumIteCcap; // counter for Ccap calculation iterations [-]
14475 : int NumTUInList; // number of terminal units is list
14476 : int SolFla; // Solve flag for SolveRoot [-]
14477 : int TUListNum; // index to TU List
14478 : Real64 Cap_Eva0; // Evaporating capacity calculated based on physics model, used in the iterations [W]
14479 : Real64 Cap_Eva1; // Evaporating capacity calculated by curves, used in the iterations [W]
14480 : Real64 CapDiff; // Evaporating capacity difference used in the iterations [W]
14481 : Real64 C_cap_operation; // Compressor capacity modification algorithm_modified Cap [-]
14482 : Real64 SmallLoadTe; // Updated suction temperature at small load conditions (Te') [C]
14483 : Real64 Modifi_SH; // Temperature between compressor inlet temperature and evaporative temperature Te' [C]
14484 : Real64 MinOutdoorUnitPe; // The minimum pressure that Pe can be at cooling mode (only used for calculating Min capacity)
14485 : Real64 Modifi_Pe; // Compressor power modification algorithm_modified Pe [Pa]
14486 : Real64 Pipe_h_comp_in; // Piping Loss Algorithm Parameter: Enthalpy after piping loss (compressor inlet) [kJ/kg]
14487 : Real64 Q_evap_req; // Required evaporative capacity [W]
14488 : Real64 RefTSat; // Saturated temperature of the refrigerant [C]
14489 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
14490 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
14491 5271 : Real64 constexpr Tolerance(0.05); // Tolerance for condensing temperature calculation [C}
14492 5271 : Array1D<Real64> CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W]
14493 5271 : Array1D<Real64> CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W]
14494 :
14495 : static constexpr std::string_view RoutineName("VRFOU_CalcCompH");
14496 :
14497 : // variable initializations
14498 5271 : NumOfCompSpdInput = this->CompressorSpeed.size();
14499 5271 : CompEvaporatingPWRSpd.dimension(NumOfCompSpdInput);
14500 5271 : CompEvaporatingCAPSpd.dimension(NumOfCompSpdInput);
14501 5271 : Q_evap_req = TU_load + Pipe_Q - Ncomp;
14502 :
14503 5271 : TUListNum = this->ZoneTUListPtr;
14504 5271 : RefPLow = this->refrig->PsLowPresValue;
14505 5271 : RefPHigh = this->refrig->PsHighPresValue;
14506 5271 : NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
14507 :
14508 : // Calculate capacity modification factor
14509 5271 : MinOutdoorUnitPe = this->refrig->getSatPressure(state, T_suction, RoutineName);
14510 5271 : RefTSat = this->refrig->getSatTemperature(state, max(min(MinOutdoorUnitPe, RefPHigh), RefPLow), RoutineName);
14511 : Pipe_h_comp_in =
14512 5271 : this->refrig->getSupHeatEnthalpy(state, max(RefTSat, T_suction + this->SH), max(min(MinOutdoorUnitPe, RefPHigh), RefPLow), RoutineName);
14513 5271 : C_cap_operation = this->VRFOU_CapModFactor(
14514 5271 : state, Pipe_h_comp_in, Pipe_h_out_ave, max(min(MinOutdoorUnitPe, RefPHigh), RefPLow), T_suction + this->SH, T_suction + 8, IUMaxCondTemp - 5);
14515 :
14516 : // Perform iterations to find the compressor speed that can meet the required heating load, Iteration DoName2
14517 10413 : for (CounterCompSpdTemp = 1; CounterCompSpdTemp <= NumOfCompSpdInput; CounterCompSpdTemp++) {
14518 :
14519 20826 : CompEvaporatingPWRSpd(CounterCompSpdTemp) =
14520 10413 : this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction);
14521 20826 : CompEvaporatingCAPSpd(CounterCompSpdTemp) =
14522 10413 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction);
14523 :
14524 10413 : if ((Q_evap_req * C_cap_operation) <= CompEvaporatingCAPSpd(CounterCompSpdTemp)) {
14525 : // Compressor Capacity is greater than the required, finish Iteration DoName2
14526 :
14527 5271 : if (CounterCompSpdTemp > 1) {
14528 : // Compressor runs at higher speed than min speed
14529 5142 : CompSpdLB = CounterCompSpdTemp - 1;
14530 5142 : CompSpdUB = CounterCompSpdTemp;
14531 :
14532 5142 : CompSpdActual = this->CompressorSpeed(CompSpdLB) + (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB)) /
14533 5142 : (CompEvaporatingCAPSpd(CompSpdUB) - CompEvaporatingCAPSpd(CompSpdLB)) *
14534 5142 : (Q_evap_req * C_cap_operation - CompEvaporatingCAPSpd(CompSpdLB));
14535 5142 : Modifi_SH = this->SH;
14536 5142 : Ncomp = CompEvaporatingPWRSpd(CompSpdLB) + (CompEvaporatingPWRSpd(CompSpdUB) - CompEvaporatingPWRSpd(CompSpdLB)) /
14537 5142 : (this->CompressorSpeed(CompSpdUB) - this->CompressorSpeed(CompSpdLB)) *
14538 5142 : (CompSpdActual - this->CompressorSpeed(CompSpdLB));
14539 :
14540 5142 : break; // EXIT DoName2
14541 :
14542 : } else {
14543 : // Compressor runs at the min speed
14544 : // Low Load Modifications
14545 :
14546 129 : NumIteCcap = 1;
14547 : bool converged_19;
14548 : // triggered in VariableRefrigerantFlow_FluidTCtrl_HR_5Zone.idf
14549 : do {
14550 1985 : Q_evap_req = max(0.0, TU_load + Pipe_Q - Ncomp);
14551 :
14552 : // Update Te'( SmallLoadTe ) to meet the required evaporator capacity
14553 1985 : CompSpdActual = this->CompressorSpeed(1);
14554 1985 : Real64 CondHeat = Q_evap_req * C_cap_operation / this->RatedEvapCapacity;
14555 1985 : int CAPFT = this->OUCoolingCAPFT(CounterCompSpdTemp);
14556 :
14557 4122 : auto f = [&state, T_discharge, CondHeat, CAPFT](Real64 const T_suc) {
14558 4122 : return CompResidual_FluidTCtrl(state, T_discharge, CondHeat, CAPFT, T_suc);
14559 1985 : };
14560 1985 : General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, SmallLoadTe, f, MinOutdoorUnitTe, T_suction);
14561 1985 : if (SolFla < 0) {
14562 1950 : SmallLoadTe = MinOutdoorUnitTe;
14563 : }
14564 :
14565 1985 : T_suction = SmallLoadTe;
14566 :
14567 : // Update SH and Pe to calculate Modification Factor, which is used to update rps to for N_comp calculations
14568 1985 : if (this->C3Te == 0) {
14569 0 : Modifi_SH = -(this->C1Te - Tfs + T_suction) / this->C2Te;
14570 : } else {
14571 1985 : if ((pow_2(this->C2Te) - 4 * (this->C1Te - Tfs + T_suction) * this->C3Te) < 0.0) {
14572 0 : Modifi_SH = this->C2Te / (-2 * (this->C1Te - Tfs + T_suction));
14573 : } else {
14574 1985 : Modifi_SH = (-this->C2Te + std::pow((pow_2(this->C2Te) - 4 * (this->C1Te - Tfs + T_suction) * this->C3Te), 0.5)) /
14575 1985 : (2 * this->C3Te);
14576 : }
14577 : }
14578 :
14579 1985 : Modifi_Pe = this->refrig->getSatPressure(state, T_suction, RoutineName);
14580 :
14581 : // Calculate capacity modification factor
14582 1985 : RefTSat = this->refrig->getSatTemperature(state, max(min(Modifi_Pe, RefPHigh), RefPLow), RoutineName);
14583 1985 : Pipe_h_comp_in = this->refrig->getSupHeatEnthalpy(
14584 : state, max(RefTSat, T_suction + Modifi_SH), max(min(Modifi_Pe, RefPHigh), RefPLow), RoutineName);
14585 1985 : C_cap_operation = this->VRFOU_CapModFactor(state,
14586 : Pipe_h_comp_in,
14587 : Pipe_h_out_ave,
14588 : max(min(Modifi_Pe, RefPHigh), RefPLow),
14589 : T_suction + Modifi_SH,
14590 : T_suction + 8,
14591 : IUMaxCondTemp - 5);
14592 :
14593 1985 : Cap_Eva0 = Q_evap_req * C_cap_operation;
14594 3970 : Cap_Eva1 = this->CoffEvapCap * this->RatedEvapCapacity *
14595 1985 : CurveValue(state, this->OUCoolingCAPFT(CounterCompSpdTemp), T_discharge, T_suction);
14596 1985 : CapDiff = std::abs(Cap_Eva1 - Cap_Eva0);
14597 1985 : converged_19 = (CapDiff <= (Tolerance * Cap_Eva0)) || (NumIteCcap >= 30);
14598 1985 : NumIteCcap = NumIteCcap + 1;
14599 1985 : } while (!converged_19);
14600 129 : if (CapDiff > (Tolerance * Cap_Eva0) && (Cap_Eva1 - Cap_Eva0) >= 0.0) {
14601 64 : NumIteCcap = 999;
14602 64 : CyclingRatio = Cap_Eva0 / Cap_Eva1;
14603 : } else {
14604 65 : CyclingRatio = 1.0;
14605 : }
14606 :
14607 129 : Ncomp = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction) * CyclingRatio;
14608 : // Cap_Eva1 is the updated compressor min speed capacity
14609 129 : OUEvapHeatExtract = Cap_Eva1;
14610 129 : this->EvaporatingTemp = T_suction;
14611 129 : this->CondensingTemp = T_discharge;
14612 129 : this->IUCondensingTemp = T_discharge;
14613 129 : break; // EXIT DoName2
14614 :
14615 : } // End: if( CounterCompSpdTemp <= 1 ) Low load modification
14616 :
14617 : } // End: if( Q_evap_req <= CompEvaporatingCAPSpd( CounterCompSpdTemp ) )
14618 :
14619 : } // End: Iteration DoName2
14620 :
14621 5271 : if (CounterCompSpdTemp > NumOfCompSpdInput) {
14622 : // Required heating load is beyond the maximum system capacity
14623 0 : CompEvaporatingCAPSpd(NumOfCompSpdInput) =
14624 0 : this->CoffEvapCap * this->RatedEvapCapacity * CurveValue(state, this->OUCoolingCAPFT(NumOfCompSpdInput), T_discharge, T_suction);
14625 0 : OUEvapHeatExtract = CompEvaporatingCAPSpd(NumOfCompSpdInput);
14626 0 : CompSpdActual = this->CompressorSpeed(NumOfCompSpdInput);
14627 0 : Ncomp = CompEvaporatingPWRSpd(NumOfCompSpdInput);
14628 : }
14629 5271 : }
14630 :
14631 1 : void VRFCondenserEquipment::VRFHR_OU_HR_Mode(EnergyPlusData &state,
14632 : Real64 const h_IU_evap_in, // enthalpy of IU evaporator at inlet [kJ/kg]
14633 : Real64 const h_comp_out, // enthalpy of refrigerant at compressor outlet [kJ/kg]
14634 : Real64 const Q_c_TU_PL, // IU evaporator load, including piping loss [W]
14635 : Real64 const Q_h_TU_PL, // IU condenser load, including piping loss [W]
14636 : Real64 const Tdischarge, // VRF Compressor discharge refrigerant temperature [C]
14637 : Real64 &Tsuction, // VRF compressor suction refrigerant temperature [C]
14638 : Real64 &Te_update, // updated evaporating temperature, only updated when Tsuction is updated [C]
14639 : Real64 &h_comp_in, // enthalpy of refrigerant at compressor inlet [kJ/kg]
14640 : Real64 &h_IU_PLc_out, // enthalpy of refrigerant at the outlet of IU evaporator side main pipe [kJ/kg]
14641 : Real64 &Pipe_Q_c, // IU evaporator side piping loss [W]
14642 : Real64 &Q_c_OU, // OU evaporator load [W]
14643 : Real64 &Q_h_OU, // OU condenser load [W]
14644 : Real64 &m_ref_IU_evap, // mass flow rate of Refrigerant through IU evaporators [kg/s]
14645 : Real64 &m_ref_OU_evap, // mass flow rate of Refrigerant through OU evaporator [kg/s]
14646 : Real64 &m_ref_OU_cond, // mass flow rate of Refrigerant through OU condenser [kg/s]
14647 : Real64 &N_fan_OU, // outdoor unit fan power [W]
14648 : Real64 &CompSpdActual, // Actual compressor running speed [rps]
14649 : Real64 &Ncomp // compressor power [W]
14650 : )
14651 : {
14652 :
14653 : // SUBROUTINE INFORMATION:
14654 : // AUTHOR Rongpeng Zhang, LBNL
14655 : // DATE WRITTEN Jan 2016
14656 : // MODIFIED na
14657 : //
14658 : // RE-ENGINEERED na
14659 : //
14660 : // PURPOSE OF THIS SUBROUTINE:
14661 : // Determine the operational mode of the VRF-HR system, given the terminal unit side load conditions.
14662 : // Compressor and OU hex performance are analyzed for each mode.
14663 : // A number of OU side operational parameters are also calculated here, including:
14664 : // (1) OU evaporator load Q_c_OU (2) OU condenser load Q_h_OU (3) OU fan energy consumption
14665 : // (4) OU compressor speed and energy consumption
14666 : // Note that Te and Te' may be updated here, and thus IU evaporator side piping loss recalculations.
14667 : // Then a number of operational parameters need to be updated, including:
14668 : // (1) IU evaporating temperature Te (2) OU evaporating temperature Te' etc.
14669 : //
14670 : // METHODOLOGY EMPLOYED:
14671 : // This is part of the physics based VRF model applicable for Fluid Temperature Control.
14672 :
14673 : using General::SolveRoot;
14674 :
14675 1 : Real64 constexpr ErrorTol(0.1); // tolerance for RegulaFalsi iterations
14676 1 : int constexpr MaxIte(100); // maximum number of iterations
14677 1 : int HRMode(0); // HR operational mode [W]
14678 1 : int HRMode_sub(0); // HR operational mode (sub) [W]
14679 : int SolFla; // Flag of RegulaFalsi solver
14680 : Real64 C_OU_HexRatio; // capacity ratio between the OU condenser and OU evaporator [-]
14681 : Real64 m_air_rated; // OU coil air mass flow rate [kg/s]
14682 : Real64 m_air_evap; // OU evaporator air mass flow rate [kg/s]
14683 : Real64 m_air_cond; // OU condenser air mass flow rate [kg/s]
14684 : Real64 m_air_evap_rated; // Rated OU evaporator air mass flow rate [kg/s]
14685 1 : Real64 N_fan_OU_evap(0); // OU evaporator air mass flow rate [kg/s]
14686 1 : Real64 N_fan_OU_cond(0); // OU condenser air mass flow rate [kg/s]
14687 : Real64 RhoAir; // outdoor air density [kg/m3]
14688 : Real64 Q_c_tot; // Total evaporator capacity [W]
14689 : Real64 Q_h_tot; // Total condenser capacity [W]
14690 : Real64 Pipe_Q_c_new; // IU evaporator side piping loss (new), updated because of Te update [W]
14691 : Real64 rps1_evap; // compressor speed satisfying IU cooling load
14692 : Real64 rps2_cond; // compressor speed satisfying IU heating load
14693 : Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa]
14694 : Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa]
14695 : Real64 Tfs; // temperature of the air at coil surface [C]
14696 1 : Real64 Tolerance(0.05); // Tolerance for condensing temperature calculation [C}
14697 : Real64 Tsuction_new; // VRF compressor suction refrigerant temperature (new) [C]
14698 :
14699 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14700 : static constexpr std::string_view RoutineName("VRFHR_OU_Mode");
14701 :
14702 : // Initialization: operational parameters
14703 1 : RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
14704 1 : m_air_rated = this->OUAirFlowRate * RhoAir;
14705 1 : C_OU_HexRatio = this->HROUHexRatio;
14706 :
14707 : // Initializations: component index
14708 1 : RefPLow = this->refrig->PsLowPresValue;
14709 1 : RefPHigh = this->refrig->PsHighPresValue;
14710 :
14711 : // **Q_OU: HR mode determination
14712 : // HRMode-1. Cooling Only
14713 : // HRMode-2. Cooling Dominant w/o HR Loss
14714 : // HRMode-3. Cooling Dominant w/ HR Loss
14715 : // HRMode-4. Heating Dominant w/ HR Loss
14716 : // HRMode-5. Heating Dominant w/o HR Loss
14717 : // HRMode-6. Heating Only
14718 : // HRMode-7. OU Hex not running
14719 : {
14720 :
14721 : bool FlagMode5; // true if compressor speed satisfying IU cooling load < that satisfying IU heating load
14722 : bool FlagToLower; // true if To-5 is lower than the Tsuction determined by IU part
14723 : Real64 temp_Tsuction;
14724 :
14725 : // Determine FlagToLower
14726 1 : if (state.dataEnvrn->OutDryBulbTemp - this->DiffOUTeTo < Tsuction) {
14727 0 : temp_Tsuction = state.dataEnvrn->OutDryBulbTemp - this->DiffOUTeTo;
14728 0 : FlagToLower = true;
14729 : } else {
14730 1 : temp_Tsuction = Tsuction;
14731 1 : FlagToLower = false;
14732 : }
14733 :
14734 : // Calculate compressor speed satisfying IU loads: rps1_evap & rps2_cond
14735 1 : this->VRFOU_CompSpd(state, Q_c_TU_PL, HXOpMode::EvapMode, temp_Tsuction, Tdischarge, h_IU_evap_in, h_IU_PLc_out, rps1_evap);
14736 1 : this->VRFOU_CompSpd(state, Q_h_TU_PL, HXOpMode::CondMode, temp_Tsuction, Tdischarge, h_IU_evap_in, h_IU_PLc_out, rps2_cond);
14737 :
14738 : // Determine FlagMode5
14739 1 : if (rps1_evap <= rps2_cond) {
14740 1 : FlagMode5 = true;
14741 : } else {
14742 0 : FlagMode5 = false;
14743 : }
14744 :
14745 : // Determine HR Mode
14746 1 : if (FlagMode5) {
14747 1 : HRMode = 5;
14748 1 : if (FlagToLower) {
14749 0 : HRMode_sub = 1;
14750 : } else {
14751 1 : HRMode_sub = 2;
14752 : }
14753 : } else {
14754 :
14755 0 : if (FlagToLower) {
14756 0 : HRMode = 3; // Mode 3&4 share the same logics below
14757 : } else {
14758 0 : HRMode = 2;
14759 : }
14760 : }
14761 :
14762 1 : this->VRFOperationSimPath = HRMode * 10 + HRMode_sub;
14763 : }
14764 :
14765 : // **Simulate outdoor unit and compressor performance, including
14766 : // (1) compressor spd/power (2) OU hex capacity (3) OU fan flow rate and power
14767 : // Tsuction/Te may also need updates
14768 1 : if (HRMode == 5 && HRMode_sub == 2) {
14769 :
14770 1 : CompSpdActual = rps2_cond; // constant in this mode
14771 : // Tsuction = Te'_iu < OutDryBulbTemp - 5; constant in this mode
14772 :
14773 : // compressor: Ncomp & Q_c_tot
14774 1 : this->VRFOU_CompCap(state, CompSpdActual, Tsuction, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot, Ncomp);
14775 :
14776 : // OU hex capacity
14777 1 : Q_c_OU = Q_c_tot - Q_c_TU_PL;
14778 1 : Q_h_OU = 0;
14779 :
14780 : // OU fan flow rate and power
14781 : m_air_evap =
14782 1 : this->VRFOU_FlowRate(state, HXOpMode::EvapMode, Tsuction, this->SH, Q_c_OU, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
14783 1 : m_air_evap_rated = m_air_rated;
14784 1 : N_fan_OU_evap = this->RatedOUFanPower * m_air_evap / m_air_evap_rated;
14785 1 : N_fan_OU_cond = 0;
14786 :
14787 0 : } else if (HRMode == 5 && HRMode_sub == 1) {
14788 :
14789 : // local parameters
14790 : int Counter_Iter_Ncomp;
14791 0 : bool Flag_Iter_Ncomp(true); // Flag to perform iterations
14792 : Real64 Ncomp_ini;
14793 : Real64 Ncomp_new;
14794 : Real64 Q_c_tot_temp;
14795 : Real64 Q_c_OU_temp;
14796 :
14797 : //===**Ncomp Iterations
14798 :
14799 : // initialization: Ncomp_ini, CompSpdActual
14800 0 : Counter_Iter_Ncomp = 1;
14801 0 : CompSpdActual = rps2_cond;
14802 0 : Tsuction_new = state.dataEnvrn->OutDryBulbTemp - this->DiffOUTeTo;
14803 0 : Pipe_Q_c_new = Pipe_Q_c;
14804 :
14805 0 : this->VRFOU_CompCap(state, CompSpdActual, Tsuction_new, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot, Ncomp_ini);
14806 :
14807 0 : while (Flag_Iter_Ncomp) {
14808 :
14809 0 : Q_c_tot_temp = Q_h_TU_PL - Ncomp_ini; // Q_h_OU = 0
14810 0 : Q_c_OU_temp = Q_c_tot_temp - Q_c_TU_PL;
14811 :
14812 : // Tsuction_new updated based on OU evaporator air-side calculations (Tsuction_new < To)
14813 0 : m_air_evap_rated = m_air_rated;
14814 0 : this->VRFOU_TeTc(state,
14815 : HXOpMode::EvapMode,
14816 : Q_c_OU_temp,
14817 : this->SH,
14818 : m_air_evap_rated,
14819 0 : state.dataEnvrn->OutDryBulbTemp,
14820 0 : state.dataEnvrn->OutHumRat,
14821 0 : state.dataEnvrn->OutBaroPress,
14822 : Tfs,
14823 : Tsuction_new);
14824 0 : Tsuction_new = min(Tsuction_new, Tsuction); // should be lower than Tsuction_IU
14825 :
14826 : // Calculate updated rps corresponding to updated Tsuction_new and Q_c_tot_temp
14827 0 : this->VRFOU_CompSpd(state, Q_c_tot_temp, HXOpMode::EvapMode, Tsuction_new, Tdischarge, h_IU_evap_in, h_comp_in, CompSpdActual);
14828 :
14829 : // Calculate Ncomp_new, using updated CompSpdActual and Tsuction_new
14830 0 : this->VRFOU_CompCap(state, CompSpdActual, Tsuction_new, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot_temp, Ncomp_new);
14831 :
14832 0 : if ((std::abs(Ncomp_new - Ncomp_ini) > (Tolerance * Ncomp_ini)) && (Counter_Iter_Ncomp < 30)) {
14833 0 : Ncomp_ini = 0.5 * Ncomp_ini + 0.5 * Ncomp_new;
14834 0 : Counter_Iter_Ncomp = Counter_Iter_Ncomp + 1;
14835 0 : continue;
14836 : }
14837 :
14838 0 : Flag_Iter_Ncomp = false;
14839 : }
14840 :
14841 : // Ncomp Iterations Update
14842 0 : Ncomp = Ncomp_new;
14843 0 : Q_c_tot = Q_c_tot_temp;
14844 :
14845 0 : if (Tsuction_new < Tsuction) {
14846 : // Need to update the Tsuction, and thus update Te_update & Pipe_Q_c_new.
14847 : // Iteration continues.
14848 :
14849 : // temporary parameters
14850 : Real64 Pe_update;
14851 : Real64 Pipe_SH_merged;
14852 : Real64 Pipe_DeltP;
14853 : Real64 Pipe_h_IU_out;
14854 :
14855 : // Get an updated Te (Te_update) corresponding to the updated Te' (Tsuction_new). PL_c is re-performed.
14856 0 : this->VRFOU_TeModification(state,
14857 : this->EvaporatingTemp,
14858 : Tsuction_new,
14859 : h_IU_evap_in,
14860 0 : state.dataEnvrn->OutDryBulbTemp,
14861 : Te_update,
14862 : Pe_update,
14863 : m_ref_IU_evap,
14864 : Pipe_h_IU_out,
14865 : Pipe_SH_merged);
14866 :
14867 : // Re-calculate piping loss, update Pipe_Q_c_new
14868 0 : this->VRFOU_PipeLossC(state,
14869 : m_ref_IU_evap,
14870 : Pe_update,
14871 : Pipe_h_IU_out,
14872 : Pipe_SH_merged,
14873 0 : state.dataEnvrn->OutDryBulbTemp,
14874 : Pipe_Q_c_new,
14875 : Pipe_DeltP,
14876 : h_IU_PLc_out);
14877 :
14878 0 : Tsuction = Tsuction_new;
14879 0 : Pipe_Q_c = Pipe_Q_c_new;
14880 : }
14881 :
14882 : // No need to update the Tsuction.
14883 :
14884 : //===**Ncomp Iteration Ends (Label200)
14885 :
14886 : // OU hex capacity
14887 0 : Q_c_OU = Q_c_tot - Q_c_TU_PL;
14888 0 : Q_h_OU = 0;
14889 :
14890 : // OU fan power
14891 0 : N_fan_OU_evap = this->RatedOUFanPower;
14892 0 : N_fan_OU_cond = 0;
14893 :
14894 0 : } else if (HRMode == 3) { // Mode3 & Mode4 share the same algorithm
14895 :
14896 : // local parameters
14897 : Real64 Ncomp_new;
14898 : Real64 Q_c_tot_temp;
14899 : Real64 Q_c_OU_temp;
14900 0 : Real64 Tsuction_LB = state.dataEnvrn->OutDryBulbTemp - this->DiffOUTeTo;
14901 0 : Real64 Tsuction_HB = Tsuction;
14902 :
14903 : // compressor speed is fixed in this mode
14904 0 : CompSpdActual = rps1_evap; // constant in this mode
14905 0 : m_air_evap_rated = m_air_rated * (1 - C_OU_HexRatio);
14906 0 : m_air_evap = m_air_evap_rated; // may be updated
14907 :
14908 : // perform iterations to calculate Te at the given compressor speed and operational conditions
14909 : {
14910 :
14911 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) {
14912 0 : int VRFCond = state.dataHVACVarRefFlow->VRFTU(state.dataHVACVarRefFlow->TerminalUnitList(this->ZoneTUListPtr).ZoneTUPtr(1))
14913 0 : .VRFSysNum; // VRFCond;
14914 :
14915 : Real64 Ncomp_temp; // compressor power [W]
14916 : Real64 Q_c_tot_temp; // total evaporator load, including piping loss [W]
14917 : Real64 Q_c_OU_temp; // OU evaporator load, including piping loss [W]
14918 : Real64 Te_new; // newly calculated OU evaporating temperature
14919 : Real64 Tfs; // OU evaporator coil surface temperature [C]
14920 :
14921 0 : state.dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CompCap(
14922 : state, CompSpdActual, Te, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot_temp, Ncomp_temp);
14923 0 : Q_c_OU_temp = Q_c_tot_temp - Q_c_TU_PL;
14924 :
14925 : // Tsuction_new calculated based on OU evaporator air-side calculations (Tsuction_new < To)
14926 0 : state.dataHVACVarRefFlow->VRF(VRFCond).VRFOU_TeTc(state,
14927 : HXOpMode::EvapMode,
14928 : Q_c_OU_temp,
14929 0 : state.dataHVACVarRefFlow->VRF(VRFCond).SH,
14930 : m_air_evap_rated,
14931 0 : state.dataEnvrn->OutDryBulbTemp,
14932 0 : state.dataEnvrn->OutHumRat,
14933 0 : state.dataEnvrn->OutBaroPress,
14934 : Tfs,
14935 : Te_new);
14936 :
14937 0 : return Te_new - Te;
14938 0 : };
14939 :
14940 0 : General::SolveRoot(state, ErrorTol, MaxIte, SolFla, Tsuction_new, f, Tsuction_LB, Tsuction_HB);
14941 0 : if (SolFla < 0) {
14942 0 : Tsuction_new = Tsuction_LB;
14943 : }
14944 :
14945 : // Update Q_c_tot_temp using updated Tsuction_new
14946 0 : this->VRFOU_CompCap(state, CompSpdActual, Tsuction_new, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot_temp, Ncomp_new);
14947 0 : Q_c_OU_temp = Q_c_tot_temp - Q_c_TU_PL;
14948 :
14949 : // Iterations_Te Update
14950 0 : Ncomp = Ncomp_new;
14951 0 : Tsuction = Tsuction_new;
14952 0 : Q_c_tot = Q_c_tot_temp;
14953 0 : Q_c_OU = Q_c_OU_temp;
14954 : }
14955 :
14956 0 : if (Tsuction >= Tsuction_HB) {
14957 : // modify m_air_evap to adjust OU evaporator capacity;
14958 : // update Ncomp, Q_c_OU, m_air_evap
14959 :
14960 0 : Tsuction = Tsuction_HB;
14961 :
14962 : // Q_c_tot
14963 0 : this->VRFOU_CompCap(state, CompSpdActual, Tsuction_new, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot, Ncomp);
14964 0 : Q_c_OU = Q_c_tot - Q_c_TU_PL;
14965 :
14966 : // OU evaporator fan flow rate and power
14967 0 : m_air_evap = this->VRFOU_FlowRate(
14968 0 : state, HXOpMode::EvapMode, Tsuction, this->SH, Q_c_OU_temp, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
14969 :
14970 : } else {
14971 : // Need to update Te_update & Pipe_Q_c_new, corresponding to Tsuction update.
14972 :
14973 : // temporary parameters
14974 : Real64 Pe_update;
14975 : Real64 Pipe_SH_merged;
14976 : Real64 Pipe_DeltP;
14977 : Real64 Pipe_h_IU_out;
14978 :
14979 : // Get an updated Te (Te_update) corresponding to the updated Te' (Tsuction_new). PL_c is re-performed.
14980 0 : this->VRFOU_TeModification(state,
14981 : this->EvaporatingTemp,
14982 : Tsuction_new,
14983 : h_IU_evap_in,
14984 0 : state.dataEnvrn->OutDryBulbTemp,
14985 : Te_update,
14986 : Pe_update,
14987 : m_ref_IU_evap,
14988 : Pipe_h_IU_out,
14989 : Pipe_SH_merged);
14990 :
14991 : // Re-calculate piping loss, update Pipe_Q_c_new
14992 0 : this->VRFOU_PipeLossC(state,
14993 : m_ref_IU_evap,
14994 : Pe_update,
14995 : Pipe_h_IU_out,
14996 : Pipe_SH_merged,
14997 0 : state.dataEnvrn->OutDryBulbTemp,
14998 : Pipe_Q_c_new,
14999 : Pipe_DeltP,
15000 : h_IU_PLc_out);
15001 0 : Pipe_Q_c = Pipe_Q_c_new;
15002 : }
15003 :
15004 : // Q_h_ou
15005 0 : Q_h_tot = Q_c_tot + Ncomp;
15006 0 : Q_h_OU = Q_h_tot - Q_h_TU_PL;
15007 :
15008 : // OU condenser fan flow rate and power
15009 0 : m_air_cond = this->VRFOU_FlowRate(
15010 0 : state, HXOpMode::CondMode, Tdischarge, this->SC, Q_h_OU, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
15011 :
15012 : // OU fan power
15013 0 : N_fan_OU_evap = this->RatedOUFanPower * m_air_evap / m_air_rated;
15014 0 : N_fan_OU_cond = this->RatedOUFanPower * m_air_cond / m_air_rated;
15015 :
15016 0 : } else if (HRMode == 2) {
15017 :
15018 0 : CompSpdActual = rps1_evap; // constant in this mode
15019 : // Tsuction = Te'_iu < OutDryBulbTemp - 5; constant in this mode
15020 :
15021 : // compressor: Ncomp & Q_c_tot
15022 0 : this->VRFOU_CompCap(state, CompSpdActual, Tsuction, Tdischarge, h_IU_evap_in, h_comp_in, Q_c_tot, Ncomp);
15023 :
15024 : // OU hex capacity
15025 0 : Q_h_tot = Q_c_tot + Ncomp;
15026 0 : Q_h_OU = Q_h_tot - Q_h_TU_PL;
15027 0 : Q_c_OU = 0;
15028 :
15029 : // OU fan flow rate and power
15030 0 : m_air_cond = this->VRFOU_FlowRate(
15031 0 : state, HXOpMode::CondMode, Tdischarge, this->SC, Q_h_OU, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
15032 0 : N_fan_OU_cond = this->RatedOUFanPower * m_air_cond / m_air_rated;
15033 0 : N_fan_OU_evap = 0;
15034 :
15035 : } else {
15036 0 : Ncomp = 0;
15037 0 : CompSpdActual = 0;
15038 0 : Q_c_OU = 0;
15039 0 : Q_h_OU = 0;
15040 0 : N_fan_OU_evap = 0;
15041 0 : N_fan_OU_cond = 0;
15042 : }
15043 :
15044 : // OU fan power
15045 1 : N_fan_OU = N_fan_OU_evap + N_fan_OU_cond;
15046 :
15047 : // Calculate the m_ref_OU_evap & m_ref_OU_cond, with updated Tsuction
15048 : {
15049 : Real64 h_OU_evap_in; // enthalpy of OU evaporator at inlet [kJ/kg]
15050 : Real64 h_OU_evap_out; // enthalpy of OU evaporator at outlet [kJ/kg]
15051 : Real64 h_OU_cond_in; // enthalpy of OU condenser at inlet [kJ/kg]
15052 : Real64 h_OU_cond_out; // enthalpy of OU condenser at outlet [kJ/kg]
15053 :
15054 1 : Real64 Psuction = this->refrig->getSatPressure(state, Tsuction, RoutineName);
15055 :
15056 : // enthalpy of OU evaporator/condenser inlets and outlets
15057 1 : h_OU_evap_in = h_IU_evap_in;
15058 1 : h_OU_cond_in = h_comp_out;
15059 1 : h_OU_evap_out = this->refrig->getSupHeatEnthalpy(state, Tsuction + this->SH, max(min(Psuction, RefPHigh), RefPLow), RoutineName);
15060 1 : h_OU_cond_out = this->refrig->getSatEnthalpy(state, Tdischarge - this->SC, 0.0, RoutineName);
15061 :
15062 1 : if ((Q_c_OU == 0) || (h_OU_evap_out - h_OU_evap_in) <= 0) {
15063 0 : m_ref_OU_evap = 0;
15064 : } else {
15065 1 : m_ref_OU_evap = Q_c_OU / (h_OU_evap_out - h_OU_evap_in);
15066 : }
15067 :
15068 1 : if ((Q_h_OU == 0) || (h_OU_cond_in - h_OU_cond_out <= 0)) {
15069 1 : m_ref_OU_cond = 0;
15070 : } else {
15071 0 : m_ref_OU_cond = Q_h_OU / (h_OU_cond_in - h_OU_cond_out);
15072 : }
15073 :
15074 : // Calculate the parameters of refrigerant at compressor inlet, which is
15075 : // a combination of refrigerant from IU evaporators and OU evaporator
15076 1 : if ((m_ref_OU_evap + m_ref_IU_evap) > 0) {
15077 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);
15078 : }
15079 : }
15080 1 : }
15081 :
15082 9036 : void VRFCondenserEquipment::VRFOU_PipeLossC(
15083 : EnergyPlusData &state,
15084 : Real64 const Pipe_m_ref, // Refrigerant mass flow rate [kg/s]
15085 : Real64 const Pevap, // VRF evaporating pressure [Pa]
15086 : Real64 const Pipe_h_IU_out, // Enthalpy of IU at outlet [kJ/kg]
15087 : Real64 const Pipe_SH_merged, // Average super heating degrees after the indoor units [C]
15088 : Real64 const OutdoorDryBulb, // outdoor dry-bulb temperature (C)
15089 : Real64 &Pipe_Q, // unit part load ratio
15090 : Real64 &Pipe_DeltP, // ratio of compressor ON airflow to AVERAGE airflow over timestep
15091 : Real64 &Pipe_h_comp_in // Piping Loss Algorithm Parameter: Enthalpy after piping loss (compressor inlet) [kJ/kg]
15092 : )
15093 : {
15094 :
15095 : // SUBROUTINE INFORMATION:
15096 : // AUTHOR Rongpeng Zhang
15097 : // DATE WRITTEN Nov 2015
15098 : // MODIFIED na
15099 : // RE-ENGINEERED na
15100 :
15101 : // PURPOSE OF THIS SUBROUTINE:
15102 : // Determine the piping loss of the refrigerant, including both the heat loss and pressure drop.
15103 : // This happens at VRF cooling mode, within the Main Pipe connecting Outdoor Unit to Indoor Units.
15104 :
15105 : // METHODOLOGY EMPLOYED:
15106 : // Use a physics based piping loss model.
15107 :
15108 : using General::SolveRoot;
15109 :
15110 : int TUListNum; // index to TU List
15111 : int NumTUInList; // number of terminal units is list
15112 : int NumIUActivated; // number of the used indoor units [-]
15113 :
15114 : Real64 Pipe_v_ref; // Piping Loss Algorithm Parameter: Refrigerant velocity [m/s]
15115 : Real64 Pipe_T_room; // Piping Loss Algorithm Parameter: Average Room Temperature [C]
15116 : Real64 Pipe_Num_Re; // Piping Loss Algorithm Parameter: refrigerant Re Number [-]
15117 : Real64 Pipe_Num_Pr; // Piping Loss Algorithm Parameter: refrigerant Pr Number [-]
15118 : Real64 Pipe_Num_Nu; // Piping Loss Algorithm Parameter: refrigerant Nu Number [-]
15119 : Real64 Pipe_Num_St; // Piping Loss Algorithm Parameter: refrigerant St Number [-]
15120 : Real64 Pipe_Coe_k1; // Piping Loss Algorithm Parameter: coefficients [-]
15121 : Real64 Pipe_Coe_k2; // Piping Loss Algorithm Parameter: coefficients [-]
15122 : Real64 Pipe_Coe_k3; // Piping Loss Algorithm Parameter: coefficients [-]
15123 : Real64 Pipe_cp_ref; // Piping Loss Algorithm_[kJ/kg/K]
15124 : Real64 Pipe_conductivity_ref; // Piping Loss Algorithm: refrigerant conductivity [W/m/K]
15125 : Real64 Pipe_viscosity_ref; // Piping Loss Algorithm Parameter: refrigerant viscosity [MuPa*s]
15126 : Real64 Ref_Coe_v1; // Piping Loss Algorithm Parameter: coefficient to calculate Pipe_viscosity_ref [-]
15127 : Real64 Ref_Coe_v2; // Piping Loss Algorithm Parameter: coefficient to calculate Pipe_viscosity_ref [-]
15128 : Real64 Ref_Coe_v3; // Piping Loss Algorithm Parameter: coefficient to calculate Pipe_viscosity_ref [-]
15129 : Real64 RefPipInsH; // Heat transfer coefficient for calculating piping loss [W/m2K]
15130 :
15131 : static constexpr std::string_view RoutineName("VRFOU_PipeLossC");
15132 :
15133 9036 : TUListNum = this->ZoneTUListPtr;
15134 9036 : NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
15135 9036 : Pipe_conductivity_ref = this->RefPipInsCon;
15136 :
15137 9036 : RefPipInsH = 9.3;
15138 9036 : Pipe_cp_ref = 1.6;
15139 :
15140 : // Refrigerant data
15141 9036 : Real64 RefPLow = this->refrig->PsLowPresValue; // Low Pressure Value for Ps (>0.0)
15142 9036 : Real64 RefPHigh = this->refrig->PsHighPresValue; // High Pressure Value for Ps (max in tables)
15143 :
15144 : // Calculate Pipe_T_room
15145 9036 : Pipe_T_room = 0;
15146 9036 : NumIUActivated = 0;
15147 18072 : for (int NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
15148 9036 : int TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
15149 9036 : int CoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).CoolCoilIndex;
15150 :
15151 9036 : if (state.dataDXCoils->DXCoil(CoilIndex).TotalCoolingEnergyRate > 0.0) {
15152 9006 : Pipe_T_room = Pipe_T_room + state.dataDXCoils->DXCoil(CoilIndex).InletAirTemp;
15153 9006 : NumIUActivated = NumIUActivated + 1;
15154 : }
15155 : }
15156 9036 : if (NumIUActivated > 0) {
15157 9006 : Pipe_T_room = Pipe_T_room / NumIUActivated;
15158 : } else {
15159 30 : Pipe_T_room = 24;
15160 : }
15161 :
15162 9036 : if (Pipe_m_ref > 0) {
15163 9006 : if (this->RefPipDiaSuc <= 0) {
15164 0 : this->RefPipDiaSuc = 0.025;
15165 : }
15166 :
15167 9006 : Ref_Coe_v1 = Pevap / 1000000 / 4.926;
15168 9006 : Ref_Coe_v2 = Pipe_h_IU_out / 383.5510343;
15169 9006 : Ref_Coe_v3 = (this->EvaporatingTemp + Pipe_SH_merged + 273.15) / 344.39;
15170 :
15171 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) +
15172 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 -
15173 9006 : 218.48 * Ref_Coe_v2 * Ref_Coe_v3 + 21.58;
15174 9006 : if (Pipe_viscosity_ref <= 0) {
15175 0 : Pipe_viscosity_ref = 16.26; // default superheated vapor viscosity data (MuPa*s) at T=353.15 K, P=2MPa
15176 : }
15177 :
15178 9006 : Pipe_v_ref = Pipe_m_ref / (Constant::Pi * pow_2(this->RefPipDiaSuc) * 0.25) /
15179 9006 : this->refrig->getSupHeatDensity(state, this->EvaporatingTemp + Pipe_SH_merged, max(min(Pevap, RefPHigh), RefPLow), RoutineName);
15180 9006 : Pipe_Num_Re = Pipe_m_ref / (Constant::Pi * pow_2(this->RefPipDiaSuc) * 0.25) * this->RefPipDiaSuc / Pipe_viscosity_ref * 1000000;
15181 9006 : Pipe_Num_Pr = Pipe_viscosity_ref * Pipe_cp_ref * 0.001 / Pipe_conductivity_ref;
15182 9006 : Pipe_Num_Nu = 0.023 * std::pow(Pipe_Num_Re, 0.8) * std::pow(Pipe_Num_Pr, 0.3);
15183 9006 : Pipe_Num_St = Pipe_Num_Nu / Pipe_Num_Re / Pipe_Num_Pr;
15184 :
15185 18012 : Pipe_DeltP = max(
15186 : 0.0,
15187 18012 : 8 * Pipe_Num_St * std::pow(Pipe_Num_Pr, 0.6667) * this->RefPipEquLen / this->RefPipDiaSuc *
15188 9006 : this->refrig->getSupHeatDensity(state, this->EvaporatingTemp + Pipe_SH_merged, max(min(Pevap, RefPHigh), RefPLow), RoutineName) *
15189 9006 : pow_2(Pipe_v_ref) / 2 -
15190 18012 : this->RefPipHei *
15191 9006 : this->refrig->getSupHeatDensity(state, this->EvaporatingTemp + Pipe_SH_merged, max(min(Pevap, RefPHigh), RefPLow), RoutineName) *
15192 : 9.80665);
15193 :
15194 9006 : Pipe_Coe_k1 = Pipe_Num_Nu * Pipe_viscosity_ref;
15195 9006 : Pipe_Coe_k3 = RefPipInsH * (this->RefPipDiaSuc + 2 * this->RefPipInsThi);
15196 9006 : if (this->RefPipInsThi >= 0.0) {
15197 9006 : Pipe_Coe_k2 = 2 * this->RefPipInsCon / std::log1p(2 * this->RefPipInsThi / this->RefPipDiaSuc);
15198 : } else {
15199 0 : Pipe_Coe_k2 = 9999.9;
15200 : }
15201 :
15202 18012 : Pipe_Q = max(0.0,
15203 9006 : (Constant::Pi * this->RefPipLen) * (OutdoorDryBulb / 2 + Pipe_T_room / 2 - this->EvaporatingTemp - Pipe_SH_merged) /
15204 9006 : (1 / Pipe_Coe_k1 + 1 / Pipe_Coe_k2 + 1 / Pipe_Coe_k3));
15205 :
15206 9006 : Pipe_h_comp_in = Pipe_h_IU_out + Pipe_Q / Pipe_m_ref;
15207 : // when Pipe_m_ref is close to 0, there will still be Pipe_Q, Pipe_Q / Pipe_m_ref will blow up
15208 : // At low flow rate (stationary flow)
15209 : // Pipe_h_comp_in = Pipe_h_IU_out + Cp * deltaT
15210 : // where deltaT is the refrigerant temperature change over time t,
15211 : // deltaT = Pipe_Q * t / (refrigerant_mass_in_pipe * Cp)
15212 : // so Pipe_h_comp_in = Pipe_h_IU_out + Cp * Pipe_Q / refrigerant_mass_in_pipe
15213 : // assume 0.001 is the cutoff Re for stationary flow
15214 9006 : if (Pipe_Num_Re < 0.001) { // low flow rate calculation
15215 108 : Pipe_h_comp_in =
15216 108 : Pipe_h_IU_out + Pipe_Q * state.dataHVACGlobal->TimeStepSysSec /
15217 108 : ((Constant::Pi * std::pow(this->RefPipDiaSuc / 2, 2) * this->RefPipLen *
15218 216 : this->refrig->getSupHeatDensity(
15219 108 : state, this->EvaporatingTemp + Pipe_SH_merged, max(min(Pevap, RefPHigh), RefPLow), RoutineName)));
15220 : }
15221 :
15222 : } else {
15223 30 : Pipe_DeltP = 0;
15224 30 : Pipe_Q = 0;
15225 30 : Pipe_h_comp_in = Pipe_h_IU_out;
15226 : }
15227 9036 : }
15228 :
15229 2908 : void VRFCondenserEquipment::VRFOU_PipeLossH(
15230 : EnergyPlusData &state,
15231 : Real64 const Pipe_m_ref, // Refrigerant mass flow rate [kg/s]
15232 : Real64 const Pcond, // VRF condensing pressure [Pa]
15233 : Real64 const Pipe_h_IU_in, // Enthalpy of IU at outlet [kJ/kg]
15234 : Real64 const OutdoorDryBulb, // outdoor dry-bulb temperature (C)
15235 : Real64 &Pipe_Q, // unit part load ratio
15236 : Real64 &Pipe_DeltP, // ratio of compressor ON airflow to AVERAGE airflow over timestep
15237 : Real64 &Pipe_h_comp_out // Piping Loss Algorithm Parameter: Enthalpy before piping loss (compressor outlet) [kJ/kg]
15238 : ) const
15239 : {
15240 :
15241 : // SUBROUTINE INFORMATION:
15242 : // AUTHOR Rongpeng Zhang
15243 : // DATE WRITTEN Nov 2015
15244 : // MODIFIED na
15245 : // RE-ENGINEERED na
15246 :
15247 : // PURPOSE OF THIS SUBROUTINE:
15248 : // Determine the piping loss of the refrigerant, including both the heat loss and pressure drop.
15249 : // This happens at VRF cooling mode, within the Main Pipe connecting Outdoor Unit to Indoor Units.
15250 :
15251 : // METHODOLOGY EMPLOYED:
15252 : // Use a physics based piping loss model.
15253 :
15254 : using General::SolveRoot;
15255 :
15256 : int TUListNum; // index to TU List
15257 : int NumTUInList; // number of terminal units is list
15258 : int NumIUActivated; // number of the used indoor units [-]
15259 :
15260 : Real64 Pipe_v_ref; // Piping Loss Algorithm Parameter: Refrigerant velocity [m/s]
15261 : Real64 Pipe_T_room; // Piping Loss Algorithm Parameter: Average Room Temperature [C]
15262 : Real64 Pipe_T_IU_in; // Piping Loss Algorithm Parameter: Average Refrigerant Temperature [C]
15263 : Real64 Pipe_Num_Re; // Piping Loss Algorithm Parameter: refrigerant Re Number [-]
15264 : Real64 Pipe_Num_Pr; // Piping Loss Algorithm Parameter: refrigerant Pr Number [-]
15265 : Real64 Pipe_Num_Nu; // Piping Loss Algorithm Parameter: refrigerant Nu Number [-]
15266 : Real64 Pipe_Num_St; // Piping Loss Algorithm Parameter: refrigerant St Number [-]
15267 : Real64 Pipe_Coe_k1; // Piping Loss Algorithm Parameter: coefficients [-]
15268 : Real64 Pipe_Coe_k2; // Piping Loss Algorithm Parameter: coefficients [-]
15269 : Real64 Pipe_Coe_k3; // Piping Loss Algorithm Parameter: coefficients [-]
15270 : Real64 Pipe_cp_ref; // Piping Loss Algorithm_[kJ/kg/K]
15271 : Real64 Pipe_conductivity_ref; // Piping Loss Algorithm: refrigerant conductivity [W/m/K]
15272 : Real64 Pipe_viscosity_ref; // Piping Loss Algorithm Parameter: refrigerant viscosity [MuPa*s]
15273 : Real64 Ref_Coe_v1; // Piping Loss Algorithm Parameter: coefficient to calculate Pipe_viscosity_ref [-]
15274 : Real64 Ref_Coe_v2; // Piping Loss Algorithm Parameter: coefficient to calculate Pipe_viscosity_ref [-]
15275 : Real64 Ref_Coe_v3; // Piping Loss Algorithm Parameter: coefficient to calculate Pipe_viscosity_ref [-]
15276 : Real64 RefPipInsH; // Heat transfer coefficient for calculating piping loss [W/m2K]
15277 :
15278 : static constexpr std::string_view RoutineName("VRFOU_PipeLossH");
15279 :
15280 2908 : TUListNum = this->ZoneTUListPtr;
15281 2908 : NumTUInList = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).NumTUInList;
15282 2908 : Pipe_conductivity_ref = this->RefPipInsCon;
15283 :
15284 2908 : RefPipInsH = 9.3;
15285 2908 : Pipe_cp_ref = 1.6;
15286 :
15287 : // Refrigerant data
15288 2908 : Real64 RefTHigh = this->refrig->PsHighTempValue; // High Temperature Value for Ps (max in tables)
15289 2908 : Real64 RefPLow = this->refrig->PsLowPresValue; // Low Pressure Value for Ps (>0.0)
15290 2908 : Real64 RefPHigh = this->refrig->PsHighPresValue; // High Pressure Value for Ps (max in tables)
15291 2908 : Real64 RefTSat = this->refrig->getSatTemperature(state, max(min(Pcond, RefPHigh), RefPLow), RoutineName);
15292 :
15293 : // Perform iteration to calculate Pipe_T_IU_in, given P and h
15294 2908 : Pipe_T_IU_in = this->refrig->getSupHeatTemp(state,
15295 : max(min(Pcond, RefPHigh), RefPLow),
15296 : Pipe_h_IU_in,
15297 2908 : max(this->IUCondensingTemp, RefTSat),
15298 2908 : min(this->IUCondensingTemp + 50, RefTHigh),
15299 : RoutineName);
15300 2908 : Pipe_T_IU_in = min(RefTHigh, Pipe_T_IU_in);
15301 :
15302 : // Calculate average room temperature
15303 2908 : Pipe_T_room = 0;
15304 2908 : NumIUActivated = 0;
15305 5816 : for (int NumTU = 1; NumTU <= NumTUInList; ++NumTU) {
15306 2908 : int TUIndex = state.dataHVACVarRefFlow->TerminalUnitList(TUListNum).ZoneTUPtr(NumTU);
15307 2908 : int CoilIndex = state.dataHVACVarRefFlow->VRFTU(TUIndex).HeatCoilIndex;
15308 :
15309 2908 : if (state.dataDXCoils->DXCoil(CoilIndex).TotalHeatingEnergyRate > 0.0) {
15310 2908 : Pipe_T_room = Pipe_T_room + state.dataDXCoils->DXCoil(CoilIndex).InletAirTemp;
15311 2908 : NumIUActivated = NumIUActivated + 1;
15312 : }
15313 : }
15314 2908 : if (NumIUActivated > 0) {
15315 2908 : Pipe_T_room = Pipe_T_room / NumIUActivated;
15316 : } else {
15317 0 : Pipe_T_room = 18;
15318 : }
15319 :
15320 : // Calculate piping loss
15321 2908 : if (Pipe_m_ref > 0) {
15322 2908 : Ref_Coe_v1 = Pcond / 1000000 / 4.926;
15323 2908 : Ref_Coe_v2 = Pipe_h_IU_in / 383.5510343;
15324 2908 : Ref_Coe_v3 = (Pipe_T_IU_in + 273.15) / 344.39;
15325 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) +
15326 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 -
15327 2908 : 218.48 * Ref_Coe_v2 * Ref_Coe_v3 + 21.58;
15328 2908 : if (Pipe_viscosity_ref <= 0) {
15329 0 : Pipe_viscosity_ref = 16.26; // default superheated vapor viscosity data (MuPa*s) at T=353.15 K, P=2MPa
15330 : }
15331 :
15332 2908 : Pipe_v_ref = Pipe_m_ref / (Constant::Pi * pow_2(this->RefPipDiaDis) * 0.25) /
15333 2908 : this->refrig->getSupHeatDensity(state, Pipe_T_IU_in, max(min(Pcond, RefPHigh), RefPLow), RoutineName);
15334 2908 : Pipe_Num_Re = Pipe_m_ref / (Constant::Pi * pow_2(this->RefPipDiaDis) * 0.25) * this->RefPipDiaDis / Pipe_viscosity_ref * 1000000;
15335 2908 : Pipe_Num_Pr = Pipe_viscosity_ref * Pipe_cp_ref * 0.001 / Pipe_conductivity_ref;
15336 2908 : Pipe_Num_Nu = 0.023 * std::pow(Pipe_Num_Re, 0.8) * std::pow(Pipe_Num_Pr, 0.4);
15337 2908 : Pipe_Num_St = Pipe_Num_Nu / Pipe_Num_Re / Pipe_Num_Pr;
15338 :
15339 2908 : Pipe_Coe_k1 = Pipe_Num_Nu * Pipe_viscosity_ref;
15340 2908 : Pipe_Coe_k2 = this->RefPipInsCon * (this->RefPipDiaDis + this->RefPipInsThi) / this->RefPipInsThi;
15341 2908 : Pipe_Coe_k3 = RefPipInsH * (this->RefPipDiaDis + 2 * this->RefPipInsThi);
15342 :
15343 5816 : Pipe_Q = max(0.0,
15344 2908 : (Constant::Pi * this->RefPipLen) * (Pipe_T_IU_in - OutdoorDryBulb / 2 - Pipe_T_room / 2) /
15345 2908 : (1 / Pipe_Coe_k1 + 1 / Pipe_Coe_k2 + 1 / Pipe_Coe_k3)); // [W]
15346 5816 : Pipe_DeltP = max(
15347 : 0.0,
15348 5816 : 8 * Pipe_Num_St * std::pow(Pipe_Num_Pr, 0.6667) * this->RefPipEquLen / this->RefPipDiaDis *
15349 2908 : this->refrig->getSupHeatDensity(state, Pipe_T_IU_in, max(min(Pcond, RefPHigh), RefPLow), RoutineName) * pow_2(Pipe_v_ref) / 2 -
15350 2908 : this->RefPipHei * this->refrig->getSupHeatDensity(state, Pipe_T_IU_in, max(min(Pcond, RefPHigh), RefPLow), RoutineName) * 9.80665);
15351 :
15352 2908 : Pipe_h_comp_out = Pipe_h_IU_in + Pipe_Q / Pipe_m_ref;
15353 :
15354 : } else {
15355 0 : Pipe_DeltP = 0;
15356 0 : Pipe_Q = 0;
15357 0 : Pipe_h_comp_out = Pipe_h_IU_in;
15358 : }
15359 2908 : }
15360 0 : void VRFCondenserEquipment::oneTimeInit([[maybe_unused]] EnergyPlusData &state)
15361 : {
15362 0 : }
15363 1 : void VRFCondenserEquipment::oneTimeInit_new([[maybe_unused]] EnergyPlusData &state)
15364 : {
15365 1 : }
15366 :
15367 40 : void VRFTerminalUnitEquipment::CalcVRFSuppHeatingCoil(EnergyPlusData &state,
15368 : int const VRFTUNum, // index of vrf terminal unit
15369 : bool const FirstHVACIteration, // True when first HVAC iteration
15370 : Real64 const PartLoadRatio, // coil operating part-load ratio
15371 : Real64 &SuppCoilLoad // supp heating coil load max (W)
15372 : )
15373 : {
15374 :
15375 : // PURPOSE OF THIS SUBROUTINE:
15376 : // Manages VRF terminal unit supplemental heaters simulation.
15377 :
15378 : // Locals
15379 : // subroutine parameter definitions:
15380 40 : int constexpr MaxIte(500); // Maximum number of iterations for solver
15381 40 : Real64 constexpr Acc(1.e-3); // Accuracy of solver result
15382 :
15383 : // local variable declaration:
15384 : Real64 SuppHeatCoilLoad; // load passed to supplemental heating coil (W)
15385 : Real64 QActual; // actual coil output (W)
15386 : Real64 PartLoadFrac; // temporary PLR variable
15387 :
15388 40 : QActual = 0.0;
15389 40 : PartLoadFrac = 0.0;
15390 40 : SuppHeatCoilLoad = 0.0;
15391 :
15392 : // simulate gas, electric, hot water, and steam heating coils
15393 40 : if (state.dataEnvrn->OutDryBulbTemp <= this->MaxOATSuppHeatingCoil) {
15394 40 : SuppHeatCoilLoad = SuppCoilLoad;
15395 : } else {
15396 0 : SuppHeatCoilLoad = 0.0;
15397 : }
15398 :
15399 40 : switch (this->SuppHeatCoilType_Num) {
15400 36 : case HVAC::Coil_HeatingGasOrOtherFuel:
15401 : case HVAC::Coil_HeatingElectric: {
15402 144 : HeatingCoils::SimulateHeatingCoilComponents(
15403 108 : state, this->SuppHeatCoilName, FirstHVACIteration, SuppHeatCoilLoad, this->SuppHeatCoilIndex, QActual, true, this->fanOp, PartLoadRatio);
15404 36 : SuppHeatCoilLoad = QActual;
15405 36 : } break;
15406 2 : case HVAC::Coil_HeatingWater: {
15407 2 : if (SuppHeatCoilLoad > HVAC::SmallLoad) {
15408 : // see if HW coil has enough capacity to meet the load
15409 2 : Real64 mdot = this->SuppHeatCoilFluidMaxFlow;
15410 2 : state.dataLoopNodes->Node(this->SuppHeatCoilFluidInletNode).MassFlowRate = mdot;
15411 : // simulate hot water coil to find the full flow operating capacity
15412 6 : WaterCoils::SimulateWaterCoilComponents(
15413 4 : state, this->SuppHeatCoilName, FirstHVACIteration, this->SuppHeatCoilIndex, QActual, this->fanOp, PartLoadRatio);
15414 2 : if (QActual > SuppHeatCoilLoad) {
15415 : int SolFla; // Flag of solver, num iterations if >0, else error index
15416 20 : auto f = [&state, VRFTUNum, FirstHVACIteration, SuppHeatCoilLoad](Real64 const PartLoadFrac) {
15417 20 : Real64 QActual = 0.0; // actual heating load delivered [W]
15418 20 : Real64 mdot = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow * PartLoadFrac;
15419 20 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode).MassFlowRate = mdot;
15420 60 : WaterCoils::SimulateWaterCoilComponents(state,
15421 20 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
15422 : FirstHVACIteration,
15423 20 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex,
15424 : QActual,
15425 20 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp,
15426 : PartLoadFrac);
15427 20 : if (std::abs(SuppHeatCoilLoad) == 0.0) {
15428 0 : return (QActual - SuppHeatCoilLoad) / 100.0;
15429 : } else {
15430 20 : return (QActual - SuppHeatCoilLoad) / SuppHeatCoilLoad;
15431 : }
15432 2 : };
15433 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
15434 2 : this->SuppHeatPartLoadRatio = PartLoadFrac;
15435 : } else {
15436 0 : this->SuppHeatPartLoadRatio = 1.0;
15437 0 : SuppHeatCoilLoad = QActual;
15438 : }
15439 : } else {
15440 0 : this->SuppHeatPartLoadRatio = 0.0;
15441 0 : Real64 mdot = 0.0;
15442 0 : SuppHeatCoilLoad = 0.0;
15443 0 : PlantUtilities::SetComponentFlowRate(
15444 0 : state, mdot, this->SuppHeatCoilFluidInletNode, this->SuppHeatCoilFluidOutletNode, this->SuppHeatCoilPlantLoc);
15445 : }
15446 : // simulate water heating coil
15447 4 : WaterCoils::SimulateWaterCoilComponents(
15448 4 : state, this->SuppHeatCoilName, FirstHVACIteration, this->SuppHeatCoilIndex, SuppHeatCoilLoad, this->fanOp, this->SuppHeatPartLoadRatio);
15449 2 : } break;
15450 2 : case HVAC::Coil_HeatingSteam: {
15451 : // simulate steam heating coil
15452 2 : Real64 mdot = this->SuppHeatCoilFluidMaxFlow * PartLoadRatio;
15453 2 : state.dataLoopNodes->Node(this->SuppHeatCoilFluidInletNode).MassFlowRate = mdot;
15454 6 : SteamCoils::SimulateSteamCoilComponents(
15455 4 : state, this->SuppHeatCoilName, FirstHVACIteration, this->SuppHeatCoilIndex, SuppHeatCoilLoad, QActual, this->fanOp, PartLoadRatio);
15456 2 : SuppHeatCoilLoad = QActual;
15457 2 : } break;
15458 0 : default:
15459 0 : break;
15460 : }
15461 :
15462 40 : SuppCoilLoad = SuppHeatCoilLoad;
15463 40 : }
15464 :
15465 0 : Real64 VRFTerminalUnitEquipment::HotWaterHeatingCoilResidual(EnergyPlusData &state,
15466 : Real64 const PartLoadFrac, // water heating coil part-load ratio
15467 : std::vector<Real64> const &Par // par(1) = index to current VRF terminal unit
15468 : )
15469 : {
15470 :
15471 : // PURPOSE OF THIS FUNCTION:
15472 : // Calculates supplemental hot water heating coils load fraction residual [(QActual - Load)/Load]
15473 : // hot water Coil output depends on the part load ratio which is being varied to drive the load
15474 : // fraction residual to zero.
15475 :
15476 : // METHODOLOGY EMPLOYED:
15477 : // runs Coil:Heating:Water component object to get the actual heating load delivered [W] at a
15478 : // given part load ratio and calculates the residual as defined above
15479 :
15480 : // Return value
15481 : Real64 Residuum; // Residual to be minimized to zero
15482 :
15483 : // local variables declaration:
15484 0 : int VRFTUNum = int(Par[1]); // index to current terminal unit simulated
15485 0 : bool FirstHVACIteration = Par[2]; // 0 flag if it first HVAC iteration, or else 1
15486 0 : Real64 SuppHeatCoilLoad = Par[3]; // supplemental heating coil load to be met [W]
15487 0 : Real64 QActual = 0.0; // actual heating load delivered [W]
15488 :
15489 : // Real64 mdot = min(state.dataLoopNodes->Node(VRFTU(VRFTUNum).SuppHeatCoilFluidOutletNode).MassFlowRateMaxAvail,
15490 : // VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow * PartLoadFrac);
15491 :
15492 0 : Real64 mdot = state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidMaxFlow * PartLoadFrac;
15493 0 : state.dataLoopNodes->Node(state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilFluidInletNode).MassFlowRate = mdot;
15494 0 : WaterCoils::SimulateWaterCoilComponents(state,
15495 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilName,
15496 : FirstHVACIteration,
15497 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).SuppHeatCoilIndex,
15498 : QActual,
15499 0 : state.dataHVACVarRefFlow->VRFTU(VRFTUNum).fanOp,
15500 : PartLoadFrac);
15501 :
15502 0 : if (std::abs(SuppHeatCoilLoad) == 0.0) {
15503 0 : Residuum = (QActual - SuppHeatCoilLoad) / 100.0;
15504 : } else {
15505 0 : Residuum = (QActual - SuppHeatCoilLoad) / SuppHeatCoilLoad;
15506 : }
15507 :
15508 0 : return Residuum;
15509 : }
15510 :
15511 1 : Real64 VRFTerminalUnitEquipment::HeatingCoilCapacityLimit(
15512 : EnergyPlusData &state,
15513 : Real64 const HeatCoilAirInletNode, // supplemental heating coil air inlet node
15514 : Real64 const HeatCoilMaxSATAllowed // supplemental heating coil maximum supply air temperature allowed [C]
15515 : )
15516 : {
15517 : // PURPOSE OF THIS FUNCTION:
15518 : // Calculates supplemental heating coils maximum heating capacity allowed based on the maximum
15519 : // supply air temperature limit specified.
15520 :
15521 : // METHODOLOGY EMPLOYED:
15522 : // ( m_dot_air * Cp_air_avg * DeltaT_air_across_heating_coil) [W]
15523 :
15524 : // Return value
15525 : Real64 HeatCoilCapacityAllowed; // heating coil maximum capacity that can be delivered at current time [W]
15526 :
15527 1 : Real64 MDotAir = state.dataLoopNodes->Node(HeatCoilAirInletNode).MassFlowRate;
15528 1 : Real64 CpAirIn = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(HeatCoilAirInletNode).HumRat);
15529 1 : Real64 HCDeltaT = max(0.0, HeatCoilMaxSATAllowed - state.dataLoopNodes->Node(HeatCoilAirInletNode).Temp);
15530 1 : HeatCoilCapacityAllowed = MDotAir * CpAirIn * HCDeltaT;
15531 :
15532 1 : return HeatCoilCapacityAllowed;
15533 : }
15534 :
15535 : } // namespace EnergyPlus::HVACVariableRefrigerantFlow
|