Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, 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 <cmath>
50 : #include <string>
51 :
52 : // ObjexxFCL Headers
53 : #include <ObjexxFCL/Fmath.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <EnergyPlus/Autosizing/All_Simple_Sizing.hh>
57 : #include <EnergyPlus/Autosizing/CoolingAirFlowSizing.hh>
58 : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
59 : #include <EnergyPlus/Autosizing/CoolingSHRSizing.hh>
60 : #include <EnergyPlus/Autosizing/HeatingAirFlowSizing.hh>
61 : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
62 : #include <EnergyPlus/BranchNodeConnections.hh>
63 : #include <EnergyPlus/CurveManager.hh>
64 : #include <EnergyPlus/DXCoils.hh>
65 : #include <EnergyPlus/Data/EnergyPlusData.hh>
66 : #include <EnergyPlus/DataAirSystems.hh>
67 : #include <EnergyPlus/DataBranchNodeConnections.hh>
68 : #include <EnergyPlus/DataContaminantBalance.hh>
69 : #include <EnergyPlus/DataEnvironment.hh>
70 : #include <EnergyPlus/DataGlobalConstants.hh>
71 : #include <EnergyPlus/DataHeatBalance.hh>
72 : #include <EnergyPlus/DataLoopNode.hh>
73 : #include <EnergyPlus/DataPrecisionGlobals.hh>
74 : #include <EnergyPlus/DataSizing.hh>
75 : #include <EnergyPlus/DataWater.hh>
76 : #include <EnergyPlus/EMSManager.hh>
77 : #include <EnergyPlus/Fans.hh>
78 : #include <EnergyPlus/General.hh>
79 : #include <EnergyPlus/GeneralRoutines.hh>
80 : #include <EnergyPlus/GlobalNames.hh>
81 : #include <EnergyPlus/HVACVariableRefrigerantFlow.hh>
82 : #include <EnergyPlus/HeatBalanceInternalHeatGains.hh>
83 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
84 : #include <EnergyPlus/NodeInputManager.hh>
85 : #include <EnergyPlus/OutAirNodeManager.hh>
86 : #include <EnergyPlus/OutputProcessor.hh>
87 : #include <EnergyPlus/OutputReportPredefined.hh>
88 : #include <EnergyPlus/Psychrometrics.hh>
89 : #include <EnergyPlus/ScheduleManager.hh>
90 : #include <EnergyPlus/SimAirServingZones.hh>
91 : #include <EnergyPlus/StandardRatings.hh>
92 : #include <EnergyPlus/UtilityRoutines.hh>
93 : #include <EnergyPlus/WaterManager.hh>
94 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
95 :
96 : namespace EnergyPlus::DXCoils {
97 :
98 : // Module containing the DX coil simulation routines
99 :
100 : // MODULE INFORMATION:
101 : // AUTHOR Fred Buhl
102 : // DATE WRITTEN May 2000
103 : // MODIFIED Aug 2000, Don Shirey, Sept 2000, Feb/Oct 2001, Sept 2003, Jan 2004
104 : // Feb 2005, M. J. Witte, GARD Analytics, Inc., Add new coil type COIL:DX:MultiMode:CoolingEmpirical: Work supported by
105 : // ASHRAE research project 1254-RP Aug 2006, B Griffith, NREL, Added water system interactions for new water manager, Feb
106 : // 2010, B Nigusse, FSEC, Added Standard Rating for Coil:Cooling:DX:SingleSpeed Apr 2010, Chandan Sharma, FSEC, Added basin
107 : // heater routines for Coil:Cooling:DX:SingleSpeed, Coil:Cooling:DX:TwoSpeed,
108 : // Coil:Cooling:DX:MultiSpeed, and Coil:Cooling:DX:TwoStageWithHumidityControlMode
109 : // Feb 2013, Bereket Nigusse, FSEC, Added DX Coil Model For 100% OA systems
110 : // Jul 2015, RP Zhang, XF Pang, LBNL, Added new coil type for VRF-FluidTemperatureControl Model
111 :
112 : // PURPOSE OF THIS MODULE:
113 : // To encapsulate the data and algorithms required to simulate DX cooling coils in
114 : // EnergyPlus. Module currently models air-cooled or evap-cooled direct expansion systems
115 : // (split or packaged). Air-side performance is modeled to determine coil discharge
116 : // air conditions. The module also determines the DX unit's electrical energy usage.
117 : // Neither the air-side performance nor the electrical energy usage includes the effect
118 : // of supply air fan heat/energy usage. The supply air fan is modeled by other modules.
119 :
120 : // USE STATEMENTS:
121 : // Use statements for data only modules
122 : // Using/Aliasing
123 : using namespace DataLoopNode;
124 : using namespace Psychrometrics;
125 :
126 : // Use statements for access to subroutines in other modules
127 : using namespace ScheduleManager;
128 :
129 : // Functions
130 :
131 47491188 : void SimDXCoil(EnergyPlusData &state,
132 : std::string_view CompName, // name of the fan coil unit
133 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
134 : bool const FirstHVACIteration, // True when first HVAC iteration
135 : int &CompIndex,
136 : HVAC::FanOp const fanOp, // allows parent object to control fan mode
137 : ObjexxFCL::Optional<Real64 const> PartLoadRatio, // part load ratio (for single speed cycling unit)
138 : ObjexxFCL::Optional<Real64 const> OnOffAFR, // ratio of compressor on airflow to compressor off airflow
139 : ObjexxFCL::Optional<Real64 const> CoilCoolingHeatingPLRRatio, // used for cycling fan RH control
140 : ObjexxFCL::Optional<Real64 const> MaxCap, // maximum cooling capacity of VRF terminal units
141 : ObjexxFCL::Optional<Real64 const> CompCyclingRatio // cycling ratio of VRF condenser connected to this TU
142 : )
143 : {
144 :
145 : // SUBROUTINE INFORMATION:
146 : // AUTHOR Fred Buhl
147 : // DATE WRITTEN May 2000
148 : // MODIFIED Don Shirey, Sept 2000, October 2001, June 2005
149 :
150 : // PURPOSE OF THIS SUBROUTINE:
151 : // Manages the simulation of a single speed on/off DX coil.
152 :
153 : // Using/Aliasing
154 :
155 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
156 : int DXCoilNum; // index of fan coil unit being simulated
157 : Real64 AirFlowRatio; // ratio of compressor on airflow to compressor off airflow
158 : Real64 CompCycRatio; // compressor cycling ratio of VRF condenser
159 :
160 : // First time SimDXCoil is called, get the input for all the DX coils (condensing units)
161 47491188 : if (state.dataDXCoils->GetCoilsInputFlag) {
162 0 : GetDXCoils(state);
163 0 : state.dataDXCoils->GetCoilsInputFlag = false; // Set GetInputFlag false so you don't get coil inputs again
164 : }
165 :
166 47491188 : if (CompIndex == 0) {
167 22 : DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
168 22 : if (DXCoilNum == 0) {
169 0 : ShowFatalError(state, format("DX Coil not found={}", CompName));
170 : }
171 22 : CompIndex = DXCoilNum;
172 : } else {
173 47491166 : DXCoilNum = CompIndex;
174 47491166 : if (DXCoilNum > state.dataDXCoils->NumDXCoils || DXCoilNum < 1) {
175 0 : ShowFatalError(state,
176 0 : format("SimDXCoil: Invalid CompIndex passed={}, Number of DX Coils={}, Coil name={}",
177 : DXCoilNum,
178 0 : state.dataDXCoils->NumDXCoils,
179 : CompName));
180 : }
181 47491166 : if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
182 827 : if (!CompName.empty() && CompName != state.dataDXCoils->DXCoil(DXCoilNum).Name) {
183 0 : ShowFatalError(state,
184 0 : format("SimDXCoil: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
185 : DXCoilNum,
186 : CompName,
187 0 : state.dataDXCoils->DXCoil(DXCoilNum).Name));
188 : }
189 827 : state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
190 : }
191 : }
192 :
193 47491188 : if (present(OnOffAFR)) {
194 43615116 : AirFlowRatio = OnOffAFR;
195 : } else {
196 3876072 : AirFlowRatio = 1.0;
197 : }
198 :
199 47491188 : if (present(CompCyclingRatio)) {
200 1516035 : CompCycRatio = CompCyclingRatio;
201 : } else {
202 45975153 : CompCycRatio = 1.0;
203 : }
204 :
205 : // Initialize the DX coil unit
206 47491188 : InitDXCoil(state, DXCoilNum);
207 :
208 : // Select the correct unit type
209 47491188 : switch (state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType_Num) { // Autodesk:OPTIONAL PartLoadRatio, MaxCap used in this block without PRESENT check
210 36196184 : case HVAC::CoilDX_CoolingSingleSpeed: {
211 36196184 : if (present(CoilCoolingHeatingPLRRatio)) {
212 30229503 : CalcDoe2DXCoil(state, DXCoilNum, compressorOp, FirstHVACIteration, PartLoadRatio, fanOp, _, AirFlowRatio, CoilCoolingHeatingPLRRatio);
213 : } else {
214 5966681 : CalcDoe2DXCoil(state, DXCoilNum, compressorOp, FirstHVACIteration, PartLoadRatio, fanOp, _, AirFlowRatio);
215 : }
216 36196184 : } break;
217 5887090 : case HVAC::CoilDX_HeatingEmpirical: {
218 5887090 : CalcDXHeatingCoil(state, DXCoilNum, PartLoadRatio, fanOp, AirFlowRatio);
219 5887090 : } break;
220 631844 : case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
221 : case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
222 : // call the HPWHDXCoil routine to calculate water side performance set up the DX coil info for air-side calcs
223 631844 : CalcHPWHDXCoil(state, DXCoilNum, PartLoadRatio);
224 : // CALL CalcDoe2DXCoil(state, DXCoilNum, compressorOp, FirstHVACIteration,PartLoadRatio), perform air-side calculations
225 631844 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp);
226 631844 : } break;
227 1704059 : case HVAC::CoilVRF_Cooling: {
228 1704059 : CalcVRFCoolingCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, CompCycRatio, _, AirFlowRatio, MaxCap);
229 1704059 : } break;
230 1704059 : case HVAC::CoilVRF_Heating: {
231 1704059 : CalcDXHeatingCoil(state, DXCoilNum, PartLoadRatio, fanOp, AirFlowRatio, MaxCap);
232 1704059 : } break;
233 683976 : case HVAC::CoilVRF_FluidTCtrl_Cooling: {
234 683976 : CalcVRFCoolingCoil_FluidTCtrl(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, CompCycRatio, _, _);
235 683976 : } break;
236 683976 : case HVAC::CoilVRF_FluidTCtrl_Heating: {
237 683976 : CalcVRFHeatingCoil_FluidTCtrl(state, compressorOp, DXCoilNum, PartLoadRatio, fanOp, _, MaxCap);
238 683976 : } break;
239 0 : default: {
240 0 : ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
241 0 : ShowContinueError(state, format("Invalid DX Coil Type={}", state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType));
242 0 : ShowFatalError(state, "Preceding condition causes termination.");
243 0 : } break;
244 : }
245 :
246 : // Update the unit outlet nodes
247 47491188 : UpdateDXCoil(state, DXCoilNum);
248 :
249 : // Report the result of the simulation
250 47491188 : ReportDXCoil(state, DXCoilNum);
251 47491188 : }
252 :
253 15913849 : void SimDXCoilMultiSpeed(EnergyPlusData &state,
254 : std::string_view CompName, // name of the fan coil unit
255 : Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) /
256 : Real64 const CycRatio, // cycling part load ratio for variable speed
257 : int &CompIndex,
258 : ObjexxFCL::Optional_int_const SpeedNum, // Speed number for multispeed cooling coil onlyn
259 : ObjexxFCL::Optional<HVAC::FanOp const> fanOp, // Fan operation mode
260 : HVAC::CompressorOp compressorOp, // Compressor on/off; 1=on, 0=off
261 : ObjexxFCL::Optional_int_const SingleMode // Single mode operation Yes/No; 1=Yes, 0=No
262 : )
263 : {
264 :
265 : // SUBROUTINE INFORMATION:
266 : // AUTHOR Fred Buhl
267 : // DATE WRITTEN September 2002
268 : // MODIFIED Lixing Gu, Sep. 2007
269 :
270 : // PURPOSE OF THIS SUBROUTINE:
271 : // Manages the simulation of a multi speed DX coil.
272 :
273 : // Using/Aliasing
274 :
275 : // Locals
276 : // SUBROUTINE ARGUMENT DEFINITIONS:
277 : // (CompressorSpeedMax - CompressorSpeedMin)
278 : // for variable speed or 2 speed compressors
279 : // or 2 speed compressors
280 :
281 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
282 : int DXCoilNum; // index of fan coil unit being simulated
283 : int SingleModeOper; // SingleMode Operation
284 :
285 : // First time SimDXCoil is called, get the input for all the DX coils (condensing units)
286 15913849 : if (state.dataDXCoils->GetCoilsInputFlag) {
287 0 : GetDXCoils(state);
288 0 : state.dataDXCoils->GetCoilsInputFlag = false; // Set GetInputFlag false so you don't get coil inputs again
289 : }
290 :
291 : // find correct DX Coil
292 :
293 15913849 : if (CompIndex == 0) {
294 0 : DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
295 0 : if (DXCoilNum == 0) {
296 0 : ShowFatalError(state, format("DX Coil not found={}", CompName));
297 : }
298 0 : CompIndex = DXCoilNum;
299 : } else {
300 15913849 : DXCoilNum = CompIndex;
301 15913849 : if (DXCoilNum > state.dataDXCoils->NumDXCoils || DXCoilNum < 1) {
302 0 : ShowFatalError(state,
303 0 : format("SimDXCoilMultiSpeed: Invalid CompIndex passed={}, Number of DX Coils={}, Coil name={}",
304 : DXCoilNum,
305 0 : state.dataDXCoils->NumDXCoils,
306 : CompName));
307 : }
308 15913849 : if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
309 138 : if (!CompName.empty() && CompName != state.dataDXCoils->DXCoil(DXCoilNum).Name) {
310 0 : ShowFatalError(state,
311 0 : format("SimDXCoilMultiSpeed: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
312 : DXCoilNum,
313 : CompName,
314 0 : state.dataDXCoils->DXCoil(DXCoilNum).Name));
315 : }
316 138 : state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
317 : }
318 : }
319 :
320 15913849 : if (present(SingleMode)) {
321 9026329 : SingleModeOper = SingleMode;
322 : } else {
323 6887520 : SingleModeOper = 0;
324 : }
325 :
326 : // Initialize the DX coil unit
327 15913849 : InitDXCoil(state, DXCoilNum);
328 :
329 : // Select the correct unit type
330 15913849 : switch (state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType_Num) {
331 2186570 : case HVAC::CoilDX_CoolingTwoSpeed: {
332 2186570 : CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio);
333 2186570 : } break;
334 6868303 : case HVAC::CoilDX_MultiSpeedCooling: {
335 6868303 : if (present(SpeedNum))
336 6868303 : CalcMultiSpeedDXCoilCooling(state,
337 : DXCoilNum,
338 : SpeedRatio,
339 : CycRatio,
340 : SpeedNum,
341 : fanOp,
342 : compressorOp,
343 : SingleModeOper); // Autodesk:OPTIONAL fanOp, CompressorOp used without PRESENT check
344 :
345 6868303 : } break;
346 6858976 : case HVAC::CoilDX_MultiSpeedHeating: {
347 6858976 : if (present(SpeedNum))
348 6858976 : CalcMultiSpeedDXCoilHeating(state,
349 : DXCoilNum,
350 : SpeedRatio,
351 : CycRatio,
352 : SpeedNum,
353 : fanOp,
354 : SingleModeOper); // Autodesk:OPTIONAL fanOp used without PRESENT check
355 :
356 6858976 : } break;
357 0 : default: {
358 0 : ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
359 0 : ShowContinueError(state, format("Invalid DX Coil Type={}", state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType));
360 0 : ShowFatalError(state, "Preceding condition causes termination.");
361 0 : } break;
362 : }
363 :
364 : // Update the unit outlet nodes
365 15913849 : UpdateDXCoil(state, DXCoilNum);
366 :
367 : // Report the result of the simulation
368 15913849 : ReportDXCoil(state, DXCoilNum);
369 15913849 : }
370 :
371 130449 : void SimDXCoilMultiMode(EnergyPlusData &state,
372 : std::string_view CompName, // name of the fan coil unit
373 : [[maybe_unused]] HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off !unused1208
374 : bool const FirstHVACIteration, // true if first hvac iteration
375 : Real64 const PartLoadRatio, // part load ratio
376 : HVAC::CoilMode const DehumidMode, // dehumidification mode (0=normal, 1=enhanced)
377 : int &CompIndex,
378 : HVAC::FanOp const fanOp // allows parent object to control fan mode
379 : )
380 : {
381 :
382 : // SUBROUTINE INFORMATION:
383 : // AUTHOR M. J. Witte (based on SimDXCoilMultiSpeed by Fred Buhl)
384 : // DATE WRITTEN February 2005
385 : // MODIFIED April 2010, Chandan sharma, added basin heater
386 :
387 : // PURPOSE OF THIS SUBROUTINE:
388 : // Manages the simulation of a DX coil with multiple performance modes, such as
389 : // multiple stages, or sub-cool reheat for humidity control.
390 :
391 : // Using/Aliasing
392 :
393 : // SUBROUTINE PARAMETER DEFINITIONS:
394 : static constexpr std::string_view RoutineName("SimDXCoilMultiMode");
395 :
396 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
397 : int DXCoilNum; // index of coil being simulated
398 : int PerfMode; // Performance mode for MultiMode DX coil; Always 1 for other coil types
399 : // 1-2=normal mode: 1=stage 1 only, 2=stage 1&2
400 : // 3-4=enhanced dehumidification mode: 3=stage 1 only, 4=stage 1&2
401 : Real64 AirMassFlow; // Dry air mass flow rate through coil [kg/s]
402 :
403 : Real64 S1OutletAirTemp; // Stage 1 Outlet air dry bulb temp [C]
404 : Real64 S1OutletAirHumRat; // Stage 1 Outlet air humidity ratio [kgWater/kgDryAir]
405 : Real64 S1OutletAirEnthalpy; // Stage 1 Outlet air enthalpy
406 : Real64 S1PLR; // Stage 1 Ratio of actual sensible cooling load to
407 : // steady-state sensible cooling capacity
408 : Real64 S1TotalCoolingEnergyRate; // Stage 1 Total cooling rate [W]
409 : Real64 S1SensCoolingEnergyRate; // Stage 1 Sensible cooling rate [W]
410 : Real64 S1LatCoolingEnergyRate; // Stage 1 Latent cooling rate [W]
411 : Real64 S1ElecCoolingPower; // Stage 1 Electric power input [W]
412 130449 : Real64 S1RuntimeFraction(0.0); // Stage 1 Run time fraction (overlaps with stage1&2 run time)
413 : Real64 S1EvapCondPumpElecPower; // Stage 1 Evaporative condenser pump electric power input [W]
414 : Real64 S1EvapWaterConsumpRate; // Stage 1 Evap condenser water consumption rate [m3/s]
415 : Real64 S1CrankcaseHeaterPower; // Stage 1 Report variable for average crankcase heater power [W]
416 : Real64 S1FFullLoadOutAirTemp; // Stage 1 Full load outlet temperature [C]
417 : Real64 S1FullLoadOutAirHumRat; // Stage 1 Full load outlet humidity ratio [kgWater/kgDryAir]
418 :
419 : Real64 S12OutletAirTemp; // Stage 1&2 Outlet air dry bulb temp [C]
420 : Real64 S12OutletAirHumRat; // Stage 1&2 Outlet air humidity ratio [kgWater/kgDryAir]
421 : Real64 S12OutletAirEnthalpy; // Stage 1&2 Outlet air enthalpy
422 : // ! steady-state sensible cooling capacity
423 : Real64 S12TotalCoolingEnergyRate; // Stage 1&2 Total cooling rate [W]
424 : Real64 S12SensCoolingEnergyRate; // Stage 1&2 Sensible cooling rate [W]
425 : Real64 S12LatCoolingEnergyRate; // Stage 1&2 Latent cooling rate [W]
426 : Real64 S12ElecCoolingPower; // Stage 1&2 Electric power input [W]
427 : Real64 S12ElecCoolFullLoadPower; // Stage 1&2 Electric power input at full load (PLR=1) [W]
428 130449 : Real64 S12RuntimeFraction(0.0); // Stage 1&2 Run time fraction (overlaps with stage1 run time)
429 : Real64 S12EvapCondPumpElecPower; // Stage 1&2 Evaporative condenser pump electric power input [W]
430 : Real64 S12EvapWaterConsumpRate; // Stage 1&2 Evap condenser water consumption rate [m3/s]
431 : Real64 S12CrankcaseHeaterPower; // Stage 1&2 Report variable for average crankcase heater power [W]
432 : Real64 S2PLR; // Stage 2 Ratio of actual sensible cooling load to
433 : // steady-state sensible cooling capacity
434 : Real64 TSat; // calculation to avoid calling psych routines twice
435 : Real64 NodePress; // Pressure at condenser inlet node (Pa)
436 :
437 : // First time SimDXCoil is called, get the input for all the DX coils (condensing units)
438 130449 : if (state.dataDXCoils->GetCoilsInputFlag) {
439 0 : GetDXCoils(state);
440 0 : state.dataDXCoils->GetCoilsInputFlag = false; // Set GetInputFlag false so you don't get coil inputs again
441 : }
442 :
443 : // find correct DX Coil
444 130449 : if (CompIndex == 0) {
445 2 : DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
446 2 : if (DXCoilNum == 0) {
447 0 : ShowFatalError(state, format("DX Coil not found={}", CompName));
448 : }
449 2 : CompIndex = DXCoilNum;
450 : } else {
451 130447 : DXCoilNum = CompIndex;
452 130447 : if (DXCoilNum > state.dataDXCoils->NumDXCoils || DXCoilNum < 1) {
453 0 : ShowFatalError(state,
454 0 : format("SimDXCoilMultiMode: Invalid CompIndex passed={}, Number of DX Coils={}, Coil name={}",
455 : DXCoilNum,
456 0 : state.dataDXCoils->NumDXCoils,
457 : CompName));
458 : }
459 130447 : if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
460 11 : if ((CompName != "") && (CompName != state.dataDXCoils->DXCoil(DXCoilNum).Name)) {
461 0 : ShowFatalError(state,
462 0 : format("SimDXCoilMultiMode: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
463 : DXCoilNum,
464 : CompName,
465 0 : state.dataDXCoils->DXCoil(DXCoilNum).Name));
466 : }
467 11 : state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
468 : }
469 : }
470 :
471 : // Initialize the DX coil unit
472 130449 : InitDXCoil(state, DXCoilNum);
473 :
474 130449 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
475 : // Select the correct unit type
476 130449 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
477 : // Initialize local variables
478 130449 : S1RuntimeFraction = 0.0;
479 130449 : S1OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
480 130449 : S1OutletAirHumRat = thisDXCoil.InletAirHumRat;
481 130449 : S1OutletAirTemp = thisDXCoil.InletAirTemp;
482 130449 : S1ElecCoolingPower = 0.0;
483 130449 : S1TotalCoolingEnergyRate = 0.0;
484 130449 : S1SensCoolingEnergyRate = 0.0;
485 130449 : S1LatCoolingEnergyRate = 0.0;
486 130449 : S1CrankcaseHeaterPower = 0.0;
487 130449 : S1EvapWaterConsumpRate = 0.0;
488 130449 : S1EvapCondPumpElecPower = 0.0;
489 :
490 130449 : S12RuntimeFraction = 0.0;
491 130449 : S12OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
492 130449 : S12OutletAirHumRat = thisDXCoil.InletAirHumRat;
493 130449 : S12OutletAirTemp = thisDXCoil.InletAirTemp;
494 130449 : S12ElecCoolingPower = 0.0;
495 130449 : S12TotalCoolingEnergyRate = 0.0;
496 130449 : S12SensCoolingEnergyRate = 0.0;
497 130449 : S12LatCoolingEnergyRate = 0.0;
498 130449 : S12CrankcaseHeaterPower = 0.0;
499 130449 : S12EvapWaterConsumpRate = 0.0;
500 130449 : S12EvapCondPumpElecPower = 0.0;
501 :
502 130449 : thisDXCoil.DehumidificationMode = DehumidMode;
503 130449 : if ((int)DehumidMode > thisDXCoil.NumDehumidModes) {
504 0 : ShowFatalError(state,
505 0 : format("{} \"{}\" - Requested enhanced dehumidification mode not available.", thisDXCoil.DXCoilType, thisDXCoil.Name));
506 : }
507 :
508 : // If a single-stage coil OR If part load is zero,
509 : // run stage 1 at zero part load to set leaving conditions
510 130449 : if ((thisDXCoil.NumCapacityStages == 1) || (PartLoadRatio <= 0.0)) {
511 : // Run stage 1 at its part load
512 78555 : PerfMode = (int)DehumidMode * 2 + 1; // This. This is not good. Don't do math on enums.
513 78555 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, PerfMode);
514 78555 : S1PLR = PartLoadRatio;
515 78555 : S2PLR = 0.0;
516 : } else {
517 : // If a two-stage coil
518 : // Run stage 1 at full load
519 51894 : PerfMode = (int)DehumidMode * 2 + 1;
520 51894 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, 1.0, fanOp, PerfMode);
521 51894 : S1SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
522 51894 : if (S1SensCoolingEnergyRate > 0.0) {
523 51894 : S1PLR = PartLoadRatio;
524 : } else {
525 0 : S1PLR = 0.0;
526 : }
527 : // Run stage 1+2 at full load
528 51894 : if (thisDXCoil.NumCapacityStages >= 2) {
529 51894 : PerfMode = (int)DehumidMode * 2 + 2;
530 51894 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, 1.0, fanOp, PerfMode);
531 51894 : S12SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
532 51894 : S12ElecCoolFullLoadPower = thisDXCoil.ElecCoolingPower;
533 : }
534 :
535 : // Determine run-time fractions for each stage based on sensible capacities
536 : // Relationships:
537 : // Stage 1 PLR1= Load/Cap1
538 : // Stage1+2 PLR12= Load/Cap12
539 : // Stage 2 PLR2= (Load-Cap1)/(Cap2)
540 : // PLR = Load/(Cap1+Cap2)
541 : // Load= PLR*(Cap1+Cap2)
542 : // PLR1= MIN(1,(PLR*(Cap1+Cap2)/Cap1))
543 : // PLR2= MIN(1,((PLR*(Cap1+Cap2)-Cap1)/Cap2))
544 :
545 51894 : if (S1SensCoolingEnergyRate > 0.0) {
546 51894 : S1PLR = PartLoadRatio * S12SensCoolingEnergyRate / S1SensCoolingEnergyRate;
547 : } else {
548 0 : S1PLR = 0.0;
549 : }
550 51894 : S1PLR = min(1.0, S1PLR);
551 51894 : S1PLR = max(0.0, S1PLR);
552 51894 : if ((S12SensCoolingEnergyRate - S1SensCoolingEnergyRate) > 0.0) {
553 51894 : S2PLR = (PartLoadRatio * S12SensCoolingEnergyRate - S1SensCoolingEnergyRate) / (S12SensCoolingEnergyRate - S1SensCoolingEnergyRate);
554 : } else {
555 0 : S2PLR = 0.0;
556 : }
557 51894 : S2PLR = min(1.0, S2PLR);
558 51894 : S2PLR = max(0.0, S2PLR);
559 :
560 : // Run stage 1 at its part load
561 51894 : PerfMode = (int)DehumidMode * 2 + 1;
562 51894 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, S1PLR, fanOp, PerfMode);
563 : }
564 : // For stage-1 only operation, all outputs are set by CalcDoe2DXCoil.
565 : // No further adjustments are necessary.
566 :
567 : // Run stage 2 if needed and available
568 130449 : if ((S2PLR > 0.0) && (thisDXCoil.NumCapacityStages >= 2)) {
569 : // Store stage 1 outputs
570 46420 : S1RuntimeFraction = thisDXCoil.CoolingCoilRuntimeFraction;
571 46420 : S1OutletAirEnthalpy = thisDXCoil.OutletAirEnthalpy;
572 46420 : S1OutletAirHumRat = thisDXCoil.OutletAirHumRat;
573 46420 : S1OutletAirTemp = thisDXCoil.OutletAirTemp;
574 46420 : S1ElecCoolingPower = thisDXCoil.ElecCoolingPower;
575 46420 : S1TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate;
576 46420 : S1SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
577 46420 : S1LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate;
578 46420 : S1CrankcaseHeaterPower = thisDXCoil.CrankcaseHeaterPower;
579 46420 : S1EvapWaterConsumpRate = thisDXCoil.EvapWaterConsumpRate;
580 46420 : S1EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecPower;
581 :
582 : // Save first stage full load outlet conditions to pass to heat recovery
583 46420 : S1FFullLoadOutAirTemp = state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum);
584 46420 : S1FullLoadOutAirHumRat = state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum);
585 :
586 : // Run stage 1+2 at its part load
587 46420 : PerfMode = (int)DehumidMode * 2 + 2;
588 46420 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, S2PLR, fanOp, PerfMode);
589 46420 : S12RuntimeFraction = thisDXCoil.CoolingCoilRuntimeFraction;
590 46420 : S12OutletAirEnthalpy = thisDXCoil.OutletAirEnthalpy;
591 46420 : S12OutletAirHumRat = thisDXCoil.OutletAirHumRat;
592 46420 : S12OutletAirTemp = thisDXCoil.OutletAirTemp;
593 46420 : S12ElecCoolingPower = thisDXCoil.ElecCoolingPower;
594 46420 : S12TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate;
595 46420 : S12SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
596 46420 : S12LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate;
597 46420 : S12CrankcaseHeaterPower = thisDXCoil.CrankcaseHeaterPower;
598 46420 : S12EvapWaterConsumpRate = thisDXCoil.EvapWaterConsumpRate;
599 46420 : S12EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecPower;
600 :
601 : // Determine combined performance
602 46420 : thisDXCoil.OutletAirEnthalpy = (1.0 - S2PLR) * S1OutletAirEnthalpy + S2PLR * S12OutletAirEnthalpy;
603 46420 : thisDXCoil.OutletAirHumRat = (1.0 - S2PLR) * S1OutletAirHumRat + S2PLR * S12OutletAirHumRat;
604 46420 : thisDXCoil.OutletAirTemp = PsyTdbFnHW(thisDXCoil.OutletAirEnthalpy, thisDXCoil.OutletAirHumRat);
605 : // Check for saturation error and modify temperature at constant enthalpy
606 46420 : if (thisDXCoil.CondenserInletNodeNum(PerfMode) != 0) {
607 0 : NodePress = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(PerfMode)).Press;
608 : // If node is not connected to anything, pressure = default, use weather data
609 0 : if (NodePress == state.dataLoopNodes->DefaultNodeValues.Press) NodePress = state.dataEnvrn->OutBaroPress;
610 0 : TSat = PsyTsatFnHPb(state, thisDXCoil.OutletAirEnthalpy, NodePress, RoutineName);
611 0 : if (thisDXCoil.OutletAirTemp < TSat) {
612 0 : thisDXCoil.OutletAirTemp = TSat;
613 : }
614 0 : thisDXCoil.OutletAirHumRat = PsyWFnTdbH(state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirEnthalpy, RoutineName);
615 : } else {
616 46420 : TSat = PsyTsatFnHPb(state, thisDXCoil.OutletAirEnthalpy, state.dataEnvrn->OutBaroPress, RoutineName);
617 46420 : if (thisDXCoil.OutletAirTemp < TSat) {
618 0 : thisDXCoil.OutletAirTemp = TSat;
619 : }
620 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
621 : // IF(DXCoil(DXCoilNum)%OutletAirTemp .LT. PsyTsatFnHPb(DXCoil(DXCoilNum)%OutletAirEnthalpy, &
622 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)) THEN
623 : // DXCoil(DXCoilNum)%OutletAirTemp = PsyTsatFnHPb(DXCoil(DXCoilNum)%OutletAirEnthalpy, &
624 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)
625 46420 : thisDXCoil.OutletAirHumRat = PsyWFnTdbH(state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirEnthalpy, RoutineName);
626 : }
627 :
628 : // DXCoil(DXCoilNum)%ElecCoolingPower = (1-S12RuntimeFraction)*S1ElecCoolingPower &
629 : // +S12RuntimeFraction*S12ElecCoolingPower
630 : // S12ElecCoolingPower overstates S1 portion of power, because it is also adjust by S12PLR
631 : // So, must make an adjustment for S12ElecCoolingPower/S12ElecCoolFullLoadPower
632 : // when subtracting off S1ElecCoolingPower
633 46420 : if (S12ElecCoolFullLoadPower > 0.0) {
634 46420 : thisDXCoil.ElecCoolingPower =
635 46420 : S1RuntimeFraction * S1ElecCoolingPower +
636 46420 : S12RuntimeFraction * (S12ElecCoolingPower - S1ElecCoolingPower * S12ElecCoolingPower / S12ElecCoolFullLoadPower);
637 : } else {
638 0 : thisDXCoil.ElecCoolingPower = 0.0;
639 : }
640 :
641 46420 : thisDXCoil.CoolingCoilRuntimeFraction = S1RuntimeFraction;
642 :
643 46420 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
644 46420 : CalcComponentSensibleLatentOutput(AirMassFlow,
645 : thisDXCoil.InletAirTemp,
646 : thisDXCoil.InletAirHumRat,
647 : thisDXCoil.OutletAirTemp,
648 : thisDXCoil.OutletAirHumRat,
649 46420 : thisDXCoil.SensCoolingEnergyRate,
650 46420 : thisDXCoil.LatCoolingEnergyRate,
651 46420 : thisDXCoil.TotalCoolingEnergyRate);
652 :
653 46420 : thisDXCoil.EvapWaterConsumpRate = (1.0 - S12RuntimeFraction) * S1EvapWaterConsumpRate + S12RuntimeFraction * S12EvapWaterConsumpRate;
654 46420 : thisDXCoil.EvapCondPumpElecPower = (1.0 - S12RuntimeFraction) * S1EvapCondPumpElecPower + S12RuntimeFraction * S12EvapCondPumpElecPower;
655 :
656 : // Stage 1 runtime sets the crankcase heater power
657 46420 : thisDXCoil.CrankcaseHeaterPower = S1CrankcaseHeaterPower;
658 :
659 46420 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
660 46420 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
661 :
662 : // calculate average full load outlet conditions for second stage operation
663 46420 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) =
664 46420 : (1.0 - S2PLR) * S1FFullLoadOutAirTemp + S2PLR * state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum);
665 46420 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) =
666 46420 : (1.0 - S2PLR) * S1FullLoadOutAirHumRat + S2PLR * state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum);
667 :
668 : } // End if stage 2 is operating
669 :
670 : // set the part load ratio and heat reclaim capacity for use by desuperheater heating coils
671 130449 : thisDXCoil.PartLoadRatio = S1PLR;
672 130449 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = S1PLR;
673 :
674 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
675 130449 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
676 :
677 130449 : thisDXCoil.CoolingCoilStg2RuntimeFrac = S12RuntimeFraction;
678 :
679 : // Calculate basin heater power
680 130449 : CalcBasinHeaterPowerForMultiModeDXCoil(state, DXCoilNum, DehumidMode);
681 : } else {
682 0 : ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
683 0 : ShowContinueError(state, format("Invalid DX Coil Type={}", thisDXCoil.DXCoilType));
684 0 : ShowFatalError(state, "Preceding condition causes termination.");
685 : }
686 :
687 : // Update the unit outlet nodes
688 130449 : UpdateDXCoil(state, DXCoilNum);
689 :
690 : // Report the result of the simulation
691 130449 : ReportDXCoil(state, DXCoilNum);
692 130449 : }
693 :
694 247 : void GetDXCoils(EnergyPlusData &state)
695 : {
696 :
697 : // SUBROUTINE INFORMATION:
698 : // AUTHOR Fred Buhl
699 : // DATE WRITTEN May 2000
700 : // MODIFIED Aug 2000, Don Shirey, Sept 2000, Feb/Oct 2001, Sept 2003, Jan/July 2004
701 : // Feb 2005, M. J. Witte, GARD Analytics, Inc., Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
702 : // May 2005, Rich Raustad, FSEC, Added COIL:DX:HeatPumpWaterHeater
703 : // Jun 2007, L. Gu, FSEC, Added new coil type COIL:DX:MULTISPEED:COOLING and COIL:DX:MULTISPEED:HEATING
704 : // Apr 2010, Chandan Sharma, FSEC, added basin heater inputs
705 : // Jul 2015, RP Zhang, XF Pang, LBNL, Added new coil type for VRF-FluidTemperatureControl Model
706 :
707 : // PURPOSE OF THIS SUBROUTINE:
708 : // Obtains input data for DX coils and stores it in DX coil data structure
709 :
710 : // METHODOLOGY EMPLOYED:
711 : // Uses "Get" routines to read in data.
712 :
713 : // Using/Aliasing
714 : using BranchNodeConnections::TestCompSet;
715 : using Curve::checkCurveIsNormalizedToOne;
716 : using Curve::CurveValue;
717 : using Curve::GetCurveIndex;
718 : using DataSizing::AutoSize;
719 : using EMSManager::ManageEMS;
720 :
721 : using GlobalNames::VerifyUniqueCoilName;
722 : using NodeInputManager::GetOnlySingleNode;
723 : using OutAirNodeManager::CheckOutAirNodeNumber;
724 : using ScheduleManager::GetScheduleIndex;
725 : using WaterManager::SetupTankDemandComponent;
726 : using WaterManager::SetupTankSupplyComponent;
727 :
728 : // SUBROUTINE PARAMETER DEFINITIONS:
729 : static constexpr std::string_view RoutineName("GetDXCoils: "); // include trailing blank space
730 247 : constexpr Real64 minOATCompDXCooling = -25.0; // min OAT for compressor operation for DX cooling coils
731 :
732 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
733 : int DXCoilIndex; // loop index
734 : int DXCoilNum; // current DX coil number
735 : int NumAlphas; // Number of alphas in input
736 : int NumNumbers; // Number of numeric items in input
737 247 : Array1D_string Alphas2; // Alpha input items for object
738 247 : Array1D<Real64> Numbers2; // Numeric input items for object
739 247 : Array1D_string cAlphaFields2; // Alpha field names
740 247 : Array1D_string cNumericFields2; // Numeric field names
741 247 : Array1D_bool lAlphaBlanks2; // Logical array, alpha field input BLANK = .TRUE.
742 247 : Array1D_bool lNumericBlanks2; // Logical array, numeric field input BLANK = .TRUE.
743 : int NumAlphas2; // Number of alphas in input for performance object
744 : int NumNumbers2; // Number of numeric items in input for performance object
745 : int IOStatus; // Input status returned from GetObjectItem
746 247 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
747 : int DXHPWaterHeaterCoilNum; // Loop index for 1,NumDXHeatPumpWaterHeaterCoils
748 : int CapacityStageNum; // Loop index for 1,Number of capacity stages
749 : int DehumidModeNum; // Loop index for 1,Number of enhanced dehumidification modes
750 : int PerfModeNum; // Performance mode index
751 : int PerfObjectNum; // Item number for performance object
752 : int AlphaIndex; // Index for current alpha field
753 247 : std::string CurrentModuleObject; // Object type for getting and error messages
754 247 : std::string PerfObjectType; // Performance object type for getting and error messages
755 247 : std::string PerfObjectName; // Performance object name for getting and error messages
756 : Real64 InletAirTemp; // Used to pass proper inlet air temp to HPWH DX coil performance curves
757 : Real64 InletWaterTemp; // Used to pass proper inlet water temp to HPWH DX coil performance curves
758 : int I; // Index of speeds
759 : Real64 CurveVal; // Used to verify modifier curves equal 1 at rated conditions
760 247 : Array1D_string Alphas; // Alpha input items for object
761 247 : Array1D_string cAlphaFields; // Alpha field names
762 247 : Array1D_string cNumericFields; // Numeric field names
763 247 : Array1D<Real64> Numbers; // Numeric input items for object
764 247 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
765 247 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
766 247 : int MaxNumbers(0); // Maximum number of numeric input fields
767 247 : int MaxAlphas(0); // Maximum number of alpha input fields
768 247 : int TotalArgs(0); // Total number of alpha and numeric arguments (max) for a
769 : // certain object in the input file
770 : Real64 MinCurveVal; // used for testing PLF curve output
771 : Real64 MinCurvePLR; // used for testing PLF curve output
772 : Real64 MaxCurveVal; // used for testing PLF curve output
773 : Real64 MaxCurvePLR; // used for testing PLF curve output
774 : Real64 CurveInput; // index used for testing PLF curve output
775 :
776 : // find number of each type of DX coil and calculate the total number
777 247 : state.dataDXCoils->NumDoe2DXCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:SingleSpeed");
778 247 : state.dataDXCoils->NumDXHeatingCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:DX:SingleSpeed");
779 247 : state.dataDXCoils->NumDXMulSpeedCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:TwoSpeed");
780 494 : state.dataDXCoils->NumDXMulModeCoils =
781 247 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:TwoStageWithHumidityControlMode");
782 494 : state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils =
783 247 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped));
784 494 : state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils =
785 247 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped));
786 247 : state.dataDXCoils->NumDXMulSpeedCoolCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:MultiSpeed");
787 247 : state.dataDXCoils->NumDXMulSpeedHeatCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:DX:MultiSpeed");
788 494 : state.dataDXCoils->NumVRFCoolingCoils =
789 247 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling));
790 494 : state.dataDXCoils->NumVRFHeatingCoils =
791 247 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating));
792 494 : state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils =
793 247 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling));
794 494 : state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils =
795 247 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating));
796 :
797 247 : state.dataDXCoils->NumDXCoils = state.dataDXCoils->NumDoe2DXCoils + state.dataDXCoils->NumDXHeatingCoils + state.dataDXCoils->NumDXMulSpeedCoils +
798 247 : state.dataDXCoils->NumDXMulModeCoils + state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils +
799 247 : state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils + state.dataDXCoils->NumDXMulSpeedCoolCoils +
800 247 : state.dataDXCoils->NumDXMulSpeedHeatCoils + state.dataDXCoils->NumVRFCoolingCoils +
801 247 : state.dataDXCoils->NumVRFHeatingCoils + state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils +
802 247 : state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils;
803 :
804 : // Determine max number of alpha and numeric arguments for all objects being read, in order to allocate local arrays
805 247 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:SingleSpeed", TotalArgs, NumAlphas, NumNumbers);
806 247 : MaxNumbers = NumNumbers;
807 247 : MaxAlphas = NumAlphas;
808 247 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:DX:SingleSpeed", TotalArgs, NumAlphas, NumNumbers);
809 247 : MaxNumbers = max(MaxNumbers, NumNumbers);
810 247 : MaxAlphas = max(MaxAlphas, NumAlphas);
811 247 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:TwoSpeed", TotalArgs, NumAlphas, NumNumbers);
812 247 : MaxNumbers = max(MaxNumbers, NumNumbers);
813 247 : MaxAlphas = max(MaxAlphas, NumAlphas);
814 247 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
815 : state, "Coil:Cooling:DX:TwoStageWithHumidityControlMode", TotalArgs, NumAlphas, NumNumbers);
816 247 : MaxNumbers = max(MaxNumbers, NumNumbers);
817 247 : MaxAlphas = max(MaxAlphas, NumAlphas);
818 494 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
819 247 : state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped), TotalArgs, NumAlphas, NumNumbers);
820 247 : MaxNumbers = max(MaxNumbers, NumNumbers);
821 247 : MaxAlphas = max(MaxAlphas, NumAlphas);
822 494 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
823 247 : state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped), TotalArgs, NumAlphas, NumNumbers);
824 247 : MaxNumbers = max(MaxNumbers, NumNumbers);
825 247 : MaxAlphas = max(MaxAlphas, NumAlphas);
826 247 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:MultiSpeed", TotalArgs, NumAlphas, NumNumbers);
827 247 : MaxNumbers = max(MaxNumbers, NumNumbers);
828 247 : MaxAlphas = max(MaxAlphas, NumAlphas);
829 247 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:DX:MultiSpeed", TotalArgs, NumAlphas, NumNumbers);
830 247 : MaxNumbers = max(MaxNumbers, NumNumbers);
831 247 : MaxAlphas = max(MaxAlphas, NumAlphas);
832 494 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
833 247 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling), TotalArgs, NumAlphas, NumNumbers);
834 247 : MaxNumbers = max(MaxNumbers, NumNumbers);
835 247 : MaxAlphas = max(MaxAlphas, NumAlphas);
836 494 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
837 247 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating), TotalArgs, NumAlphas, NumNumbers);
838 247 : MaxNumbers = max(MaxNumbers, NumNumbers);
839 247 : MaxAlphas = max(MaxAlphas, NumAlphas);
840 494 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
841 247 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling), TotalArgs, NumAlphas, NumNumbers);
842 247 : MaxNumbers = max(MaxNumbers, NumNumbers);
843 247 : MaxAlphas = max(MaxAlphas, NumAlphas);
844 494 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
845 247 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating), TotalArgs, NumAlphas, NumNumbers);
846 247 : MaxNumbers = max(MaxNumbers, NumNumbers);
847 247 : MaxAlphas = max(MaxAlphas, NumAlphas);
848 247 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "CoilPerformance:DX:Cooling", TotalArgs, NumAlphas, NumNumbers);
849 247 : MaxNumbers = max(MaxNumbers, NumNumbers);
850 247 : MaxAlphas = max(MaxAlphas, NumAlphas);
851 :
852 247 : Alphas.allocate(MaxAlphas);
853 247 : cAlphaFields.allocate(MaxAlphas);
854 247 : cNumericFields.allocate(MaxNumbers);
855 247 : Numbers.dimension(MaxNumbers, 0.0);
856 247 : lAlphaBlanks.dimension(MaxAlphas, true);
857 247 : lNumericBlanks.dimension(MaxNumbers, true);
858 :
859 247 : Alphas2.allocate(MaxAlphas);
860 247 : cAlphaFields2.allocate(MaxAlphas);
861 247 : cNumericFields2.allocate(MaxNumbers);
862 247 : Numbers2.dimension(MaxNumbers, 0.0);
863 247 : lAlphaBlanks2.dimension(MaxAlphas, true);
864 247 : lNumericBlanks2.dimension(MaxNumbers, true);
865 :
866 : // allocate the data structure
867 :
868 : // Derived types
869 247 : state.dataDXCoils->DXCoil.allocate(state.dataDXCoils->NumDXCoils);
870 247 : state.dataDXCoils->DXCoilNumericFields.allocate(state.dataDXCoils->NumDXCoils);
871 247 : state.dataHeatBal->HeatReclaimDXCoil.allocate(state.dataDXCoils->NumDXCoils);
872 247 : state.dataDXCoils->CheckEquipName.dimension(state.dataDXCoils->NumDXCoils, true);
873 :
874 : // Module level variable arrays
875 247 : state.dataDXCoils->DXCoilOutletTemp.allocate(state.dataDXCoils->NumDXCoils);
876 247 : state.dataDXCoils->DXCoilOutletHumRat.allocate(state.dataDXCoils->NumDXCoils);
877 247 : state.dataDXCoils->DXCoilPartLoadRatio.allocate(state.dataDXCoils->NumDXCoils);
878 247 : state.dataDXCoils->DXCoilFanOp.allocate(state.dataDXCoils->NumDXCoils);
879 247 : state.dataDXCoils->DXCoilFullLoadOutAirTemp.allocate(state.dataDXCoils->NumDXCoils);
880 247 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat.allocate(state.dataDXCoils->NumDXCoils);
881 247 : state.dataDXCoils->DXCoilTotalCooling.allocate(state.dataDXCoils->NumDXCoils);
882 247 : state.dataDXCoils->DXCoilTotalHeating.allocate(state.dataDXCoils->NumDXCoils);
883 247 : state.dataDXCoils->DXCoilCoolInletAirWBTemp.allocate(state.dataDXCoils->NumDXCoils);
884 247 : state.dataDXCoils->DXCoilHeatInletAirDBTemp.allocate(state.dataDXCoils->NumDXCoils);
885 247 : state.dataDXCoils->DXCoilHeatInletAirWBTemp.allocate(state.dataDXCoils->NumDXCoils);
886 :
887 : // initialize the module level arrays
888 247 : state.dataDXCoils->DXCoilOutletTemp = 0.0;
889 247 : state.dataDXCoils->DXCoilOutletHumRat = 0.0;
890 247 : state.dataDXCoils->DXCoilPartLoadRatio = 0.0;
891 247 : state.dataDXCoils->DXCoilFanOp = HVAC::FanOp::Invalid;
892 247 : state.dataDXCoils->DXCoilFullLoadOutAirTemp = 0.0;
893 247 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat = 0.0;
894 :
895 : // initialize the coil counter
896 247 : DXCoilNum = 0;
897 :
898 : // Loop over the Doe2 DX Coils and get & load the data
899 247 : CurrentModuleObject = "Coil:Cooling:DX:SingleSpeed";
900 859 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDoe2DXCoils; ++DXCoilIndex) {
901 :
902 612 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
903 : CurrentModuleObject,
904 : DXCoilIndex,
905 : Alphas,
906 : NumAlphas,
907 : Numbers,
908 : NumNumbers,
909 : IOStatus,
910 : lNumericBlanks,
911 : lAlphaBlanks,
912 : cAlphaFields,
913 : cNumericFields);
914 :
915 612 : ++DXCoilNum;
916 : // allocate single performance mode for numeric field strings used for sizing routine
917 612 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
918 612 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
919 612 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
920 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
921 612 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
922 :
923 612 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
924 612 : thisDXCoil.Name = Alphas(1);
925 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
926 612 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
927 612 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
928 612 : thisDXCoil.DXCoilType = CurrentModuleObject;
929 612 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingSingleSpeed;
930 612 : thisDXCoil.Schedule = Alphas(2);
931 612 : if (lAlphaBlanks(2)) {
932 81 : thisDXCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
933 : } else {
934 531 : thisDXCoil.SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
935 531 : if (thisDXCoil.SchedPtr == 0) {
936 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
937 0 : ShowContinueError(state, format("...{}=\"{}\".", cAlphaFields(2), Alphas(2)));
938 0 : ErrorsFound = true;
939 : }
940 : }
941 612 : thisDXCoil.RatedTotCap(1) = Numbers(1);
942 612 : thisDXCoil.RatedSHR(1) = Numbers(2);
943 612 : thisDXCoil.RatedCOP(1) = Numbers(3);
944 612 : if (thisDXCoil.RatedCOP(1) <= 0.0) {
945 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
946 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(3), Numbers(3)));
947 0 : ErrorsFound = true;
948 : }
949 :
950 612 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(4);
951 612 : thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(5);
952 612 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(6);
953 :
954 612 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
955 612 : Alphas(3),
956 : ErrorsFound,
957 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
958 612 : Alphas(1),
959 : DataLoopNode::NodeFluidType::Air,
960 : DataLoopNode::ConnectionType::Inlet,
961 : NodeInputManager::CompFluidStream::Primary,
962 : ObjectIsNotParent);
963 :
964 612 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
965 612 : Alphas(4),
966 : ErrorsFound,
967 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
968 612 : Alphas(1),
969 : DataLoopNode::NodeFluidType::Air,
970 : DataLoopNode::ConnectionType::Outlet,
971 : NodeInputManager::CompFluidStream::Primary,
972 : ObjectIsNotParent);
973 :
974 612 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
975 :
976 612 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
977 612 : if (thisDXCoil.CCapFTemp(1) == 0) {
978 0 : if (lAlphaBlanks(5)) {
979 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
980 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
981 : } else {
982 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
983 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
984 : }
985 0 : ErrorsFound = true;
986 : } else {
987 : // Verify Curve Object, only legal type is BiQuadratic
988 1224 : ErrorsFound |= Curve::CheckCurveDims(state,
989 612 : thisDXCoil.CCapFTemp(1), // Curve index
990 : {2}, // Valid dimensions
991 : RoutineName, // Routine name
992 : CurrentModuleObject, // Object Type
993 : thisDXCoil.Name, // Object Name
994 612 : cAlphaFields(5)); // Field Name
995 :
996 612 : if (!ErrorsFound) {
997 612 : checkCurveIsNormalizedToOne(state,
998 1224 : std::string{RoutineName} + CurrentModuleObject,
999 612 : thisDXCoil.Name,
1000 612 : thisDXCoil.CCapFTemp(1),
1001 612 : cAlphaFields(5),
1002 612 : Alphas(5),
1003 : RatedInletWetBulbTemp,
1004 : RatedOutdoorAirTemp);
1005 : }
1006 : }
1007 :
1008 612 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
1009 612 : if (thisDXCoil.CCapFFlow(1) == 0) {
1010 0 : if (lAlphaBlanks(6)) {
1011 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1012 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
1013 : } else {
1014 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1015 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
1016 : }
1017 0 : ErrorsFound = true;
1018 : } else {
1019 : // Verify Curve Object, only legal type is Quadratic
1020 1224 : ErrorsFound |= Curve::CheckCurveDims(state,
1021 612 : thisDXCoil.CCapFFlow(1), // Curve index
1022 : {1}, // Valid dimensions
1023 : RoutineName, // Routine name
1024 : CurrentModuleObject, // Object Type
1025 : thisDXCoil.Name, // Object Name
1026 612 : cAlphaFields(6)); // Field Name
1027 :
1028 612 : if (!ErrorsFound) {
1029 612 : checkCurveIsNormalizedToOne(
1030 1224 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
1031 : }
1032 : }
1033 :
1034 612 : thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
1035 612 : if (thisDXCoil.EIRFTemp(1) == 0) {
1036 0 : if (lAlphaBlanks(7)) {
1037 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1038 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
1039 : } else {
1040 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1041 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
1042 : }
1043 0 : ErrorsFound = true;
1044 : } else {
1045 : // Verify Curve Object, only legal type is BiQuadratic
1046 1224 : ErrorsFound |= Curve::CheckCurveDims(state,
1047 612 : thisDXCoil.EIRFTemp(1), // Curve index
1048 : {2}, // Valid dimensions
1049 : RoutineName, // Routine name
1050 : CurrentModuleObject, // Object Type
1051 : thisDXCoil.Name, // Object Name
1052 612 : cAlphaFields(7)); // Field Name
1053 :
1054 612 : if (!ErrorsFound) {
1055 612 : checkCurveIsNormalizedToOne(state,
1056 1224 : std::string{RoutineName} + CurrentModuleObject,
1057 612 : thisDXCoil.Name,
1058 612 : thisDXCoil.EIRFTemp(1),
1059 612 : cAlphaFields(7),
1060 612 : Alphas(7),
1061 : RatedInletWetBulbTemp,
1062 : RatedOutdoorAirTemp);
1063 : }
1064 : }
1065 :
1066 612 : thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
1067 612 : if (thisDXCoil.EIRFFlow(1) == 0) {
1068 0 : if (lAlphaBlanks(8)) {
1069 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1070 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
1071 : } else {
1072 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1073 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
1074 : }
1075 0 : ErrorsFound = true;
1076 : } else {
1077 : // Verify Curve Object, only legal type is Quadratic
1078 1224 : ErrorsFound |= Curve::CheckCurveDims(state,
1079 612 : thisDXCoil.EIRFFlow(1), // Curve index
1080 : {1}, // Valid dimensions
1081 : RoutineName, // Routine name
1082 : CurrentModuleObject, // Object Type
1083 : thisDXCoil.Name, // Object Name
1084 612 : cAlphaFields(8)); // Field Name
1085 :
1086 612 : if (!ErrorsFound) {
1087 612 : checkCurveIsNormalizedToOne(
1088 1224 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
1089 : }
1090 : }
1091 :
1092 612 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
1093 612 : if (thisDXCoil.PLFFPLR(1) == 0) {
1094 0 : if (lAlphaBlanks(9)) {
1095 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1096 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
1097 : } else {
1098 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1099 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
1100 : }
1101 0 : ErrorsFound = true;
1102 : } else {
1103 : // Verify Curve Object, only legal types are Quadratic or Cubic
1104 1224 : ErrorsFound |= Curve::CheckCurveDims(state,
1105 612 : thisDXCoil.PLFFPLR(1), // Curve index
1106 : {1}, // Valid dimensions
1107 : RoutineName, // Routine name
1108 : CurrentModuleObject, // Object Type
1109 : thisDXCoil.Name, // Object Name
1110 612 : cAlphaFields(9)); // Field Name
1111 :
1112 612 : if (!ErrorsFound) {
1113 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
1114 612 : MinCurveVal = 999.0;
1115 612 : MaxCurveVal = -999.0;
1116 612 : CurveInput = 0.0;
1117 61812 : while (CurveInput <= 1.0) {
1118 61200 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
1119 61200 : if (CurveVal < MinCurveVal) {
1120 612 : MinCurveVal = CurveVal;
1121 612 : MinCurvePLR = CurveInput;
1122 : }
1123 61200 : if (CurveVal > MaxCurveVal) {
1124 60408 : MaxCurveVal = CurveVal;
1125 60408 : MaxCurvePLR = CurveInput;
1126 : }
1127 61200 : CurveInput += 0.01;
1128 : }
1129 612 : if (MinCurveVal < 0.7) {
1130 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1131 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFields(9), Alphas(9)));
1132 0 : ShowContinueError(state,
1133 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
1134 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
1135 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
1136 : }
1137 :
1138 612 : if (MaxCurveVal > 1.0) {
1139 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1140 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
1141 0 : ShowContinueError(state,
1142 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
1143 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
1144 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
1145 : }
1146 : }
1147 : }
1148 :
1149 : // Set minimum OAT for compressor operation
1150 612 : thisDXCoil.MinOATCompressor = Numbers(7);
1151 612 : if (NumNumbers < 6)
1152 0 : thisDXCoil.MinOATCompressor = minOATCompDXCooling; // input field is after min fields and won't default if field not included
1153 :
1154 612 : thisDXCoil.Twet_Rated(1) = Numbers(8);
1155 612 : thisDXCoil.Gamma_Rated(1) = Numbers(9);
1156 612 : thisDXCoil.MaxONOFFCyclesperHour(1) = Numbers(10);
1157 612 : thisDXCoil.LatentCapacityTimeConstant(1) = Numbers(11);
1158 :
1159 : // Numbers (7) through (11) must all be greater than zero to use the latent capacity degradation model
1160 639 : if ((Numbers(8) > 0.0 || Numbers(9) > 0.0 || Numbers(10) > 0.0 || Numbers(11) > 0.0) &&
1161 27 : (Numbers(8) <= 0.0 || Numbers(9) <= 0.0 || Numbers(10) <= 0.0 || Numbers(11) <= 0.0)) {
1162 0 : ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1163 0 : ShowContinueError(state, "...At least one of the four input parameters for the latent capacity degradation model");
1164 0 : ShowContinueError(state, "...is set to zero. Therefore, the latent degradation model will not be used for this simulation.");
1165 : }
1166 :
1167 : // outdoor condenser node
1168 612 : if (lAlphaBlanks(10)) {
1169 505 : thisDXCoil.CondenserInletNodeNum(1) = 0;
1170 : } else {
1171 214 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
1172 107 : Alphas(10),
1173 : ErrorsFound,
1174 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
1175 107 : thisDXCoil.Name,
1176 : DataLoopNode::NodeFluidType::Air,
1177 : DataLoopNode::ConnectionType::OutsideAirReference,
1178 : NodeInputManager::CompFluidStream::Primary,
1179 : ObjectIsNotParent);
1180 :
1181 107 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
1182 0 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1183 0 : ShowContinueError(
1184 : state,
1185 0 : format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(10), Alphas(10)));
1186 0 : ShowContinueError(
1187 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
1188 : }
1189 : }
1190 :
1191 612 : if ((Util::SameString(Alphas(11), "AirCooled")) || lAlphaBlanks(11)) {
1192 610 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
1193 2 : } else if (Util::SameString(Alphas(11), "EvaporativelyCooled")) {
1194 2 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
1195 2 : thisDXCoil.ReportEvapCondVars = true;
1196 : } else {
1197 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1198 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(11), Alphas(11)));
1199 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
1200 0 : ErrorsFound = true;
1201 : }
1202 :
1203 612 : thisDXCoil.EvapCondEffect(1) = Numbers(12);
1204 612 : if (thisDXCoil.EvapCondEffect(1) < 0.0 || thisDXCoil.EvapCondEffect(1) > 1.0) {
1205 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1206 0 : ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields(11)));
1207 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(12)));
1208 0 : ErrorsFound = true;
1209 : }
1210 :
1211 612 : thisDXCoil.EvapCondAirFlow(1) = Numbers(13);
1212 612 : if (thisDXCoil.EvapCondAirFlow(1) < 0.0 && thisDXCoil.EvapCondAirFlow(1) != AutoSize) {
1213 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1214 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(12)));
1215 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(13)));
1216 0 : ErrorsFound = true;
1217 : }
1218 :
1219 612 : thisDXCoil.EvapCondPumpElecNomPower(1) = Numbers(14);
1220 612 : if (thisDXCoil.EvapCondPumpElecNomPower(1) < 0.0 && thisDXCoil.EvapCondPumpElecNomPower(1) != AutoSize) {
1221 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1222 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(13)));
1223 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(14)));
1224 0 : ErrorsFound = true;
1225 : }
1226 :
1227 : // Set crankcase heater capacity
1228 612 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(15);
1229 612 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
1230 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1231 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(14)));
1232 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(15)));
1233 0 : ErrorsFound = true;
1234 : }
1235 :
1236 : // Set crankcase heater cutout temperature
1237 612 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(16);
1238 :
1239 612 : if (thisDXCoil.RatedCOP(1) > 0.0) {
1240 612 : thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
1241 : }
1242 :
1243 : // A12, \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
1244 612 : if (!lAlphaBlanks(12)) {
1245 1 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(12));
1246 1 : ErrorsFound |= Curve::CheckCurveDims(state,
1247 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
1248 : {1}, // Valid dimensions
1249 : RoutineName, // Routine name
1250 : CurrentModuleObject, // Object Type
1251 : thisDXCoil.Name, // Object Name
1252 1 : cAlphaFields(12)); // Field Name
1253 : }
1254 :
1255 : // Get Water System tank connections
1256 : // A13, \field Name of Water Storage Tank for Supply
1257 612 : thisDXCoil.EvapWaterSupplyName = Alphas(13);
1258 612 : if (lAlphaBlanks(13)) {
1259 612 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
1260 : } else {
1261 0 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
1262 0 : SetupTankDemandComponent(state,
1263 : thisDXCoil.Name,
1264 : CurrentModuleObject,
1265 : thisDXCoil.EvapWaterSupplyName,
1266 : ErrorsFound,
1267 0 : thisDXCoil.EvapWaterSupTankID,
1268 0 : thisDXCoil.EvapWaterTankDemandARRID);
1269 : }
1270 :
1271 : // A14; \field Name of Water Storage Tank for Condensate Collection
1272 612 : thisDXCoil.CondensateCollectName = Alphas(14);
1273 612 : if (lAlphaBlanks(14)) {
1274 612 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
1275 : } else {
1276 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
1277 0 : SetupTankSupplyComponent(state,
1278 : thisDXCoil.Name,
1279 : CurrentModuleObject,
1280 : thisDXCoil.CondensateCollectName,
1281 : ErrorsFound,
1282 0 : thisDXCoil.CondensateTankID,
1283 0 : thisDXCoil.CondensateTankSupplyARRID);
1284 : }
1285 :
1286 : // Basin heater power as a function of temperature must be greater than or equal to 0
1287 612 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(17);
1288 612 : if (Numbers(17) < 0.0) {
1289 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1290 0 : ShowContinueError(state, format("...{} must be >= 0.0.", cNumericFields(16)));
1291 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(17)));
1292 0 : ErrorsFound = true;
1293 : }
1294 :
1295 612 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(18);
1296 612 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
1297 3 : if (NumNumbers < 18) {
1298 1 : thisDXCoil.BasinHeaterSetPointTemp = 2.0;
1299 : }
1300 3 : if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
1301 0 : ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1302 0 : ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(17)));
1303 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(18)));
1304 : }
1305 : }
1306 :
1307 612 : if (!lAlphaBlanks(15)) {
1308 0 : thisDXCoil.BasinHeaterSchedulePtr = GetScheduleIndex(state, Alphas(15));
1309 0 : if (thisDXCoil.BasinHeaterSchedulePtr == 0) {
1310 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1311 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15), Alphas(15)));
1312 0 : ShowContinueError(state, "Basin heater will be available to operate throughout the simulation.");
1313 : }
1314 : }
1315 :
1316 612 : if (!lAlphaBlanks(16) && NumAlphas > 15) {
1317 0 : thisDXCoil.SHRFTemp(1) = GetCurveIndex(state, Alphas(16)); // convert curve name to number
1318 0 : if (thisDXCoil.SHRFTemp(1) == 0) {
1319 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1320 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
1321 : } else {
1322 : // Verify Curve Object, only legal type is BiQuadratic
1323 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1324 0 : thisDXCoil.SHRFTemp(1), // Curve index
1325 : {2}, // Valid dimensions
1326 : RoutineName, // Routine name
1327 : CurrentModuleObject, // Object Type
1328 : thisDXCoil.Name, // Object Name
1329 0 : cAlphaFields(16)); // Field Name
1330 : }
1331 : }
1332 :
1333 612 : if (!lAlphaBlanks(17) && NumAlphas > 16) {
1334 0 : thisDXCoil.SHRFFlow(1) = GetCurveIndex(state, Alphas(17)); // convert curve name to number
1335 0 : if (thisDXCoil.SHRFTemp(1) == 0) {
1336 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1337 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
1338 : } else {
1339 : // Verify Curve Object, only legal type is Quadratic and Cubic
1340 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1341 0 : thisDXCoil.SHRFFlow(1), // Curve index
1342 : {1}, // Valid dimensions
1343 : RoutineName, // Routine name
1344 : CurrentModuleObject, // Object Type
1345 : thisDXCoil.Name, // Object Name
1346 0 : cAlphaFields(17)); // Field Name
1347 : }
1348 : }
1349 :
1350 612 : if (thisDXCoil.SHRFTemp(1) > 0 && thisDXCoil.SHRFFlow(1) > 0) {
1351 0 : thisDXCoil.UserSHRCurveExists = true;
1352 : }
1353 : // get User Input flag for ASHRAE Standard 127 Standard Ratings Reporting
1354 612 : if (lAlphaBlanks(18)) {
1355 604 : thisDXCoil.ASHRAE127StdRprt = false;
1356 : } else {
1357 8 : if (Alphas(18) == "YES" || Alphas(18) == "Yes") {
1358 8 : thisDXCoil.ASHRAE127StdRprt = true;
1359 : } else {
1360 0 : thisDXCoil.ASHRAE127StdRprt = false;
1361 : }
1362 : }
1363 : // A19; \field Zone Name for Condenser Placement
1364 612 : if (!lAlphaBlanks(19) && NumAlphas > 18) {
1365 1 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(19), state.dataHeatBal->Zone);
1366 :
1367 1 : if (thisDXCoil.SecZonePtr > 0) {
1368 1 : SetupZoneInternalGain(state,
1369 : thisDXCoil.SecZonePtr,
1370 : thisDXCoil.Name,
1371 : DataHeatBalance::IntGainType::SecCoolingDXCoilSingleSpeed,
1372 : &thisDXCoil.SecCoilSensibleHeatGainRate);
1373 1 : thisDXCoil.IsSecondaryDXCoilInZone = true;
1374 : } else {
1375 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1376 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(19), Alphas(19)));
1377 : }
1378 : }
1379 :
1380 : } // end of the Doe2 DX coil loop
1381 :
1382 247 : if (ErrorsFound) {
1383 0 : ShowFatalError(state,
1384 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
1385 : }
1386 :
1387 : // Loop over the Multimode DX Coils and get & load the data
1388 247 : CurrentModuleObject = "Coil:Cooling:DX:TwoStageWithHumidityControlMode";
1389 258 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulModeCoils; ++DXCoilIndex) {
1390 :
1391 11 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1392 : CurrentModuleObject,
1393 : DXCoilIndex,
1394 : Alphas,
1395 : NumAlphas,
1396 : Numbers,
1397 : NumNumbers,
1398 : IOStatus,
1399 : lNumericBlanks,
1400 : lAlphaBlanks,
1401 : cAlphaFields,
1402 : cNumericFields);
1403 :
1404 11 : ++DXCoilNum;
1405 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
1406 11 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
1407 :
1408 11 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
1409 11 : thisDXCoil.Name = Alphas(1);
1410 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
1411 11 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
1412 11 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
1413 11 : thisDXCoil.DXCoilType = CurrentModuleObject;
1414 11 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingTwoStageWHumControl;
1415 11 : thisDXCoil.Schedule = Alphas(2);
1416 11 : if (lAlphaBlanks(2)) {
1417 4 : thisDXCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
1418 : } else {
1419 7 : thisDXCoil.SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
1420 7 : if (thisDXCoil.SchedPtr == 0) {
1421 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1422 0 : ShowContinueError(state, format("...{}=\"{}\".", cAlphaFields(2), Alphas(2)));
1423 0 : ErrorsFound = true;
1424 : }
1425 : }
1426 :
1427 11 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
1428 11 : Alphas(3),
1429 : ErrorsFound,
1430 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoStageWithHumidityControlMode,
1431 11 : Alphas(1),
1432 : DataLoopNode::NodeFluidType::Air,
1433 : DataLoopNode::ConnectionType::Inlet,
1434 : NodeInputManager::CompFluidStream::Primary,
1435 : ObjectIsNotParent);
1436 :
1437 11 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
1438 11 : Alphas(4),
1439 : ErrorsFound,
1440 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoStageWithHumidityControlMode,
1441 11 : Alphas(1),
1442 : DataLoopNode::NodeFluidType::Air,
1443 : DataLoopNode::ConnectionType::Outlet,
1444 : NodeInputManager::CompFluidStream::Primary,
1445 : ObjectIsNotParent);
1446 :
1447 11 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
1448 :
1449 : // A5; \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
1450 11 : if (!lAlphaBlanks(5)) {
1451 0 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
1452 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1453 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
1454 : {1}, // Valid dimensions
1455 : RoutineName, // Routine name
1456 : CurrentModuleObject, // Object Type
1457 : thisDXCoil.Name, // Object Name
1458 0 : cAlphaFields(5)); // Field Name
1459 : }
1460 :
1461 : // Set crankcase heater capacity
1462 11 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(1);
1463 11 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
1464 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1465 0 : ShowContinueError(state, format("...{} must be >= 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
1466 0 : ErrorsFound = true;
1467 : }
1468 :
1469 : // Set crankcase heater cutout temperature
1470 11 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(2);
1471 :
1472 : // Number of capacity stages
1473 11 : thisDXCoil.NumCapacityStages = Numbers(3);
1474 : // Check if requested number of capacity stages exceeds limits
1475 11 : if ((thisDXCoil.NumCapacityStages > MaxCapacityStages) || (thisDXCoil.NumCapacityStages < 1)) {
1476 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1477 0 : ShowContinueError(state, format("...illegal {} = {}", cNumericFields(3), thisDXCoil.NumCapacityStages));
1478 0 : ShowContinueError(state, format("...Valid range is 1 to {}", MaxCapacityStages));
1479 0 : ErrorsFound = true;
1480 : }
1481 :
1482 : // Number of enhanced dehumidification modes
1483 11 : thisDXCoil.NumDehumidModes = Numbers(4);
1484 : // Check if requested number of enhanced dehumidification modes exceeds limits
1485 11 : if ((thisDXCoil.NumDehumidModes > MaxDehumidModes) || (thisDXCoil.NumDehumidModes < 0)) {
1486 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1487 0 : ShowContinueError(state, format("...illegal {} = {}", cNumericFields(4), thisDXCoil.NumDehumidModes));
1488 0 : ShowContinueError(state, format("...Valid range is 0 to {}", MaxDehumidModes));
1489 0 : ErrorsFound = true;
1490 : }
1491 :
1492 : // Set starting alpha index for coil performance inputs
1493 11 : AlphaIndex = 6;
1494 : // allocate performance modes for numeric field strings used for sizing routine
1495 22 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(
1496 11 : thisDXCoil.NumDehumidModes * 2 + thisDXCoil.NumCapacityStages * 2); // not sure this math is correct, ask MW
1497 :
1498 : // Loop through capacity stages and dehumidification modes
1499 29 : for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
1500 53 : for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
1501 : // Check if sufficient number of fields entered
1502 35 : if ((AlphaIndex + 1) > NumAlphas) {
1503 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1504 0 : ShowContinueError(state, "...not enough remaining fields for specified Number of Operating Modes.");
1505 0 : ShowContinueError(state, "...Need additional Coil Performance Object Type and Coil Performance Object Name fields.");
1506 0 : ErrorsFound = true;
1507 : } else {
1508 35 : PerfObjectType = Alphas(AlphaIndex);
1509 35 : PerfObjectName = Alphas(AlphaIndex + 1);
1510 35 : PerfModeNum = DehumidModeNum * 2 + CapacityStageNum;
1511 35 : thisDXCoil.CoilPerformanceType(PerfModeNum) = PerfObjectType;
1512 35 : if (Util::SameString(PerfObjectType, "CoilPerformance:DX:Cooling")) {
1513 35 : thisDXCoil.CoilPerformanceType_Num(PerfModeNum) = HVAC::CoilPerfDX_CoolBypassEmpirical;
1514 : } else {
1515 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1516 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(AlphaIndex), PerfObjectType));
1517 0 : ShowContinueError(state, "Must be \"CoilPerformance:DX:Cooling\".");
1518 0 : ErrorsFound = true;
1519 : }
1520 35 : thisDXCoil.CoilPerformanceName(PerfModeNum) = PerfObjectName;
1521 : // Get for CoilPerformance object
1522 35 : PerfObjectNum = state.dataInputProcessing->inputProcessor->getObjectItemNum(state, PerfObjectType, PerfObjectName);
1523 35 : if (PerfObjectNum > 0) {
1524 :
1525 35 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1526 : PerfObjectType,
1527 : PerfObjectNum,
1528 : Alphas2,
1529 : NumAlphas2,
1530 : Numbers2,
1531 : NumNumbers2,
1532 : IOStatus,
1533 : lNumericBlanks2,
1534 : lAlphaBlanks2,
1535 : cAlphaFields2,
1536 : cNumericFields2);
1537 :
1538 : // allocate performance mode numeric field strings used for sizing routine
1539 35 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum)
1540 35 : .PerfMode(PerfModeNum)
1541 35 : .FieldNames.allocate(NumNumbers2); // use MaxNumbers here??
1542 35 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(PerfModeNum).FieldNames = cNumericFields2;
1543 :
1544 35 : thisDXCoil.RatedTotCap(PerfModeNum) = Numbers2(1);
1545 35 : thisDXCoil.RatedSHR(PerfModeNum) = Numbers2(2);
1546 35 : thisDXCoil.RatedCOP(PerfModeNum) = Numbers2(3);
1547 : // Rated flow is immediately adjusted for bypass fraction if not autosized
1548 35 : thisDXCoil.BypassedFlowFrac(PerfModeNum) = Numbers2(5);
1549 35 : thisDXCoil.RatedAirVolFlowRate(PerfModeNum) = Numbers2(4);
1550 35 : if (thisDXCoil.RatedAirVolFlowRate(PerfModeNum) != AutoSize) {
1551 7 : thisDXCoil.RatedAirVolFlowRate(PerfModeNum) *= (1.0 - thisDXCoil.BypassedFlowFrac(PerfModeNum));
1552 : }
1553 :
1554 35 : thisDXCoil.CCapFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(2)); // convert curve name to number
1555 35 : if (thisDXCoil.CCapFTemp(PerfModeNum) == 0) {
1556 0 : if (lAlphaBlanks2(2)) {
1557 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1558 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(2)));
1559 : } else {
1560 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1561 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(2), Alphas2(2)));
1562 : }
1563 0 : ErrorsFound = true;
1564 : } else {
1565 : // Verify Curve Object, only legal type is BiQuadratic
1566 70 : ErrorsFound |= Curve::CheckCurveDims(state,
1567 35 : thisDXCoil.CCapFTemp(PerfModeNum), // Curve index
1568 : {2}, // Valid dimensions
1569 : RoutineName, // Routine name
1570 : CurrentModuleObject, // Object Type
1571 : thisDXCoil.Name, // Object Name
1572 35 : cAlphaFields2(2)); // Field Name
1573 :
1574 35 : if (!ErrorsFound) {
1575 35 : checkCurveIsNormalizedToOne(state,
1576 70 : std::string{RoutineName} + CurrentModuleObject,
1577 35 : thisDXCoil.Name,
1578 35 : thisDXCoil.CCapFTemp(PerfModeNum),
1579 35 : cAlphaFields2(2),
1580 35 : Alphas2(2),
1581 : RatedInletWetBulbTemp,
1582 : RatedOutdoorAirTemp);
1583 : }
1584 : }
1585 :
1586 35 : thisDXCoil.CCapFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(3)); // convert curve name to number
1587 35 : if (thisDXCoil.CCapFFlow(PerfModeNum) == 0) {
1588 0 : if (lAlphaBlanks2(3)) {
1589 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1590 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(3)));
1591 : } else {
1592 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1593 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(3), Alphas2(3)));
1594 : }
1595 0 : ErrorsFound = true;
1596 : } else {
1597 : // Verify Curve Object, only legal type is Quadratic
1598 70 : ErrorsFound |= Curve::CheckCurveDims(state,
1599 35 : thisDXCoil.CCapFFlow(PerfModeNum), // Curve index
1600 : {1}, // Valid dimensions
1601 : RoutineName, // Routine name
1602 : CurrentModuleObject, // Object Type
1603 : thisDXCoil.Name, // Object Name
1604 35 : cAlphaFields2(3)); // Field Name
1605 :
1606 35 : if (!ErrorsFound) {
1607 35 : checkCurveIsNormalizedToOne(state,
1608 70 : std::string{RoutineName} + CurrentModuleObject,
1609 35 : thisDXCoil.Name,
1610 35 : thisDXCoil.CCapFFlow(PerfModeNum),
1611 35 : cAlphaFields2(3),
1612 35 : Alphas2(3),
1613 : 1.0);
1614 : }
1615 : }
1616 :
1617 35 : thisDXCoil.EIRFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(4)); // convert curve name to number
1618 35 : if (thisDXCoil.EIRFTemp(PerfModeNum) == 0) {
1619 0 : if (lAlphaBlanks2(4)) {
1620 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1621 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(4)));
1622 : } else {
1623 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1624 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(4), Alphas2(4)));
1625 : }
1626 0 : ErrorsFound = true;
1627 : } else {
1628 : // Verify Curve Object, only legal type is BiQuadratic
1629 70 : ErrorsFound |= Curve::CheckCurveDims(state,
1630 35 : thisDXCoil.EIRFTemp(PerfModeNum), // Curve index
1631 : {2}, // Valid dimensions
1632 : RoutineName, // Routine name
1633 : CurrentModuleObject, // Object Type
1634 : thisDXCoil.Name, // Object Name
1635 35 : cAlphaFields2(4)); // Field Name
1636 :
1637 35 : if (!ErrorsFound) {
1638 35 : checkCurveIsNormalizedToOne(state,
1639 70 : std::string{RoutineName} + CurrentModuleObject,
1640 35 : thisDXCoil.Name,
1641 35 : thisDXCoil.EIRFTemp(PerfModeNum),
1642 35 : cAlphaFields2(4),
1643 35 : Alphas2(4),
1644 : RatedInletWetBulbTemp,
1645 : RatedOutdoorAirTemp);
1646 : }
1647 : }
1648 :
1649 35 : thisDXCoil.EIRFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(5)); // convert curve name to number
1650 35 : if (thisDXCoil.EIRFFlow(PerfModeNum) == 0) {
1651 0 : if (lAlphaBlanks2(5)) {
1652 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1653 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(5)));
1654 : } else {
1655 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1656 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(5), Alphas2(5)));
1657 : }
1658 0 : ErrorsFound = true;
1659 : } else {
1660 : // Verify Curve Object, only legal type is Quadratic
1661 70 : ErrorsFound |= Curve::CheckCurveDims(state,
1662 35 : thisDXCoil.EIRFFlow(PerfModeNum), // Curve index
1663 : {1}, // Valid dimensions
1664 : RoutineName, // Routine name
1665 : CurrentModuleObject, // Object Type
1666 : thisDXCoil.Name, // Object Name
1667 35 : cAlphaFields2(5)); // Field Name
1668 :
1669 35 : if (!ErrorsFound) {
1670 35 : checkCurveIsNormalizedToOne(state,
1671 70 : std::string{RoutineName} + CurrentModuleObject,
1672 35 : thisDXCoil.Name,
1673 35 : thisDXCoil.EIRFFlow(PerfModeNum),
1674 35 : cAlphaFields2(5),
1675 35 : Alphas2(5),
1676 : 1.0);
1677 : }
1678 : }
1679 :
1680 35 : thisDXCoil.PLFFPLR(PerfModeNum) = GetCurveIndex(state, Alphas2(6)); // convert curve name to number
1681 35 : if (thisDXCoil.PLFFPLR(PerfModeNum) == 0) {
1682 0 : if (lAlphaBlanks2(6)) {
1683 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1684 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(6)));
1685 : } else {
1686 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1687 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(6), Alphas2(6)));
1688 : }
1689 0 : ErrorsFound = true;
1690 : } else {
1691 : // Verify Curve Object, only legal types are Quadratic or Cubic
1692 70 : ErrorsFound |= Curve::CheckCurveDims(state,
1693 35 : thisDXCoil.PLFFPLR(PerfModeNum), // Curve index
1694 : {1}, // Valid dimensions
1695 : RoutineName, // Routine name
1696 : CurrentModuleObject, // Object Type
1697 : thisDXCoil.Name, // Object Name
1698 35 : cAlphaFields2(6)); // Field Name
1699 :
1700 35 : if (!ErrorsFound) {
1701 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
1702 35 : MinCurveVal = 999.0;
1703 35 : MaxCurveVal = -999.0;
1704 35 : CurveInput = 0.0;
1705 3535 : while (CurveInput <= 1.0) {
1706 3500 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(PerfModeNum), CurveInput);
1707 3500 : if (CurveVal < MinCurveVal) {
1708 35 : MinCurveVal = CurveVal;
1709 35 : MinCurvePLR = CurveInput;
1710 : }
1711 3500 : if (CurveVal > MaxCurveVal) {
1712 3500 : MaxCurveVal = CurveVal;
1713 3500 : MaxCurvePLR = CurveInput;
1714 : }
1715 3500 : CurveInput += 0.01;
1716 : }
1717 35 : if (MinCurveVal < 0.7) {
1718 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1719 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields2(6), Alphas2(6)));
1720 0 : ShowContinueError(
1721 : state,
1722 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
1723 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
1724 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 0.7);
1725 : }
1726 :
1727 35 : if (MaxCurveVal > 1.0) {
1728 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1729 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields2(6), Alphas2(6)));
1730 0 : ShowContinueError(
1731 : state,
1732 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
1733 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
1734 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 1.0);
1735 : }
1736 : }
1737 : }
1738 :
1739 35 : thisDXCoil.Twet_Rated(PerfModeNum) = Numbers2(6);
1740 35 : thisDXCoil.Gamma_Rated(PerfModeNum) = Numbers2(7);
1741 35 : thisDXCoil.MaxONOFFCyclesperHour(PerfModeNum) = Numbers2(8);
1742 35 : thisDXCoil.LatentCapacityTimeConstant(PerfModeNum) = Numbers2(9);
1743 : // Numbers2 (6) through (9) must all be greater than zero to use the latent capacity degradation model
1744 35 : if ((Numbers2(6) > 0.0 || Numbers2(7) > 0.0 || Numbers2(8) > 0.0 || Numbers2(9) > 0.0) &&
1745 0 : (Numbers2(6) <= 0.0 || Numbers2(7) <= 0.0 || Numbers2(8) <= 0.0 || Numbers2(9) <= 0.0)) {
1746 0 : ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, PerfObjectType, PerfObjectName));
1747 0 : ShowContinueError(state, "...At least one of the four input parameters for the latent capacity degradation model");
1748 0 : ShowContinueError(state,
1749 : "...is set to zero. Therefore, the latent degradation model will not be used for this simulation.");
1750 : }
1751 :
1752 : // outdoor condenser node
1753 35 : if (lAlphaBlanks2(7)) {
1754 35 : thisDXCoil.CondenserInletNodeNum(PerfModeNum) = 0;
1755 : } else {
1756 0 : thisDXCoil.CondenserInletNodeNum(PerfModeNum) =
1757 0 : GetOnlySingleNode(state,
1758 0 : Alphas2(7),
1759 : ErrorsFound,
1760 0 : (DataLoopNode::ConnectionObjectType)getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC,
1761 0 : Util::makeUPPER(PerfObjectType)),
1762 : PerfObjectName,
1763 : DataLoopNode::NodeFluidType::Air,
1764 : DataLoopNode::ConnectionType::OutsideAirReference,
1765 : NodeInputManager::CompFluidStream::Primary,
1766 : ObjectIsNotParent);
1767 0 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(PerfModeNum))) {
1768 0 : ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, PerfObjectType, PerfObjectName));
1769 0 : ShowContinueError(state, format("may not be valid {}=\"{}\".", cAlphaFields2(7), Alphas2(7)));
1770 0 : ShowContinueError(state, "node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
1771 0 : ShowContinueError(state,
1772 : "This node needs to be included in an air system or the coil model will not be valid, and the "
1773 : "simulation continues");
1774 : }
1775 : }
1776 35 : if ((Util::SameString(Alphas2(8), "AirCooled")) || lAlphaBlanks2(8)) {
1777 35 : thisDXCoil.CondenserType(PerfModeNum) = DataHeatBalance::RefrigCondenserType::Air;
1778 0 : } else if (Util::SameString(Alphas2(8), "EvaporativelyCooled")) {
1779 0 : thisDXCoil.CondenserType(PerfModeNum) = DataHeatBalance::RefrigCondenserType::Evap;
1780 0 : thisDXCoil.ReportEvapCondVars = true;
1781 : } else {
1782 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1783 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields2(8), Alphas2(8)));
1784 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
1785 0 : ErrorsFound = true;
1786 : }
1787 :
1788 35 : thisDXCoil.EvapCondEffect(PerfModeNum) = Numbers2(10);
1789 35 : if (thisDXCoil.EvapCondEffect(PerfModeNum) < 0.0 || thisDXCoil.EvapCondEffect(PerfModeNum) > 1.0) {
1790 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1791 0 : ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields2(10)));
1792 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(10)));
1793 0 : ErrorsFound = true;
1794 : }
1795 :
1796 35 : thisDXCoil.EvapCondAirFlow(PerfModeNum) = Numbers2(11);
1797 35 : if (thisDXCoil.EvapCondAirFlow(PerfModeNum) < 0.0 && thisDXCoil.EvapCondAirFlow(PerfModeNum) != AutoSize) {
1798 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1799 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields2(11)));
1800 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(11)));
1801 0 : ErrorsFound = true;
1802 : }
1803 :
1804 35 : thisDXCoil.EvapCondPumpElecNomPower(PerfModeNum) = Numbers2(12);
1805 35 : if (thisDXCoil.EvapCondPumpElecNomPower(PerfModeNum) < 0.0 && thisDXCoil.EvapCondAirFlow(PerfModeNum) != AutoSize) {
1806 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1807 0 : ShowContinueError(state, format("...{} cannot be less than zero.", cNumericFields2(12)));
1808 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(12)));
1809 0 : ErrorsFound = true;
1810 : }
1811 :
1812 35 : thisDXCoil.RatedEIR(PerfModeNum) = 1.0 / thisDXCoil.RatedCOP(PerfModeNum);
1813 :
1814 : // read in user specified SHR modifer curves
1815 35 : if (!lAlphaBlanks2(9) && NumAlphas2 > 8) {
1816 0 : thisDXCoil.SHRFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(9)); // convert curve name to number
1817 0 : if (thisDXCoil.SHRFTemp(PerfModeNum) == 0) {
1818 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1819 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(9), Alphas2(9)));
1820 : } else {
1821 : // Verify Curve Object, only legal type is BiQuadratic
1822 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1823 0 : thisDXCoil.SHRFTemp(PerfModeNum), // Curve index
1824 : {2}, // Valid dimensions
1825 : RoutineName, // Routine name
1826 : CurrentModuleObject, // Object Type
1827 : thisDXCoil.Name, // Object Name
1828 0 : cAlphaFields2(9)); // Field Name
1829 : }
1830 : }
1831 :
1832 35 : if (!lAlphaBlanks2(10) && NumAlphas2 > 9) {
1833 0 : thisDXCoil.SHRFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(10)); // convert curve name to number
1834 0 : if (thisDXCoil.SHRFTemp(PerfModeNum) == 0) {
1835 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1836 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(10), Alphas2(10)));
1837 : } else {
1838 : // Verify Curve Object, only legal type is BiQuadratic
1839 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1840 0 : thisDXCoil.SHRFFlow(PerfModeNum), // Curve index
1841 : {1}, // Valid dimensions
1842 : RoutineName, // Routine name
1843 : CurrentModuleObject, // Object Type
1844 : thisDXCoil.Name, // Object Name
1845 0 : cAlphaFields2(10)); // Field Name
1846 : }
1847 : }
1848 35 : if (thisDXCoil.SHRFTemp(PerfModeNum) > 0 && thisDXCoil.SHRFFlow(PerfModeNum) > 0) {
1849 0 : thisDXCoil.UserSHRCurveExists = true;
1850 : } else {
1851 35 : thisDXCoil.UserSHRCurveExists = false;
1852 : }
1853 :
1854 : } else { // invalid performance object
1855 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1856 0 : ShowContinueError(state, format("... not found {}=\"{}\".", PerfObjectType, PerfObjectName));
1857 0 : ErrorsFound = true;
1858 : } // end of valid performance object check
1859 35 : AlphaIndex += 2;
1860 : } // end of sufficient number of fields entered check
1861 : } // End of multimode DX capacity stages loop
1862 : // Warn if inputs entered for unused capacity stages
1863 19 : for (CapacityStageNum = (thisDXCoil.NumCapacityStages + 1); CapacityStageNum <= MaxCapacityStages; ++CapacityStageNum) {
1864 1 : if ((AlphaIndex <= NumAlphas) && ((!Alphas(AlphaIndex).empty()) || (!Alphas(AlphaIndex + 1).empty()))) {
1865 0 : ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1866 0 : ShowContinueError(state, format("...Capacity Stage {} not active. Therefore,{}", CapacityStageNum, cAlphaFields(AlphaIndex)));
1867 0 : ShowContinueError(state, format("... and {} fields will be ignored.", cAlphaFields(AlphaIndex + 1)));
1868 : }
1869 1 : AlphaIndex += 2;
1870 : } // End of unused capacity stages loop
1871 : } // End of multimode DX dehumidification modes loo
1872 :
1873 : // Get Water System tank connections
1874 : // A14, \field Name of Water Storage Tank for Supply
1875 11 : thisDXCoil.EvapWaterSupplyName = Alphas(14);
1876 11 : if (lAlphaBlanks(14)) {
1877 11 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
1878 : } else {
1879 0 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
1880 0 : SetupTankDemandComponent(state,
1881 : thisDXCoil.Name,
1882 : CurrentModuleObject,
1883 : thisDXCoil.EvapWaterSupplyName,
1884 : ErrorsFound,
1885 0 : thisDXCoil.EvapWaterSupTankID,
1886 0 : thisDXCoil.EvapWaterTankDemandARRID);
1887 : }
1888 :
1889 : // A15; \field Name of Water Storage Tank for Condensate Collection
1890 11 : thisDXCoil.CondensateCollectName = Alphas(15);
1891 11 : if (lAlphaBlanks(15)) {
1892 11 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
1893 : } else {
1894 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
1895 0 : SetupTankSupplyComponent(state,
1896 : thisDXCoil.Name,
1897 : CurrentModuleObject,
1898 : thisDXCoil.CondensateCollectName,
1899 : ErrorsFound,
1900 0 : thisDXCoil.CondensateTankID,
1901 0 : thisDXCoil.CondensateTankSupplyARRID);
1902 : }
1903 :
1904 : // Set minimum OAT for compressor operation
1905 11 : thisDXCoil.MinOATCompressor = Numbers(5);
1906 11 : if (NumNumbers < 5)
1907 8 : thisDXCoil.MinOATCompressor = minOATCompDXCooling; // input field is after min fields and won't default if field not included
1908 :
1909 : // Basin heater power as a function of temperature must be greater than or equal to 0
1910 11 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(6);
1911 11 : if (Numbers(6) < 0.0) {
1912 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1913 0 : ShowContinueError(state, format("...{} must be >= 0.", cNumericFields(6)));
1914 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(6)));
1915 0 : ErrorsFound = true;
1916 : }
1917 :
1918 11 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(7);
1919 11 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
1920 0 : if (NumNumbers < 7) {
1921 0 : thisDXCoil.BasinHeaterSetPointTemp = 2.0;
1922 : }
1923 0 : if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
1924 0 : ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1925 0 : ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(7)));
1926 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(7)));
1927 : }
1928 : }
1929 :
1930 11 : if (!lAlphaBlanks(16)) {
1931 0 : thisDXCoil.BasinHeaterSchedulePtr = GetScheduleIndex(state, Alphas(16));
1932 0 : if (thisDXCoil.BasinHeaterSchedulePtr == 0) {
1933 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1934 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
1935 0 : ShowContinueError(state, "Basin heater will be available to operate throughout the simulation.");
1936 : }
1937 : }
1938 :
1939 : } // end of the Multimode DX coil loop
1940 :
1941 247 : if (ErrorsFound) {
1942 0 : ShowFatalError(state,
1943 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
1944 : }
1945 :
1946 : //************* Read Heat Pump (DX Heating Coil) Input **********
1947 247 : CurrentModuleObject = "Coil:Heating:DX:SingleSpeed";
1948 322 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXHeatingCoils; ++DXCoilIndex) {
1949 :
1950 75 : ++DXCoilNum;
1951 :
1952 75 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1953 : CurrentModuleObject,
1954 : DXCoilIndex,
1955 : Alphas,
1956 : NumAlphas,
1957 : Numbers,
1958 : NumNumbers,
1959 : IOStatus,
1960 : lNumericBlanks,
1961 : lAlphaBlanks,
1962 : cAlphaFields,
1963 : cNumericFields);
1964 :
1965 : // allocate single performance mode for numeric field strings used for sizing routine
1966 75 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
1967 75 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
1968 75 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
1969 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
1970 75 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
1971 :
1972 75 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
1973 75 : thisDXCoil.Name = Alphas(1);
1974 75 : thisDXCoil.DXCoilType = CurrentModuleObject;
1975 75 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatingEmpirical;
1976 75 : thisDXCoil.Schedule = Alphas(2);
1977 75 : if (lAlphaBlanks(2)) {
1978 22 : thisDXCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
1979 : } else {
1980 53 : thisDXCoil.SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
1981 53 : if (thisDXCoil.SchedPtr == 0) {
1982 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1983 0 : ShowContinueError(state, format("...{}=\"{}\".", cAlphaFields(2), Alphas(2)));
1984 0 : ErrorsFound = true;
1985 : }
1986 : }
1987 :
1988 75 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
1989 75 : Alphas(3),
1990 : ErrorsFound,
1991 : DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
1992 75 : Alphas(1),
1993 : DataLoopNode::NodeFluidType::Air,
1994 : DataLoopNode::ConnectionType::Inlet,
1995 : NodeInputManager::CompFluidStream::Primary,
1996 : ObjectIsNotParent);
1997 :
1998 75 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
1999 75 : Alphas(4),
2000 : ErrorsFound,
2001 : DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
2002 75 : Alphas(1),
2003 : DataLoopNode::NodeFluidType::Air,
2004 : DataLoopNode::ConnectionType::Outlet,
2005 : NodeInputManager::CompFluidStream::Primary,
2006 : ObjectIsNotParent);
2007 :
2008 75 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
2009 :
2010 75 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
2011 75 : if (thisDXCoil.CCapFTemp(1) == 0) {
2012 0 : if (lAlphaBlanks(5)) {
2013 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2014 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
2015 : } else {
2016 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2017 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
2018 : }
2019 0 : ErrorsFound = true;
2020 : } else {
2021 : // only legal types are Quadratic, BiQuadratic and Cubic
2022 150 : ErrorsFound |= Curve::CheckCurveDims(state,
2023 75 : thisDXCoil.CCapFTemp(1), // Curve index
2024 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2025 : RoutineName, // Routine name
2026 : CurrentModuleObject, // Object Type
2027 : thisDXCoil.Name, // Object Name
2028 75 : cAlphaFields(5)); // Field Name
2029 :
2030 75 : if (!ErrorsFound) {
2031 75 : if (state.dataCurveManager->PerfCurve(thisDXCoil.CCapFTemp(1))->numDims == 1) {
2032 74 : checkCurveIsNormalizedToOne(state,
2033 148 : std::string{RoutineName} + CurrentModuleObject,
2034 74 : thisDXCoil.Name,
2035 74 : thisDXCoil.CCapFTemp(1),
2036 74 : cAlphaFields(5),
2037 74 : Alphas(5),
2038 : RatedOutdoorAirTempHeat);
2039 : } else {
2040 1 : checkCurveIsNormalizedToOne(state,
2041 2 : std::string{RoutineName} + CurrentModuleObject,
2042 1 : thisDXCoil.Name,
2043 1 : thisDXCoil.CCapFTemp(1),
2044 1 : cAlphaFields(5),
2045 1 : Alphas(5),
2046 : RatedInletAirTempHeat,
2047 : RatedOutdoorAirTempHeat);
2048 : }
2049 : }
2050 : }
2051 :
2052 75 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
2053 75 : if (thisDXCoil.CCapFFlow(1) == 0) {
2054 0 : if (lAlphaBlanks(6)) {
2055 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2056 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
2057 : } else {
2058 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2059 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
2060 : }
2061 0 : ErrorsFound = true;
2062 : } else {
2063 : // Verify Curve Object, only legal type is Quadratic
2064 150 : ErrorsFound |= Curve::CheckCurveDims(state,
2065 75 : thisDXCoil.CCapFFlow(1), // Curve index
2066 : {1}, // Valid dimensions
2067 : RoutineName, // Routine name
2068 : CurrentModuleObject, // Object Type
2069 : thisDXCoil.Name, // Object Name
2070 75 : cAlphaFields(6)); // Field Name
2071 :
2072 75 : if (!ErrorsFound) {
2073 75 : checkCurveIsNormalizedToOne(
2074 150 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
2075 : }
2076 : }
2077 :
2078 75 : thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
2079 75 : if (thisDXCoil.EIRFTemp(1) == 0) {
2080 0 : if (lAlphaBlanks(7)) {
2081 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2082 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
2083 : } else {
2084 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2085 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
2086 : }
2087 0 : ErrorsFound = true;
2088 : } else {
2089 : // only legal types are Quadratic, BiQuadratic and Cubic
2090 150 : ErrorsFound |= Curve::CheckCurveDims(state,
2091 75 : thisDXCoil.EIRFTemp(1), // Curve index
2092 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2093 : RoutineName, // Routine name
2094 : CurrentModuleObject, // Object Type
2095 : thisDXCoil.Name, // Object Name
2096 75 : cAlphaFields(7)); // Field Name
2097 :
2098 75 : if (!ErrorsFound) {
2099 75 : if (state.dataCurveManager->PerfCurve(thisDXCoil.EIRFTemp(1))->numDims == 1) {
2100 74 : checkCurveIsNormalizedToOne(state,
2101 148 : std::string{RoutineName} + CurrentModuleObject,
2102 74 : thisDXCoil.Name,
2103 74 : thisDXCoil.EIRFTemp(1),
2104 74 : cAlphaFields(7),
2105 74 : Alphas(7),
2106 : RatedOutdoorAirTempHeat);
2107 : } else {
2108 1 : checkCurveIsNormalizedToOne(state,
2109 2 : std::string{RoutineName} + CurrentModuleObject,
2110 1 : thisDXCoil.Name,
2111 1 : thisDXCoil.EIRFTemp(1),
2112 1 : cAlphaFields(7),
2113 1 : Alphas(7),
2114 : RatedInletAirTempHeat,
2115 : RatedOutdoorAirTempHeat);
2116 : }
2117 : }
2118 : }
2119 :
2120 75 : thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
2121 75 : if (thisDXCoil.EIRFFlow(1) == 0) {
2122 0 : if (lAlphaBlanks(8)) {
2123 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2124 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
2125 : } else {
2126 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2127 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
2128 : }
2129 0 : ErrorsFound = true;
2130 : } else {
2131 : // Verify Curve Object, only legal type is Quadratic or Cubic
2132 150 : ErrorsFound |= Curve::CheckCurveDims(state,
2133 75 : thisDXCoil.EIRFFlow(1), // Curve index
2134 : {1}, // Valid dimensions
2135 : RoutineName, // Routine name
2136 : CurrentModuleObject, // Object Type
2137 : thisDXCoil.Name, // Object Name
2138 75 : cAlphaFields(8)); // Field Name
2139 :
2140 75 : if (!ErrorsFound) {
2141 75 : checkCurveIsNormalizedToOne(
2142 150 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
2143 : }
2144 : }
2145 :
2146 75 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
2147 75 : if (thisDXCoil.PLFFPLR(1) == 0) {
2148 0 : if (lAlphaBlanks(9)) {
2149 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2150 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
2151 : } else {
2152 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2153 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
2154 : }
2155 0 : ErrorsFound = true;
2156 : } else {
2157 : // Verify Curve Object, only legal types are Quadratic or Cubic
2158 150 : ErrorsFound |= Curve::CheckCurveDims(state,
2159 75 : thisDXCoil.PLFFPLR(1), // Curve index
2160 : {1}, // Valid dimensions
2161 : RoutineName, // Routine name
2162 : CurrentModuleObject, // Object Type
2163 : thisDXCoil.Name, // Object Name
2164 75 : cAlphaFields(9)); // Field Name
2165 :
2166 75 : if (!ErrorsFound) {
2167 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
2168 75 : MinCurveVal = 999.0;
2169 75 : MaxCurveVal = -999.0;
2170 75 : CurveInput = 0.0;
2171 7575 : while (CurveInput <= 1.0) {
2172 7500 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
2173 7500 : if (CurveVal < MinCurveVal) {
2174 75 : MinCurveVal = CurveVal;
2175 75 : MinCurvePLR = CurveInput;
2176 : }
2177 7500 : if (CurveVal > MaxCurveVal) {
2178 7500 : MaxCurveVal = CurveVal;
2179 7500 : MaxCurvePLR = CurveInput;
2180 : }
2181 7500 : CurveInput += 0.01;
2182 : }
2183 75 : if (MinCurveVal < 0.7) {
2184 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2185 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
2186 0 : ShowContinueError(state,
2187 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
2188 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
2189 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
2190 : }
2191 :
2192 75 : if (MaxCurveVal > 1.0) {
2193 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2194 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
2195 0 : ShowContinueError(state,
2196 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
2197 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
2198 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
2199 : }
2200 : }
2201 : }
2202 :
2203 : // Only required for reverse cycle heat pumps
2204 75 : thisDXCoil.DefrostEIRFT = GetCurveIndex(state, Alphas(10)); // convert curve name to number
2205 : // A11; \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
2206 75 : if (!lAlphaBlanks(11)) {
2207 1 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(11));
2208 1 : ErrorsFound |= Curve::CheckCurveDims(state,
2209 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
2210 : {1}, // Valid dimensions
2211 : RoutineName, // Routine name
2212 : CurrentModuleObject, // Object Type
2213 : thisDXCoil.Name, // Object Name
2214 1 : cAlphaFields(11)); // Field Name
2215 : }
2216 :
2217 75 : if (Util::SameString(Alphas(12), "ReverseCycle")) {
2218 :
2219 27 : if (thisDXCoil.DefrostEIRFT == 0) {
2220 0 : if (lAlphaBlanks(10)) {
2221 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2222 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(10)));
2223 0 : ShowContinueError(state, format("...field is required because {} is \"ReverseCycle\".", cAlphaFields(12)));
2224 : } else {
2225 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2226 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
2227 : }
2228 0 : ErrorsFound = true;
2229 : } else {
2230 : // Verify Curve Object, only legal type is BiQuadratic
2231 27 : ErrorsFound |= Curve::CheckCurveDims(state,
2232 : thisDXCoil.DefrostEIRFT, // Curve index
2233 : {2}, // Valid dimensions
2234 : RoutineName, // Routine name
2235 : CurrentModuleObject, // Object Type
2236 : thisDXCoil.Name, // Object Name
2237 27 : cAlphaFields(10)); // Field Name
2238 :
2239 27 : if (!ErrorsFound) {
2240 27 : checkCurveIsNormalizedToOne(state,
2241 54 : std::string{RoutineName} + CurrentModuleObject,
2242 27 : thisDXCoil.Name,
2243 : thisDXCoil.DefrostEIRFT,
2244 27 : cAlphaFields(10),
2245 27 : Alphas(10),
2246 : RatedInletAirTempHeat,
2247 : RatedOutdoorAirTempHeat);
2248 : }
2249 : }
2250 : }
2251 :
2252 75 : if (Util::SameString(Alphas(12), "ReverseCycle")) thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
2253 75 : if (Util::SameString(Alphas(12), "Resistive")) thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
2254 :
2255 75 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
2256 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2257 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(12), Alphas(12)));
2258 0 : ShowContinueError(state, "...valid values for this field are ReverseCycle or Resistive.");
2259 0 : ErrorsFound = true;
2260 : }
2261 :
2262 75 : if (Util::SameString(Alphas(13), "Timed")) thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::Timed;
2263 75 : if (Util::SameString(Alphas(13), "OnDemand")) thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
2264 75 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
2265 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2266 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(13), Alphas(13)));
2267 0 : ShowContinueError(state, "...valid values for this field are Timed or OnDemand.");
2268 0 : ErrorsFound = true;
2269 : }
2270 :
2271 75 : thisDXCoil.RatedSHR(1) = 1.0;
2272 75 : thisDXCoil.RatedTotCap(1) = Numbers(1);
2273 75 : thisDXCoil.RatedCOP(1) = Numbers(2);
2274 75 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(3);
2275 75 : thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(4);
2276 75 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(5);
2277 :
2278 : // Set minimum OAT for heat pump compressor operation
2279 75 : thisDXCoil.MinOATCompressor = Numbers(6);
2280 :
2281 75 : thisDXCoil.OATempCompressorOn = Numbers(7);
2282 :
2283 75 : if (lNumericBlanks(7) || lNumericBlanks(6)) { //??TBD:BPS 6 or 5 | 7 or 6
2284 74 : thisDXCoil.OATempCompressorOnOffBlank = true;
2285 : } else {
2286 1 : thisDXCoil.OATempCompressorOnOffBlank = false;
2287 : }
2288 :
2289 75 : if (thisDXCoil.OATempCompressorOn < thisDXCoil.MinOATCompressor) thisDXCoil.OATempCompressorOn = thisDXCoil.MinOATCompressor;
2290 :
2291 : // Set maximum outdoor temp for defrost to occur
2292 75 : thisDXCoil.MaxOATDefrost = Numbers(8);
2293 :
2294 : // Set crankcase heater capacity
2295 75 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(9);
2296 75 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
2297 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2298 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(8)));
2299 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(9)));
2300 0 : ErrorsFound = true;
2301 : }
2302 :
2303 : // Set crankcase heater cutout temperature
2304 75 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(10);
2305 :
2306 : // Set defrost time period
2307 75 : thisDXCoil.DefrostTime = Numbers(11);
2308 75 : if (thisDXCoil.DefrostTime == 0.0 && thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
2309 0 : ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2310 0 : ShowContinueError(state, format("...{} = 0.0 for defrost control = TIMED.", cNumericFields(11)));
2311 : }
2312 :
2313 : // Set defrost capacity (for resistive defrost)
2314 75 : thisDXCoil.DefrostCapacity = Numbers(12);
2315 75 : if (thisDXCoil.DefrostCapacity == 0.0 && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
2316 0 : ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2317 0 : ShowContinueError(state, format("...{} = 0.0 for defrost strategy = RESISTIVE.", cNumericFields(12)));
2318 : }
2319 :
2320 : // Set Region number for calculating HSPF
2321 75 : thisDXCoil.RegionNum = Numbers(13);
2322 :
2323 75 : if (lNumericBlanks(13)) {
2324 74 : thisDXCoil.RegionNum = 4;
2325 : }
2326 :
2327 75 : thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
2328 :
2329 : // A14 is optional evaporator node name
2330 75 : if (lAlphaBlanks(14)) {
2331 72 : thisDXCoil.CondenserInletNodeNum(1) = 0;
2332 : } else {
2333 6 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
2334 3 : Alphas(14),
2335 : ErrorsFound,
2336 : DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
2337 3 : thisDXCoil.Name,
2338 : DataLoopNode::NodeFluidType::Air,
2339 : DataLoopNode::ConnectionType::OutsideAirReference,
2340 : NodeInputManager::CompFluidStream::Primary,
2341 : ObjectIsNotParent);
2342 : // warn if not an outdoor node, but allow
2343 3 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
2344 0 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2345 0 : ShowContinueError(
2346 : state,
2347 0 : format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(14), Alphas(14)));
2348 0 : ShowContinueError(
2349 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
2350 : }
2351 : }
2352 :
2353 : // A14, \field Zone Name for Evaporator Placement
2354 75 : if (!lAlphaBlanks(15) && NumAlphas > 14) {
2355 1 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(15), state.dataHeatBal->Zone);
2356 1 : if (thisDXCoil.SecZonePtr > 0) {
2357 1 : SetupZoneInternalGain(state,
2358 : thisDXCoil.SecZonePtr,
2359 : thisDXCoil.Name,
2360 : DataHeatBalance::IntGainType::SecHeatingDXCoilSingleSpeed,
2361 : &thisDXCoil.SecCoilSensibleHeatRemovalRate,
2362 : nullptr,
2363 : nullptr,
2364 : &thisDXCoil.SecCoilLatentHeatRemovalRate);
2365 1 : thisDXCoil.IsSecondaryDXCoilInZone = true;
2366 : } else {
2367 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2368 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15), Alphas(15)));
2369 : }
2370 : }
2371 75 : if (thisDXCoil.SecZonePtr > 0) {
2372 : // N14, \field Secondary Coil Air Flow Rate
2373 1 : if (!lNumericBlanks(13)) {
2374 1 : thisDXCoil.SecCoilAirFlow = Numbers(14);
2375 : }
2376 : // N15, \field Secondary Coil Fan Flow Scaling Factor
2377 1 : if (!lNumericBlanks(15)) {
2378 1 : thisDXCoil.SecCoilAirFlowScalingFactor = Numbers(15);
2379 : }
2380 : // N16, \field Nominal Sensible Heat Ratio of Secondary Coil
2381 1 : if (!lNumericBlanks(16)) {
2382 1 : thisDXCoil.SecCoilRatedSHR = Numbers(16);
2383 : } else {
2384 0 : thisDXCoil.SecCoilRatedSHR = 1.0;
2385 : }
2386 : // A16, \field Sensible Heat Ratio Modifier Function of Temperature Curve Name
2387 1 : if (!lAlphaBlanks(16)) {
2388 1 : thisDXCoil.SecCoilSHRFT = GetCurveIndex(state, Alphas(16));
2389 1 : if (thisDXCoil.SecCoilSHRFT == 0) {
2390 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2391 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
2392 : }
2393 : }
2394 : // A17; \field Sensible Heat Ratio Function of Flow Fraction Curve Name
2395 1 : if (!lAlphaBlanks(17)) {
2396 1 : thisDXCoil.SecCoilSHRFF = GetCurveIndex(state, Alphas(17));
2397 1 : if (thisDXCoil.SecCoilSHRFF == 0) {
2398 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2399 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
2400 : }
2401 : }
2402 : }
2403 :
2404 : } // end of the DX heating coil loop
2405 :
2406 247 : if (ErrorsFound) {
2407 0 : ShowFatalError(state,
2408 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
2409 : }
2410 :
2411 247 : CurrentModuleObject = "Coil:Cooling:DX:TwoSpeed";
2412 314 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedCoils; ++DXCoilIndex) {
2413 :
2414 67 : ++DXCoilNum;
2415 :
2416 67 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2417 : CurrentModuleObject,
2418 : DXCoilIndex,
2419 : Alphas,
2420 : NumAlphas,
2421 : Numbers,
2422 : NumNumbers,
2423 : IOStatus,
2424 : lNumericBlanks,
2425 : lAlphaBlanks,
2426 : cAlphaFields,
2427 : cNumericFields);
2428 :
2429 : // allocate single performance mode for numeric field strings used for sizing routine
2430 67 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
2431 67 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
2432 67 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
2433 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
2434 67 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
2435 :
2436 67 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
2437 67 : thisDXCoil.Name = Alphas(1);
2438 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
2439 67 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
2440 67 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
2441 67 : thisDXCoil.DXCoilType = CurrentModuleObject;
2442 67 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingTwoSpeed;
2443 67 : thisDXCoil.Schedule = Alphas(2);
2444 67 : if (lAlphaBlanks(2)) {
2445 2 : thisDXCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
2446 : } else {
2447 65 : thisDXCoil.SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
2448 65 : if (thisDXCoil.SchedPtr == 0) {
2449 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2450 0 : ShowContinueError(state, format("...{}=\"{}\".", cAlphaFields(2), Alphas(2)));
2451 0 : ErrorsFound = true;
2452 : }
2453 : }
2454 67 : thisDXCoil.RatedTotCap(1) = Numbers(1);
2455 67 : thisDXCoil.RatedSHR(1) = Numbers(2);
2456 67 : thisDXCoil.RatedCOP(1) = Numbers(3);
2457 67 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(4);
2458 :
2459 67 : thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(5);
2460 67 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(6);
2461 :
2462 67 : if (!lNumericBlanks(7)) {
2463 32 : thisDXCoil.InternalStaticPressureDrop = Numbers(7);
2464 32 : thisDXCoil.RateWithInternalStaticAndFanObject = true;
2465 : } else {
2466 35 : thisDXCoil.InternalStaticPressureDrop = -999.0;
2467 35 : thisDXCoil.RateWithInternalStaticAndFanObject = false;
2468 : }
2469 :
2470 67 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
2471 67 : Alphas(3),
2472 : ErrorsFound,
2473 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
2474 67 : Alphas(1),
2475 : DataLoopNode::NodeFluidType::Air,
2476 : DataLoopNode::ConnectionType::Inlet,
2477 : NodeInputManager::CompFluidStream::Primary,
2478 : ObjectIsNotParent);
2479 :
2480 67 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
2481 67 : Alphas(4),
2482 : ErrorsFound,
2483 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
2484 67 : Alphas(1),
2485 : DataLoopNode::NodeFluidType::Air,
2486 : DataLoopNode::ConnectionType::Outlet,
2487 : NodeInputManager::CompFluidStream::Primary,
2488 : ObjectIsNotParent);
2489 :
2490 67 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
2491 :
2492 67 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
2493 67 : if (thisDXCoil.CCapFTemp(1) == 0) {
2494 0 : if (lAlphaBlanks(5)) {
2495 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2496 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
2497 : } else {
2498 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2499 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
2500 : }
2501 0 : ErrorsFound = true;
2502 : } else {
2503 : // Verify Curve Object, only legal type is BiQuadratic
2504 134 : ErrorsFound |= Curve::CheckCurveDims(state,
2505 67 : thisDXCoil.CCapFTemp(1), // Curve index
2506 : {2}, // Valid dimensions
2507 : RoutineName, // Routine name
2508 : CurrentModuleObject, // Object Type
2509 : thisDXCoil.Name, // Object Name
2510 67 : cAlphaFields(5)); // Field Name
2511 :
2512 67 : if (!ErrorsFound) {
2513 67 : checkCurveIsNormalizedToOne(state,
2514 134 : std::string{RoutineName} + CurrentModuleObject,
2515 67 : thisDXCoil.Name,
2516 67 : thisDXCoil.CCapFTemp(1),
2517 67 : cAlphaFields(5),
2518 67 : Alphas(5),
2519 : RatedInletWetBulbTemp,
2520 : RatedOutdoorAirTemp);
2521 : }
2522 : }
2523 :
2524 67 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
2525 67 : if (thisDXCoil.CCapFFlow(1) == 0) {
2526 0 : if (lAlphaBlanks(6)) {
2527 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2528 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
2529 : } else {
2530 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2531 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
2532 : }
2533 0 : ErrorsFound = true;
2534 : } else {
2535 : // Verify Curve Object, only legal type is Quadratic
2536 134 : ErrorsFound |= Curve::CheckCurveDims(state,
2537 67 : thisDXCoil.CCapFFlow(1), // Curve index
2538 : {1}, // Valid dimensions
2539 : RoutineName, // Routine name
2540 : CurrentModuleObject, // Object Type
2541 : thisDXCoil.Name, // Object Name
2542 67 : cAlphaFields(6)); // Field Name
2543 :
2544 67 : if (!ErrorsFound) {
2545 67 : checkCurveIsNormalizedToOne(
2546 134 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
2547 : }
2548 : }
2549 :
2550 67 : thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
2551 67 : if (thisDXCoil.EIRFTemp(1) == 0) {
2552 0 : if (lAlphaBlanks(7)) {
2553 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2554 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
2555 : } else {
2556 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2557 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
2558 : }
2559 0 : ErrorsFound = true;
2560 : } else {
2561 : // Verify Curve Object, only legal type is BiQuadratic
2562 134 : ErrorsFound |= Curve::CheckCurveDims(state,
2563 67 : thisDXCoil.EIRFTemp(1), // Curve index
2564 : {2}, // Valid dimensions
2565 : RoutineName, // Routine name
2566 : CurrentModuleObject, // Object Type
2567 : thisDXCoil.Name, // Object Name
2568 67 : cAlphaFields(7)); // Field Name
2569 :
2570 67 : if (!ErrorsFound) {
2571 67 : checkCurveIsNormalizedToOne(state,
2572 134 : std::string{RoutineName} + CurrentModuleObject,
2573 67 : thisDXCoil.Name,
2574 67 : thisDXCoil.EIRFTemp(1),
2575 67 : cAlphaFields(7),
2576 67 : Alphas(7),
2577 : RatedInletWetBulbTemp,
2578 : RatedOutdoorAirTemp);
2579 : }
2580 : }
2581 :
2582 67 : thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
2583 67 : if (thisDXCoil.EIRFFlow(1) == 0) {
2584 0 : if (lAlphaBlanks(8)) {
2585 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2586 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
2587 : } else {
2588 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2589 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
2590 : }
2591 0 : ErrorsFound = true;
2592 : } else {
2593 : // Verify Curve Object, only legal type is Quadratic
2594 134 : ErrorsFound |= Curve::CheckCurveDims(state,
2595 67 : thisDXCoil.EIRFFlow(1), // Curve index
2596 : {1}, // Valid dimensions
2597 : RoutineName, // Routine name
2598 : CurrentModuleObject, // Object Type
2599 : thisDXCoil.Name, // Object Name
2600 67 : cAlphaFields(8)); // Field Name
2601 :
2602 67 : if (!ErrorsFound) {
2603 67 : checkCurveIsNormalizedToOne(
2604 134 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
2605 : }
2606 : }
2607 :
2608 67 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
2609 67 : if (thisDXCoil.PLFFPLR(1) == 0) {
2610 0 : if (lAlphaBlanks(9)) {
2611 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2612 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
2613 : } else {
2614 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2615 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
2616 : }
2617 0 : ErrorsFound = true;
2618 : } else {
2619 : // Verify Curve Object, only legal types are Quadratic or Cubic
2620 134 : ErrorsFound |= Curve::CheckCurveDims(state,
2621 67 : thisDXCoil.PLFFPLR(1), // Curve index
2622 : {1}, // Valid dimensions
2623 : RoutineName, // Routine name
2624 : CurrentModuleObject, // Object Type
2625 : thisDXCoil.Name, // Object Name
2626 67 : cAlphaFields(9)); // Field Name
2627 :
2628 67 : if (!ErrorsFound) {
2629 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
2630 67 : MinCurveVal = 999.0;
2631 67 : MaxCurveVal = -999.0;
2632 67 : CurveInput = 0.0;
2633 6767 : while (CurveInput <= 1.0) {
2634 6700 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
2635 6700 : if (CurveVal < MinCurveVal) {
2636 67 : MinCurveVal = CurveVal;
2637 67 : MinCurvePLR = CurveInput;
2638 : }
2639 6700 : if (CurveVal > MaxCurveVal) {
2640 2542 : MaxCurveVal = CurveVal;
2641 2542 : MaxCurvePLR = CurveInput;
2642 : }
2643 6700 : CurveInput += 0.01;
2644 : }
2645 67 : if (MinCurveVal < 0.7) {
2646 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2647 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
2648 0 : ShowContinueError(state,
2649 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
2650 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
2651 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
2652 : }
2653 :
2654 67 : if (MaxCurveVal > 1.0) {
2655 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2656 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
2657 0 : ShowContinueError(state,
2658 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
2659 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
2660 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
2661 : }
2662 : }
2663 : }
2664 :
2665 67 : thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
2666 :
2667 67 : thisDXCoil.RatedTotCap2 = Numbers(8);
2668 67 : thisDXCoil.RatedSHR2 = Numbers(9);
2669 67 : thisDXCoil.RatedCOP2 = Numbers(10);
2670 67 : thisDXCoil.RatedAirVolFlowRate2 = Numbers(11);
2671 :
2672 67 : thisDXCoil.FanPowerPerEvapAirFlowRate_LowSpeed(1) = Numbers(12);
2673 67 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023_LowSpeed(1) = Numbers(13);
2674 :
2675 67 : if (lNumericBlanks(14)) {
2676 67 : thisDXCoil.MinOATCompressor = -25.0;
2677 : } else {
2678 0 : thisDXCoil.MinOATCompressor = Numbers(14);
2679 : }
2680 :
2681 67 : thisDXCoil.CCapFTemp2 = GetCurveIndex(state, Alphas(10)); // convert curve name to number
2682 67 : if (thisDXCoil.CCapFTemp2 == 0) {
2683 0 : if (lAlphaBlanks(10)) {
2684 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2685 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(10)));
2686 : } else {
2687 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2688 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
2689 : }
2690 0 : ErrorsFound = true;
2691 : } else {
2692 : // Verify Curve Object, only legal type is BiQuadratic
2693 67 : ErrorsFound |= Curve::CheckCurveDims(state,
2694 : thisDXCoil.CCapFTemp2, // Curve index
2695 : {2}, // Valid dimensions
2696 : RoutineName, // Routine name
2697 : CurrentModuleObject, // Object Type
2698 : thisDXCoil.Name, // Object Name
2699 67 : cAlphaFields(10)); // Field Name
2700 :
2701 67 : if (!ErrorsFound) {
2702 67 : checkCurveIsNormalizedToOne(state,
2703 134 : std::string{RoutineName} + CurrentModuleObject,
2704 67 : thisDXCoil.Name,
2705 : thisDXCoil.CCapFTemp2,
2706 67 : cAlphaFields(10),
2707 67 : Alphas(10),
2708 : RatedInletWetBulbTemp,
2709 : RatedOutdoorAirTemp);
2710 : }
2711 : }
2712 :
2713 67 : thisDXCoil.EIRFTemp2 = GetCurveIndex(state, Alphas(11)); // convert curve name to number
2714 67 : if (thisDXCoil.EIRFTemp2 == 0) {
2715 0 : if (lAlphaBlanks(11)) {
2716 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2717 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(11)));
2718 : } else {
2719 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2720 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
2721 : }
2722 0 : ErrorsFound = true;
2723 : } else {
2724 : // Verify Curve Object, only legal type is BiQuadratic
2725 67 : ErrorsFound |= Curve::CheckCurveDims(state,
2726 : thisDXCoil.EIRFTemp2, // Curve index
2727 : {2}, // Valid dimensions
2728 : RoutineName, // Routine name
2729 : CurrentModuleObject, // Object Type
2730 : thisDXCoil.Name, // Object Name
2731 67 : cAlphaFields(11)); // Field Name
2732 :
2733 67 : if (!ErrorsFound) {
2734 67 : checkCurveIsNormalizedToOne(state,
2735 134 : std::string{RoutineName} + CurrentModuleObject,
2736 67 : thisDXCoil.Name,
2737 : thisDXCoil.EIRFTemp2,
2738 67 : cAlphaFields(11),
2739 67 : Alphas(11),
2740 : RatedInletWetBulbTemp,
2741 : RatedOutdoorAirTemp);
2742 : }
2743 : }
2744 :
2745 : // outdoor condenser node
2746 67 : if (lAlphaBlanks(12)) {
2747 58 : thisDXCoil.CondenserInletNodeNum(1) = 0;
2748 : } else {
2749 18 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
2750 9 : Alphas(12),
2751 : ErrorsFound,
2752 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
2753 9 : thisDXCoil.Name,
2754 : DataLoopNode::NodeFluidType::Air,
2755 : DataLoopNode::ConnectionType::OutsideAirReference,
2756 : NodeInputManager::CompFluidStream::Primary,
2757 : ObjectIsNotParent);
2758 9 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
2759 0 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2760 0 : ShowContinueError(
2761 : state,
2762 0 : format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(12), Alphas(12)));
2763 0 : ShowContinueError(
2764 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
2765 : }
2766 : }
2767 :
2768 67 : if ((Util::SameString(Alphas(13), "AirCooled")) || lAlphaBlanks(13)) {
2769 66 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
2770 1 : } else if (Util::SameString(Alphas(13), "EvaporativelyCooled")) {
2771 1 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
2772 1 : thisDXCoil.ReportEvapCondVars = true;
2773 : } else {
2774 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2775 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(13), Alphas(13)));
2776 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
2777 0 : ErrorsFound = true;
2778 : }
2779 :
2780 67 : thisDXCoil.EvapCondEffect(1) = Numbers(15);
2781 67 : if (thisDXCoil.EvapCondEffect(1) < 0.0 || thisDXCoil.EvapCondEffect(1) > 1.0) {
2782 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2783 0 : ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields(15)));
2784 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(15)));
2785 0 : ErrorsFound = true;
2786 : }
2787 :
2788 67 : thisDXCoil.EvapCondAirFlow(1) = Numbers(16);
2789 67 : if (thisDXCoil.EvapCondAirFlow(1) < 0.0 && thisDXCoil.EvapCondAirFlow(1) != AutoSize) {
2790 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2791 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(16)));
2792 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(16)));
2793 0 : ErrorsFound = true;
2794 : }
2795 :
2796 67 : thisDXCoil.EvapCondPumpElecNomPower(1) = Numbers(17);
2797 67 : if (thisDXCoil.EvapCondPumpElecNomPower(1) < 0.0 && thisDXCoil.EvapCondPumpElecNomPower(1) != AutoSize) {
2798 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2799 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(17)));
2800 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(17)));
2801 0 : ErrorsFound = true;
2802 : }
2803 :
2804 67 : thisDXCoil.EvapCondEffect2 = Numbers(18);
2805 67 : if (thisDXCoil.EvapCondEffect2 < 0.0 || thisDXCoil.EvapCondEffect2 > 1.0) {
2806 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2807 0 : ShowContinueError(state, format("...{} cannot be cannot be < 0.0 or > 1.0.", cNumericFields(18)));
2808 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(18)));
2809 0 : ErrorsFound = true;
2810 : }
2811 :
2812 67 : thisDXCoil.EvapCondAirFlow2 = Numbers(19);
2813 67 : if (thisDXCoil.EvapCondAirFlow2 < 0.0 && thisDXCoil.EvapCondAirFlow2 != AutoSize) {
2814 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2815 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(19)));
2816 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(19)));
2817 0 : ErrorsFound = true;
2818 : }
2819 :
2820 67 : thisDXCoil.EvapCondPumpElecNomPower2 = Numbers(20);
2821 67 : if (thisDXCoil.EvapCondPumpElecNomPower2 < 0.0 && thisDXCoil.EvapCondPumpElecNomPower2 != AutoSize) {
2822 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2823 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(20)));
2824 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(20)));
2825 0 : ErrorsFound = true;
2826 : }
2827 :
2828 67 : thisDXCoil.RatedEIR2 = 1.0 / thisDXCoil.RatedCOP2;
2829 :
2830 : // Get Water System tank connections
2831 : // A14, \field Name of Water Storage Tank for Supply
2832 67 : thisDXCoil.EvapWaterSupplyName = Alphas(14);
2833 67 : if (lAlphaBlanks(14)) {
2834 67 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
2835 : } else {
2836 0 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
2837 0 : SetupTankDemandComponent(state,
2838 : thisDXCoil.Name,
2839 : CurrentModuleObject,
2840 : thisDXCoil.EvapWaterSupplyName,
2841 : ErrorsFound,
2842 0 : thisDXCoil.EvapWaterSupTankID,
2843 0 : thisDXCoil.EvapWaterTankDemandARRID);
2844 : }
2845 :
2846 : // A15; \field Name of Water Storage Tank for Condensate Collection
2847 67 : thisDXCoil.CondensateCollectName = Alphas(15);
2848 67 : if (lAlphaBlanks(15)) {
2849 67 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
2850 : } else {
2851 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
2852 0 : SetupTankSupplyComponent(state,
2853 : thisDXCoil.Name,
2854 : CurrentModuleObject,
2855 : thisDXCoil.CondensateCollectName,
2856 : ErrorsFound,
2857 0 : thisDXCoil.CondensateTankID,
2858 0 : thisDXCoil.CondensateTankSupplyARRID);
2859 : }
2860 :
2861 : // Basin heater power as a function of temperature must be greater than or equal to 0
2862 67 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(21);
2863 67 : if (Numbers(21) < 0.0) {
2864 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2865 0 : ShowContinueError(state, format("...{} must be >= 0.0.", cNumericFields(21)));
2866 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(21)));
2867 0 : ErrorsFound = true;
2868 : }
2869 :
2870 67 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(22);
2871 67 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
2872 1 : if (NumNumbers < 22) {
2873 0 : thisDXCoil.BasinHeaterSetPointTemp = 2.0;
2874 : }
2875 1 : if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
2876 0 : ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2877 0 : ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(22)));
2878 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(22)));
2879 : }
2880 : }
2881 :
2882 67 : if (!lAlphaBlanks(16)) {
2883 1 : thisDXCoil.BasinHeaterSchedulePtr = GetScheduleIndex(state, Alphas(16));
2884 1 : if (thisDXCoil.BasinHeaterSchedulePtr == 0) {
2885 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2886 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
2887 0 : ShowContinueError(state, "Basin heater will be available to operate throughout the simulation.");
2888 : }
2889 : }
2890 :
2891 67 : if (!lAlphaBlanks(17) && NumAlphas > 16) {
2892 1 : thisDXCoil.SHRFTemp(1) = GetCurveIndex(state, Alphas(17)); // convert curve name to number
2893 : // DXCoil(DXCoilNum)%SHRFTemp2 = DXCoil(DXCoilNum)%SHRFTemp(1)
2894 1 : if (thisDXCoil.SHRFTemp(1) == 0) {
2895 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2896 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
2897 : } else {
2898 : // Verify Curve Object, only legal type is BiQuadratic
2899 2 : ErrorsFound |= Curve::CheckCurveDims(state,
2900 1 : thisDXCoil.SHRFTemp(1), // Curve index
2901 : {2}, // Valid dimensions
2902 : RoutineName, // Routine name
2903 : CurrentModuleObject, // Object Type
2904 : thisDXCoil.Name, // Object Name
2905 1 : cAlphaFields(17)); // Field Name
2906 : }
2907 : }
2908 :
2909 67 : if (!lAlphaBlanks(18) && NumAlphas > 17) {
2910 1 : thisDXCoil.SHRFFlow(1) = GetCurveIndex(state, Alphas(18)); // convert curve name to number
2911 : // DXCoil(DXCoilNum)%SHRFFlow2 = DXCoil(DXCoilNum)%SHRFFlow(1)
2912 1 : if (thisDXCoil.SHRFFlow(1) == 0) {
2913 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2914 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(18), Alphas(18)));
2915 : } else {
2916 : // Verify Curve Object, only legal type is BiQuadratic
2917 2 : ErrorsFound |= Curve::CheckCurveDims(state,
2918 1 : thisDXCoil.SHRFFlow(1), // Curve index
2919 : {1}, // Valid dimensions
2920 : RoutineName, // Routine name
2921 : CurrentModuleObject, // Object Type
2922 : thisDXCoil.Name, // Object Name
2923 1 : cAlphaFields(18)); // Field Name
2924 : }
2925 : }
2926 :
2927 67 : if (!lAlphaBlanks(19) && NumAlphas > 18) {
2928 1 : thisDXCoil.SHRFTemp2 = GetCurveIndex(state, Alphas(19)); // convert curve name to number
2929 1 : if (thisDXCoil.SHRFTemp2 == 0) {
2930 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2931 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(19), Alphas(19)));
2932 : } else {
2933 : // Verify Curve Object, only legal type is BiQuadratic
2934 1 : ErrorsFound |= Curve::CheckCurveDims(state,
2935 : thisDXCoil.SHRFTemp2, // Curve index
2936 : {2}, // Valid dimensions
2937 : RoutineName, // Routine name
2938 : CurrentModuleObject, // Object Type
2939 : thisDXCoil.Name, // Object Name
2940 1 : cAlphaFields(19)); // Field Name
2941 : }
2942 : }
2943 :
2944 67 : if (!lAlphaBlanks(20) && NumAlphas > 19) {
2945 1 : thisDXCoil.SHRFFlow2 = GetCurveIndex(state, Alphas(20)); // convert curve name to number
2946 1 : if (thisDXCoil.SHRFTemp2 == 0) {
2947 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2948 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(20), Alphas(20)));
2949 : } else {
2950 : // Verify Curve Object, only legal type is BiQuadratic
2951 1 : ErrorsFound |= Curve::CheckCurveDims(state,
2952 : thisDXCoil.SHRFFlow2, // Curve index
2953 : {1}, // Valid dimensions
2954 : RoutineName, // Routine name
2955 : CurrentModuleObject, // Object Type
2956 : thisDXCoil.Name, // Object Name
2957 1 : cAlphaFields(20)); // Field Name
2958 : }
2959 : }
2960 67 : if (thisDXCoil.SHRFTemp(1) > 0 && thisDXCoil.SHRFFlow(1) > 0 && thisDXCoil.SHRFTemp2 > 0 && thisDXCoil.SHRFFlow2 > 0) {
2961 1 : thisDXCoil.UserSHRCurveExists = true;
2962 : } else {
2963 66 : thisDXCoil.UserSHRCurveExists = false;
2964 : }
2965 : // A21; \field Zone Name for Condenser Placement
2966 67 : if (!lAlphaBlanks(21) && NumAlphas > 20) {
2967 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(21), state.dataHeatBal->Zone);
2968 0 : if (thisDXCoil.SecZonePtr > 0) {
2969 0 : SetupZoneInternalGain(state,
2970 : thisDXCoil.SecZonePtr,
2971 : thisDXCoil.Name,
2972 : DataHeatBalance::IntGainType::SecCoolingDXCoilTwoSpeed,
2973 : &thisDXCoil.SecCoilSensibleHeatGainRate);
2974 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
2975 : } else {
2976 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2977 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(21), Alphas(21)));
2978 : }
2979 : }
2980 : }
2981 :
2982 247 : if (ErrorsFound) {
2983 0 : ShowFatalError(state,
2984 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
2985 : }
2986 :
2987 : // Loop over the Pumped DX Water Heater Coils and get & load the data
2988 247 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped);
2989 260 : for (DXHPWaterHeaterCoilNum = 1; DXHPWaterHeaterCoilNum <= state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils; ++DXHPWaterHeaterCoilNum) {
2990 :
2991 13 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2992 : CurrentModuleObject,
2993 : DXHPWaterHeaterCoilNum,
2994 : Alphas,
2995 : NumAlphas,
2996 : Numbers,
2997 : NumNumbers,
2998 : IOStatus,
2999 : lNumericBlanks,
3000 : lAlphaBlanks,
3001 : cAlphaFields,
3002 : cNumericFields);
3003 :
3004 13 : ++DXCoilNum;
3005 :
3006 : // allocate single performance mode for numeric field strings used for sizing routine
3007 13 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
3008 13 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
3009 13 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
3010 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
3011 13 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
3012 :
3013 13 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
3014 13 : thisDXCoil.Name = Alphas(1);
3015 13 : thisDXCoil.DXCoilType = CurrentModuleObject;
3016 13 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatPumpWaterHeaterPumped;
3017 13 : thisDXCoil.SchedPtr = 0; // heat pump water heater DX coil has no schedule
3018 :
3019 : // Store the HPWH DX coil heating capacity in RatedTotCap2. After backing off pump and fan heat,
3020 : // move to RatedTotCap() for use by DX coil
3021 13 : thisDXCoil.RatedTotCap2 = Numbers(1);
3022 13 : if (thisDXCoil.RatedTotCap2 <= 0.0) {
3023 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3024 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
3025 0 : ErrorsFound = true;
3026 : }
3027 :
3028 13 : thisDXCoil.RatedCOP(1) = Numbers(2);
3029 13 : if (thisDXCoil.RatedCOP(1) <= 0.0) {
3030 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3031 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(2), Numbers(2)));
3032 0 : ErrorsFound = true;
3033 : }
3034 :
3035 13 : thisDXCoil.RatedSHR(1) = Numbers(3);
3036 13 : if (thisDXCoil.RatedSHR(1) <= 0.0 || thisDXCoil.RatedSHR(1) > 1.0) {
3037 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3038 0 : ShowContinueError(state, format("...{} must be > 0 and <= 1. entered value=[{:.3T}].", cNumericFields(3), Numbers(3)));
3039 :
3040 0 : ErrorsFound = true;
3041 : }
3042 :
3043 13 : thisDXCoil.RatedInletDBTemp = Numbers(4);
3044 13 : if (thisDXCoil.RatedInletDBTemp <= 5.0) {
3045 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3046 0 : ShowContinueError(state, format("...{} must be > 5 {{C}}. entered value=[{:.1T}].", cNumericFields(4), Numbers(4)));
3047 0 : ErrorsFound = true;
3048 : }
3049 :
3050 13 : thisDXCoil.RatedInletWBTemp = Numbers(5);
3051 13 : if (thisDXCoil.RatedInletWBTemp <= 5.0) {
3052 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3053 0 : ShowContinueError(state, format("...{} must be > 5 {{C}}. entered value=[{:.1T}].", cNumericFields(5), Numbers(5)));
3054 0 : ErrorsFound = true;
3055 : }
3056 :
3057 13 : thisDXCoil.RatedInletWaterTemp = Numbers(6);
3058 13 : if (thisDXCoil.RatedInletWaterTemp <= 25.0) {
3059 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3060 0 : ShowContinueError(state, format("...{} must be > 25 {{C}}. entered value=[{:.1T}].", cNumericFields(6), Numbers(6)));
3061 0 : ErrorsFound = true;
3062 : }
3063 :
3064 13 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(7);
3065 13 : if (thisDXCoil.RatedAirVolFlowRate(1) != Constant::AutoCalculate) {
3066 7 : if (thisDXCoil.RatedAirVolFlowRate(1) <= 0.0) {
3067 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3068 0 : ShowContinueError(state, format("...{} must be > 0.0. entered value=[{:.3T}].", cNumericFields(7), Numbers(7)));
3069 0 : ErrorsFound = true;
3070 : }
3071 : }
3072 :
3073 13 : thisDXCoil.RatedHPWHCondWaterFlow = Numbers(8);
3074 : // move to init
3075 13 : if (thisDXCoil.RatedHPWHCondWaterFlow != Constant::AutoCalculate) {
3076 7 : if (thisDXCoil.RatedHPWHCondWaterFlow <= 0.0) {
3077 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3078 0 : ShowContinueError(state, format("...{} must be > 0.0 entered value=[{:.3T}].", cNumericFields(8), Numbers(8)));
3079 0 : ErrorsFound = true;
3080 : }
3081 : // check the range of flow rate to be >= 1 gpm/ton and <= 5 gpm/ton
3082 7 : if (thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2 < 1.79405e-8 ||
3083 7 : thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2 > 8.97024e-8) {
3084 0 : ShowWarningError(state, format("{}{}=\"{}\", outside range", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3085 0 : ShowContinueError(state,
3086 0 : format("...{} per watt of {} is outside the recommended range of >= 1.79405E-8 m3/s/W (0.083 gpm/MBH) and <= "
3087 : "8.97024E-8 m3/s/W (0.417 gpm/MBH).",
3088 : cNumericFields(8),
3089 : cNumericFields(1)));
3090 0 : ShowContinueError(
3091 0 : state, format("...Entered Flow rate per watt = [{:.10T}].", (thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2)));
3092 : }
3093 : }
3094 :
3095 13 : if (Util::SameString(Alphas(2), "Yes") || Util::SameString(Alphas(2), "No")) {
3096 : // initialized to TRUE on allocate
3097 13 : if (Util::SameString(Alphas(2), "No")) thisDXCoil.FanPowerIncludedInCOP = false;
3098 : } else {
3099 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3100 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(2), Alphas(2)));
3101 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3102 0 : ErrorsFound = true;
3103 : }
3104 :
3105 13 : if (Util::SameString(Alphas(3), "Yes") || Util::SameString(Alphas(3), "No")) {
3106 : // initialized to FALSE on allocate
3107 13 : if (Util::SameString(Alphas(3), "Yes")) thisDXCoil.CondPumpPowerInCOP = true;
3108 : } else {
3109 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3110 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(3), Alphas(3)));
3111 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3112 0 : ErrorsFound = true;
3113 : }
3114 :
3115 13 : if (Util::SameString(Alphas(4), "Yes") || Util::SameString(Alphas(4), "No")) {
3116 : // initialized to FALSE on allocate
3117 13 : if (Util::SameString(Alphas(4), "Yes")) thisDXCoil.CondPumpHeatInCapacity = true;
3118 : } else {
3119 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3120 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(4), Alphas(4)));
3121 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3122 0 : ErrorsFound = true;
3123 : }
3124 :
3125 13 : thisDXCoil.HPWHCondPumpElecNomPower = Numbers(9);
3126 13 : if (thisDXCoil.HPWHCondPumpElecNomPower < 0.0) {
3127 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3128 0 : ShowContinueError(state, format("...{} must be >= 0.0 entered value=[{:.3T}].", cNumericFields(9), Numbers(9)));
3129 0 : ErrorsFound = true;
3130 : }
3131 :
3132 13 : thisDXCoil.HPWHCondPumpFracToWater = Numbers(10);
3133 13 : if (thisDXCoil.HPWHCondPumpFracToWater <= 0.0 || thisDXCoil.HPWHCondPumpFracToWater > 1.0) {
3134 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3135 0 : ShowContinueError(state, format("...{} must be >= 0 and <= 1. entered value=[{:.3T}].", cNumericFields(10), Numbers(10)));
3136 0 : ErrorsFound = true;
3137 : }
3138 :
3139 : // Air nodes
3140 13 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
3141 13 : Alphas(5),
3142 : ErrorsFound,
3143 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3144 13 : Alphas(1),
3145 : DataLoopNode::NodeFluidType::Air,
3146 : DataLoopNode::ConnectionType::Inlet,
3147 : NodeInputManager::CompFluidStream::Primary,
3148 : ObjectIsNotParent);
3149 :
3150 13 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
3151 13 : Alphas(6),
3152 : ErrorsFound,
3153 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3154 13 : Alphas(1),
3155 : DataLoopNode::NodeFluidType::Air,
3156 : DataLoopNode::ConnectionType::Outlet,
3157 : NodeInputManager::CompFluidStream::Primary,
3158 : ObjectIsNotParent);
3159 :
3160 13 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(5), Alphas(6), "Air Nodes");
3161 :
3162 : // Check if the air inlet node is OA node, to justify whether the coil is placed in zone or not
3163 13 : thisDXCoil.IsDXCoilInZone = !CheckOutAirNodeNumber(state, thisDXCoil.AirInNode);
3164 :
3165 : // Water nodes
3166 13 : thisDXCoil.WaterInNode = GetOnlySingleNode(state,
3167 13 : Alphas(7),
3168 : ErrorsFound,
3169 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3170 13 : Alphas(1),
3171 : DataLoopNode::NodeFluidType::Water,
3172 : DataLoopNode::ConnectionType::Inlet,
3173 : NodeInputManager::CompFluidStream::Secondary,
3174 : ObjectIsNotParent);
3175 :
3176 13 : thisDXCoil.WaterOutNode = GetOnlySingleNode(state,
3177 13 : Alphas(8),
3178 : ErrorsFound,
3179 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3180 13 : Alphas(1),
3181 : DataLoopNode::NodeFluidType::Water,
3182 : DataLoopNode::ConnectionType::Outlet,
3183 : NodeInputManager::CompFluidStream::Secondary,
3184 : ObjectIsNotParent);
3185 :
3186 13 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(7), Alphas(8), "Water Nodes");
3187 :
3188 13 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(11);
3189 13 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
3190 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3191 0 : ShowContinueError(state, format("...{} must be >= 0.0 entered value=[{:.1T}].", cNumericFields(11), Numbers(11)));
3192 0 : ErrorsFound = true;
3193 : }
3194 :
3195 13 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(12);
3196 13 : if (thisDXCoil.MaxOATCrankcaseHeater < 0.0) {
3197 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3198 0 : ShowContinueError(state, format("...{} must be >= 0 {{C}}. entered value=[{:.1T}].", cNumericFields(12), Numbers(12)));
3199 0 : ErrorsFound = true;
3200 : }
3201 :
3202 13 : if (!lAlphaBlanks(9)) {
3203 0 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(9));
3204 0 : ErrorsFound |= Curve::CheckCurveDims(state,
3205 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
3206 : {1}, // Valid dimensions
3207 : RoutineName, // Routine name
3208 : CurrentModuleObject, // Object Type
3209 : thisDXCoil.Name, // Object Name
3210 0 : cAlphaFields(9)); // Field Name
3211 : }
3212 :
3213 13 : thisDXCoil.InletAirTemperatureType = static_cast<HVAC::OATType>(getEnumValue(HVAC::oatTypeNamesUC, Alphas(10)));
3214 :
3215 : // set rated inlet air temperature for curve object verification
3216 13 : if (thisDXCoil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
3217 13 : InletAirTemp = thisDXCoil.RatedInletWBTemp;
3218 : } else {
3219 0 : InletAirTemp = thisDXCoil.RatedInletDBTemp;
3220 : }
3221 : // set rated water temperature for curve object verification
3222 13 : InletWaterTemp = thisDXCoil.RatedInletWaterTemp;
3223 :
3224 13 : if (!lAlphaBlanks(11)) {
3225 13 : thisDXCoil.HCapFTemp = GetCurveIndex(state, Alphas(11));
3226 13 : if (thisDXCoil.HCapFTemp == 0) {
3227 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3228 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
3229 0 : ErrorsFound = true;
3230 : } else {
3231 : // Verify Curve Object, only legal types are BiQuadratic or Cubic
3232 13 : ErrorsFound |= Curve::CheckCurveDims(state,
3233 : thisDXCoil.HCapFTemp, // Curve index
3234 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
3235 : RoutineName, // Routine name
3236 : CurrentModuleObject, // Object Type
3237 : thisDXCoil.Name, // Object Name
3238 13 : cAlphaFields(11)); // Field Name
3239 :
3240 13 : if (!ErrorsFound) {
3241 13 : if (state.dataCurveManager->PerfCurve(thisDXCoil.HCapFTemp)->numDims == 1) {
3242 0 : checkCurveIsNormalizedToOne(state,
3243 0 : std::string{RoutineName} + CurrentModuleObject,
3244 0 : thisDXCoil.Name,
3245 : thisDXCoil.HCapFTemp,
3246 0 : cAlphaFields(11),
3247 0 : Alphas(11),
3248 : InletAirTemp);
3249 : } else {
3250 13 : checkCurveIsNormalizedToOne(state,
3251 26 : std::string{RoutineName} + CurrentModuleObject,
3252 13 : thisDXCoil.Name,
3253 : thisDXCoil.HCapFTemp,
3254 13 : cAlphaFields(11),
3255 13 : Alphas(11),
3256 : InletAirTemp,
3257 : InletWaterTemp);
3258 : }
3259 : }
3260 : }
3261 : }
3262 :
3263 13 : if (!lAlphaBlanks(12)) {
3264 0 : thisDXCoil.HCapFAirFlow = GetCurveIndex(state, Alphas(12));
3265 0 : if (thisDXCoil.HCapFAirFlow == 0) {
3266 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3267 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(12), Alphas(12)));
3268 0 : ErrorsFound = true;
3269 : } else {
3270 : // Verify Curve Object, only legal types are Cubic or Quadratic
3271 0 : ErrorsFound |= Curve::CheckCurveDims(state,
3272 : thisDXCoil.HCapFAirFlow, // Curve index
3273 : {1}, // Valid dimensions
3274 : RoutineName, // Routine name
3275 : CurrentModuleObject, // Object Type
3276 : thisDXCoil.Name, // Object Name
3277 0 : cAlphaFields(12)); // Field Name
3278 :
3279 0 : if (!ErrorsFound) {
3280 0 : checkCurveIsNormalizedToOne(state,
3281 0 : std::string{RoutineName} + CurrentModuleObject,
3282 0 : thisDXCoil.Name,
3283 : thisDXCoil.HCapFAirFlow,
3284 0 : cAlphaFields(12),
3285 0 : Alphas(12),
3286 : 1.0);
3287 : }
3288 : }
3289 : }
3290 :
3291 13 : if (!lAlphaBlanks(13)) {
3292 0 : thisDXCoil.HCapFWaterFlow = GetCurveIndex(state, Alphas(13));
3293 0 : if (thisDXCoil.HCapFWaterFlow == 0) {
3294 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3295 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(13), Alphas(13)));
3296 0 : ErrorsFound = true;
3297 : } else {
3298 : // Verify Curve Object, only legal types are Cubic or Quadratic
3299 0 : ErrorsFound |= Curve::CheckCurveDims(state,
3300 : thisDXCoil.HCapFWaterFlow, // Curve index
3301 : {1}, // Valid dimensions
3302 : RoutineName, // Routine name
3303 : CurrentModuleObject, // Object Type
3304 : thisDXCoil.Name, // Object Name
3305 0 : cAlphaFields(13)); // Field Name
3306 :
3307 0 : if (!ErrorsFound) {
3308 0 : checkCurveIsNormalizedToOne(state,
3309 0 : std::string{RoutineName} + CurrentModuleObject,
3310 0 : thisDXCoil.Name,
3311 : thisDXCoil.HCapFWaterFlow,
3312 0 : cAlphaFields(13),
3313 0 : Alphas(13),
3314 : 1.0);
3315 : }
3316 : }
3317 : }
3318 :
3319 13 : if (!lAlphaBlanks(14)) {
3320 13 : thisDXCoil.HCOPFTemp = GetCurveIndex(state, Alphas(14));
3321 13 : if (thisDXCoil.HCOPFTemp == 0) {
3322 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3323 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14), Alphas(14)));
3324 0 : ErrorsFound = true;
3325 : } else {
3326 : // Verify Curve Object, only legal types are BiQuadratic or Cubic
3327 13 : ErrorsFound |= Curve::CheckCurveDims(state,
3328 : thisDXCoil.HCOPFTemp, // Curve index
3329 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
3330 : RoutineName, // Routine name
3331 : CurrentModuleObject, // Object Type
3332 : thisDXCoil.Name, // Object Name
3333 13 : cAlphaFields(14)); // Field Name
3334 :
3335 13 : if (!ErrorsFound) {
3336 13 : if (state.dataCurveManager->PerfCurve(thisDXCoil.HCOPFTemp)->numDims == 1) {
3337 0 : checkCurveIsNormalizedToOne(state,
3338 0 : std::string{RoutineName} + CurrentModuleObject,
3339 0 : thisDXCoil.Name,
3340 : thisDXCoil.HCOPFTemp,
3341 0 : cAlphaFields(14),
3342 0 : Alphas(14),
3343 : InletAirTemp);
3344 : } else {
3345 13 : checkCurveIsNormalizedToOne(state,
3346 26 : std::string{RoutineName} + CurrentModuleObject,
3347 13 : thisDXCoil.Name,
3348 : thisDXCoil.HCOPFTemp,
3349 13 : cAlphaFields(14),
3350 13 : Alphas(14),
3351 : InletAirTemp,
3352 : InletWaterTemp);
3353 : }
3354 : }
3355 : }
3356 : }
3357 :
3358 13 : if (!lAlphaBlanks(15)) {
3359 0 : thisDXCoil.HCOPFAirFlow = GetCurveIndex(state, Alphas(15));
3360 0 : if (thisDXCoil.HCOPFAirFlow == 0) {
3361 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3362 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15), Alphas(15)));
3363 0 : ErrorsFound = true;
3364 : } else {
3365 : // Verify Curve Object, only legal types are Cubic or Quadratic
3366 0 : ErrorsFound |= Curve::CheckCurveDims(state,
3367 : thisDXCoil.HCOPFAirFlow, // Curve index
3368 : {1}, // Valid dimensions
3369 : RoutineName, // Routine name
3370 : CurrentModuleObject, // Object Type
3371 : thisDXCoil.Name, // Object Name
3372 0 : cAlphaFields(15)); // Field Name
3373 :
3374 0 : if (!ErrorsFound) {
3375 0 : checkCurveIsNormalizedToOne(state,
3376 0 : std::string{RoutineName} + CurrentModuleObject,
3377 0 : thisDXCoil.Name,
3378 : thisDXCoil.HCOPFAirFlow,
3379 0 : cAlphaFields(15),
3380 0 : Alphas(15),
3381 : 1.0);
3382 : }
3383 : }
3384 : }
3385 :
3386 13 : if (!lAlphaBlanks(16)) {
3387 0 : thisDXCoil.HCOPFWaterFlow = GetCurveIndex(state, Alphas(16));
3388 0 : if (thisDXCoil.HCOPFWaterFlow == 0) {
3389 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3390 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
3391 0 : ErrorsFound = true;
3392 : } else {
3393 : // Verify Curve Object, only legal types are Cubic or Quadratic
3394 0 : ErrorsFound |= Curve::CheckCurveDims(state,
3395 : thisDXCoil.HCOPFWaterFlow, // Curve index
3396 : {1}, // Valid dimensions
3397 : RoutineName, // Routine name
3398 : CurrentModuleObject, // Object Type
3399 : thisDXCoil.Name, // Object Name
3400 0 : cAlphaFields(16)); // Field Name
3401 :
3402 0 : if (!ErrorsFound) {
3403 0 : checkCurveIsNormalizedToOne(state,
3404 0 : std::string{RoutineName} + CurrentModuleObject,
3405 0 : thisDXCoil.Name,
3406 : thisDXCoil.HCOPFWaterFlow,
3407 0 : cAlphaFields(16),
3408 0 : Alphas(16),
3409 : 1.0);
3410 : }
3411 : }
3412 : }
3413 :
3414 13 : if (!lAlphaBlanks(17)) {
3415 13 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(17));
3416 13 : if (thisDXCoil.PLFFPLR(1) == 0) {
3417 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3418 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
3419 0 : ErrorsFound = true;
3420 : } else {
3421 : // Verify Curve Object, only legal types are Cubic or Quadratic
3422 26 : ErrorsFound |= Curve::CheckCurveDims(state,
3423 13 : thisDXCoil.PLFFPLR(1), // Curve index
3424 : {1}, // Valid dimensions
3425 : RoutineName, // Routine name
3426 : CurrentModuleObject, // Object Type
3427 : thisDXCoil.Name, // Object Name
3428 13 : cAlphaFields(17)); // Field Name
3429 :
3430 13 : if (!ErrorsFound) {
3431 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
3432 13 : MinCurveVal = 999.0;
3433 13 : MaxCurveVal = -999.0;
3434 13 : CurveInput = 0.0;
3435 1313 : while (CurveInput <= 1.0) {
3436 1300 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
3437 1300 : if (CurveVal < MinCurveVal) {
3438 13 : MinCurveVal = CurveVal;
3439 13 : MinCurvePLR = CurveInput;
3440 : }
3441 1300 : if (CurveVal > MaxCurveVal) {
3442 1300 : MaxCurveVal = CurveVal;
3443 1300 : MaxCurvePLR = CurveInput;
3444 : }
3445 1300 : CurveInput += 0.01;
3446 : }
3447 13 : if (MinCurveVal < 0.7) {
3448 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3449 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(17), Alphas(17)));
3450 0 : ShowContinueError(state,
3451 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
3452 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
3453 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
3454 : }
3455 :
3456 13 : if (MaxCurveVal > 1.0) {
3457 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3458 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(17), Alphas(17)));
3459 0 : ShowContinueError(state,
3460 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
3461 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
3462 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
3463 : }
3464 : }
3465 : }
3466 : }
3467 :
3468 : // assume compressor resides at the inlet to the DX Coil
3469 13 : thisDXCoil.CondenserInletNodeNum(1) = thisDXCoil.AirInNode;
3470 :
3471 : // set condenser type as HPWH
3472 13 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::WaterHeater;
3473 :
3474 : } // end of the DX water heater coil loop
3475 :
3476 247 : if (ErrorsFound) {
3477 0 : ShowFatalError(state,
3478 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
3479 : }
3480 : // Loop over the Wrapped DX Water Heater Coils and get & load the data
3481 247 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped);
3482 250 : for (DXHPWaterHeaterCoilNum = 1; DXHPWaterHeaterCoilNum <= state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils; ++DXHPWaterHeaterCoilNum) {
3483 :
3484 3 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3485 : CurrentModuleObject,
3486 : DXHPWaterHeaterCoilNum,
3487 : Alphas,
3488 : NumAlphas,
3489 : Numbers,
3490 : NumNumbers,
3491 : IOStatus,
3492 : lNumericBlanks,
3493 : lAlphaBlanks,
3494 : cAlphaFields,
3495 : cNumericFields);
3496 :
3497 3 : ++DXCoilNum;
3498 :
3499 : // allocate single performance mode for numeric field strings used for sizing routine
3500 3 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
3501 3 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
3502 3 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
3503 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
3504 3 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
3505 :
3506 3 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
3507 3 : thisDXCoil.Name = Alphas(1);
3508 3 : thisDXCoil.DXCoilType = CurrentModuleObject;
3509 3 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatPumpWaterHeaterWrapped;
3510 3 : thisDXCoil.SchedPtr = 0; // heat pump water heater DX coil has no schedule
3511 :
3512 : // Store the HPWH DX coil heating capacity in RatedTotCap2. After backing off pump and fan heat,
3513 : // move to RatedTotCap() for use by DX coil
3514 3 : thisDXCoil.RatedTotCap2 = Numbers(1);
3515 3 : if (thisDXCoil.RatedTotCap2 <= 0.0) {
3516 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3517 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
3518 0 : ErrorsFound = true;
3519 : }
3520 :
3521 3 : thisDXCoil.RatedCOP(1) = Numbers(2);
3522 3 : if (thisDXCoil.RatedCOP(1) <= 0.0) {
3523 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3524 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(2), Numbers(2)));
3525 0 : ErrorsFound = true;
3526 : }
3527 :
3528 3 : thisDXCoil.RatedSHR(1) = Numbers(3);
3529 3 : if (thisDXCoil.RatedSHR(1) <= 0.0 || thisDXCoil.RatedSHR(1) > 1.0) {
3530 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3531 0 : ShowContinueError(state, format("...{} must be > 0 and <= 1. entered value=[{:.3T}].", cNumericFields(3), Numbers(3)));
3532 :
3533 0 : ErrorsFound = true;
3534 : }
3535 :
3536 3 : thisDXCoil.RatedInletDBTemp = Numbers(4);
3537 3 : if (thisDXCoil.RatedInletDBTemp <= 5.0) {
3538 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3539 0 : ShowContinueError(state, format("...{} must be > 5 {{C}}. entered value=[{:.1T}].", cNumericFields(4), Numbers(4)));
3540 0 : ErrorsFound = true;
3541 : }
3542 :
3543 3 : thisDXCoil.RatedInletWBTemp = Numbers(5);
3544 3 : if (thisDXCoil.RatedInletWBTemp <= 5.0) {
3545 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3546 0 : ShowContinueError(state, format("...{} must be > 5 {{C}}. entered value=[{:.1T}].", cNumericFields(5), Numbers(5)));
3547 0 : ErrorsFound = true;
3548 : }
3549 :
3550 3 : thisDXCoil.RatedInletWaterTemp = Numbers(6);
3551 3 : if (thisDXCoil.RatedInletWaterTemp <= 25.0) {
3552 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3553 0 : ShowContinueError(state, format("...{} must be > 25 {{C}}. entered value=[{:.1T}].", cNumericFields(6), Numbers(6)));
3554 0 : ErrorsFound = true;
3555 : }
3556 :
3557 3 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(7);
3558 3 : if (thisDXCoil.RatedAirVolFlowRate(1) != Constant::AutoCalculate) {
3559 3 : if (thisDXCoil.RatedAirVolFlowRate(1) <= 0.0) {
3560 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3561 0 : ShowContinueError(state, format("...{} must be > 0.0. entered value=[{:.3T}].", cNumericFields(7), Numbers(7)));
3562 0 : ErrorsFound = true;
3563 : }
3564 : }
3565 :
3566 3 : if (Util::SameString(Alphas(2), "Yes") || Util::SameString(Alphas(2), "No")) {
3567 : // initialized to TRUE on allocate
3568 3 : if (Util::SameString(Alphas(2), "No")) thisDXCoil.FanPowerIncludedInCOP = false;
3569 : } else {
3570 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3571 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(2), Alphas(2)));
3572 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3573 0 : ErrorsFound = true;
3574 : }
3575 :
3576 : // Air nodes
3577 3 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
3578 3 : Alphas(3),
3579 : ErrorsFound,
3580 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3581 3 : Alphas(1),
3582 : DataLoopNode::NodeFluidType::Air,
3583 : DataLoopNode::ConnectionType::Inlet,
3584 : NodeInputManager::CompFluidStream::Primary,
3585 : ObjectIsNotParent);
3586 :
3587 3 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
3588 3 : Alphas(4),
3589 : ErrorsFound,
3590 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3591 3 : Alphas(1),
3592 : DataLoopNode::NodeFluidType::Air,
3593 : DataLoopNode::ConnectionType::Outlet,
3594 : NodeInputManager::CompFluidStream::Primary,
3595 : ObjectIsNotParent);
3596 :
3597 3 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
3598 :
3599 : // Check if the air inlet node is OA node, to justify whether the coil is placed in zone or not
3600 3 : thisDXCoil.IsDXCoilInZone = !CheckOutAirNodeNumber(state, thisDXCoil.AirInNode);
3601 :
3602 3 : std::string const DummyCondenserInletName("DUMMY CONDENSER INLET " + thisDXCoil.Name);
3603 3 : std::string const DummyCondenserOutletName("DUMMY CONDENSER OUTLET " + thisDXCoil.Name);
3604 3 : thisDXCoil.WaterInNode = GetOnlySingleNode(state,
3605 : DummyCondenserInletName,
3606 : ErrorsFound,
3607 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3608 3 : Alphas(1),
3609 : DataLoopNode::NodeFluidType::Water,
3610 : DataLoopNode::ConnectionType::Inlet,
3611 : NodeInputManager::CompFluidStream::Secondary,
3612 : ObjectIsNotParent);
3613 :
3614 3 : thisDXCoil.WaterOutNode = GetOnlySingleNode(state,
3615 : DummyCondenserOutletName,
3616 : ErrorsFound,
3617 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3618 3 : Alphas(1),
3619 : DataLoopNode::NodeFluidType::Water,
3620 : DataLoopNode::ConnectionType::Outlet,
3621 : NodeInputManager::CompFluidStream::Secondary,
3622 : ObjectIsNotParent);
3623 :
3624 3 : TestCompSet(state, CurrentModuleObject, Alphas(1), DummyCondenserInletName, DummyCondenserOutletName, "Water Nodes");
3625 :
3626 3 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(8);
3627 3 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
3628 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3629 0 : ShowContinueError(state, format("...{} must be >= 0.0 entered value=[{:.1T}].", cNumericFields(8), Numbers(8)));
3630 0 : ErrorsFound = true;
3631 : }
3632 :
3633 3 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(9);
3634 3 : if (thisDXCoil.MaxOATCrankcaseHeater < 0.0) {
3635 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3636 0 : ShowContinueError(state, format("...{} must be >= 0 {{C}}. entered value=[{:.1T}].", cNumericFields(9), Numbers(9)));
3637 0 : ErrorsFound = true;
3638 : }
3639 :
3640 : // Coil:WaterHeating:AirToWaterHeatPump:Wrapped
3641 3 : if (!lAlphaBlanks(5)) {
3642 0 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
3643 0 : ErrorsFound |= Curve::CheckCurveDims(state,
3644 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
3645 : {1}, // Valid dimensions
3646 : RoutineName, // Routine name
3647 : CurrentModuleObject, // Object Type
3648 : thisDXCoil.Name, // Object Name
3649 0 : cAlphaFields(5)); // Field Name
3650 : }
3651 :
3652 3 : if (Util::SameString(Alphas(6), "DryBulbTemperature")) {
3653 0 : thisDXCoil.InletAirTemperatureType = HVAC::OATType::DryBulb;
3654 3 : } else if (Util::SameString(Alphas(6), "WetBulbTemperature")) {
3655 3 : thisDXCoil.InletAirTemperatureType = HVAC::OATType::WetBulb;
3656 : } else {
3657 : // wrong temperature type selection
3658 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3659 0 : ShowContinueError(state, format("...{} must be DryBulbTemperature or WetBulbTemperature.", cAlphaFields(6)));
3660 0 : ShowContinueError(state, format("...entered value=\"{}\".", Alphas(6)));
3661 0 : ErrorsFound = true;
3662 : }
3663 :
3664 : // set rated inlet air temperature for curve object verification
3665 3 : if (thisDXCoil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
3666 3 : InletAirTemp = thisDXCoil.RatedInletWBTemp;
3667 : } else {
3668 0 : InletAirTemp = thisDXCoil.RatedInletDBTemp;
3669 : }
3670 : // set rated water temperature for curve object verification
3671 3 : InletWaterTemp = thisDXCoil.RatedInletWaterTemp;
3672 :
3673 3 : if (!lAlphaBlanks(7)) {
3674 3 : thisDXCoil.HCapFTemp = GetCurveIndex(state, Alphas(7));
3675 3 : if (thisDXCoil.HCapFTemp == 0) {
3676 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3677 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
3678 0 : ErrorsFound = true;
3679 : } else {
3680 : // Verify Curve Object, only legal types are BiQuadratic or Cubic
3681 3 : ErrorsFound |= Curve::CheckCurveDims(state,
3682 : thisDXCoil.HCapFTemp, // Curve index
3683 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
3684 : RoutineName, // Routine name
3685 : CurrentModuleObject, // Object Type
3686 : thisDXCoil.Name, // Object Name
3687 3 : cAlphaFields(7)); // Field Name
3688 :
3689 3 : if (!ErrorsFound) {
3690 3 : if (state.dataCurveManager->PerfCurve(thisDXCoil.HCapFTemp)->numDims == 1) {
3691 0 : checkCurveIsNormalizedToOne(state,
3692 0 : std::string{RoutineName} + CurrentModuleObject,
3693 0 : thisDXCoil.Name,
3694 : thisDXCoil.HCapFTemp,
3695 0 : cAlphaFields(7),
3696 0 : Alphas(7),
3697 : InletAirTemp);
3698 : } else {
3699 3 : checkCurveIsNormalizedToOne(state,
3700 6 : std::string{RoutineName} + CurrentModuleObject,
3701 3 : thisDXCoil.Name,
3702 : thisDXCoil.HCapFTemp,
3703 3 : cAlphaFields(7),
3704 3 : Alphas(7),
3705 : InletAirTemp,
3706 : InletWaterTemp);
3707 : }
3708 : }
3709 : }
3710 : }
3711 :
3712 3 : if (!lAlphaBlanks(8)) {
3713 0 : thisDXCoil.HCapFAirFlow = GetCurveIndex(state, Alphas(8));
3714 0 : if (thisDXCoil.HCapFAirFlow == 0) {
3715 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3716 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
3717 0 : ErrorsFound = true;
3718 : } else {
3719 : // Verify Curve Object, only legal types are Cubic or Quadratic
3720 0 : ErrorsFound |= Curve::CheckCurveDims(state,
3721 : thisDXCoil.HCapFAirFlow, // Curve index
3722 : {1}, // Valid dimensions
3723 : RoutineName, // Routine name
3724 : CurrentModuleObject, // Object Type
3725 : thisDXCoil.Name, // Object Name
3726 0 : cAlphaFields(8)); // Field Name
3727 :
3728 0 : if (!ErrorsFound) {
3729 0 : checkCurveIsNormalizedToOne(state,
3730 0 : std::string{RoutineName} + CurrentModuleObject,
3731 0 : thisDXCoil.Name,
3732 : thisDXCoil.HCapFAirFlow,
3733 0 : cAlphaFields(8),
3734 0 : Alphas(8),
3735 : 1.0);
3736 : }
3737 : }
3738 : }
3739 :
3740 3 : if (!lAlphaBlanks(9)) {
3741 3 : thisDXCoil.HCOPFTemp = GetCurveIndex(state, Alphas(9));
3742 3 : if (thisDXCoil.HCOPFTemp == 0) {
3743 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3744 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
3745 0 : ErrorsFound = true;
3746 : } else {
3747 : // Verify Curve Object, only legal types are BiQuadratic or Cubic
3748 3 : ErrorsFound |= Curve::CheckCurveDims(state,
3749 : thisDXCoil.HCOPFTemp, // Curve index
3750 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
3751 : RoutineName, // Routine name
3752 : CurrentModuleObject, // Object Type
3753 : thisDXCoil.Name, // Object Name
3754 3 : cAlphaFields(9)); // Field Name
3755 :
3756 3 : if (!ErrorsFound) {
3757 3 : if (state.dataCurveManager->PerfCurve(thisDXCoil.HCOPFTemp)->numDims == 1) {
3758 0 : checkCurveIsNormalizedToOne(state,
3759 0 : std::string{RoutineName} + CurrentModuleObject,
3760 0 : thisDXCoil.Name,
3761 : thisDXCoil.HCOPFTemp,
3762 0 : cAlphaFields(9),
3763 0 : Alphas(9),
3764 : InletAirTemp);
3765 : } else {
3766 3 : checkCurveIsNormalizedToOne(state,
3767 6 : std::string{RoutineName} + CurrentModuleObject,
3768 3 : thisDXCoil.Name,
3769 : thisDXCoil.HCOPFTemp,
3770 3 : cAlphaFields(9),
3771 3 : Alphas(9),
3772 : InletAirTemp,
3773 : InletWaterTemp);
3774 : }
3775 : }
3776 : }
3777 : }
3778 :
3779 3 : if (!lAlphaBlanks(10)) {
3780 0 : thisDXCoil.HCOPFAirFlow = GetCurveIndex(state, Alphas(10));
3781 0 : if (thisDXCoil.HCOPFAirFlow == 0) {
3782 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3783 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
3784 0 : ErrorsFound = true;
3785 : } else {
3786 : // Verify Curve Object, only legal types are Cubic or Quadratic
3787 0 : ErrorsFound |= Curve::CheckCurveDims(state,
3788 : thisDXCoil.HCOPFAirFlow, // Curve index
3789 : {1}, // Valid dimensions
3790 : RoutineName, // Routine name
3791 : CurrentModuleObject, // Object Type
3792 : thisDXCoil.Name, // Object Name
3793 0 : cAlphaFields(10)); // Field Name
3794 :
3795 0 : if (!ErrorsFound) {
3796 0 : checkCurveIsNormalizedToOne(state,
3797 0 : std::string{RoutineName} + CurrentModuleObject,
3798 0 : thisDXCoil.Name,
3799 : thisDXCoil.HCOPFAirFlow,
3800 0 : cAlphaFields(10),
3801 0 : Alphas(10),
3802 : 1.0);
3803 : }
3804 : }
3805 : }
3806 :
3807 3 : if (!lAlphaBlanks(11)) {
3808 3 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(11));
3809 3 : if (thisDXCoil.PLFFPLR(1) == 0) {
3810 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3811 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
3812 0 : ErrorsFound = true;
3813 : } else {
3814 : // Verify Curve Object, only legal types are Cubic or Quadratic
3815 6 : ErrorsFound |= Curve::CheckCurveDims(state,
3816 3 : thisDXCoil.PLFFPLR(1), // Curve index
3817 : {1}, // Valid dimensions
3818 : RoutineName, // Routine name
3819 : CurrentModuleObject, // Object Type
3820 : thisDXCoil.Name, // Object Name
3821 3 : cAlphaFields(11)); // Field Name
3822 :
3823 3 : if (!ErrorsFound) {
3824 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
3825 3 : MinCurveVal = 999.0;
3826 3 : MaxCurveVal = -999.0;
3827 3 : CurveInput = 0.0;
3828 303 : while (CurveInput <= 1.0) {
3829 300 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
3830 300 : if (CurveVal < MinCurveVal) {
3831 3 : MinCurveVal = CurveVal;
3832 3 : MinCurvePLR = CurveInput;
3833 : }
3834 300 : if (CurveVal > MaxCurveVal) {
3835 3 : MaxCurveVal = CurveVal;
3836 3 : MaxCurvePLR = CurveInput;
3837 : }
3838 300 : CurveInput += 0.01;
3839 : }
3840 3 : if (MinCurveVal < 0.7) {
3841 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3842 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(11), Alphas(11)));
3843 0 : ShowContinueError(state,
3844 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
3845 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
3846 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
3847 : }
3848 :
3849 3 : if (MaxCurveVal > 1.0) {
3850 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3851 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(11), Alphas(11)));
3852 0 : ShowContinueError(state,
3853 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
3854 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
3855 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
3856 : }
3857 : }
3858 : }
3859 : }
3860 :
3861 : // assume compressor resides at the inlet to the DX Coil
3862 3 : thisDXCoil.CondenserInletNodeNum(1) = thisDXCoil.AirInNode;
3863 :
3864 : // set condenser type as HPWH
3865 3 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::WaterHeater;
3866 :
3867 3 : } // end of the DX water heater wrapped coil loop
3868 :
3869 247 : if (ErrorsFound) {
3870 0 : ShowFatalError(state,
3871 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
3872 : }
3873 :
3874 : // DX Multispeed cooling coil
3875 247 : CurrentModuleObject = "Coil:Cooling:DX:MultiSpeed";
3876 296 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedCoolCoils; ++DXCoilIndex) {
3877 :
3878 49 : ++DXCoilNum;
3879 :
3880 49 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3881 : CurrentModuleObject,
3882 : DXCoilIndex,
3883 : Alphas,
3884 : NumAlphas,
3885 : Numbers,
3886 : NumNumbers,
3887 : IOStatus,
3888 : lNumericBlanks,
3889 : lAlphaBlanks,
3890 : cAlphaFields,
3891 : cNumericFields);
3892 :
3893 : // allocate single performance mode for numeric field strings used for sizing routine (all fields are in this object)
3894 49 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
3895 49 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
3896 49 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
3897 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
3898 49 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
3899 :
3900 49 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
3901 49 : thisDXCoil.Name = Alphas(1);
3902 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
3903 49 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
3904 49 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
3905 49 : thisDXCoil.DXCoilType = CurrentModuleObject;
3906 49 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_MultiSpeedCooling;
3907 49 : thisDXCoil.Schedule = Alphas(2);
3908 49 : if (lAlphaBlanks(2)) {
3909 2 : thisDXCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
3910 : } else {
3911 47 : thisDXCoil.SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
3912 47 : if (thisDXCoil.SchedPtr == 0) {
3913 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3914 0 : ShowContinueError(state, format("...{}=\"{}\".", cAlphaFields(2), Alphas(2)));
3915 0 : ErrorsFound = true;
3916 : }
3917 : }
3918 :
3919 49 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
3920 49 : Alphas(3),
3921 : ErrorsFound,
3922 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
3923 49 : Alphas(1),
3924 : DataLoopNode::NodeFluidType::Air,
3925 : DataLoopNode::ConnectionType::Inlet,
3926 : NodeInputManager::CompFluidStream::Primary,
3927 : ObjectIsNotParent);
3928 :
3929 49 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
3930 49 : Alphas(4),
3931 : ErrorsFound,
3932 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
3933 49 : Alphas(1),
3934 : DataLoopNode::NodeFluidType::Air,
3935 : DataLoopNode::ConnectionType::Outlet,
3936 : NodeInputManager::CompFluidStream::Primary,
3937 : ObjectIsNotParent);
3938 :
3939 49 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
3940 :
3941 : // outdoor condenser node
3942 49 : if (lAlphaBlanks(5)) {
3943 33 : thisDXCoil.CondenserInletNodeNum(1) = 0;
3944 : } else {
3945 32 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
3946 16 : Alphas(5),
3947 : ErrorsFound,
3948 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
3949 16 : thisDXCoil.Name,
3950 : DataLoopNode::NodeFluidType::Air,
3951 : DataLoopNode::ConnectionType::OutsideAirReference,
3952 : NodeInputManager::CompFluidStream::Primary,
3953 : ObjectIsNotParent);
3954 16 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
3955 0 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3956 0 : ShowContinueError(
3957 0 : state, format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(5), Alphas(5)));
3958 0 : ShowContinueError(
3959 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
3960 : }
3961 : }
3962 :
3963 49 : if ((Util::SameString(Alphas(6), "AirCooled")) || lAlphaBlanks(6)) {
3964 49 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
3965 0 : } else if (Util::SameString(Alphas(6), "EvaporativelyCooled")) {
3966 0 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
3967 0 : thisDXCoil.ReportEvapCondVars = true;
3968 : } else {
3969 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3970 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(6), Alphas(6)));
3971 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
3972 0 : ErrorsFound = true;
3973 : }
3974 :
3975 : // Get Water System tank connections
3976 : // A8, \field Name of Water Storage Tank for Supply
3977 49 : thisDXCoil.EvapWaterSupplyName = Alphas(7);
3978 49 : if (lAlphaBlanks(7)) {
3979 49 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
3980 : } else {
3981 0 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
3982 0 : SetupTankDemandComponent(state,
3983 : thisDXCoil.Name,
3984 : CurrentModuleObject,
3985 : thisDXCoil.EvapWaterSupplyName,
3986 : ErrorsFound,
3987 0 : thisDXCoil.EvapWaterSupTankID,
3988 0 : thisDXCoil.EvapWaterTankDemandARRID);
3989 : }
3990 :
3991 : // A9; \field Name of Water Storage Tank for Condensate Collection
3992 49 : thisDXCoil.CondensateCollectName = Alphas(8);
3993 49 : if (lAlphaBlanks(8)) {
3994 49 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
3995 : } else {
3996 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
3997 0 : SetupTankSupplyComponent(state,
3998 : thisDXCoil.Name,
3999 : CurrentModuleObject,
4000 : thisDXCoil.CondensateCollectName,
4001 : ErrorsFound,
4002 0 : thisDXCoil.CondensateTankID,
4003 0 : thisDXCoil.CondensateTankSupplyARRID);
4004 : }
4005 :
4006 : // Set minimum OAT for compressor operation
4007 49 : thisDXCoil.MinOATCompressor = Numbers(1);
4008 :
4009 : // Set crankcase heater capacity
4010 49 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(2);
4011 49 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
4012 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4013 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(2)));
4014 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(2)));
4015 0 : ErrorsFound = true;
4016 : }
4017 :
4018 : // Set crankcase heater cutout temperature
4019 49 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(3);
4020 :
4021 49 : if (Util::SameString(Alphas(9), "Yes")) {
4022 0 : thisDXCoil.PLRImpact = true;
4023 49 : } else if (Util::SameString(Alphas(9), "No")) {
4024 49 : thisDXCoil.PLRImpact = false;
4025 : } else {
4026 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4027 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(9), Alphas(9)));
4028 0 : ShowContinueError(state, "The allowed choices are Yes or No.");
4029 0 : ErrorsFound = true;
4030 : }
4031 :
4032 49 : if (Util::SameString(Alphas(10), "Yes")) {
4033 0 : thisDXCoil.LatentImpact = true;
4034 49 : } else if (Util::SameString(Alphas(10), "No")) {
4035 49 : thisDXCoil.LatentImpact = false;
4036 : } else {
4037 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4038 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(10), Alphas(10)));
4039 0 : ShowContinueError(state, "The allowed choices are Yes or No.");
4040 0 : ErrorsFound = true;
4041 : }
4042 :
4043 : // Basin heater power as a function of temperature must be greater than or equal to 0
4044 49 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(4);
4045 49 : if (Numbers(4) < 0.0) {
4046 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4047 0 : ShowContinueError(state, format("...{} must be >= 0.0, entered value=[{:.3T}].", cNumericFields(4), Numbers(4)));
4048 0 : ErrorsFound = true;
4049 : }
4050 :
4051 49 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(5);
4052 49 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
4053 0 : if (NumNumbers < 5) {
4054 0 : thisDXCoil.BasinHeaterSetPointTemp = 2.0;
4055 : }
4056 0 : if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
4057 0 : ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4058 0 : ShowContinueError(state, format("...{} is less than 2 {{C}}. Freezing could occur.", cNumericFields(5)));
4059 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(5)));
4060 : }
4061 : }
4062 :
4063 49 : if (!lAlphaBlanks(11)) {
4064 0 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(11));
4065 0 : ErrorsFound |= Curve::CheckCurveDims(state,
4066 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
4067 : {1}, // Valid dimensions
4068 : RoutineName, // Routine name
4069 : CurrentModuleObject, // Object Type
4070 : thisDXCoil.Name, // Object Name
4071 0 : cAlphaFields(11)); // Field Name
4072 : }
4073 :
4074 49 : if (!lAlphaBlanks(12)) {
4075 0 : thisDXCoil.BasinHeaterSchedulePtr = GetScheduleIndex(state, Alphas(12));
4076 0 : if (thisDXCoil.BasinHeaterSchedulePtr == 0) {
4077 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4078 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(12), Alphas(12)));
4079 0 : ShowContinueError(state, "Basin heater will be available to operate throughout the simulation.");
4080 : }
4081 : }
4082 :
4083 : // A13; \field Fuel type, Validate fuel type input
4084 49 : thisDXCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(13)));
4085 :
4086 49 : thisDXCoil.NumOfSpeeds = Numbers(6); // Number of speeds
4087 49 : if (thisDXCoil.NumOfSpeeds < 2) {
4088 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4089 0 : ShowContinueError(state, format("...{} must be >= 2. entered number is {:.0T}", cNumericFields(6), Numbers(6)));
4090 0 : ErrorsFound = true;
4091 : }
4092 :
4093 : // Allocate arrays based on the number of speeds
4094 49 : thisDXCoil.MSErrIndex.allocate(thisDXCoil.NumOfSpeeds);
4095 49 : thisDXCoil.MSErrIndex = 0;
4096 49 : thisDXCoil.MSRatedTotCap.allocate(thisDXCoil.NumOfSpeeds);
4097 49 : thisDXCoil.MSRatedTotCapDes.allocate(thisDXCoil.NumOfSpeeds);
4098 49 : thisDXCoil.MSRatedSHR.allocate(thisDXCoil.NumOfSpeeds);
4099 49 : thisDXCoil.MSRatedCOP.allocate(thisDXCoil.NumOfSpeeds);
4100 49 : thisDXCoil.MSRatedAirVolFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4101 49 : thisDXCoil.MSRatedAirMassFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4102 49 : thisDXCoil.MSRatedAirMassFlowRate = 1.0; // avoid divide by 0, will get overwritten in InitDXCoil
4103 49 : thisDXCoil.MSCCapFTemp.allocate(thisDXCoil.NumOfSpeeds);
4104 49 : thisDXCoil.MSCCapFFlow.allocate(thisDXCoil.NumOfSpeeds);
4105 49 : thisDXCoil.MSEIRFTemp.allocate(thisDXCoil.NumOfSpeeds);
4106 49 : thisDXCoil.MSEIRFFlow.allocate(thisDXCoil.NumOfSpeeds);
4107 49 : thisDXCoil.MSWasteHeat.allocate(thisDXCoil.NumOfSpeeds);
4108 49 : thisDXCoil.MSEvapCondEffect.allocate(thisDXCoil.NumOfSpeeds);
4109 49 : thisDXCoil.MSEvapCondAirFlow.allocate(thisDXCoil.NumOfSpeeds);
4110 49 : thisDXCoil.MSEvapCondPumpElecNomPower.allocate(thisDXCoil.NumOfSpeeds);
4111 49 : thisDXCoil.MSRatedCBF.allocate(thisDXCoil.NumOfSpeeds);
4112 49 : thisDXCoil.MSWasteHeatFrac.allocate(thisDXCoil.NumOfSpeeds);
4113 49 : thisDXCoil.MSPLFFPLR.allocate(thisDXCoil.NumOfSpeeds);
4114 49 : thisDXCoil.MSTwet_Rated.allocate(thisDXCoil.NumOfSpeeds);
4115 49 : thisDXCoil.MSGamma_Rated.allocate(thisDXCoil.NumOfSpeeds);
4116 49 : thisDXCoil.MSMaxONOFFCyclesperHour.allocate(thisDXCoil.NumOfSpeeds);
4117 49 : thisDXCoil.MSLatentCapacityTimeConstant.allocate(thisDXCoil.NumOfSpeeds);
4118 49 : thisDXCoil.MSFanPowerPerEvapAirFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4119 49 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023.allocate(thisDXCoil.NumOfSpeeds);
4120 :
4121 162 : for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
4122 113 : thisDXCoil.MSRatedTotCap(I) = Numbers(7 + (I - 1) * 14);
4123 113 : thisDXCoil.MSRatedSHR(I) = Numbers(8 + (I - 1) * 14);
4124 113 : thisDXCoil.MSRatedCOP(I) = Numbers(9 + (I - 1) * 14);
4125 113 : thisDXCoil.MSRatedAirVolFlowRate(I) = Numbers(10 + (I - 1) * 14);
4126 113 : thisDXCoil.MSFanPowerPerEvapAirFlowRate(I) = Numbers(11 + (I - 1) * 14);
4127 113 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023(I) = Numbers(12 + (I - 1) * 14);
4128 :
4129 113 : thisDXCoil.MSCCapFTemp(I) = GetCurveIndex(state, Alphas(14 + (I - 1) * 6)); // convert curve name to number
4130 113 : if (thisDXCoil.MSCCapFTemp(I) == 0) {
4131 0 : if (lAlphaBlanks(14 + (I - 1) * 6)) {
4132 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4133 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(14 + (I - 1) * 6)));
4134 : } else {
4135 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4136 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14 + (I - 1) * 6), Alphas(14 + (I - 1) * 6)));
4137 : }
4138 0 : ErrorsFound = true;
4139 : } else {
4140 : // Verify Curve Object, only legal type is BiQuadratic
4141 226 : ErrorsFound |= Curve::CheckCurveDims(state,
4142 113 : thisDXCoil.MSCCapFTemp(I), // Curve index
4143 : {2}, // Valid dimensions
4144 : RoutineName, // Routine name
4145 : CurrentModuleObject, // Object Type
4146 : thisDXCoil.Name, // Object Name
4147 113 : cAlphaFields(14 + (I - 1) * 6)); // Field Name
4148 :
4149 113 : if (!ErrorsFound) {
4150 113 : checkCurveIsNormalizedToOne(state,
4151 226 : std::string{RoutineName} + CurrentModuleObject,
4152 113 : thisDXCoil.Name,
4153 113 : thisDXCoil.MSCCapFTemp(I),
4154 113 : cAlphaFields(14 + (I - 1) * 6),
4155 113 : Alphas(14 + (I - 1) * 6),
4156 : RatedInletWetBulbTemp,
4157 : RatedOutdoorAirTemp);
4158 : }
4159 : }
4160 :
4161 113 : thisDXCoil.MSCCapFFlow(I) = GetCurveIndex(state, Alphas(15 + (I - 1) * 6)); // convert curve name to number
4162 113 : if (thisDXCoil.MSCCapFFlow(I) == 0) {
4163 0 : if (lAlphaBlanks(15 + (I - 1) * 6)) {
4164 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4165 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(15 + (I - 1) * 6)));
4166 : } else {
4167 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4168 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
4169 : }
4170 0 : ErrorsFound = true;
4171 : } else {
4172 : // Verify Curve Object, only legal type is Quadratic
4173 226 : ErrorsFound |= Curve::CheckCurveDims(state,
4174 113 : thisDXCoil.MSCCapFFlow(I), // Curve index
4175 : {1}, // Valid dimensions
4176 : RoutineName, // Routine name
4177 : CurrentModuleObject, // Object Type
4178 : thisDXCoil.Name, // Object Name
4179 113 : cAlphaFields(15 + (I - 1) * 6)); // Field Name
4180 :
4181 113 : if (!ErrorsFound) {
4182 113 : checkCurveIsNormalizedToOne(state,
4183 226 : std::string{RoutineName} + CurrentModuleObject,
4184 113 : thisDXCoil.Name,
4185 113 : thisDXCoil.MSCCapFFlow(I),
4186 113 : cAlphaFields(15 + (I - 1) * 6),
4187 113 : Alphas(15 + (I - 1) * 6),
4188 : 1.0);
4189 : }
4190 : }
4191 :
4192 113 : thisDXCoil.MSEIRFTemp(I) = GetCurveIndex(state, Alphas(16 + (I - 1) * 6)); // convert curve name to number
4193 113 : if (thisDXCoil.MSEIRFTemp(I) == 0) {
4194 0 : if (lAlphaBlanks(16 + (I - 1) * 6)) {
4195 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4196 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(16 + (I - 1) * 6)));
4197 : } else {
4198 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4199 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16 + (I - 1) * 6), Alphas(16 + (I - 1) * 6)));
4200 : }
4201 0 : ErrorsFound = true;
4202 : } else {
4203 : // Verify Curve Object, only legal type is BiQuadratic
4204 226 : ErrorsFound |= Curve::CheckCurveDims(state,
4205 113 : thisDXCoil.MSEIRFTemp(I), // Curve index
4206 : {2}, // Valid dimensions
4207 : RoutineName, // Routine name
4208 : CurrentModuleObject, // Object Type
4209 : thisDXCoil.Name, // Object Name
4210 113 : cAlphaFields(16 + (I - 1) * 6)); // Field Name
4211 :
4212 113 : if (!ErrorsFound) {
4213 113 : checkCurveIsNormalizedToOne(state,
4214 226 : std::string{RoutineName} + CurrentModuleObject,
4215 113 : thisDXCoil.Name,
4216 113 : thisDXCoil.MSEIRFTemp(I),
4217 113 : cAlphaFields(16 + (I - 1) * 6),
4218 113 : Alphas(16 + (I - 1) * 6),
4219 : RatedInletWetBulbTemp,
4220 : RatedOutdoorAirTemp);
4221 : }
4222 : }
4223 :
4224 113 : thisDXCoil.MSEIRFFlow(I) = GetCurveIndex(state, Alphas(17 + (I - 1) * 6)); // convert curve name to number
4225 113 : if (thisDXCoil.MSEIRFFlow(I) == 0) {
4226 0 : if (lAlphaBlanks(17 + (I - 1) * 6)) {
4227 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4228 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(17 + (I - 1) * 6)));
4229 : } else {
4230 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4231 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17 + (I - 1) * 6), Alphas(17 + (I - 1) * 6)));
4232 : }
4233 0 : ErrorsFound = true;
4234 : } else {
4235 : // Verify Curve Object, only legal type is Quadratic
4236 226 : ErrorsFound |= Curve::CheckCurveDims(state,
4237 113 : thisDXCoil.MSEIRFFlow(I), // Curve index
4238 : {1}, // Valid dimensions
4239 : RoutineName, // Routine name
4240 : CurrentModuleObject, // Object Type
4241 : thisDXCoil.Name, // Object Name
4242 113 : cAlphaFields(17 + (I - 1) * 6)); // Field Name
4243 :
4244 113 : if (!ErrorsFound) {
4245 113 : checkCurveIsNormalizedToOne(state,
4246 226 : std::string{RoutineName} + CurrentModuleObject,
4247 113 : thisDXCoil.Name,
4248 113 : thisDXCoil.MSEIRFFlow(I),
4249 113 : cAlphaFields(17 + (I - 1) * 6),
4250 113 : Alphas(17 + (I - 1) * 6),
4251 : 1.0);
4252 : }
4253 : }
4254 :
4255 113 : thisDXCoil.MSPLFFPLR(I) = GetCurveIndex(state, Alphas(18 + (I - 1) * 6)); // convert curve name to number
4256 113 : if (thisDXCoil.MSPLFFPLR(I) == 0) {
4257 0 : if (lAlphaBlanks(18 + (I - 1) * 6)) {
4258 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4259 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(18 + (I - 1) * 6)));
4260 : } else {
4261 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4262 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(18 + (I - 1) * 6), Alphas(18 + (I - 1) * 6)));
4263 : }
4264 0 : ErrorsFound = true;
4265 : } else {
4266 : // Verify Curve Object, only legal types are Quadratic or Cubic
4267 226 : ErrorsFound |= Curve::CheckCurveDims(state,
4268 113 : thisDXCoil.MSPLFFPLR(I), // Curve index
4269 : {1}, // Valid dimensions
4270 : RoutineName, // Routine name
4271 : CurrentModuleObject, // Object Type
4272 : thisDXCoil.Name, // Object Name
4273 113 : cAlphaFields(18 + (I - 1) * 6)); // Field Name
4274 :
4275 113 : if (!ErrorsFound) {
4276 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
4277 113 : MinCurveVal = 999.0;
4278 113 : MaxCurveVal = -999.0;
4279 113 : CurveInput = 0.0;
4280 11413 : while (CurveInput <= 1.0) {
4281 11300 : CurveVal = CurveValue(state, thisDXCoil.MSPLFFPLR(I), CurveInput);
4282 11300 : if (CurveVal < MinCurveVal) {
4283 113 : MinCurveVal = CurveVal;
4284 113 : MinCurvePLR = CurveInput;
4285 : }
4286 11300 : if (CurveVal > MaxCurveVal) {
4287 11300 : MaxCurveVal = CurveVal;
4288 11300 : MaxCurvePLR = CurveInput;
4289 : }
4290 11300 : CurveInput += 0.01;
4291 : }
4292 113 : if (MinCurveVal < 0.7) {
4293 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4294 0 : ShowContinueError(state,
4295 0 : format("...{} = {} has out of range value.", cAlphaFields2(18 + (I - 1) * 6), Alphas2(18 + (I - 1) * 6)));
4296 0 : ShowContinueError(state,
4297 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
4298 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
4299 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 0.7);
4300 : }
4301 :
4302 113 : if (MaxCurveVal > 1.0) {
4303 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4304 0 : ShowContinueError(state,
4305 0 : format("...{} = {} has out of range value.", cAlphaFields2(18 + (I - 1) * 6), Alphas2(18 + (I - 1) * 6)));
4306 0 : ShowContinueError(state,
4307 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
4308 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
4309 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 1.0);
4310 : }
4311 : }
4312 : }
4313 :
4314 : // read data for latent degradation
4315 113 : thisDXCoil.MSTwet_Rated(I) = Numbers(13 + (I - 1) * 14);
4316 113 : if (thisDXCoil.MSTwet_Rated(I) < 0.0) {
4317 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4318 0 : ShowContinueError(
4319 0 : state, format("...{} cannot be < 0.0, entered value=[{:.4T}].", cNumericFields(13 + (I - 1) * 14), thisDXCoil.MSTwet_Rated(I)));
4320 0 : ErrorsFound = true;
4321 : }
4322 113 : thisDXCoil.MSGamma_Rated(I) = Numbers(14 + (I - 1) * 14);
4323 113 : if (thisDXCoil.MSGamma_Rated(I) < 0.0) {
4324 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4325 0 : ShowContinueError(
4326 0 : state, format("...{} cannot be < 0.0, entered value=[{:.4T}].", cNumericFields(14 + (I - 1) * 14), thisDXCoil.MSGamma_Rated(I)));
4327 0 : ErrorsFound = true;
4328 : }
4329 113 : thisDXCoil.MSMaxONOFFCyclesperHour(I) = Numbers(15 + (I - 1) * 14);
4330 113 : if (thisDXCoil.Gamma_Rated(I) < 0.0) {
4331 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4332 0 : ShowContinueError(state,
4333 0 : format("...{} cannot be < 0.0, entered value=[{:.2T}].",
4334 0 : cNumericFields(15 + (I - 1) * 14),
4335 : thisDXCoil.MSMaxONOFFCyclesperHour(I)));
4336 0 : ErrorsFound = true;
4337 : }
4338 113 : thisDXCoil.MSLatentCapacityTimeConstant(I) = Numbers(16 + (I - 1) * 14);
4339 113 : if (thisDXCoil.Gamma_Rated(I) < 0.0) {
4340 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4341 0 : ShowContinueError(state,
4342 0 : format("...{} cannot be < 0.0, entered value=[{:.2T}].",
4343 0 : cNumericFields(16 + (I - 1) * 14),
4344 : thisDXCoil.MSLatentCapacityTimeConstant(I)));
4345 0 : ErrorsFound = true;
4346 : }
4347 :
4348 113 : thisDXCoil.MSWasteHeatFrac(I) = Numbers(17 + (I - 1) * 14);
4349 :
4350 : // Read waste heat modifier curve name
4351 113 : thisDXCoil.MSWasteHeat(I) = GetCurveIndex(state, Alphas(19 + (I - 1) * 6)); // convert curve name to number
4352 113 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
4353 24 : if (thisDXCoil.MSWasteHeat(I) > 0) {
4354 : // Verify Curve Object, only legal types are BiQuadratic
4355 48 : ErrorsFound |= Curve::CheckCurveDims(state,
4356 24 : thisDXCoil.MSWasteHeat(I), // Curve index
4357 : {2}, // Valid dimensions
4358 : RoutineName, // Routine name
4359 : CurrentModuleObject, // Object Type
4360 : thisDXCoil.Name, // Object Name
4361 24 : cAlphaFields(19 + (I - 1) * 6)); // Field Name
4362 :
4363 24 : if (!ErrorsFound) {
4364 24 : CurveVal = CurveValue(state, thisDXCoil.MSWasteHeat(I), RatedOutdoorAirTemp, RatedInletAirTemp);
4365 24 : if (CurveVal > 1.10 || CurveVal < 0.90) {
4366 0 : ShowWarningError(state, format("{}{}=\"{}\", curve values", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4367 0 : ShowContinueError(state, format("{} = {}", cAlphaFields(19 + (I - 1) * 6), Alphas(19 + (I - 1) * 6)));
4368 0 : ShowContinueError(
4369 0 : state, format("...{} output is not equal to 1.0 (+ or - 10%) at rated conditions.", cAlphaFields(19 + (I - 1) * 6)));
4370 0 : ShowContinueError(state, format("...Curve output at rated conditions = {:.3T}", CurveVal));
4371 : }
4372 : }
4373 : }
4374 : }
4375 :
4376 113 : thisDXCoil.MSEvapCondEffect(I) = Numbers(18 + (I - 1) * 14);
4377 113 : if (thisDXCoil.MSEvapCondEffect(I) < 0.0 || thisDXCoil.MSEvapCondEffect(I) > 1.0) {
4378 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4379 0 : ShowContinueError(
4380 : state,
4381 0 : format("...{} cannot be < 0.0 or > 1.0, entered value=[{:.3T}].", cNumericFields(18 + (I - 1) * 14), Numbers(18 + (I - 1) * 14)));
4382 0 : ErrorsFound = true;
4383 : }
4384 :
4385 113 : thisDXCoil.MSEvapCondAirFlow(I) = Numbers(19 + (I - 1) * 14);
4386 113 : if (thisDXCoil.MSEvapCondAirFlow(I) < 0.0 && thisDXCoil.MSEvapCondAirFlow(I) != AutoSize) {
4387 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4388 0 : ShowContinueError(
4389 0 : state, format("...{} cannot be < 0.0, entered value=[{:.3T}].", cNumericFields(19 + (I - 1) * 14), Numbers(19 + (I - 1) * 14)));
4390 0 : ErrorsFound = true;
4391 : }
4392 :
4393 113 : thisDXCoil.MSEvapCondPumpElecNomPower(I) = Numbers(20 + (I - 1) * 14);
4394 113 : if (thisDXCoil.MSEvapCondPumpElecNomPower(I) < 0.0 && thisDXCoil.MSEvapCondPumpElecNomPower(I) != AutoSize) {
4395 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4396 0 : ShowContinueError(
4397 0 : state, format("...{} cannot be < 0.0, entered value=[{:.3T}].", cNumericFields(20 + (I - 1) * 14), Numbers(20 + (I - 1) * 14)));
4398 0 : ErrorsFound = true;
4399 : }
4400 : }
4401 : // A38; \field Zone Name for Condenser Placement
4402 49 : if (!lAlphaBlanks(38) && NumAlphas > 37) {
4403 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(38), state.dataHeatBal->Zone);
4404 0 : if (thisDXCoil.SecZonePtr > 0) {
4405 0 : SetupZoneInternalGain(state,
4406 : thisDXCoil.SecZonePtr,
4407 : thisDXCoil.Name,
4408 : DataHeatBalance::IntGainType::SecCoolingDXCoilMultiSpeed,
4409 : &thisDXCoil.SecCoilSensibleHeatGainRate);
4410 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
4411 : } else {
4412 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4413 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(38), Alphas(38)));
4414 : }
4415 : }
4416 : }
4417 :
4418 247 : if (ErrorsFound) {
4419 0 : ShowFatalError(state,
4420 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
4421 : }
4422 :
4423 : // DX multispeed heating coil
4424 247 : CurrentModuleObject = "Coil:Heating:DX:MultiSpeed";
4425 269 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedHeatCoils; ++DXCoilIndex) {
4426 :
4427 22 : ++DXCoilNum;
4428 :
4429 22 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4430 : CurrentModuleObject,
4431 : DXCoilIndex,
4432 : Alphas,
4433 : NumAlphas,
4434 : Numbers,
4435 : NumNumbers,
4436 : IOStatus,
4437 : lNumericBlanks,
4438 : lAlphaBlanks,
4439 : cAlphaFields,
4440 : cNumericFields);
4441 :
4442 : // *** will have to circle back to this one to fix since the multispeed coil has all fields in this coil object ***
4443 : // allocate single performance mode for numeric field strings used for sizing routine
4444 22 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
4445 22 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
4446 22 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
4447 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
4448 22 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
4449 :
4450 22 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
4451 22 : thisDXCoil.Name = Alphas(1);
4452 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
4453 22 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
4454 22 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
4455 22 : thisDXCoil.DXCoilType = CurrentModuleObject;
4456 22 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_MultiSpeedHeating;
4457 22 : thisDXCoil.Schedule = Alphas(2);
4458 22 : if (lAlphaBlanks(2)) {
4459 8 : thisDXCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
4460 : } else {
4461 14 : thisDXCoil.SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
4462 14 : if (thisDXCoil.SchedPtr == 0) {
4463 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4464 0 : ShowContinueError(state, format("...{}=\"{}\".", cAlphaFields(2), Alphas(2)));
4465 0 : ErrorsFound = true;
4466 : }
4467 : }
4468 :
4469 22 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
4470 22 : Alphas(3),
4471 : ErrorsFound,
4472 : DataLoopNode::ConnectionObjectType::CoilHeatingDXMultiSpeed,
4473 22 : Alphas(1),
4474 : DataLoopNode::NodeFluidType::Air,
4475 : DataLoopNode::ConnectionType::Inlet,
4476 : NodeInputManager::CompFluidStream::Primary,
4477 : ObjectIsNotParent);
4478 :
4479 22 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
4480 22 : Alphas(4),
4481 : ErrorsFound,
4482 : DataLoopNode::ConnectionObjectType::CoilHeatingDXMultiSpeed,
4483 22 : Alphas(1),
4484 : DataLoopNode::NodeFluidType::Air,
4485 : DataLoopNode::ConnectionType::Outlet,
4486 : NodeInputManager::CompFluidStream::Primary,
4487 : ObjectIsNotParent);
4488 :
4489 22 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
4490 :
4491 : // Set minimum OAT for heat pump compressor operation
4492 22 : thisDXCoil.MinOATCompressor = Numbers(1);
4493 :
4494 : // set Minimum Outdoor Dry-Bulb Temperature for Compressor Operation
4495 22 : thisDXCoil.OATempCompressorOn = Numbers(2);
4496 : // Set crankcase heater capacity
4497 22 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(3);
4498 22 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
4499 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4500 0 : ShowContinueError(state, format("...{} cannot be < 0.0, entered value=[{:.2T}].", cNumericFields(3), Numbers(3)));
4501 0 : ErrorsFound = true;
4502 : }
4503 :
4504 : // Set crankcase heater cutout temperature
4505 22 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(4);
4506 :
4507 22 : if (!lAlphaBlanks(5)) {
4508 0 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
4509 0 : ErrorsFound |= Curve::CheckCurveDims(state,
4510 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
4511 : {1}, // Valid dimensions
4512 : RoutineName, // Routine name
4513 : CurrentModuleObject, // Object Type
4514 : thisDXCoil.Name, // Object Name
4515 0 : cAlphaFields(5)); // Field Name
4516 : }
4517 :
4518 : // Only required for reverse cycle heat pumps
4519 22 : thisDXCoil.DefrostEIRFT = GetCurveIndex(state, Alphas(6)); // convert curve name to number
4520 22 : if (Util::SameString(Alphas(7), "ReverseCycle")) {
4521 22 : if (thisDXCoil.DefrostEIRFT == 0) {
4522 0 : if (lAlphaBlanks(6)) {
4523 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4524 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
4525 : } else {
4526 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4527 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
4528 : }
4529 0 : ErrorsFound = true;
4530 : } else {
4531 : // Verify Curve Object, only legal type is BiQuadratic
4532 22 : ErrorsFound |= Curve::CheckCurveDims(state,
4533 : thisDXCoil.DefrostEIRFT, // Curve index
4534 : {2}, // Valid dimensions
4535 : RoutineName, // Routine name
4536 : CurrentModuleObject, // Object Type
4537 : thisDXCoil.Name, // Object Name
4538 22 : cAlphaFields(6)); // Field Name
4539 :
4540 22 : if (!ErrorsFound) {
4541 22 : checkCurveIsNormalizedToOne(state,
4542 44 : std::string{RoutineName} + CurrentModuleObject,
4543 22 : thisDXCoil.Name,
4544 : thisDXCoil.DefrostEIRFT,
4545 22 : cAlphaFields(6),
4546 22 : Alphas(6),
4547 : RatedInletWetBulbTempHeat,
4548 : RatedOutdoorAirTempHeat);
4549 : }
4550 : }
4551 : }
4552 :
4553 22 : if (Util::SameString(Alphas(7), "ReverseCycle")) thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
4554 22 : if (Util::SameString(Alphas(7), "Resistive")) thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
4555 22 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
4556 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4557 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(7), Alphas(7)));
4558 0 : ShowContinueError(state, "...valid values for this field are ReverseCycle or Resistive.");
4559 0 : ErrorsFound = true;
4560 : }
4561 :
4562 22 : if (Util::SameString(Alphas(8), "Timed")) thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::Timed;
4563 22 : if (Util::SameString(Alphas(8), "OnDemand")) thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
4564 22 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
4565 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4566 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(8), Alphas(8)));
4567 0 : ShowContinueError(state, "...valid values for this field are Timed or OnDemand.");
4568 0 : ErrorsFound = true;
4569 : }
4570 :
4571 : // Set maximum outdoor temp for defrost to occur
4572 22 : thisDXCoil.MaxOATDefrost = Numbers(5);
4573 :
4574 : // Set defrost time period
4575 22 : thisDXCoil.DefrostTime = Numbers(6);
4576 22 : if (thisDXCoil.DefrostTime == 0.0 && thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
4577 0 : ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4578 0 : ShowContinueError(state, format("...{} = 0.0 for defrost control = TIMED.", cNumericFields(5)));
4579 : }
4580 :
4581 : // Set defrost capacity (for resistive defrost)
4582 22 : thisDXCoil.DefrostCapacity = Numbers(7);
4583 22 : if (thisDXCoil.DefrostCapacity == 0.0 && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
4584 0 : ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4585 0 : ShowContinueError(state, format("...{} = 0.0 for defrost strategy = RESISTIVE.", cNumericFields(7)));
4586 : }
4587 :
4588 22 : if (Util::SameString(Alphas(9), "Yes")) {
4589 0 : thisDXCoil.PLRImpact = true;
4590 22 : } else if (Util::SameString(Alphas(9), "No")) {
4591 22 : thisDXCoil.PLRImpact = false;
4592 : } else {
4593 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4594 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(9), Alphas(9)));
4595 0 : ShowContinueError(state, "The allowed choices are Yes or No.");
4596 0 : ErrorsFound = true;
4597 : }
4598 :
4599 : // A10; \field Fuel type, Validate fuel type input
4600 22 : thisDXCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(10)));
4601 :
4602 22 : thisDXCoil.RegionNum = Numbers(8); // Region Number for HSPF Calc
4603 22 : thisDXCoil.NumOfSpeeds = Numbers(9); // Number of speeds
4604 22 : if (thisDXCoil.NumOfSpeeds < 2) {
4605 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4606 0 : ShowContinueError(state, format("...{} must be >= 2. entered number is {:.0T}", cNumericFields(9), Numbers(9)));
4607 0 : ErrorsFound = true;
4608 : }
4609 :
4610 : // Allocate arrays based on the number of speeds
4611 22 : thisDXCoil.MSErrIndex.allocate(thisDXCoil.NumOfSpeeds);
4612 22 : thisDXCoil.MSErrIndex = 0;
4613 22 : thisDXCoil.MSRatedTotCap.allocate(thisDXCoil.NumOfSpeeds);
4614 22 : thisDXCoil.MSRatedCOP.allocate(thisDXCoil.NumOfSpeeds);
4615 22 : thisDXCoil.MSRatedAirVolFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4616 22 : thisDXCoil.MSRatedAirMassFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4617 22 : thisDXCoil.MSRatedAirMassFlowRate = 1.0; // avoid divide by 0, will get overwritten in InitDXCoil
4618 22 : thisDXCoil.MSCCapFTemp.allocate(thisDXCoil.NumOfSpeeds);
4619 22 : thisDXCoil.MSCCapFFlow.allocate(thisDXCoil.NumOfSpeeds);
4620 22 : thisDXCoil.MSEIRFTemp.allocate(thisDXCoil.NumOfSpeeds);
4621 22 : thisDXCoil.MSEIRFFlow.allocate(thisDXCoil.NumOfSpeeds);
4622 22 : thisDXCoil.MSWasteHeat.allocate(thisDXCoil.NumOfSpeeds);
4623 22 : thisDXCoil.MSPLFFPLR.allocate(thisDXCoil.NumOfSpeeds);
4624 22 : thisDXCoil.MSRatedCBF.allocate(thisDXCoil.NumOfSpeeds);
4625 22 : thisDXCoil.MSWasteHeatFrac.allocate(thisDXCoil.NumOfSpeeds);
4626 22 : thisDXCoil.MSFanPowerPerEvapAirFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4627 22 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023.allocate(thisDXCoil.NumOfSpeeds);
4628 22 : thisDXCoil.MSSecCoilSHRFT.allocate(thisDXCoil.NumOfSpeeds);
4629 22 : thisDXCoil.MSSecCoilSHRFF.allocate(thisDXCoil.NumOfSpeeds);
4630 22 : thisDXCoil.MSSecCoilAirFlow.allocate(thisDXCoil.NumOfSpeeds);
4631 22 : thisDXCoil.MSSecCoilAirFlowScalingFactor.allocate(thisDXCoil.NumOfSpeeds);
4632 22 : thisDXCoil.MSSecCoilRatedSHR.allocate(thisDXCoil.NumOfSpeeds);
4633 :
4634 22 : thisDXCoil.RatedSHR(1) = 1.0;
4635 :
4636 92 : for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
4637 70 : thisDXCoil.MSRatedTotCap(I) = Numbers(10 + (I - 1) * 6);
4638 70 : thisDXCoil.MSRatedCOP(I) = Numbers(11 + (I - 1) * 6);
4639 70 : thisDXCoil.MSRatedAirVolFlowRate(I) = Numbers(12 + (I - 1) * 6);
4640 70 : thisDXCoil.MSFanPowerPerEvapAirFlowRate(I) = Numbers(13 + (I - 1) * 6);
4641 70 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023(I) = Numbers(14 + (I - 1) * 6);
4642 70 : thisDXCoil.MSWasteHeatFrac(I) = Numbers(15 + (I - 1) * 6);
4643 :
4644 70 : thisDXCoil.MSCCapFTemp(I) = GetCurveIndex(state, Alphas(11 + (I - 1) * 6)); // convert curve name to number
4645 70 : if (thisDXCoil.MSCCapFTemp(I) == 0) {
4646 0 : ShowSevereError(state,
4647 0 : format("{}, \"{}\" {} not found:{}",
4648 : CurrentModuleObject,
4649 0 : thisDXCoil.Name,
4650 0 : cAlphaFields(11 + (I - 1) * 6),
4651 0 : Alphas(11 + (I - 1) * 6)));
4652 0 : ErrorsFound = true;
4653 : } else {
4654 : // only legal types are Quadratic, BiQuadratic and Cubic
4655 140 : ErrorsFound |= Curve::CheckCurveDims(state,
4656 70 : thisDXCoil.MSCCapFTemp(I), // Curve index
4657 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
4658 : RoutineName, // Routine name
4659 : CurrentModuleObject, // Object Type
4660 : thisDXCoil.Name, // Object Name
4661 70 : cAlphaFields(11 + (I - 1) * 6)); // Field Name
4662 :
4663 70 : if (!ErrorsFound) {
4664 70 : if (state.dataCurveManager->PerfCurve(thisDXCoil.MSCCapFTemp(I))->numDims == 1) {
4665 52 : checkCurveIsNormalizedToOne(state,
4666 104 : std::string{RoutineName} + CurrentModuleObject,
4667 52 : thisDXCoil.Name,
4668 52 : thisDXCoil.MSCCapFTemp(I),
4669 52 : cAlphaFields(11 + (I - 1) * 6),
4670 52 : Alphas(11 + (I - 1) * 6),
4671 : RatedOutdoorAirTempHeat);
4672 : } else {
4673 18 : checkCurveIsNormalizedToOne(state,
4674 36 : std::string{RoutineName} + CurrentModuleObject,
4675 18 : thisDXCoil.Name,
4676 18 : thisDXCoil.MSCCapFTemp(I),
4677 18 : cAlphaFields(11 + (I - 1) * 6),
4678 18 : Alphas(11 + (I - 1) * 6),
4679 : RatedInletAirTempHeat,
4680 : RatedOutdoorAirTempHeat);
4681 : }
4682 : }
4683 : }
4684 :
4685 70 : thisDXCoil.MSCCapFFlow(I) = GetCurveIndex(state, Alphas(12 + (I - 1) * 6)); // convert curve name to number
4686 70 : if (thisDXCoil.MSCCapFFlow(I) == 0) {
4687 0 : if (lAlphaBlanks(12 + (I - 1) * 6)) {
4688 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4689 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(12 + (I - 1) * 6)));
4690 : } else {
4691 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4692 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(12 + (I - 1) * 6), Alphas(12 + (I - 1) * 6)));
4693 : }
4694 0 : ErrorsFound = true;
4695 : } else {
4696 : // Verify Curve Object, only legal type is Quadratic
4697 140 : ErrorsFound |= Curve::CheckCurveDims(state,
4698 70 : thisDXCoil.MSCCapFFlow(I), // Curve index
4699 : {1}, // Valid dimensions
4700 : RoutineName, // Routine name
4701 : CurrentModuleObject, // Object Type
4702 : thisDXCoil.Name, // Object Name
4703 70 : cAlphaFields(12 + (I - 1) * 6)); // Field Name
4704 :
4705 70 : if (!ErrorsFound) {
4706 70 : checkCurveIsNormalizedToOne(state,
4707 140 : std::string{RoutineName} + CurrentModuleObject,
4708 70 : thisDXCoil.Name,
4709 70 : thisDXCoil.MSCCapFFlow(I),
4710 70 : cAlphaFields(12 + (I - 1) * 6),
4711 70 : Alphas(12 + (I - 1) * 6),
4712 : 1.0);
4713 : }
4714 : }
4715 :
4716 70 : thisDXCoil.MSEIRFTemp(I) = GetCurveIndex(state, Alphas(13 + (I - 1) * 6)); // convert curve name to number
4717 70 : if (thisDXCoil.MSEIRFTemp(I) == 0) {
4718 0 : if (lAlphaBlanks(13 + (I - 1) * 6)) {
4719 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4720 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(13 + (I - 1) * 6)));
4721 : } else {
4722 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4723 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(13 + (I - 1) * 6), Alphas(13 + (I - 1) * 6)));
4724 : }
4725 0 : ErrorsFound = true;
4726 : } else {
4727 : // only legal types are Quadratic, BiQuadratic and Cubic
4728 140 : ErrorsFound |= Curve::CheckCurveDims(state,
4729 70 : thisDXCoil.MSEIRFTemp(I), // Curve index
4730 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
4731 : RoutineName, // Routine name
4732 : CurrentModuleObject, // Object Type
4733 : thisDXCoil.Name, // Object Name
4734 70 : cAlphaFields(13 + (I - 1) * 6)); // Field Name
4735 :
4736 70 : if (!ErrorsFound) {
4737 70 : if (state.dataCurveManager->PerfCurve(thisDXCoil.MSEIRFTemp(I))->numDims == 1) {
4738 52 : checkCurveIsNormalizedToOne(state,
4739 104 : std::string{RoutineName} + CurrentModuleObject,
4740 52 : thisDXCoil.Name,
4741 52 : thisDXCoil.MSEIRFTemp(I),
4742 52 : cAlphaFields(13 + (I - 1) * 6),
4743 52 : Alphas(13 + (I - 1) * 6),
4744 : RatedOutdoorAirTempHeat);
4745 : } else {
4746 18 : checkCurveIsNormalizedToOne(state,
4747 36 : std::string{RoutineName} + CurrentModuleObject,
4748 18 : thisDXCoil.Name,
4749 18 : thisDXCoil.MSEIRFTemp(I),
4750 18 : cAlphaFields(13 + (I - 1) * 6),
4751 18 : Alphas(13 + (I - 1) * 6),
4752 : RatedInletAirTempHeat,
4753 : RatedOutdoorAirTempHeat);
4754 : }
4755 : }
4756 : }
4757 :
4758 70 : thisDXCoil.MSEIRFFlow(I) = GetCurveIndex(state, Alphas(14 + (I - 1) * 6)); // convert curve name to number
4759 70 : if (thisDXCoil.MSEIRFFlow(I) == 0) {
4760 0 : if (lAlphaBlanks(14 + (I - 1) * 6)) {
4761 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4762 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(14 + (I - 1) * 6)));
4763 : } else {
4764 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4765 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14 + (I - 1) * 6), Alphas(14 + (I - 1) * 6)));
4766 : }
4767 0 : ErrorsFound = true;
4768 : } else {
4769 : // Verify Curve Object, only legal type is Quadratic
4770 140 : ErrorsFound |= Curve::CheckCurveDims(state,
4771 70 : thisDXCoil.MSEIRFFlow(I), // Curve index
4772 : {1}, // Valid dimensions
4773 : RoutineName, // Routine name
4774 : CurrentModuleObject, // Object Type
4775 : thisDXCoil.Name, // Object Name
4776 70 : cAlphaFields(14 + (I - 1) * 6)); // Field Name
4777 :
4778 70 : if (!ErrorsFound) {
4779 70 : checkCurveIsNormalizedToOne(state,
4780 140 : std::string{RoutineName} + CurrentModuleObject,
4781 70 : thisDXCoil.Name,
4782 70 : thisDXCoil.MSEIRFFlow(I),
4783 70 : cAlphaFields(14 + (I - 1) * 6),
4784 70 : Alphas(14 + (I - 1) * 6),
4785 : 1.0);
4786 : }
4787 : }
4788 :
4789 70 : thisDXCoil.MSPLFFPLR(I) = GetCurveIndex(state, Alphas(15 + (I - 1) * 6)); // convert curve name to number
4790 70 : if (thisDXCoil.MSPLFFPLR(I) == 0) {
4791 0 : if (lAlphaBlanks(15 + (I - 1) * 6)) {
4792 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4793 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(15 + (I - 1) * 6)));
4794 : } else {
4795 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4796 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
4797 : }
4798 0 : ErrorsFound = true;
4799 : } else {
4800 : // Verify Curve Object, only legal types are Quadratic or Cubic
4801 140 : ErrorsFound |= Curve::CheckCurveDims(state,
4802 70 : thisDXCoil.MSPLFFPLR(I), // Curve index
4803 : {1}, // Valid dimensions
4804 : RoutineName, // Routine name
4805 : CurrentModuleObject, // Object Type
4806 : thisDXCoil.Name, // Object Name
4807 70 : cAlphaFields(15 + (I - 1) * 6)); // Field Name
4808 :
4809 70 : if (!ErrorsFound) {
4810 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
4811 70 : MinCurveVal = 999.0;
4812 70 : MaxCurveVal = -999.0;
4813 70 : CurveInput = 0.0;
4814 7070 : while (CurveInput <= 1.0) {
4815 7000 : CurveVal = CurveValue(state, thisDXCoil.MSPLFFPLR(I), CurveInput);
4816 7000 : if (CurveVal < MinCurveVal) {
4817 70 : MinCurveVal = CurveVal;
4818 70 : MinCurvePLR = CurveInput;
4819 : }
4820 7000 : if (CurveVal > MaxCurveVal) {
4821 7000 : MaxCurveVal = CurveVal;
4822 7000 : MaxCurvePLR = CurveInput;
4823 : }
4824 7000 : CurveInput += 0.01;
4825 : }
4826 70 : if (MinCurveVal < 0.7) {
4827 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4828 0 : ShowContinueError(state,
4829 0 : format("...{} = {} has out of range value.", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
4830 0 : ShowContinueError(state,
4831 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
4832 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
4833 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 0.7);
4834 : }
4835 :
4836 70 : if (MaxCurveVal > 1.0) {
4837 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4838 0 : ShowContinueError(state,
4839 0 : format("...{} = {} has out of range value.", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
4840 0 : ShowContinueError(state,
4841 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
4842 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
4843 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 1.0);
4844 : }
4845 : }
4846 : }
4847 :
4848 : // Read waste heat modifier curve name
4849 70 : thisDXCoil.MSWasteHeat(I) = GetCurveIndex(state, Alphas(16 + (I - 1) * 6)); // convert curve name to number
4850 70 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
4851 16 : if (thisDXCoil.MSWasteHeat(I) > 0) {
4852 : // Verify Curve Object, only legal types are BiQuadratic
4853 32 : ErrorsFound |= Curve::CheckCurveDims(state,
4854 16 : thisDXCoil.MSWasteHeat(I), // Curve index
4855 : {2}, // Valid dimensions
4856 : RoutineName, // Routine name
4857 : CurrentModuleObject, // Object Type
4858 : thisDXCoil.Name, // Object Name
4859 16 : cAlphaFields(16 + (I - 1) * 6)); // Field Name
4860 :
4861 16 : if (!ErrorsFound) {
4862 16 : checkCurveIsNormalizedToOne(state,
4863 32 : std::string{RoutineName} + CurrentModuleObject,
4864 16 : thisDXCoil.Name,
4865 16 : thisDXCoil.MSWasteHeat(I),
4866 16 : cAlphaFields(16 + (I - 1) * 6),
4867 16 : Alphas(16 + (I - 1) * 6),
4868 : RatedOutdoorAirTempHeat,
4869 : RatedInletAirTempHeat);
4870 : }
4871 : }
4872 : }
4873 : }
4874 : // A35; \field Zone Name for Condenser Placement
4875 22 : if (!lAlphaBlanks(35) && NumAlphas > 34) {
4876 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(35), state.dataHeatBal->Zone);
4877 0 : if (thisDXCoil.SecZonePtr > 0) {
4878 0 : SetupZoneInternalGain(state,
4879 : thisDXCoil.SecZonePtr,
4880 : thisDXCoil.Name,
4881 : DataHeatBalance::IntGainType::SecHeatingDXCoilMultiSpeed,
4882 : &thisDXCoil.SecCoilSensibleHeatRemovalRate,
4883 : nullptr,
4884 : nullptr,
4885 : &thisDXCoil.SecCoilLatentHeatRemovalRate);
4886 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
4887 : } else {
4888 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4889 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(35), Alphas(35)));
4890 : }
4891 : }
4892 22 : if (thisDXCoil.SecZonePtr > 0) {
4893 0 : for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
4894 0 : thisDXCoil.MSSecCoilAirFlow(I) = Numbers(34 + (I - 1) * 3);
4895 0 : thisDXCoil.MSSecCoilAirFlowScalingFactor(I) = Numbers(35 + (I - 1) * 3);
4896 0 : thisDXCoil.MSSecCoilRatedSHR(I) = Numbers(36 + (I - 1) * 3);
4897 : // Read SHR modifier curve function of temperature
4898 0 : if (!lAlphaBlanks(36 + (I - 1) * 2)) {
4899 0 : thisDXCoil.MSSecCoilSHRFT(I) = GetCurveIndex(state, Alphas(36 + (I - 1) * 2)); // convert curve name to number
4900 0 : if (thisDXCoil.MSSecCoilSHRFT(I) == 0) {
4901 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4902 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(36 + (I - 1) * 2), Alphas(36 + (I - 1) * 2)));
4903 : }
4904 : }
4905 : // Read SHR modifier curve function of flow fraction
4906 0 : if (!lAlphaBlanks(36 + (I - 1) * 2)) {
4907 0 : thisDXCoil.MSSecCoilSHRFF(I) = GetCurveIndex(state, Alphas(36 + (I - 1) * 2)); // convert curve name to number
4908 0 : if (thisDXCoil.MSSecCoilSHRFF(I) == 0) {
4909 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4910 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(36 + (I - 1) * 2), Alphas(36 + (I - 1) * 2)));
4911 : }
4912 : }
4913 : }
4914 : }
4915 : }
4916 :
4917 : // Loop over the VRF Cooling Coils and get & load the data
4918 247 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling);
4919 293 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFCoolingCoils; ++DXCoilIndex) {
4920 :
4921 46 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4922 : CurrentModuleObject,
4923 : DXCoilIndex,
4924 : Alphas,
4925 : NumAlphas,
4926 : Numbers,
4927 : NumNumbers,
4928 : IOStatus,
4929 : lNumericBlanks,
4930 : lAlphaBlanks,
4931 : cAlphaFields,
4932 : cNumericFields);
4933 :
4934 46 : ++DXCoilNum;
4935 :
4936 : // allocate single performance mode for numeric field strings used for sizing routine
4937 46 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
4938 46 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
4939 46 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
4940 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
4941 46 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
4942 :
4943 46 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
4944 46 : thisDXCoil.Name = Alphas(1);
4945 46 : thisDXCoil.DXCoilType = CurrentModuleObject;
4946 46 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_Cooling;
4947 46 : thisDXCoil.Schedule = Alphas(2);
4948 46 : if (lAlphaBlanks(2)) {
4949 5 : thisDXCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
4950 : } else {
4951 41 : thisDXCoil.SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
4952 41 : if (thisDXCoil.SchedPtr == 0) {
4953 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4954 0 : ShowContinueError(state, format("...{}=\"{}\".", cAlphaFields(2), Alphas(2)));
4955 0 : ErrorsFound = true;
4956 : }
4957 : }
4958 46 : thisDXCoil.RatedTotCap(1) = Numbers(1);
4959 46 : thisDXCoil.RatedSHR(1) = Numbers(2);
4960 46 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(3);
4961 :
4962 46 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(3));
4963 : // Verify Curve Object, only legal type is Linear, Quadratic, Cubic, or BiQuadratic
4964 92 : ErrorsFound |= Curve::CheckCurveDims(state,
4965 46 : thisDXCoil.CCapFTemp(1), // Curve index
4966 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
4967 : RoutineName, // Routine name
4968 : CurrentModuleObject, // Object Type
4969 : thisDXCoil.Name, // Object Name
4970 46 : cAlphaFields(3)); // Field Name
4971 :
4972 46 : if (!ErrorsFound) {
4973 46 : if (state.dataCurveManager->PerfCurve(thisDXCoil.CCapFTemp(1))->numDims == 1) {
4974 31 : checkCurveIsNormalizedToOne(state,
4975 62 : std::string{RoutineName} + CurrentModuleObject,
4976 31 : thisDXCoil.Name,
4977 31 : thisDXCoil.CCapFTemp(1),
4978 31 : cAlphaFields(3),
4979 31 : Alphas(3),
4980 : RatedInletWetBulbTemp);
4981 : } else {
4982 15 : checkCurveIsNormalizedToOne(state,
4983 30 : std::string{RoutineName} + CurrentModuleObject,
4984 15 : thisDXCoil.Name,
4985 15 : thisDXCoil.CCapFTemp(1),
4986 15 : cAlphaFields(3),
4987 15 : Alphas(3),
4988 : RatedInletWetBulbTemp,
4989 : RatedOutdoorAirTemp);
4990 : }
4991 : }
4992 :
4993 46 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(4)); // convert curve name to number
4994 46 : if (thisDXCoil.CCapFFlow(1) == 0) {
4995 0 : if (lAlphaBlanks(4)) {
4996 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4997 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(4)));
4998 : } else {
4999 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5000 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(4), Alphas(4)));
5001 : }
5002 0 : ErrorsFound = true;
5003 : } else {
5004 : // Verify Curve Object, only legal type is Linear, Quadratic or Cubic
5005 92 : ErrorsFound |= Curve::CheckCurveDims(state,
5006 46 : thisDXCoil.CCapFFlow(1), // Curve index
5007 : {1}, // Valid dimensions
5008 : RoutineName, // Routine name
5009 : CurrentModuleObject, // Object Type
5010 : thisDXCoil.Name, // Object Name
5011 46 : cAlphaFields(4)); // Field Name
5012 :
5013 46 : if (!ErrorsFound) {
5014 46 : checkCurveIsNormalizedToOne(
5015 92 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(4), Alphas(4), 1.0);
5016 : }
5017 : }
5018 :
5019 46 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5020 46 : Alphas(5),
5021 : ErrorsFound,
5022 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlow,
5023 46 : Alphas(1),
5024 : DataLoopNode::NodeFluidType::Air,
5025 : DataLoopNode::ConnectionType::Inlet,
5026 : NodeInputManager::CompFluidStream::Primary,
5027 : ObjectIsNotParent);
5028 :
5029 46 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5030 46 : Alphas(6),
5031 : ErrorsFound,
5032 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlow,
5033 46 : Alphas(1),
5034 : DataLoopNode::NodeFluidType::Air,
5035 : DataLoopNode::ConnectionType::Outlet,
5036 : NodeInputManager::CompFluidStream::Primary,
5037 : ObjectIsNotParent);
5038 :
5039 46 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(5), Alphas(6), "Air Nodes");
5040 :
5041 46 : thisDXCoil.CondensateCollectName = Alphas(7);
5042 46 : if (lAlphaBlanks(7)) {
5043 46 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
5044 : } else {
5045 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
5046 0 : SetupTankSupplyComponent(state,
5047 : thisDXCoil.Name,
5048 : CurrentModuleObject,
5049 : thisDXCoil.CondensateCollectName,
5050 : ErrorsFound,
5051 0 : thisDXCoil.CondensateTankID,
5052 0 : thisDXCoil.CondensateTankSupplyARRID);
5053 : }
5054 : }
5055 :
5056 247 : if (ErrorsFound) {
5057 0 : ShowFatalError(state,
5058 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5059 : }
5060 :
5061 : // Loop over the VRF Heating Coils and get & load the data
5062 247 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating);
5063 293 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFHeatingCoils; ++DXCoilIndex) {
5064 :
5065 46 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5066 : CurrentModuleObject,
5067 : DXCoilIndex,
5068 : Alphas,
5069 : NumAlphas,
5070 : Numbers,
5071 : NumNumbers,
5072 : IOStatus,
5073 : lNumericBlanks,
5074 : lAlphaBlanks,
5075 : cAlphaFields,
5076 : cNumericFields);
5077 :
5078 46 : ++DXCoilNum;
5079 :
5080 : // allocate single performance mode for numeric field strings used for sizing routine
5081 46 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
5082 46 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
5083 46 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
5084 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
5085 46 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
5086 :
5087 46 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5088 46 : thisDXCoil.Name = Alphas(1);
5089 46 : thisDXCoil.DXCoilType = CurrentModuleObject;
5090 46 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_Heating;
5091 46 : thisDXCoil.Schedule = Alphas(2);
5092 46 : if (lAlphaBlanks(2)) {
5093 5 : thisDXCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
5094 : } else {
5095 41 : thisDXCoil.SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
5096 41 : if (thisDXCoil.SchedPtr == 0) {
5097 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5098 0 : ShowContinueError(state, format("...{}=\"{}\".", cAlphaFields(2), Alphas(2)));
5099 0 : ErrorsFound = true;
5100 : }
5101 : }
5102 46 : thisDXCoil.RatedTotCap(1) = Numbers(1);
5103 46 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(2);
5104 :
5105 46 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5106 46 : Alphas(3),
5107 : ErrorsFound,
5108 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlow,
5109 46 : Alphas(1),
5110 : DataLoopNode::NodeFluidType::Air,
5111 : DataLoopNode::ConnectionType::Inlet,
5112 : NodeInputManager::CompFluidStream::Primary,
5113 : ObjectIsNotParent);
5114 :
5115 46 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5116 46 : Alphas(4),
5117 : ErrorsFound,
5118 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlow,
5119 46 : Alphas(1),
5120 : DataLoopNode::NodeFluidType::Air,
5121 : DataLoopNode::ConnectionType::Outlet,
5122 : NodeInputManager::CompFluidStream::Primary,
5123 : ObjectIsNotParent);
5124 :
5125 46 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
5126 :
5127 46 : thisDXCoil.CCapFTemp = GetCurveIndex(state, Alphas(5));
5128 46 : if (thisDXCoil.CCapFTemp(1) == 0) {
5129 0 : if (lAlphaBlanks(5)) {
5130 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5131 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
5132 : } else {
5133 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5134 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
5135 : }
5136 0 : ErrorsFound = true;
5137 : } else {
5138 92 : ErrorsFound |= Curve::CheckCurveDims(state,
5139 46 : thisDXCoil.CCapFTemp(1), // Curve index
5140 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
5141 : RoutineName, // Routine name
5142 : CurrentModuleObject, // Object Type
5143 : thisDXCoil.Name, // Object Name
5144 46 : cAlphaFields(5)); // Field Name
5145 :
5146 46 : if (!ErrorsFound) {
5147 46 : if (state.dataCurveManager->PerfCurve(thisDXCoil.CCapFTemp(1))->numDims == 1) {
5148 31 : checkCurveIsNormalizedToOne(state,
5149 62 : std::string{RoutineName} + CurrentModuleObject,
5150 31 : thisDXCoil.Name,
5151 31 : thisDXCoil.CCapFTemp(1),
5152 31 : cAlphaFields(5),
5153 31 : Alphas(5),
5154 : RatedInletAirTempHeat);
5155 : } else {
5156 : // Can't check this here, don't know if using outdoor dry-bulb or outdoor wet-bulb temp as input. Make this check in VRF TU
5157 : // GetInput.
5158 : }
5159 : }
5160 : }
5161 :
5162 46 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
5163 46 : if (thisDXCoil.CCapFFlow(1) == 0) {
5164 0 : if (lAlphaBlanks(6)) {
5165 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5166 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
5167 : } else {
5168 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5169 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
5170 : }
5171 0 : ErrorsFound = true;
5172 : } else {
5173 : // Verify Curve Object, only legal type is Quadratic
5174 92 : ErrorsFound |= Curve::CheckCurveDims(state,
5175 46 : thisDXCoil.CCapFFlow(1), // Curve index
5176 : {1}, // Valid dimensions
5177 : RoutineName, // Routine name
5178 : CurrentModuleObject, // Object Type
5179 : thisDXCoil.Name, // Object Name
5180 46 : cAlphaFields(6)); // Field Name
5181 :
5182 46 : if (!ErrorsFound) {
5183 46 : checkCurveIsNormalizedToOne(
5184 92 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
5185 : }
5186 : }
5187 : }
5188 :
5189 247 : if (ErrorsFound) {
5190 0 : ShowFatalError(state,
5191 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5192 : }
5193 :
5194 : // Loop over the VRF Cooling Coils for VRF FluidTCtrl Model_zrp 2015
5195 247 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling);
5196 263 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils; ++DXCoilIndex) {
5197 :
5198 16 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5199 : CurrentModuleObject,
5200 : DXCoilIndex,
5201 : Alphas,
5202 : NumAlphas,
5203 : Numbers,
5204 : NumNumbers,
5205 : IOStatus,
5206 : lNumericBlanks,
5207 : lAlphaBlanks,
5208 : cAlphaFields,
5209 : cNumericFields);
5210 :
5211 16 : ++DXCoilNum;
5212 :
5213 : // allocate single performance mode for numeric field strings used for sizing routine
5214 16 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
5215 16 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
5216 16 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
5217 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
5218 16 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
5219 :
5220 16 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5221 16 : thisDXCoil.Name = Alphas(1);
5222 16 : thisDXCoil.DXCoilType = CurrentModuleObject;
5223 16 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_FluidTCtrl_Cooling;
5224 16 : thisDXCoil.Schedule = Alphas(2);
5225 16 : if (lAlphaBlanks(2)) {
5226 0 : thisDXCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
5227 : } else {
5228 16 : thisDXCoil.SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
5229 16 : if (thisDXCoil.SchedPtr == 0) {
5230 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5231 0 : ShowContinueError(state, format("...{}=\"{}\".", cAlphaFields(2), Alphas(2)));
5232 0 : ErrorsFound = true;
5233 : }
5234 : }
5235 :
5236 16 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5237 16 : Alphas(3),
5238 : ErrorsFound,
5239 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl,
5240 16 : Alphas(1),
5241 : DataLoopNode::NodeFluidType::Air,
5242 : DataLoopNode::ConnectionType::Inlet,
5243 : NodeInputManager::CompFluidStream::Primary,
5244 : ObjectIsNotParent);
5245 16 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5246 16 : Alphas(4),
5247 : ErrorsFound,
5248 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl,
5249 16 : Alphas(1),
5250 : DataLoopNode::NodeFluidType::Air,
5251 : DataLoopNode::ConnectionType::Outlet,
5252 : NodeInputManager::CompFluidStream::Primary,
5253 : ObjectIsNotParent);
5254 16 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
5255 :
5256 16 : thisDXCoil.RatedTotCap(1) = Numbers(1);
5257 16 : thisDXCoil.RatedSHR(1) = Numbers(2);
5258 16 : thisDXCoil.SH = Numbers(3);
5259 : // @@ DXCoil( DXCoilNum ).RateBFVRFIUEvap = 0.0592; there will be a new field for this, which will be handled in a separate issue to
5260 : // update VRF-HP idd. It is not hanlded here to avoide tranistion issues for VRF-HP.
5261 :
5262 16 : int indexSHCurve = GetCurveIndex(state, Alphas(5)); // convert curve name to index number
5263 : // Verify curve name and type
5264 16 : if (indexSHCurve == 0) {
5265 0 : if (lAlphaBlanks(5)) {
5266 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5267 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
5268 : } else {
5269 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5270 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
5271 : }
5272 0 : ErrorsFound = true;
5273 : } else {
5274 : {
5275 16 : if (state.dataCurveManager->PerfCurve(indexSHCurve)->curveType == Curve::CurveType::Quadratic) {
5276 16 : thisDXCoil.C1Te = state.dataCurveManager->PerfCurve(indexSHCurve)->coeff[0];
5277 16 : thisDXCoil.C2Te = state.dataCurveManager->PerfCurve(indexSHCurve)->coeff[1];
5278 16 : thisDXCoil.C3Te = state.dataCurveManager->PerfCurve(indexSHCurve)->coeff[2];
5279 :
5280 : } else {
5281 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5282 0 : ShowContinueError(state,
5283 0 : format("...illegal {} type for this object = {}",
5284 : cAlphaFields(5),
5285 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->PerfCurve(indexSHCurve)->curveType)]));
5286 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
5287 0 : ErrorsFound = true;
5288 : }
5289 : }
5290 : }
5291 :
5292 16 : thisDXCoil.CondensateCollectName = Alphas(6);
5293 16 : if (lAlphaBlanks(6)) {
5294 16 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
5295 : } else {
5296 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
5297 0 : SetupTankSupplyComponent(state,
5298 : thisDXCoil.Name,
5299 : CurrentModuleObject,
5300 : thisDXCoil.CondensateCollectName,
5301 : ErrorsFound,
5302 0 : thisDXCoil.CondensateTankID,
5303 0 : thisDXCoil.CondensateTankSupplyARRID);
5304 : }
5305 : }
5306 :
5307 247 : if (ErrorsFound) {
5308 0 : ShowFatalError(state,
5309 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5310 : }
5311 :
5312 : // Loop over the VRF Heating Coils for VRF FluidTCtrl Model_zrp 2015
5313 247 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating);
5314 263 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils; ++DXCoilIndex) {
5315 :
5316 16 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5317 : CurrentModuleObject,
5318 : DXCoilIndex,
5319 : Alphas,
5320 : NumAlphas,
5321 : Numbers,
5322 : NumNumbers,
5323 : IOStatus,
5324 : lNumericBlanks,
5325 : lAlphaBlanks,
5326 : cAlphaFields,
5327 : cNumericFields);
5328 :
5329 16 : ++DXCoilNum;
5330 :
5331 : // allocate single performance mode for numeric field strings used for sizing routine
5332 16 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
5333 16 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
5334 16 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
5335 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
5336 16 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
5337 :
5338 16 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5339 16 : thisDXCoil.Name = Alphas(1);
5340 16 : thisDXCoil.DXCoilType = CurrentModuleObject;
5341 16 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_FluidTCtrl_Heating;
5342 16 : thisDXCoil.Schedule = Alphas(2);
5343 16 : if (lAlphaBlanks(2)) {
5344 0 : thisDXCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
5345 : } else {
5346 16 : thisDXCoil.SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
5347 16 : if (thisDXCoil.SchedPtr == 0) {
5348 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5349 0 : ShowContinueError(state, format("...{}=\"{}\".", cAlphaFields(2), Alphas(2)));
5350 0 : ErrorsFound = true;
5351 : }
5352 : }
5353 :
5354 16 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5355 16 : Alphas(3),
5356 : ErrorsFound,
5357 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl,
5358 16 : Alphas(1),
5359 : DataLoopNode::NodeFluidType::Air,
5360 : DataLoopNode::ConnectionType::Inlet,
5361 : NodeInputManager::CompFluidStream::Primary,
5362 : ObjectIsNotParent);
5363 16 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5364 16 : Alphas(4),
5365 : ErrorsFound,
5366 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl,
5367 16 : Alphas(1),
5368 : DataLoopNode::NodeFluidType::Air,
5369 : DataLoopNode::ConnectionType::Outlet,
5370 : NodeInputManager::CompFluidStream::Primary,
5371 : ObjectIsNotParent);
5372 16 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
5373 :
5374 16 : thisDXCoil.RatedTotCap(1) = Numbers(1);
5375 16 : thisDXCoil.SC = Numbers(2);
5376 : //@@ DXCoil( DXCoilNum ).RateBFVRFIUCond = 0.136;
5377 :
5378 16 : int indexSCCurve = GetCurveIndex(state, Alphas(5)); // convert curve name to index number
5379 : // Verify curve name and type
5380 16 : if (indexSCCurve == 0) {
5381 0 : if (lAlphaBlanks(5)) {
5382 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5383 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
5384 : } else {
5385 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5386 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
5387 : }
5388 0 : ErrorsFound = true;
5389 : } else {
5390 : {
5391 16 : if (state.dataCurveManager->PerfCurve(indexSCCurve)->curveType == Curve::CurveType::Quadratic) {
5392 16 : thisDXCoil.C1Tc = state.dataCurveManager->PerfCurve(indexSCCurve)->coeff[0];
5393 16 : thisDXCoil.C2Tc = state.dataCurveManager->PerfCurve(indexSCCurve)->coeff[1];
5394 16 : thisDXCoil.C3Tc = state.dataCurveManager->PerfCurve(indexSCCurve)->coeff[2];
5395 :
5396 : } else {
5397 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5398 0 : ShowContinueError(state,
5399 0 : format("...illegal {} type for this object = {}",
5400 : cAlphaFields(5),
5401 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->PerfCurve(indexSCCurve)->curveType)]));
5402 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
5403 0 : ErrorsFound = true;
5404 : }
5405 : }
5406 : }
5407 : }
5408 :
5409 247 : if (ErrorsFound) {
5410 0 : ShowFatalError(state,
5411 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5412 : }
5413 :
5414 1223 : for (DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDXCoils; ++DXCoilNum) {
5415 :
5416 976 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5417 :
5418 976 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
5419 : // Setup Report Variables for Cooling Equipment
5420 : // CurrentModuleObject='Coil:Cooling:DX:SingleSpeed/Coil:Cooling:DX:TwoStageWithHumidityControlMode'
5421 1246 : SetupOutputVariable(state,
5422 : "Cooling Coil Total Cooling Rate",
5423 : Constant::Units::W,
5424 623 : thisDXCoil.TotalCoolingEnergyRate,
5425 : OutputProcessor::TimeStepType::System,
5426 : OutputProcessor::StoreType::Average,
5427 623 : thisDXCoil.Name);
5428 1246 : SetupOutputVariable(state,
5429 : "Cooling Coil Total Cooling Energy",
5430 : Constant::Units::J,
5431 623 : thisDXCoil.TotalCoolingEnergy,
5432 : OutputProcessor::TimeStepType::System,
5433 : OutputProcessor::StoreType::Sum,
5434 623 : thisDXCoil.Name,
5435 : Constant::eResource::EnergyTransfer,
5436 : OutputProcessor::Group::HVAC,
5437 : OutputProcessor::EndUseCat::CoolingCoils);
5438 1246 : SetupOutputVariable(state,
5439 : "Cooling Coil Sensible Cooling Rate",
5440 : Constant::Units::W,
5441 623 : thisDXCoil.SensCoolingEnergyRate,
5442 : OutputProcessor::TimeStepType::System,
5443 : OutputProcessor::StoreType::Average,
5444 623 : thisDXCoil.Name);
5445 1246 : SetupOutputVariable(state,
5446 : "Cooling Coil Sensible Cooling Energy",
5447 : Constant::Units::J,
5448 623 : thisDXCoil.SensCoolingEnergy,
5449 : OutputProcessor::TimeStepType::System,
5450 : OutputProcessor::StoreType::Sum,
5451 623 : thisDXCoil.Name);
5452 1246 : SetupOutputVariable(state,
5453 : "Cooling Coil Latent Cooling Rate",
5454 : Constant::Units::W,
5455 623 : thisDXCoil.LatCoolingEnergyRate,
5456 : OutputProcessor::TimeStepType::System,
5457 : OutputProcessor::StoreType::Average,
5458 623 : thisDXCoil.Name);
5459 1246 : SetupOutputVariable(state,
5460 : "Cooling Coil Latent Cooling Energy",
5461 : Constant::Units::J,
5462 623 : thisDXCoil.LatCoolingEnergy,
5463 : OutputProcessor::TimeStepType::System,
5464 : OutputProcessor::StoreType::Sum,
5465 623 : thisDXCoil.Name);
5466 1246 : SetupOutputVariable(state,
5467 : "Cooling Coil Electricity Rate",
5468 : Constant::Units::W,
5469 623 : thisDXCoil.ElecCoolingPower,
5470 : OutputProcessor::TimeStepType::System,
5471 : OutputProcessor::StoreType::Average,
5472 623 : thisDXCoil.Name);
5473 1246 : SetupOutputVariable(state,
5474 : "Cooling Coil Electricity Energy",
5475 : Constant::Units::J,
5476 623 : thisDXCoil.ElecCoolingConsumption,
5477 : OutputProcessor::TimeStepType::System,
5478 : OutputProcessor::StoreType::Sum,
5479 623 : thisDXCoil.Name,
5480 : Constant::eResource::Electricity,
5481 : OutputProcessor::Group::HVAC,
5482 : OutputProcessor::EndUseCat::Cooling);
5483 1246 : SetupOutputVariable(state,
5484 : "Cooling Coil Runtime Fraction",
5485 : Constant::Units::None,
5486 623 : thisDXCoil.CoolingCoilRuntimeFraction,
5487 : OutputProcessor::TimeStepType::System,
5488 : OutputProcessor::StoreType::Average,
5489 623 : thisDXCoil.Name);
5490 623 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
5491 2 : SetupOutputVariable(state,
5492 : "Secondary Coil Heat Rejection Rate",
5493 : Constant::Units::W,
5494 1 : thisDXCoil.SecCoilSensibleHeatGainRate,
5495 : OutputProcessor::TimeStepType::System,
5496 : OutputProcessor::StoreType::Average,
5497 1 : thisDXCoil.Name);
5498 : }
5499 :
5500 : // do we report these even if no storage tank?
5501 623 : if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
5502 0 : SetupOutputVariable(state,
5503 : "Cooling Coil Condensate Volume Flow Rate",
5504 : Constant::Units::m3_s,
5505 0 : thisDXCoil.CondensateVdot,
5506 : OutputProcessor::TimeStepType::System,
5507 : OutputProcessor::StoreType::Average,
5508 0 : thisDXCoil.Name);
5509 0 : SetupOutputVariable(state,
5510 : "Cooling Coil Condensate Volume",
5511 : Constant::Units::m3,
5512 0 : thisDXCoil.CondensateVol,
5513 : OutputProcessor::TimeStepType::System,
5514 : OutputProcessor::StoreType::Sum,
5515 0 : thisDXCoil.Name,
5516 : Constant::eResource::OnSiteWater,
5517 : OutputProcessor::Group::HVAC,
5518 : OutputProcessor::EndUseCat::Condensate);
5519 : }
5520 :
5521 623 : if (thisDXCoil.ReportEvapCondVars) {
5522 4 : SetupOutputVariable(state,
5523 : "Cooling Coil Condenser Inlet Temperature",
5524 : Constant::Units::C,
5525 2 : thisDXCoil.CondInletTemp,
5526 : OutputProcessor::TimeStepType::System,
5527 : OutputProcessor::StoreType::Average,
5528 2 : thisDXCoil.Name);
5529 4 : SetupOutputVariable(state,
5530 : "Cooling Coil Evaporative Condenser Water Volume",
5531 : Constant::Units::m3,
5532 2 : thisDXCoil.EvapWaterConsump,
5533 : OutputProcessor::TimeStepType::System,
5534 : OutputProcessor::StoreType::Sum,
5535 2 : thisDXCoil.Name,
5536 : Constant::eResource::Water,
5537 : OutputProcessor::Group::HVAC,
5538 : OutputProcessor::EndUseCat::Cooling);
5539 4 : SetupOutputVariable(state,
5540 : "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
5541 : Constant::Units::m3,
5542 2 : thisDXCoil.EvapWaterConsump,
5543 : OutputProcessor::TimeStepType::System,
5544 : OutputProcessor::StoreType::Sum,
5545 2 : thisDXCoil.Name,
5546 : Constant::eResource::MainsWater,
5547 : OutputProcessor::Group::HVAC,
5548 : OutputProcessor::EndUseCat::Cooling);
5549 4 : SetupOutputVariable(state,
5550 : "Cooling Coil Evaporative Condenser Pump Electricity Rate",
5551 : Constant::Units::W,
5552 2 : thisDXCoil.EvapCondPumpElecPower,
5553 : OutputProcessor::TimeStepType::System,
5554 : OutputProcessor::StoreType::Average,
5555 2 : thisDXCoil.Name);
5556 4 : SetupOutputVariable(state,
5557 : "Cooling Coil Evaporative Condenser Pump Electricity Energy",
5558 : Constant::Units::J,
5559 2 : thisDXCoil.EvapCondPumpElecConsumption,
5560 : OutputProcessor::TimeStepType::System,
5561 : OutputProcessor::StoreType::Sum,
5562 2 : thisDXCoil.Name,
5563 : Constant::eResource::Electricity,
5564 : OutputProcessor::Group::HVAC,
5565 : OutputProcessor::EndUseCat::Cooling);
5566 2 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
5567 4 : SetupOutputVariable(state,
5568 : "Cooling Coil Basin Heater Electricity Rate",
5569 : Constant::Units::W,
5570 2 : thisDXCoil.BasinHeaterPower,
5571 : OutputProcessor::TimeStepType::System,
5572 : OutputProcessor::StoreType::Average,
5573 2 : thisDXCoil.Name);
5574 4 : SetupOutputVariable(state,
5575 : "Cooling Coil Basin Heater Electricity Energy",
5576 : Constant::Units::J,
5577 2 : thisDXCoil.BasinHeaterConsumption,
5578 : OutputProcessor::TimeStepType::System,
5579 : OutputProcessor::StoreType::Sum,
5580 2 : thisDXCoil.Name,
5581 : Constant::eResource::Electricity,
5582 : OutputProcessor::Group::HVAC,
5583 : OutputProcessor::EndUseCat::Cooling);
5584 : }
5585 : }
5586 :
5587 623 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
5588 : // Setup Report Variables for Cooling Equipment
5589 : // CurrentModuleObject='Cooling:DX:TwoStageWithHumidityControlMode'
5590 22 : SetupOutputVariable(state,
5591 : "Cooling Coil Stage 2 Runtime Fraction",
5592 : Constant::Units::None,
5593 11 : thisDXCoil.CoolingCoilStg2RuntimeFrac,
5594 : OutputProcessor::TimeStepType::System,
5595 : OutputProcessor::StoreType::Average,
5596 11 : thisDXCoil.Name);
5597 11 : SetupOutputVariable(state,
5598 : "Cooling Coil Dehumidification Mode",
5599 : Constant::Units::None,
5600 11 : (int &)thisDXCoil.DehumidificationMode,
5601 : OutputProcessor::TimeStepType::System,
5602 : OutputProcessor::StoreType::Average,
5603 11 : thisDXCoil.Name);
5604 : }
5605 :
5606 : }
5607 :
5608 353 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5609 : // Setup Report Variables for Heating Equipment
5610 : // CurrentModuleObject='Coil:Heating:DX:SingleSpeed'
5611 150 : SetupOutputVariable(state,
5612 : "Heating Coil Heating Rate",
5613 : Constant::Units::W,
5614 75 : thisDXCoil.TotalHeatingEnergyRate,
5615 : OutputProcessor::TimeStepType::System,
5616 : OutputProcessor::StoreType::Average,
5617 75 : thisDXCoil.Name);
5618 150 : SetupOutputVariable(state,
5619 : "Heating Coil Heating Energy",
5620 : Constant::Units::J,
5621 75 : thisDXCoil.TotalHeatingEnergy,
5622 : OutputProcessor::TimeStepType::System,
5623 : OutputProcessor::StoreType::Sum,
5624 75 : thisDXCoil.Name,
5625 : Constant::eResource::EnergyTransfer,
5626 : OutputProcessor::Group::HVAC,
5627 : OutputProcessor::EndUseCat::HeatingCoils);
5628 150 : SetupOutputVariable(state,
5629 : "Heating Coil Electricity Rate",
5630 : Constant::Units::W,
5631 75 : thisDXCoil.ElecHeatingPower,
5632 : OutputProcessor::TimeStepType::System,
5633 : OutputProcessor::StoreType::Average,
5634 75 : thisDXCoil.Name);
5635 150 : SetupOutputVariable(state,
5636 : "Heating Coil Electricity Energy",
5637 : Constant::Units::J,
5638 75 : thisDXCoil.ElecHeatingConsumption,
5639 : OutputProcessor::TimeStepType::System,
5640 : OutputProcessor::StoreType::Sum,
5641 75 : thisDXCoil.Name,
5642 : Constant::eResource::Electricity,
5643 : OutputProcessor::Group::HVAC,
5644 : OutputProcessor::EndUseCat::Heating);
5645 150 : SetupOutputVariable(state,
5646 : "Heating Coil Defrost Electricity Rate",
5647 : Constant::Units::W,
5648 75 : thisDXCoil.DefrostPower,
5649 : OutputProcessor::TimeStepType::System,
5650 : OutputProcessor::StoreType::Average,
5651 75 : thisDXCoil.Name);
5652 150 : SetupOutputVariable(state,
5653 : "Heating Coil Defrost Electricity Energy",
5654 : Constant::Units::J,
5655 75 : thisDXCoil.DefrostConsumption,
5656 : OutputProcessor::TimeStepType::System,
5657 : OutputProcessor::StoreType::Sum,
5658 75 : thisDXCoil.Name,
5659 : Constant::eResource::Electricity,
5660 : OutputProcessor::Group::HVAC,
5661 : OutputProcessor::EndUseCat::Heating);
5662 150 : SetupOutputVariable(state,
5663 : "Heating Coil Crankcase Heater Electricity Rate",
5664 : Constant::Units::W,
5665 75 : thisDXCoil.CrankcaseHeaterPower,
5666 : OutputProcessor::TimeStepType::System,
5667 : OutputProcessor::StoreType::Average,
5668 75 : thisDXCoil.Name);
5669 150 : SetupOutputVariable(state,
5670 : "Heating Coil Crankcase Heater Electricity Energy",
5671 : Constant::Units::J,
5672 75 : thisDXCoil.CrankcaseHeaterConsumption,
5673 : OutputProcessor::TimeStepType::System,
5674 : OutputProcessor::StoreType::Sum,
5675 75 : thisDXCoil.Name,
5676 : Constant::eResource::Electricity,
5677 : OutputProcessor::Group::HVAC,
5678 : OutputProcessor::EndUseCat::Heating);
5679 150 : SetupOutputVariable(state,
5680 : "Heating Coil Runtime Fraction",
5681 : Constant::Units::None,
5682 75 : thisDXCoil.HeatingCoilRuntimeFraction,
5683 : OutputProcessor::TimeStepType::System,
5684 : OutputProcessor::StoreType::Average,
5685 75 : thisDXCoil.Name);
5686 75 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
5687 2 : SetupOutputVariable(state,
5688 : "Secondary Coil Total Heat Removal Rate",
5689 : Constant::Units::W,
5690 1 : thisDXCoil.SecCoilTotalHeatRemovalRate,
5691 : OutputProcessor::TimeStepType::System,
5692 : OutputProcessor::StoreType::Average,
5693 1 : thisDXCoil.Name);
5694 2 : SetupOutputVariable(state,
5695 : "Secondary Coil Sensible Heat Removal Rate",
5696 : Constant::Units::W,
5697 1 : thisDXCoil.SecCoilSensibleHeatRemovalRate,
5698 : OutputProcessor::TimeStepType::System,
5699 : OutputProcessor::StoreType::Average,
5700 1 : thisDXCoil.Name);
5701 2 : SetupOutputVariable(state,
5702 : "Secondary Coil Latent Heat Removal Rate",
5703 : Constant::Units::W,
5704 1 : thisDXCoil.SecCoilLatentHeatRemovalRate,
5705 : OutputProcessor::TimeStepType::System,
5706 : OutputProcessor::StoreType::Average,
5707 1 : thisDXCoil.Name);
5708 2 : SetupOutputVariable(state,
5709 : "Secondary Coil Sensible Heat Ratio",
5710 : Constant::Units::None,
5711 1 : thisDXCoil.SecCoilSHR,
5712 : OutputProcessor::TimeStepType::System,
5713 : OutputProcessor::StoreType::Average,
5714 1 : thisDXCoil.Name);
5715 2 : SetupOutputVariable(state,
5716 : "Secondary Coil Compressor Part Load Ratio",
5717 : Constant::Units::None,
5718 1 : thisDXCoil.CompressorPartLoadRatio,
5719 : OutputProcessor::TimeStepType::System,
5720 : OutputProcessor::StoreType::Average,
5721 1 : thisDXCoil.Name);
5722 : }
5723 : }
5724 :
5725 278 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
5726 : // Setup Report Variables for Cooling Equipment
5727 : // CurrentModuleObject='Coil:Cooling:DX:TwoSpeed'
5728 134 : SetupOutputVariable(state,
5729 : "Cooling Coil Total Cooling Rate",
5730 : Constant::Units::W,
5731 67 : thisDXCoil.TotalCoolingEnergyRate,
5732 : OutputProcessor::TimeStepType::System,
5733 : OutputProcessor::StoreType::Average,
5734 67 : thisDXCoil.Name);
5735 134 : SetupOutputVariable(state,
5736 : "Cooling Coil Total Cooling Energy",
5737 : Constant::Units::J,
5738 67 : thisDXCoil.TotalCoolingEnergy,
5739 : OutputProcessor::TimeStepType::System,
5740 : OutputProcessor::StoreType::Sum,
5741 67 : thisDXCoil.Name,
5742 : Constant::eResource::EnergyTransfer,
5743 : OutputProcessor::Group::HVAC,
5744 : OutputProcessor::EndUseCat::CoolingCoils);
5745 134 : SetupOutputVariable(state,
5746 : "Cooling Coil Sensible Cooling Rate",
5747 : Constant::Units::W,
5748 67 : thisDXCoil.SensCoolingEnergyRate,
5749 : OutputProcessor::TimeStepType::System,
5750 : OutputProcessor::StoreType::Average,
5751 67 : thisDXCoil.Name);
5752 134 : SetupOutputVariable(state,
5753 : "Cooling Coil Sensible Cooling Energy",
5754 : Constant::Units::J,
5755 67 : thisDXCoil.SensCoolingEnergy,
5756 : OutputProcessor::TimeStepType::System,
5757 : OutputProcessor::StoreType::Sum,
5758 67 : thisDXCoil.Name);
5759 134 : SetupOutputVariable(state,
5760 : "Cooling Coil Latent Cooling Rate",
5761 : Constant::Units::W,
5762 67 : thisDXCoil.LatCoolingEnergyRate,
5763 : OutputProcessor::TimeStepType::System,
5764 : OutputProcessor::StoreType::Average,
5765 67 : thisDXCoil.Name);
5766 134 : SetupOutputVariable(state,
5767 : "Cooling Coil Latent Cooling Energy",
5768 : Constant::Units::J,
5769 67 : thisDXCoil.LatCoolingEnergy,
5770 : OutputProcessor::TimeStepType::System,
5771 : OutputProcessor::StoreType::Sum,
5772 67 : thisDXCoil.Name);
5773 134 : SetupOutputVariable(state,
5774 : "Cooling Coil Electricity Rate",
5775 : Constant::Units::W,
5776 67 : thisDXCoil.ElecCoolingPower,
5777 : OutputProcessor::TimeStepType::System,
5778 : OutputProcessor::StoreType::Average,
5779 67 : thisDXCoil.Name);
5780 134 : SetupOutputVariable(state,
5781 : "Cooling Coil Electricity Energy",
5782 : Constant::Units::J,
5783 67 : thisDXCoil.ElecCoolingConsumption,
5784 : OutputProcessor::TimeStepType::System,
5785 : OutputProcessor::StoreType::Sum,
5786 67 : thisDXCoil.Name,
5787 : Constant::eResource::Electricity,
5788 : OutputProcessor::Group::HVAC,
5789 : OutputProcessor::EndUseCat::Cooling);
5790 134 : SetupOutputVariable(state,
5791 : "Cooling Coil Runtime Fraction",
5792 : Constant::Units::None,
5793 67 : thisDXCoil.CoolingCoilRuntimeFraction,
5794 : OutputProcessor::TimeStepType::System,
5795 : OutputProcessor::StoreType::Average,
5796 67 : thisDXCoil.Name);
5797 67 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
5798 0 : SetupOutputVariable(state,
5799 : "Secondary Coil Heat Rejection Rate",
5800 : Constant::Units::W,
5801 0 : thisDXCoil.SecCoilSensibleHeatGainRate,
5802 : OutputProcessor::TimeStepType::System,
5803 : OutputProcessor::StoreType::Average,
5804 0 : thisDXCoil.Name);
5805 : }
5806 :
5807 67 : if (thisDXCoil.ReportEvapCondVars) {
5808 2 : SetupOutputVariable(state,
5809 : "Cooling Coil Condenser Inlet Temperature",
5810 : Constant::Units::C,
5811 1 : thisDXCoil.CondInletTemp,
5812 : OutputProcessor::TimeStepType::System,
5813 : OutputProcessor::StoreType::Average,
5814 1 : thisDXCoil.Name);
5815 2 : SetupOutputVariable(state,
5816 : "Cooling Coil Evaporative Condenser Water Volume",
5817 : Constant::Units::m3,
5818 1 : thisDXCoil.EvapWaterConsump,
5819 : OutputProcessor::TimeStepType::System,
5820 : OutputProcessor::StoreType::Sum,
5821 1 : thisDXCoil.Name,
5822 : Constant::eResource::Water,
5823 : OutputProcessor::Group::HVAC,
5824 : OutputProcessor::EndUseCat::Cooling);
5825 2 : SetupOutputVariable(state,
5826 : "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
5827 : Constant::Units::m3,
5828 1 : thisDXCoil.EvapWaterConsump,
5829 : OutputProcessor::TimeStepType::System,
5830 : OutputProcessor::StoreType::Sum,
5831 1 : thisDXCoil.Name,
5832 : Constant::eResource::MainsWater,
5833 : OutputProcessor::Group::HVAC,
5834 : OutputProcessor::EndUseCat::Cooling);
5835 2 : SetupOutputVariable(state,
5836 : "Cooling Coil Evaporative Condenser Pump Electricity Rate",
5837 : Constant::Units::W,
5838 1 : thisDXCoil.EvapCondPumpElecPower,
5839 : OutputProcessor::TimeStepType::System,
5840 : OutputProcessor::StoreType::Average,
5841 1 : thisDXCoil.Name);
5842 2 : SetupOutputVariable(state,
5843 : "Cooling Coil Evaporative Condenser Pump Electricity Energy",
5844 : Constant::Units::J,
5845 1 : thisDXCoil.EvapCondPumpElecConsumption,
5846 : OutputProcessor::TimeStepType::System,
5847 : OutputProcessor::StoreType::Sum,
5848 1 : thisDXCoil.Name,
5849 : Constant::eResource::Electricity,
5850 : OutputProcessor::Group::HVAC,
5851 : OutputProcessor::EndUseCat::Cooling);
5852 1 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
5853 2 : SetupOutputVariable(state,
5854 : "Cooling Coil Basin Heater Electricity Rate",
5855 : Constant::Units::W,
5856 1 : thisDXCoil.BasinHeaterPower,
5857 : OutputProcessor::TimeStepType::System,
5858 : OutputProcessor::StoreType::Average,
5859 1 : thisDXCoil.Name);
5860 2 : SetupOutputVariable(state,
5861 : "Cooling Coil Basin Heater Electricity Energy",
5862 : Constant::Units::J,
5863 1 : thisDXCoil.BasinHeaterConsumption,
5864 : OutputProcessor::TimeStepType::System,
5865 : OutputProcessor::StoreType::Sum,
5866 1 : thisDXCoil.Name,
5867 : Constant::eResource::Electricity,
5868 : OutputProcessor::Group::HVAC,
5869 : OutputProcessor::EndUseCat::Cooling);
5870 : }
5871 : }
5872 :
5873 : }
5874 :
5875 211 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
5876 198 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
5877 : // Setup Report Variables for Cooling Equipment
5878 : // CurrentModuleObject='Coil:WaterHeating:AirToWaterHeatPump:Pumped'
5879 : // or 'Coil:WaterHeating:AirToWaterHeatPump:Wrapped'
5880 32 : SetupOutputVariable(state,
5881 : "Cooling Coil Total Cooling Rate",
5882 : Constant::Units::W,
5883 16 : thisDXCoil.TotalCoolingEnergyRate,
5884 : OutputProcessor::TimeStepType::System,
5885 : OutputProcessor::StoreType::Average,
5886 16 : thisDXCoil.Name);
5887 :
5888 16 : if (thisDXCoil.IsDXCoilInZone) {
5889 30 : SetupOutputVariable(state,
5890 : "Cooling Coil Total Cooling Energy",
5891 : Constant::Units::J,
5892 15 : thisDXCoil.TotalCoolingEnergy,
5893 : OutputProcessor::TimeStepType::System,
5894 : OutputProcessor::StoreType::Sum,
5895 15 : thisDXCoil.Name,
5896 : Constant::eResource::EnergyTransfer,
5897 : OutputProcessor::Group::HVAC,
5898 : OutputProcessor::EndUseCat::CoolingCoils);
5899 : } else {
5900 2 : SetupOutputVariable(state,
5901 : "Cooling Coil Total Cooling Energy",
5902 : Constant::Units::J,
5903 1 : thisDXCoil.TotalCoolingEnergy,
5904 : OutputProcessor::TimeStepType::System,
5905 : OutputProcessor::StoreType::Sum,
5906 1 : thisDXCoil.Name);
5907 : }
5908 :
5909 32 : SetupOutputVariable(state,
5910 : "Cooling Coil Sensible Cooling Rate",
5911 : Constant::Units::W,
5912 16 : thisDXCoil.SensCoolingEnergyRate,
5913 : OutputProcessor::TimeStepType::System,
5914 : OutputProcessor::StoreType::Average,
5915 16 : thisDXCoil.Name);
5916 32 : SetupOutputVariable(state,
5917 : "Cooling Coil Sensible Cooling Energy",
5918 : Constant::Units::J,
5919 16 : thisDXCoil.SensCoolingEnergy,
5920 : OutputProcessor::TimeStepType::System,
5921 : OutputProcessor::StoreType::Sum,
5922 16 : thisDXCoil.Name);
5923 32 : SetupOutputVariable(state,
5924 : "Cooling Coil Latent Cooling Rate",
5925 : Constant::Units::W,
5926 16 : thisDXCoil.LatCoolingEnergyRate,
5927 : OutputProcessor::TimeStepType::System,
5928 : OutputProcessor::StoreType::Average,
5929 16 : thisDXCoil.Name);
5930 32 : SetupOutputVariable(state,
5931 : "Cooling Coil Latent Cooling Energy",
5932 : Constant::Units::J,
5933 16 : thisDXCoil.LatCoolingEnergy,
5934 : OutputProcessor::TimeStepType::System,
5935 : OutputProcessor::StoreType::Sum,
5936 16 : thisDXCoil.Name);
5937 32 : SetupOutputVariable(state,
5938 : "Cooling Coil Runtime Fraction",
5939 : Constant::Units::None,
5940 16 : thisDXCoil.CoolingCoilRuntimeFraction,
5941 : OutputProcessor::TimeStepType::System,
5942 : OutputProcessor::StoreType::Average,
5943 16 : thisDXCoil.Name);
5944 :
5945 16 : if (thisDXCoil.ReportCoolingCoilCrankcasePower) {
5946 32 : SetupOutputVariable(state,
5947 : "Cooling Coil Crankcase Heater Electricity Rate",
5948 : Constant::Units::W,
5949 16 : thisDXCoil.CrankcaseHeaterPower,
5950 : OutputProcessor::TimeStepType::System,
5951 : OutputProcessor::StoreType::Average,
5952 16 : thisDXCoil.Name);
5953 32 : SetupOutputVariable(state,
5954 : "Cooling Coil Crankcase Heater Electricity Energy",
5955 : Constant::Units::J,
5956 16 : thisDXCoil.CrankcaseHeaterConsumption,
5957 : OutputProcessor::TimeStepType::System,
5958 : OutputProcessor::StoreType::Sum,
5959 16 : thisDXCoil.Name,
5960 : Constant::eResource::Electricity,
5961 : OutputProcessor::Group::Plant,
5962 : OutputProcessor::EndUseCat::WaterSystem); // DHW
5963 : }
5964 :
5965 : // new report variables for a HP water heater DX coil
5966 32 : SetupOutputVariable(state,
5967 : "Cooling Coil Total Water Heating Rate",
5968 : Constant::Units::W,
5969 16 : thisDXCoil.TotalHeatingEnergyRate,
5970 : OutputProcessor::TimeStepType::System,
5971 : OutputProcessor::StoreType::Average,
5972 16 : thisDXCoil.Name);
5973 32 : SetupOutputVariable(state,
5974 : "Cooling Coil Total Water Heating Energy",
5975 : Constant::Units::J,
5976 16 : thisDXCoil.TotalHeatingEnergy,
5977 : OutputProcessor::TimeStepType::System,
5978 : OutputProcessor::StoreType::Sum,
5979 16 : thisDXCoil.Name); //, &
5980 : // ResourceTypeKey='ENERGYTRANSFER',EndUseKey='HEATING',GroupKey='Plant')
5981 32 : SetupOutputVariable(state,
5982 : "Cooling Coil Water Heating Electricity Rate",
5983 : Constant::Units::W,
5984 16 : thisDXCoil.ElecWaterHeatingPower,
5985 : OutputProcessor::TimeStepType::System,
5986 : OutputProcessor::StoreType::Average,
5987 16 : thisDXCoil.Name);
5988 32 : SetupOutputVariable(state,
5989 : "Cooling Coil Water Heating Electricity Energy",
5990 : Constant::Units::J,
5991 16 : thisDXCoil.ElecWaterHeatingConsumption,
5992 : OutputProcessor::TimeStepType::System,
5993 : OutputProcessor::StoreType::Sum,
5994 16 : thisDXCoil.Name,
5995 : Constant::eResource::Electricity,
5996 : OutputProcessor::Group::Plant,
5997 : OutputProcessor::EndUseCat::WaterSystem); // DHW
5998 : }
5999 :
6000 195 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6001 : // Setup Report Variables for Cooling Equipment:
6002 : // CurrentModuleObject='Coil:Cooling:DX:MultiSpeed'
6003 98 : SetupOutputVariable(state,
6004 : "Cooling Coil Total Cooling Rate",
6005 : Constant::Units::W,
6006 49 : thisDXCoil.TotalCoolingEnergyRate,
6007 : OutputProcessor::TimeStepType::System,
6008 : OutputProcessor::StoreType::Average,
6009 49 : thisDXCoil.Name);
6010 98 : SetupOutputVariable(state,
6011 : "Cooling Coil Total Cooling Energy",
6012 : Constant::Units::J,
6013 49 : thisDXCoil.TotalCoolingEnergy,
6014 : OutputProcessor::TimeStepType::System,
6015 : OutputProcessor::StoreType::Sum,
6016 49 : thisDXCoil.Name,
6017 : Constant::eResource::EnergyTransfer,
6018 : OutputProcessor::Group::HVAC,
6019 : OutputProcessor::EndUseCat::CoolingCoils);
6020 98 : SetupOutputVariable(state,
6021 : "Cooling Coil Sensible Cooling Rate",
6022 : Constant::Units::W,
6023 49 : thisDXCoil.SensCoolingEnergyRate,
6024 : OutputProcessor::TimeStepType::System,
6025 : OutputProcessor::StoreType::Average,
6026 49 : thisDXCoil.Name);
6027 98 : SetupOutputVariable(state,
6028 : "Cooling Coil Sensible Cooling Energy",
6029 : Constant::Units::J,
6030 49 : thisDXCoil.SensCoolingEnergy,
6031 : OutputProcessor::TimeStepType::System,
6032 : OutputProcessor::StoreType::Sum,
6033 49 : thisDXCoil.Name);
6034 98 : SetupOutputVariable(state,
6035 : "Cooling Coil Latent Cooling Rate",
6036 : Constant::Units::W,
6037 49 : thisDXCoil.LatCoolingEnergyRate,
6038 : OutputProcessor::TimeStepType::System,
6039 : OutputProcessor::StoreType::Average,
6040 49 : thisDXCoil.Name);
6041 98 : SetupOutputVariable(state,
6042 : "Cooling Coil Latent Cooling Energy",
6043 : Constant::Units::J,
6044 49 : thisDXCoil.LatCoolingEnergy,
6045 : OutputProcessor::TimeStepType::System,
6046 : OutputProcessor::StoreType::Sum,
6047 49 : thisDXCoil.Name);
6048 98 : SetupOutputVariable(state,
6049 : "Cooling Coil Electricity Rate",
6050 : Constant::Units::W,
6051 49 : thisDXCoil.ElecCoolingPower,
6052 : OutputProcessor::TimeStepType::System,
6053 : OutputProcessor::StoreType::Average,
6054 49 : thisDXCoil.Name);
6055 98 : SetupOutputVariable(state,
6056 : "Cooling Coil Electricity Energy",
6057 : Constant::Units::J,
6058 49 : thisDXCoil.ElecCoolingConsumption,
6059 : OutputProcessor::TimeStepType::System,
6060 : OutputProcessor::StoreType::Sum,
6061 49 : thisDXCoil.Name,
6062 : Constant::eResource::Electricity,
6063 : OutputProcessor::Group::HVAC,
6064 : OutputProcessor::EndUseCat::Cooling);
6065 :
6066 49 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
6067 6 : std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
6068 18 : SetupOutputVariable(state,
6069 12 : format("Cooling Coil {} Rate", sFuelType),
6070 : Constant::Units::W,
6071 6 : thisDXCoil.FuelUsed,
6072 : OutputProcessor::TimeStepType::System,
6073 : OutputProcessor::StoreType::Average,
6074 6 : thisDXCoil.Name);
6075 18 : SetupOutputVariable(state,
6076 12 : format("Cooling Coil {} Energy", sFuelType),
6077 : Constant::Units::J,
6078 6 : thisDXCoil.FuelConsumed,
6079 : OutputProcessor::TimeStepType::System,
6080 : OutputProcessor::StoreType::Sum,
6081 6 : thisDXCoil.Name,
6082 6 : Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
6083 : OutputProcessor::Group::HVAC,
6084 : OutputProcessor::EndUseCat::Cooling);
6085 : }
6086 :
6087 98 : SetupOutputVariable(state,
6088 : "Cooling Coil Runtime Fraction",
6089 : Constant::Units::None,
6090 49 : thisDXCoil.CoolingCoilRuntimeFraction,
6091 : OutputProcessor::TimeStepType::System,
6092 : OutputProcessor::StoreType::Average,
6093 49 : thisDXCoil.Name);
6094 :
6095 49 : if (thisDXCoil.ReportEvapCondVars) {
6096 0 : SetupOutputVariable(state,
6097 : "Cooling Coil Condenser Inlet Temperature",
6098 : Constant::Units::C,
6099 0 : thisDXCoil.CondInletTemp,
6100 : OutputProcessor::TimeStepType::System,
6101 : OutputProcessor::StoreType::Average,
6102 0 : thisDXCoil.Name);
6103 0 : SetupOutputVariable(state,
6104 : "Cooling Coil Evaporative Condenser Water Volume",
6105 : Constant::Units::m3,
6106 0 : thisDXCoil.EvapWaterConsump,
6107 : OutputProcessor::TimeStepType::System,
6108 : OutputProcessor::StoreType::Sum,
6109 0 : thisDXCoil.Name,
6110 : Constant::eResource::Water,
6111 : OutputProcessor::Group::HVAC,
6112 : OutputProcessor::EndUseCat::Cooling);
6113 0 : SetupOutputVariable(state,
6114 : "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
6115 : Constant::Units::m3,
6116 0 : thisDXCoil.EvapWaterConsump,
6117 : OutputProcessor::TimeStepType::System,
6118 : OutputProcessor::StoreType::Sum,
6119 0 : thisDXCoil.Name,
6120 : Constant::eResource::MainsWater,
6121 : OutputProcessor::Group::HVAC,
6122 : OutputProcessor::EndUseCat::Cooling);
6123 0 : SetupOutputVariable(state,
6124 : "Cooling Coil Evaporative Condenser Pump Electricity Rate",
6125 : Constant::Units::W,
6126 0 : thisDXCoil.EvapCondPumpElecPower,
6127 : OutputProcessor::TimeStepType::System,
6128 : OutputProcessor::StoreType::Average,
6129 0 : thisDXCoil.Name);
6130 0 : SetupOutputVariable(state,
6131 : "Cooling Coil Evaporative Condenser Pump Electricity Energy",
6132 : Constant::Units::J,
6133 0 : thisDXCoil.EvapCondPumpElecConsumption,
6134 : OutputProcessor::TimeStepType::System,
6135 : OutputProcessor::StoreType::Sum,
6136 0 : thisDXCoil.Name,
6137 : Constant::eResource::Electricity,
6138 : OutputProcessor::Group::HVAC,
6139 : OutputProcessor::EndUseCat::Cooling);
6140 0 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
6141 0 : SetupOutputVariable(state,
6142 : "Cooling Coil Basin Heater Electricity Rate",
6143 : Constant::Units::W,
6144 0 : thisDXCoil.BasinHeaterPower,
6145 : OutputProcessor::TimeStepType::System,
6146 : OutputProcessor::StoreType::Average,
6147 0 : thisDXCoil.Name);
6148 0 : SetupOutputVariable(state,
6149 : "Cooling Coil Basin Heater Electricity Energy",
6150 : Constant::Units::J,
6151 0 : thisDXCoil.BasinHeaterConsumption,
6152 : OutputProcessor::TimeStepType::System,
6153 : OutputProcessor::StoreType::Sum,
6154 0 : thisDXCoil.Name,
6155 : Constant::eResource::Electricity,
6156 : OutputProcessor::Group::HVAC,
6157 : OutputProcessor::EndUseCat::Cooling);
6158 : }
6159 : }
6160 49 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
6161 0 : SetupOutputVariable(state,
6162 : "Secondary Coil Heat Rejection Rate",
6163 : Constant::Units::W,
6164 0 : thisDXCoil.SecCoilSensibleHeatGainRate,
6165 : OutputProcessor::TimeStepType::System,
6166 : OutputProcessor::StoreType::Average,
6167 0 : thisDXCoil.Name);
6168 : }
6169 :
6170 : }
6171 :
6172 146 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6173 : // Setup Report Variables for Heating Equipment:
6174 : // CurrentModuleObject='Coil:Heating:DX:MultiSpeed'
6175 44 : SetupOutputVariable(state,
6176 : "Heating Coil Heating Rate",
6177 : Constant::Units::W,
6178 22 : thisDXCoil.TotalHeatingEnergyRate,
6179 : OutputProcessor::TimeStepType::System,
6180 : OutputProcessor::StoreType::Average,
6181 22 : thisDXCoil.Name);
6182 44 : SetupOutputVariable(state,
6183 : "Heating Coil Heating Energy",
6184 : Constant::Units::J,
6185 22 : thisDXCoil.TotalHeatingEnergy,
6186 : OutputProcessor::TimeStepType::System,
6187 : OutputProcessor::StoreType::Sum,
6188 22 : thisDXCoil.Name,
6189 : Constant::eResource::EnergyTransfer,
6190 : OutputProcessor::Group::HVAC,
6191 : OutputProcessor::EndUseCat::HeatingCoils);
6192 44 : SetupOutputVariable(state,
6193 : "Heating Coil Electricity Rate",
6194 : Constant::Units::W,
6195 22 : thisDXCoil.ElecHeatingPower,
6196 : OutputProcessor::TimeStepType::System,
6197 : OutputProcessor::StoreType::Average,
6198 22 : thisDXCoil.Name);
6199 44 : SetupOutputVariable(state,
6200 : "Heating Coil Electricity Energy",
6201 : Constant::Units::J,
6202 22 : thisDXCoil.ElecHeatingConsumption,
6203 : OutputProcessor::TimeStepType::System,
6204 : OutputProcessor::StoreType::Sum,
6205 22 : thisDXCoil.Name,
6206 : Constant::eResource::Electricity,
6207 : OutputProcessor::Group::HVAC,
6208 : OutputProcessor::EndUseCat::Heating);
6209 :
6210 22 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
6211 4 : std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
6212 12 : SetupOutputVariable(state,
6213 8 : format("Heating Coil {} Rate", sFuelType),
6214 : Constant::Units::W,
6215 4 : thisDXCoil.FuelUsed,
6216 : OutputProcessor::TimeStepType::System,
6217 : OutputProcessor::StoreType::Average,
6218 4 : thisDXCoil.Name);
6219 12 : SetupOutputVariable(state,
6220 8 : format("Heating Coil {} Energy", sFuelType),
6221 : Constant::Units::J,
6222 4 : thisDXCoil.FuelConsumed,
6223 : OutputProcessor::TimeStepType::System,
6224 : OutputProcessor::StoreType::Sum,
6225 4 : thisDXCoil.Name,
6226 4 : Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
6227 : OutputProcessor::Group::HVAC,
6228 : OutputProcessor::EndUseCat::HeatingCoils);
6229 : }
6230 :
6231 22 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
6232 4 : std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
6233 12 : SetupOutputVariable(state,
6234 8 : format("Heating Coil Defrost {} Rate", sFuelType),
6235 : Constant::Units::W,
6236 4 : thisDXCoil.DefrostPower,
6237 : OutputProcessor::TimeStepType::System,
6238 : OutputProcessor::StoreType::Average,
6239 4 : thisDXCoil.Name);
6240 12 : SetupOutputVariable(state,
6241 8 : format("Heating Coil Defrost {} Energy", sFuelType),
6242 : Constant::Units::J,
6243 4 : thisDXCoil.DefrostConsumption,
6244 : OutputProcessor::TimeStepType::System,
6245 : OutputProcessor::StoreType::Sum,
6246 4 : thisDXCoil.Name,
6247 4 : Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
6248 : OutputProcessor::Group::HVAC,
6249 : OutputProcessor::EndUseCat::Heating);
6250 4 : } else {
6251 36 : SetupOutputVariable(state,
6252 : "Heating Coil Defrost Electricity Rate",
6253 : Constant::Units::W,
6254 18 : thisDXCoil.DefrostPower,
6255 : OutputProcessor::TimeStepType::System,
6256 : OutputProcessor::StoreType::Average,
6257 18 : thisDXCoil.Name);
6258 36 : SetupOutputVariable(state,
6259 : "Heating Coil Defrost Electricity Energy",
6260 : Constant::Units::J,
6261 18 : thisDXCoil.DefrostConsumption,
6262 : OutputProcessor::TimeStepType::System,
6263 : OutputProcessor::StoreType::Sum,
6264 18 : thisDXCoil.Name,
6265 : Constant::eResource::Electricity,
6266 : OutputProcessor::Group::HVAC,
6267 : OutputProcessor::EndUseCat::Heating);
6268 : }
6269 :
6270 44 : SetupOutputVariable(state,
6271 : "Heating Coil Crankcase Heater Electricity Rate",
6272 : Constant::Units::W,
6273 22 : thisDXCoil.CrankcaseHeaterPower,
6274 : OutputProcessor::TimeStepType::System,
6275 : OutputProcessor::StoreType::Average,
6276 22 : thisDXCoil.Name);
6277 44 : SetupOutputVariable(state,
6278 : "Heating Coil Crankcase Heater Electricity Energy",
6279 : Constant::Units::J,
6280 22 : thisDXCoil.CrankcaseHeaterConsumption,
6281 : OutputProcessor::TimeStepType::System,
6282 : OutputProcessor::StoreType::Sum,
6283 22 : thisDXCoil.Name,
6284 : Constant::eResource::Electricity,
6285 : OutputProcessor::Group::HVAC,
6286 : OutputProcessor::EndUseCat::Heating);
6287 44 : SetupOutputVariable(state,
6288 : "Heating Coil Runtime Fraction",
6289 : Constant::Units::None,
6290 22 : thisDXCoil.HeatingCoilRuntimeFraction,
6291 : OutputProcessor::TimeStepType::System,
6292 : OutputProcessor::StoreType::Average,
6293 22 : thisDXCoil.Name);
6294 :
6295 22 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
6296 0 : SetupOutputVariable(state,
6297 : "Secondary Coil Total Heat Removal Rate",
6298 : Constant::Units::W,
6299 0 : thisDXCoil.SecCoilTotalHeatRemovalRate,
6300 : OutputProcessor::TimeStepType::System,
6301 : OutputProcessor::StoreType::Average,
6302 0 : thisDXCoil.Name);
6303 0 : SetupOutputVariable(state,
6304 : "Secondary Coil Sensible Heat Removal Rate",
6305 : Constant::Units::W,
6306 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate,
6307 : OutputProcessor::TimeStepType::System,
6308 : OutputProcessor::StoreType::Average,
6309 0 : thisDXCoil.Name);
6310 0 : SetupOutputVariable(state,
6311 : "Secondary Coil Latent Heat Removal Rate",
6312 : Constant::Units::W,
6313 0 : thisDXCoil.SecCoilLatentHeatRemovalRate,
6314 : OutputProcessor::TimeStepType::System,
6315 : OutputProcessor::StoreType::Average,
6316 0 : thisDXCoil.Name);
6317 0 : SetupOutputVariable(state,
6318 : "Secondary Coil Sensible Heat Ratio",
6319 : Constant::Units::None,
6320 0 : thisDXCoil.SecCoilSHR,
6321 : OutputProcessor::TimeStepType::System,
6322 : OutputProcessor::StoreType::Average,
6323 0 : thisDXCoil.Name);
6324 : }
6325 : }
6326 :
6327 : // VRF cooling coil report variables
6328 124 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
6329 : // Setup Report Variables for Cooling Equipment:
6330 : // CurrentModuleObject='Coil:Cooling:DX:VariableRefrigerantFlow
6331 92 : SetupOutputVariable(state,
6332 : "Cooling Coil Total Cooling Rate",
6333 : Constant::Units::W,
6334 46 : thisDXCoil.TotalCoolingEnergyRate,
6335 : OutputProcessor::TimeStepType::System,
6336 : OutputProcessor::StoreType::Average,
6337 46 : thisDXCoil.Name);
6338 92 : SetupOutputVariable(state,
6339 : "Cooling Coil Total Cooling Energy",
6340 : Constant::Units::J,
6341 46 : thisDXCoil.TotalCoolingEnergy,
6342 : OutputProcessor::TimeStepType::System,
6343 : OutputProcessor::StoreType::Sum,
6344 46 : thisDXCoil.Name,
6345 : Constant::eResource::EnergyTransfer,
6346 : OutputProcessor::Group::HVAC,
6347 : OutputProcessor::EndUseCat::CoolingCoils);
6348 92 : SetupOutputVariable(state,
6349 : "Cooling Coil Sensible Cooling Rate",
6350 : Constant::Units::W,
6351 46 : thisDXCoil.SensCoolingEnergyRate,
6352 : OutputProcessor::TimeStepType::System,
6353 : OutputProcessor::StoreType::Average,
6354 46 : thisDXCoil.Name);
6355 92 : SetupOutputVariable(state,
6356 : "Cooling Coil Sensible Cooling Energy",
6357 : Constant::Units::J,
6358 46 : thisDXCoil.SensCoolingEnergy,
6359 : OutputProcessor::TimeStepType::System,
6360 : OutputProcessor::StoreType::Sum,
6361 46 : thisDXCoil.Name);
6362 92 : SetupOutputVariable(state,
6363 : "Cooling Coil Latent Cooling Rate",
6364 : Constant::Units::W,
6365 46 : thisDXCoil.LatCoolingEnergyRate,
6366 : OutputProcessor::TimeStepType::System,
6367 : OutputProcessor::StoreType::Average,
6368 46 : thisDXCoil.Name);
6369 92 : SetupOutputVariable(state,
6370 : "Cooling Coil Latent Cooling Energy",
6371 : Constant::Units::J,
6372 46 : thisDXCoil.LatCoolingEnergy,
6373 : OutputProcessor::TimeStepType::System,
6374 : OutputProcessor::StoreType::Sum,
6375 46 : thisDXCoil.Name);
6376 92 : SetupOutputVariable(state,
6377 : "Cooling Coil Runtime Fraction",
6378 : Constant::Units::None,
6379 46 : thisDXCoil.CoolingCoilRuntimeFraction,
6380 : OutputProcessor::TimeStepType::System,
6381 : OutputProcessor::StoreType::Average,
6382 46 : thisDXCoil.Name);
6383 46 : if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
6384 0 : SetupOutputVariable(state,
6385 : "Cooling Coil Condensate Volume Flow Rate",
6386 : Constant::Units::m3_s,
6387 0 : thisDXCoil.CondensateVdot,
6388 : OutputProcessor::TimeStepType::System,
6389 : OutputProcessor::StoreType::Average,
6390 0 : thisDXCoil.Name);
6391 0 : SetupOutputVariable(state,
6392 : "Cooling Coil Condensate Volume",
6393 : Constant::Units::m3,
6394 0 : thisDXCoil.CondensateVol,
6395 : OutputProcessor::TimeStepType::System,
6396 : OutputProcessor::StoreType::Sum,
6397 0 : thisDXCoil.Name,
6398 : Constant::eResource::OnSiteWater,
6399 : OutputProcessor::Group::HVAC,
6400 : OutputProcessor::EndUseCat::Condensate);
6401 : }
6402 : }
6403 :
6404 : // VRF heating coil report variables
6405 78 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
6406 : // Setup Report Variables for Heating Equipment:
6407 : // CurrentModuleObject='Coil:Heating:DX:VariableRefrigerantFlow
6408 92 : SetupOutputVariable(state,
6409 : "Heating Coil Heating Rate",
6410 : Constant::Units::W,
6411 46 : thisDXCoil.TotalHeatingEnergyRate,
6412 : OutputProcessor::TimeStepType::System,
6413 : OutputProcessor::StoreType::Average,
6414 46 : thisDXCoil.Name);
6415 92 : SetupOutputVariable(state,
6416 : "Heating Coil Heating Energy",
6417 : Constant::Units::J,
6418 46 : thisDXCoil.TotalHeatingEnergy,
6419 : OutputProcessor::TimeStepType::System,
6420 : OutputProcessor::StoreType::Sum,
6421 46 : thisDXCoil.Name,
6422 : Constant::eResource::EnergyTransfer,
6423 : OutputProcessor::Group::HVAC,
6424 : OutputProcessor::EndUseCat::HeatingCoils);
6425 92 : SetupOutputVariable(state,
6426 : "Heating Coil Runtime Fraction",
6427 : Constant::Units::None,
6428 46 : thisDXCoil.HeatingCoilRuntimeFraction,
6429 : OutputProcessor::TimeStepType::System,
6430 : OutputProcessor::StoreType::Average,
6431 46 : thisDXCoil.Name);
6432 : }
6433 :
6434 : // VRF cooling coil for FluidTCtrl, report variables
6435 32 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
6436 : // Setup Report Variables for Cooling Equipment:
6437 : // CurrentModuleObject='Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl
6438 32 : SetupOutputVariable(state,
6439 : "Cooling Coil Total Cooling Rate",
6440 : Constant::Units::W,
6441 16 : thisDXCoil.TotalCoolingEnergyRate,
6442 : OutputProcessor::TimeStepType::System,
6443 : OutputProcessor::StoreType::Average,
6444 16 : thisDXCoil.Name);
6445 32 : SetupOutputVariable(state,
6446 : "Cooling Coil Total Cooling Energy",
6447 : Constant::Units::J,
6448 16 : thisDXCoil.TotalCoolingEnergy,
6449 : OutputProcessor::TimeStepType::System,
6450 : OutputProcessor::StoreType::Sum,
6451 16 : thisDXCoil.Name,
6452 : Constant::eResource::EnergyTransfer,
6453 : OutputProcessor::Group::HVAC,
6454 : OutputProcessor::EndUseCat::CoolingCoils);
6455 32 : SetupOutputVariable(state,
6456 : "Cooling Coil Sensible Cooling Rate",
6457 : Constant::Units::W,
6458 16 : thisDXCoil.SensCoolingEnergyRate,
6459 : OutputProcessor::TimeStepType::System,
6460 : OutputProcessor::StoreType::Average,
6461 16 : thisDXCoil.Name);
6462 32 : SetupOutputVariable(state,
6463 : "Cooling Coil Sensible Cooling Energy",
6464 : Constant::Units::J,
6465 16 : thisDXCoil.SensCoolingEnergy,
6466 : OutputProcessor::TimeStepType::System,
6467 : OutputProcessor::StoreType::Sum,
6468 16 : thisDXCoil.Name);
6469 32 : SetupOutputVariable(state,
6470 : "Cooling Coil Latent Cooling Rate",
6471 : Constant::Units::W,
6472 16 : thisDXCoil.LatCoolingEnergyRate,
6473 : OutputProcessor::TimeStepType::System,
6474 : OutputProcessor::StoreType::Average,
6475 16 : thisDXCoil.Name);
6476 32 : SetupOutputVariable(state,
6477 : "Cooling Coil Latent Cooling Energy",
6478 : Constant::Units::J,
6479 16 : thisDXCoil.LatCoolingEnergy,
6480 : OutputProcessor::TimeStepType::System,
6481 : OutputProcessor::StoreType::Sum,
6482 16 : thisDXCoil.Name);
6483 32 : SetupOutputVariable(state,
6484 : "Cooling Coil Runtime Fraction",
6485 : Constant::Units::None,
6486 16 : thisDXCoil.CoolingCoilRuntimeFraction,
6487 : OutputProcessor::TimeStepType::System,
6488 : OutputProcessor::StoreType::Average,
6489 16 : thisDXCoil.Name);
6490 : // Followings for VRF_FluidTCtrl Only
6491 32 : SetupOutputVariable(state,
6492 : "Cooling Coil VRF Evaporating Temperature",
6493 : Constant::Units::C,
6494 16 : thisDXCoil.EvaporatingTemp,
6495 : OutputProcessor::TimeStepType::System,
6496 : OutputProcessor::StoreType::Average,
6497 16 : thisDXCoil.Name);
6498 32 : SetupOutputVariable(state,
6499 : "Cooling Coil VRF Super Heating Degrees",
6500 : Constant::Units::C,
6501 16 : thisDXCoil.ActualSH,
6502 : OutputProcessor::TimeStepType::System,
6503 : OutputProcessor::StoreType::Average,
6504 16 : thisDXCoil.Name);
6505 :
6506 16 : if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
6507 0 : SetupOutputVariable(state,
6508 : "Cooling Coil Condensate Volume Flow Rate",
6509 : Constant::Units::m3_s,
6510 0 : thisDXCoil.CondensateVdot,
6511 : OutputProcessor::TimeStepType::System,
6512 : OutputProcessor::StoreType::Average,
6513 0 : thisDXCoil.Name);
6514 0 : SetupOutputVariable(state,
6515 : "Cooling Coil Condensate Volume",
6516 : Constant::Units::m3,
6517 0 : thisDXCoil.CondensateVol,
6518 : OutputProcessor::TimeStepType::System,
6519 : OutputProcessor::StoreType::Sum,
6520 0 : thisDXCoil.Name,
6521 : Constant::eResource::OnSiteWater,
6522 : OutputProcessor::Group::HVAC,
6523 : OutputProcessor::EndUseCat::Condensate);
6524 : }
6525 : }
6526 :
6527 : // VRF heating coil for FluidTCtrl, report variables
6528 16 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
6529 : // Setup Report Variables for Heating Equipment:
6530 : // CurrentModuleObject='Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl
6531 32 : SetupOutputVariable(state,
6532 : "Heating Coil Heating Rate",
6533 : Constant::Units::W,
6534 16 : thisDXCoil.TotalHeatingEnergyRate,
6535 : OutputProcessor::TimeStepType::System,
6536 : OutputProcessor::StoreType::Average,
6537 16 : thisDXCoil.Name);
6538 32 : SetupOutputVariable(state,
6539 : "Heating Coil Heating Energy",
6540 : Constant::Units::J,
6541 16 : thisDXCoil.TotalHeatingEnergy,
6542 : OutputProcessor::TimeStepType::System,
6543 : OutputProcessor::StoreType::Sum,
6544 16 : thisDXCoil.Name,
6545 : Constant::eResource::EnergyTransfer,
6546 : OutputProcessor::Group::HVAC,
6547 : OutputProcessor::EndUseCat::HeatingCoils);
6548 32 : SetupOutputVariable(state,
6549 : "Heating Coil Runtime Fraction",
6550 : Constant::Units::None,
6551 16 : thisDXCoil.HeatingCoilRuntimeFraction,
6552 : OutputProcessor::TimeStepType::System,
6553 : OutputProcessor::StoreType::Average,
6554 16 : thisDXCoil.Name);
6555 : // Followings for VRF_FluidTCtrl Only
6556 32 : SetupOutputVariable(state,
6557 : "Heating Coil VRF Condensing Temperature",
6558 : Constant::Units::C,
6559 16 : thisDXCoil.CondensingTemp,
6560 : OutputProcessor::TimeStepType::System,
6561 : OutputProcessor::StoreType::Average,
6562 16 : thisDXCoil.Name);
6563 32 : SetupOutputVariable(state,
6564 : "Heating Coil VRF Subcooling Degrees",
6565 : Constant::Units::C,
6566 16 : thisDXCoil.ActualSC,
6567 : OutputProcessor::TimeStepType::System,
6568 : OutputProcessor::StoreType::Average,
6569 16 : thisDXCoil.Name);
6570 : }
6571 : }
6572 :
6573 247 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
6574 : // setup EMS sizing actuators for single speed DX
6575 183 : for (DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDoe2DXCoils; ++DXCoilNum) {
6576 :
6577 144 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
6578 :
6579 144 : SetupEMSActuator(state,
6580 : "Coil:Cooling:DX:SingleSpeed",
6581 : thisDXCoil.Name,
6582 : "Autosized Rated Air Flow Rate",
6583 : "[m3/s]",
6584 : thisDXCoil.RatedAirVolFlowRateEMSOverrideON(1),
6585 144 : thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(1));
6586 :
6587 144 : SetupEMSActuator(state,
6588 : "Coil:Cooling:DX:SingleSpeed",
6589 : thisDXCoil.Name,
6590 : "Autosized Rated Sensible Heat Ratio",
6591 : "[W/W]",
6592 : thisDXCoil.RatedSHREMSOverrideOn(1),
6593 144 : thisDXCoil.RatedSHREMSOverrideValue(1));
6594 :
6595 144 : SetupEMSActuator(state,
6596 : "Coil:Cooling:DX:SingleSpeed",
6597 : thisDXCoil.Name,
6598 : "Autosized Rated Total Cooling Capacity",
6599 : "[W]",
6600 : thisDXCoil.RatedTotCapEMSOverrideOn(1),
6601 144 : thisDXCoil.RatedTotCapEMSOverrideValue(1));
6602 : }
6603 : }
6604 247 : Alphas.deallocate();
6605 247 : cAlphaFields.deallocate();
6606 247 : cNumericFields.deallocate();
6607 247 : Numbers.deallocate();
6608 247 : lAlphaBlanks.deallocate();
6609 247 : lNumericBlanks.deallocate();
6610 :
6611 247 : Alphas2.deallocate();
6612 247 : cAlphaFields2.deallocate();
6613 247 : cNumericFields2.deallocate();
6614 247 : Numbers2.deallocate();
6615 247 : lAlphaBlanks2.deallocate();
6616 247 : lNumericBlanks2.deallocate();
6617 : bool anyEMSRan;
6618 247 : ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyEMSRan, ObjexxFCL::Optional_int_const());
6619 247 : }
6620 :
6621 63535486 : void InitDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current DX coil unit being simulated
6622 : {
6623 :
6624 : // SUBROUTINE INFORMATION:
6625 : // AUTHOR Fred Buhl
6626 : // DATE WRITTEN May 2000
6627 : // Feb 2005, M. J. Witte, GARD Analytics, Inc. Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
6628 : // Jul 2005, R. Raustad, FSEC. Add new coil type COIL:DX:HEATPUMPWATERHEATER
6629 : // Jun 2007, L. Gu, FSEC. Add new coil type COIL:DX:MULTISPEED:COOLING and HEATING
6630 : // Aug 2015, R. Zhang, LBNL. Add new coil types for VRF_FluidTCtrl
6631 :
6632 : // PURPOSE OF THIS SUBROUTINE:
6633 : // This subroutine is for initializations of DX Coil Components.
6634 :
6635 : // METHODOLOGY EMPLOYED:
6636 : // Uses the status flags to trigger initializations.
6637 :
6638 : // SUBROUTINE PARAMETER DEFINITIONS:
6639 63535486 : constexpr Real64 SmallDifferenceTest(0.00000001);
6640 : static constexpr std::string_view RoutineName("InitDXCoil");
6641 :
6642 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6643 : Real64 RatedHeatPumpIndoorAirTemp; // Indoor dry-bulb temperature to heat pump evaporator at rated conditions [C]
6644 : Real64 RatedHeatPumpIndoorHumRat; // Inlet humidity ratio to heat pump evaporator at rated conditions [kgWater/kgDryAir]
6645 : Real64 RatedVolFlowPerRatedTotCap; // Rated Air Volume Flow Rate divided by Rated Total Capacity [m3/s-W)
6646 : Real64 HPInletAirHumRat; // Rated inlet air humidity ratio for heat pump water heater [kgWater/kgDryAir]
6647 63535486 : bool ErrorsFound(false); // TRUE when errors found
6648 : int CapacityStageNum; // Loop index for 1,Number of capacity stages
6649 : int DehumidModeNum; // Loop index for 1,Number of enhanced dehumidification modes
6650 : int Mode; // Performance mode for MultiMode DX coil; Always 1 for other coil types
6651 : int DXCoilNumTemp; // Counter for crankcase heater report variable DO loop
6652 : int AirInletNode; // Air inlet node number
6653 : int SpeedNum; // Speed number for multispeed coils
6654 :
6655 63535486 : if (state.dataDXCoils->MyOneTimeFlag) {
6656 : // initialize the environment and sizing flags
6657 243 : state.dataDXCoils->MyEnvrnFlag.dimension(state.dataDXCoils->NumDXCoils, true);
6658 243 : state.dataDXCoils->MySizeFlag.dimension(state.dataDXCoils->NumDXCoils, true);
6659 243 : state.dataDXCoils->MyOneTimeFlag = false;
6660 : }
6661 :
6662 63535486 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
6663 :
6664 : // if "ISHundredPercentDOASDXCoil" =.TRUE., then set coil as 100% DOAS dx coil
6665 63535486 : state.dataHVACGlobal->DXCT = (thisDXCoil.ISHundredPercentDOASDXCoil) ? HVAC::DXCoilType::DOAS : HVAC::DXCoilType::Regular;
6666 :
6667 190183833 : if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
6668 64167330 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
6669 631844 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum)) {
6670 :
6671 16 : SizeDXCoil(state, DXCoilNum);
6672 :
6673 16 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(1) / thisDXCoil.RatedTotCap2;
6674 32 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
6675 16 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
6676 4 : ShowWarningError(state,
6677 4 : format("{} \"{}\": Rated air volume flow rate per watt of rated total water heating capacity is out of range",
6678 2 : thisDXCoil.DXCoilType,
6679 2 : thisDXCoil.Name));
6680 4 : ShowContinueError(state,
6681 4 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
6682 : "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
6683 2 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
6684 : RatedVolFlowPerRatedTotCap,
6685 2 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
6686 : }
6687 : HPInletAirHumRat =
6688 16 : PsyWFnTdbTwbPb(state, thisDXCoil.RatedInletDBTemp, thisDXCoil.RatedInletWBTemp, DataEnvironment::StdPressureSeaLevel, RoutineName);
6689 16 : state.dataHVACGlobal->HPWHInletDBTemp = thisDXCoil.RatedInletDBTemp;
6690 16 : state.dataHVACGlobal->HPWHInletWBTemp = thisDXCoil.RatedInletWBTemp;
6691 32 : thisDXCoil.RatedAirMassFlowRate(1) =
6692 16 : thisDXCoil.RatedAirVolFlowRate(1) *
6693 16 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, thisDXCoil.RatedInletDBTemp, HPInletAirHumRat, RoutineName);
6694 : // get rated coil bypass factor excluding fan heat
6695 :
6696 : // call CalcHPWHDXCoil to determine DXCoil%RatedTotCap(1) for rated CBF calculation below
6697 16 : CalcHPWHDXCoil(state, DXCoilNum, 1.0);
6698 16 : if (state.dataDXCoils->MySizeFlag(DXCoilNum)) {
6699 16 : SizeDXCoil(state, DXCoilNum);
6700 16 : state.dataDXCoils->MySizeFlag(DXCoilNum) = false;
6701 : }
6702 :
6703 16 : thisDXCoil.RatedCBF(1) = CalcCBF(state,
6704 16 : thisDXCoil.DXCoilType,
6705 16 : thisDXCoil.Name,
6706 : thisDXCoil.RatedInletDBTemp,
6707 : HPInletAirHumRat,
6708 16 : thisDXCoil.RatedTotCap(1),
6709 16 : thisDXCoil.RatedAirVolFlowRate(1),
6710 16 : thisDXCoil.RatedSHR(1),
6711 : true);
6712 16 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum) = false;
6713 : }
6714 :
6715 77262765 : if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) &&
6716 13727279 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum)) {
6717 71 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
6718 10 : if (thisDXCoil.MSHPHeatRecActive) {
6719 0 : for (SpeedNum = 1; SpeedNum <= thisDXCoil.NumOfSpeeds; ++SpeedNum) {
6720 0 : if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
6721 0 : ShowWarningError(
6722 : state,
6723 0 : format("GetDXCoils:{}. The value of Waste Heat Function of Temperature Curve is assumed to be 1. Simulation continues. ",
6724 0 : thisDXCoil.Name));
6725 0 : break;
6726 : }
6727 : }
6728 : }
6729 : }
6730 71 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum) = false;
6731 : }
6732 :
6733 : // Find the companion upstream coil (DX cooling coil) that is used with DX heating coils (HP AC units only)
6734 63535486 : if (thisDXCoil.FindCompanionUpStreamCoil) {
6735 3924847 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6736 3923968 : thisDXCoil.CompanionUpstreamDXCoil = GetHPCoolingCoilIndex(state, thisDXCoil.DXCoilType, thisDXCoil.Name, DXCoilNum);
6737 3923968 : if (thisDXCoil.CompanionUpstreamDXCoil > 0) {
6738 74 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).ReportCoolingCoilCrankcasePower = false;
6739 74 : thisDXCoil.FindCompanionUpStreamCoil = false;
6740 : // Copy condenser node number from DX cooling coil when used with a companion DX heating coil
6741 370 : for (Mode = 1; Mode <= MaxModes; ++Mode) {
6742 296 : thisDXCoil.CondenserInletNodeNum(Mode) =
6743 296 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CondenserInletNodeNum(Mode);
6744 : }
6745 : }
6746 : } else {
6747 879 : thisDXCoil.FindCompanionUpStreamCoil = false;
6748 : }
6749 : } // IF(DXCoil(DXCoilNum)%FindCompanionUpStreamCoil)THEN
6750 :
6751 : // CR7308 - Wait for zone and air loop equipment to be simulated, then print out report variables
6752 63535486 : if (state.dataDXCoils->CrankcaseHeaterReportVarFlag) {
6753 7915 : if (state.dataAirLoop->AirLoopInputsFilled) {
6754 : // Set report variables for DX cooling coils that will have a crankcase heater (all DX coils not used in a HP AC unit)
6755 1219 : for (DXCoilNumTemp = 1; DXCoilNumTemp <= state.dataDXCoils->NumDXCoils; ++DXCoilNumTemp) {
6756 976 : if ((state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) ||
6757 1329 : (state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) ||
6758 353 : (state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling)) {
6759 672 : if (state.dataDXCoils->DXCoil(DXCoilNumTemp).ReportCoolingCoilCrankcasePower) {
6760 1196 : SetupOutputVariable(state,
6761 : "Cooling Coil Crankcase Heater Electricity Rate",
6762 : Constant::Units::W,
6763 598 : state.dataDXCoils->DXCoil(DXCoilNumTemp).CrankcaseHeaterPower,
6764 : OutputProcessor::TimeStepType::System,
6765 : OutputProcessor::StoreType::Average,
6766 598 : state.dataDXCoils->DXCoil(DXCoilNumTemp).Name);
6767 1196 : SetupOutputVariable(state,
6768 : "Cooling Coil Crankcase Heater Electricity Energy",
6769 : Constant::Units::J,
6770 598 : state.dataDXCoils->DXCoil(DXCoilNumTemp).CrankcaseHeaterConsumption,
6771 : OutputProcessor::TimeStepType::System,
6772 : OutputProcessor::StoreType::Sum,
6773 598 : state.dataDXCoils->DXCoil(DXCoilNumTemp).Name,
6774 : Constant::eResource::Electricity,
6775 : OutputProcessor::Group::HVAC,
6776 : OutputProcessor::EndUseCat::Cooling);
6777 598 : state.dataDXCoils->DXCoil(DXCoilNumTemp).ReportCoolingCoilCrankcasePower = false;
6778 : }
6779 : }
6780 : }
6781 243 : state.dataDXCoils->CrankcaseHeaterReportVarFlag = false;
6782 : } //(AirLoopInputsFilled)THEN
6783 : } //(CrankcaseHeaterReportVarFlag)THEN
6784 :
6785 63535486 : if (!state.dataGlobal->SysSizingCalc && state.dataDXCoils->MySizeFlag(DXCoilNum)) {
6786 : // for each coil, do the sizing once.
6787 960 : SizeDXCoil(state, DXCoilNum);
6788 960 : state.dataDXCoils->MySizeFlag(DXCoilNum) = false;
6789 :
6790 960 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
6791 281 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
6792 :
6793 741 : Mode = 1;
6794 : // Check for zero capacity or zero max flow rate
6795 741 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
6796 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
6797 0 : ErrorsFound = true;
6798 : }
6799 741 : if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
6800 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
6801 0 : ErrorsFound = true;
6802 : }
6803 741 : if (ErrorsFound) {
6804 0 : ShowFatalError(state, "Preceding condition causes termination.");
6805 : }
6806 :
6807 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
6808 741 : if (thisDXCoil.DXCoilType_Num !=
6809 : HVAC::CoilVRF_FluidTCtrl_Cooling) { // the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil
6810 725 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
6811 1450 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
6812 725 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
6813 0 : ShowWarningError(state,
6814 0 : format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range.",
6815 0 : thisDXCoil.DXCoilType,
6816 0 : thisDXCoil.Name));
6817 0 : ShowContinueError(state,
6818 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
6819 : "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
6820 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
6821 : RatedVolFlowPerRatedTotCap,
6822 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
6823 : }
6824 : }
6825 :
6826 1482 : thisDXCoil.RatedAirMassFlowRate(Mode) =
6827 741 : thisDXCoil.RatedAirVolFlowRate(Mode) *
6828 741 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
6829 : // get high speed rated coil bypass factor
6830 741 : thisDXCoil.RatedCBF(Mode) = CalcCBF(state,
6831 741 : thisDXCoil.DXCoilType,
6832 741 : thisDXCoil.Name,
6833 : RatedInletAirTemp,
6834 : RatedInletAirHumRat,
6835 741 : thisDXCoil.RatedTotCap(Mode),
6836 741 : thisDXCoil.RatedAirVolFlowRate(Mode),
6837 741 : thisDXCoil.RatedSHR(Mode));
6838 :
6839 : // call coil model with everthing set at rating point
6840 741 : thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(Mode);
6841 741 : thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(Mode);
6842 741 : thisDXCoil.InletAirTemp = RatedInletAirTemp;
6843 : Real64 tempInletAirHumRat =
6844 741 : Psychrometrics::PsyWFnTdbTwbPb(state, RatedInletAirTemp, RatedInletWetBulbTemp, DataEnvironment::StdPressureSeaLevel, RoutineName);
6845 : // DXCoil( DXCoilNum ).InletAirHumRat = RatedInletAirHumRat; // this seems inconsistent with dry bulb and wetbulb, filed NREL issue
6846 : // #5934 Real64 tempInletAirWetBulb = Psychrometrics::PsyTwbFnTdbWPb( RatedInletAirTemp, RatedInletAirHumRat,
6847 : // DataEnvironment::StdPressureSeaLevel );
6848 741 : thisDXCoil.InletAirHumRat = tempInletAirHumRat;
6849 741 : thisDXCoil.InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTemp, tempInletAirHumRat);
6850 :
6851 : // store environment data fill back in after rating point calc is over
6852 741 : Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
6853 741 : Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
6854 741 : Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
6855 741 : Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
6856 741 : Real64 ratedOutdoorAirWetBulb = 23.9; // from I/O ref. more precise value?
6857 741 : state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTemp;
6858 741 : state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
6859 741 : state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
6860 1482 : state.dataEnvrn->OutHumRat =
6861 741 : Psychrometrics::PsyWFnTdbTwbPb(state, RatedOutdoorAirTemp, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
6862 741 : if (thisDXCoil.CondenserInletNodeNum(1) > 0) { // set condenser inlet node values
6863 162 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = RatedOutdoorAirTemp;
6864 162 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat = state.dataEnvrn->OutHumRat;
6865 162 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb = ratedOutdoorAirWetBulb;
6866 : }
6867 :
6868 : // calculate coil model at rating point
6869 741 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6870 612 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, _, 1.0);
6871 129 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
6872 67 : CalcMultiSpeedDXCoil(state, DXCoilNum, 1.0, 1.0);
6873 62 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
6874 46 : CalcVRFCoolingCoil(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, 1.0, _, _, _);
6875 16 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
6876 16 : CalcVRFCoolingCoil_FluidTCtrl(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, 1.0, _, _);
6877 : }
6878 :
6879 : // coil outlets
6880 741 : Real64 RatedOutletWetBulb(0.0);
6881 741 : RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
6882 : state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
6883 :
6884 741 : state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
6885 : state,
6886 741 : thisDXCoil.Name,
6887 741 : thisDXCoil.DXCoilType,
6888 : thisDXCoil.TotalCoolingEnergyRate, // this is the report variable
6889 : thisDXCoil.SensCoolingEnergyRate, // this is the report variable
6890 : thisDXCoil.InletAirMassFlowRate,
6891 : thisDXCoil.InletAirTemp,
6892 : thisDXCoil.InletAirHumRat,
6893 : RatedInletWetBulbTemp,
6894 : thisDXCoil.OutletAirTemp,
6895 : thisDXCoil.OutletAirHumRat,
6896 : RatedOutletWetBulb,
6897 : RatedOutdoorAirTemp,
6898 : ratedOutdoorAirWetBulb,
6899 741 : thisDXCoil.RatedCBF(Mode),
6900 : -999.0); // coil effectiveness not define for DX
6901 :
6902 : // now replace the outdoor air conditions set above for one time rating point calc
6903 741 : state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
6904 741 : state.dataEnvrn->OutHumRat = holdOutHumRat;
6905 741 : state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
6906 741 : state.dataEnvrn->OutBaroPress = holdOutBaroPress;
6907 : }
6908 :
6909 960 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
6910 29 : for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
6911 53 : for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
6912 35 : Mode = DehumidModeNum * 2 + CapacityStageNum;
6913 : // Check for zero capacity or zero max flow rate
6914 35 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
6915 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
6916 0 : ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
6917 0 : ErrorsFound = true;
6918 : }
6919 35 : if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
6920 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
6921 0 : ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
6922 0 : ErrorsFound = true;
6923 : }
6924 35 : if (ErrorsFound) {
6925 0 : ShowFatalError(state, "Preceding condition causes termination.");
6926 : }
6927 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
6928 35 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
6929 70 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
6930 35 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
6931 0 : ShowWarningError(
6932 : state,
6933 0 : format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range.",
6934 0 : thisDXCoil.DXCoilType,
6935 0 : thisDXCoil.Name));
6936 0 : ShowContinueError(state,
6937 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
6938 : "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
6939 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
6940 : RatedVolFlowPerRatedTotCap,
6941 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
6942 0 : ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
6943 : }
6944 70 : thisDXCoil.RatedAirMassFlowRate(Mode) =
6945 35 : thisDXCoil.RatedAirVolFlowRate(Mode) *
6946 35 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
6947 : // get rated coil bypass factor
6948 35 : thisDXCoil.RatedCBF(Mode) = CalcCBF(state,
6949 35 : thisDXCoil.CoilPerformanceType(Mode),
6950 35 : thisDXCoil.CoilPerformanceName(Mode),
6951 : RatedInletAirTemp,
6952 : RatedInletAirHumRat,
6953 35 : thisDXCoil.RatedTotCap(Mode),
6954 35 : thisDXCoil.RatedAirVolFlowRate(Mode),
6955 35 : thisDXCoil.RatedSHR(Mode));
6956 : } // End capacity stages loop
6957 : } // End dehumidification modes loop
6958 : }
6959 :
6960 960 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating ||
6961 839 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
6962 :
6963 137 : Mode = 1;
6964 137 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
6965 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
6966 0 : ErrorsFound = true;
6967 : }
6968 137 : if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
6969 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
6970 0 : ErrorsFound = true;
6971 : }
6972 137 : if (ErrorsFound) {
6973 0 : ShowFatalError(state, "Preceding condition causes termination.");
6974 : }
6975 137 : RatedHeatPumpIndoorAirTemp = 21.11; // 21.11C or 70F
6976 137 : RatedHeatPumpIndoorHumRat = 0.00881; // Humidity ratio corresponding to 70F dry bulb/60F wet bulb
6977 274 : thisDXCoil.RatedAirMassFlowRate(Mode) =
6978 137 : thisDXCoil.RatedAirVolFlowRate(Mode) *
6979 137 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedHeatPumpIndoorAirTemp, RatedHeatPumpIndoorHumRat, RoutineName);
6980 :
6981 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
6982 137 : if (thisDXCoil.DXCoilType_Num !=
6983 : HVAC::CoilVRF_FluidTCtrl_Heating) { // the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil
6984 121 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
6985 242 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
6986 121 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
6987 0 : ShowWarningError(state,
6988 0 : format("Sizing: {} {}: Rated air volume flow rate per watt of rated total heating capacity is out of range.",
6989 0 : thisDXCoil.DXCoilType,
6990 0 : thisDXCoil.Name));
6991 0 : ShowContinueError(state,
6992 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
6993 : "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
6994 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
6995 : RatedVolFlowPerRatedTotCap,
6996 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
6997 : }
6998 : }
6999 :
7000 : // call coil model with everthing set at rating point
7001 137 : thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(Mode);
7002 137 : thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(Mode);
7003 :
7004 137 : thisDXCoil.InletAirTemp = RatedInletAirTempHeat;
7005 137 : Real64 tempInletAirHumRat = Psychrometrics::PsyWFnTdbTwbPb(
7006 : state, RatedInletAirTempHeat, RatedInletWetBulbTempHeat, DataEnvironment::StdPressureSeaLevel, RoutineName);
7007 137 : thisDXCoil.InletAirHumRat = tempInletAirHumRat;
7008 137 : thisDXCoil.InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTempHeat, tempInletAirHumRat);
7009 :
7010 : // store environment data fill back in after rating point calc is over
7011 137 : Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
7012 137 : Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
7013 137 : Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
7014 137 : Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
7015 :
7016 137 : state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTempHeat;
7017 :
7018 137 : Real64 ratedOutdoorAirWetBulb = 6.11; // from I/O ref. more precise value?
7019 137 : state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
7020 137 : state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
7021 137 : state.dataEnvrn->OutHumRat = Psychrometrics::PsyWFnTdbTwbPb(
7022 : state, RatedOutdoorAirTempHeat, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
7023 :
7024 137 : if (thisDXCoil.CondenserInletNodeNum(1) > 0) { // set condenser inlet node values
7025 61 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = RatedOutdoorAirTempHeat;
7026 61 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat = state.dataEnvrn->OutHumRat;
7027 61 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb = ratedOutdoorAirWetBulb;
7028 : }
7029 :
7030 : // calculate coil model at rating point
7031 137 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
7032 75 : CalcDXHeatingCoil(state, DXCoilNum, 1.0, HVAC::FanOp::Cycling, 1.0);
7033 62 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
7034 46 : CalcDXHeatingCoil(state, DXCoilNum, 1.0, HVAC::FanOp::Cycling, _, _);
7035 16 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7036 16 : CalcVRFHeatingCoil_FluidTCtrl(state, HVAC::CompressorOp::On, DXCoilNum, 1.0, HVAC::FanOp::Cycling, _, _);
7037 : }
7038 : // coil outlets
7039 137 : Real64 RatedOutletWetBulb(0.0);
7040 137 : RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
7041 : state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
7042 :
7043 137 : state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
7044 : state,
7045 137 : thisDXCoil.Name,
7046 137 : thisDXCoil.DXCoilType,
7047 : thisDXCoil.TotalHeatingEnergyRate, // this is the report variable
7048 : thisDXCoil.TotalHeatingEnergyRate, // this is the report variable
7049 : thisDXCoil.InletAirMassFlowRate,
7050 : thisDXCoil.InletAirTemp,
7051 : thisDXCoil.InletAirHumRat,
7052 : RatedInletWetBulbTempHeat,
7053 : thisDXCoil.OutletAirTemp,
7054 : thisDXCoil.OutletAirHumRat,
7055 : RatedOutletWetBulb,
7056 : RatedOutdoorAirTempHeat,
7057 : ratedOutdoorAirWetBulb,
7058 137 : thisDXCoil.RatedCBF(Mode),
7059 : -999.0); // coil effectiveness not define for DX
7060 :
7061 : // now replace the outdoor air conditions set above for one time rating point calc
7062 137 : state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
7063 137 : state.dataEnvrn->OutHumRat = holdOutHumRat;
7064 137 : state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
7065 137 : state.dataEnvrn->OutBaroPress = holdOutBaroPress;
7066 : }
7067 :
7068 960 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7069 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7070 67 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate2 / thisDXCoil.RatedTotCap2;
7071 134 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7072 67 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7073 10 : ShowWarningError(state,
7074 10 : format("Coil:Cooling:DX:TwoSpeed \"{}\": At low speed rated air volume flow rate per watt of rated total cooling "
7075 : "capacity is out of range.",
7076 5 : thisDXCoil.Name));
7077 10 : ShowContinueError(state,
7078 10 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
7079 : "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
7080 5 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7081 : RatedVolFlowPerRatedTotCap,
7082 5 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7083 : }
7084 :
7085 67 : thisDXCoil.RatedAirMassFlowRate2 =
7086 134 : thisDXCoil.RatedAirVolFlowRate2 *
7087 67 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
7088 : // get low speed rated coil bypass factor
7089 134 : thisDXCoil.RatedCBF2 = CalcCBF(state,
7090 67 : thisDXCoil.DXCoilType,
7091 67 : thisDXCoil.Name,
7092 : RatedInletAirTemp,
7093 : RatedInletAirHumRat,
7094 : thisDXCoil.RatedTotCap2,
7095 : thisDXCoil.RatedAirVolFlowRate2,
7096 : thisDXCoil.RatedSHR2);
7097 :
7098 : // call for standard ratings for two-speeed DX coil
7099 67 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air) {
7100 66 : CalcTwoSpeedDXCoilStandardRating(state, DXCoilNum);
7101 : }
7102 : }
7103 :
7104 : // Multispeed Cooling
7105 960 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7106 162 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
7107 : // Check for zero capacity or zero max flow rate
7108 113 : if (thisDXCoil.MSRatedTotCap(Mode) <= 0.0) {
7109 0 : ShowSevereError(state,
7110 0 : format("Sizing: {} {} has zero rated total capacity at speed {}", thisDXCoil.DXCoilType, thisDXCoil.Name, Mode));
7111 0 : ErrorsFound = true;
7112 : }
7113 113 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) <= 0.0) {
7114 0 : ShowSevereError(state,
7115 0 : format("Sizing: {} {} has zero rated air flow rate at speed {}", thisDXCoil.DXCoilType, thisDXCoil.Name, Mode));
7116 0 : ErrorsFound = true;
7117 : }
7118 113 : if (ErrorsFound) {
7119 0 : ShowFatalError(state, "Preceding condition causes termination.");
7120 : }
7121 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7122 113 : RatedVolFlowPerRatedTotCap = thisDXCoil.MSRatedAirVolFlowRate(Mode) / thisDXCoil.MSRatedTotCap(Mode);
7123 226 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7124 113 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7125 58 : ShowWarningError(
7126 : state,
7127 58 : format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range at speed {}",
7128 29 : thisDXCoil.DXCoilType,
7129 29 : thisDXCoil.Name,
7130 : Mode));
7131 58 : ShowContinueError(state,
7132 58 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
7133 : "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
7134 29 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7135 : RatedVolFlowPerRatedTotCap,
7136 29 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7137 : }
7138 226 : thisDXCoil.MSRatedAirMassFlowRate(Mode) =
7139 113 : thisDXCoil.MSRatedAirVolFlowRate(Mode) *
7140 113 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
7141 : // get high speed rated coil bypass factor
7142 113 : thisDXCoil.MSRatedCBF(Mode) = CalcCBF(state,
7143 113 : thisDXCoil.DXCoilType,
7144 113 : thisDXCoil.Name,
7145 : RatedInletAirTemp,
7146 : RatedInletAirHumRat,
7147 113 : thisDXCoil.MSRatedTotCap(Mode),
7148 113 : thisDXCoil.MSRatedAirVolFlowRate(Mode),
7149 113 : thisDXCoil.MSRatedSHR(Mode));
7150 : }
7151 : }
7152 :
7153 : // Multispeed Heating
7154 960 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7155 22 : RatedHeatPumpIndoorAirTemp = 21.11; // 21.11C or 70F
7156 22 : RatedHeatPumpIndoorHumRat = 0.00881; // Humidity ratio corresponding to 70F dry bulb/60F wet bulb
7157 92 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
7158 :
7159 140 : thisDXCoil.MSRatedAirMassFlowRate(Mode) =
7160 70 : thisDXCoil.MSRatedAirVolFlowRate(Mode) *
7161 70 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedHeatPumpIndoorAirTemp, RatedHeatPumpIndoorHumRat, RoutineName);
7162 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7163 70 : RatedVolFlowPerRatedTotCap = thisDXCoil.MSRatedAirVolFlowRate(Mode) / thisDXCoil.MSRatedTotCap(Mode);
7164 140 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7165 70 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7166 12 : ShowWarningError(state,
7167 12 : format("Coil:Heating:DX:MultiSpeed {}: Rated air volume flow rate per watt of rated total heating capacity "
7168 : "is out of range at speed {}",
7169 6 : thisDXCoil.Name,
7170 : Mode));
7171 12 : ShowContinueError(state,
7172 12 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
7173 : "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
7174 6 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7175 : RatedVolFlowPerRatedTotCap,
7176 6 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7177 : }
7178 : }
7179 : }
7180 :
7181 : // store fan info for coil
7182 960 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
7183 960 : state, thisDXCoil.Name, thisDXCoil.DXCoilType, thisDXCoil.SupplyFanName, thisDXCoil.supplyFanType, thisDXCoil.SupplyFanIndex);
7184 : }
7185 :
7186 63535486 : AirInletNode = thisDXCoil.AirInNode;
7187 :
7188 : // Each iteration, load the coil data structure with the inlet conditions
7189 :
7190 63535486 : thisDXCoil.InletAirMassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
7191 63535486 : thisDXCoil.InletAirMassFlowRateMax =
7192 63535486 : max(state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax, state.dataLoopNodes->Node(AirInletNode).MassFlowRate);
7193 63535486 : thisDXCoil.InletAirTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
7194 63535486 : thisDXCoil.InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
7195 63535486 : thisDXCoil.InletAirEnthalpy = state.dataLoopNodes->Node(AirInletNode).Enthalpy;
7196 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
7197 : // DXCoil(DXCoilNum)%InletAirPressure = Node(AirInletNode)%Press
7198 :
7199 63535486 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7200 12746066 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
7201 81924 : thisDXCoil.EvapInletWetBulb = PsyTwbFnTdbWPb(state,
7202 81924 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr).ZT,
7203 81924 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr).airHumRat,
7204 81924 : state.dataEnvrn->OutBaroPress,
7205 : RoutineName);
7206 : }
7207 : }
7208 :
7209 63535486 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
7210 631844 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
7211 631844 : thisDXCoil.ElecWaterHeatingPower = 0.0;
7212 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
7213 : // DXCoil(DXCoilNum)%InletAirPressure = StdBaroPress
7214 :
7215 : // HPWH's that use an inlet air temperature schedule also need to have a valid barometric pressure
7216 : // The DX Coil used in HPWH's does not know if it is using a scheduled inlet temperature so check the node pressure
7217 631844 : if (thisDXCoil.CondenserInletNodeNum(1) > 0) {
7218 631844 : if (state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press == 0.0) {
7219 0 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press = state.dataEnvrn->StdBaroPress;
7220 : }
7221 : }
7222 : }
7223 63535486 : thisDXCoil.BasinHeaterPower = 0.0;
7224 :
7225 63535486 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
7226 163849 : thisDXCoil.CompressorPartLoadRatio = 0.0;
7227 163849 : thisDXCoil.SecCoilSensibleHeatGainRate = 0.0;
7228 163849 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
7229 163849 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
7230 163849 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
7231 : }
7232 63535486 : }
7233 :
7234 992 : void SizeDXCoil(EnergyPlusData &state, int const DXCoilNum)
7235 : {
7236 :
7237 : // SUBROUTINE INFORMATION:
7238 : // AUTHOR Fred Buhl
7239 : // DATE WRITTEN January 2002
7240 : // Feb 2005, M. J. Witte, GARD Analytics, Inc. Add new coil type COIL:DX:MultiMode:CoolingEmpirical.
7241 : // Jul 2005, R. Raustad, FSEC. Add new coil type COIL:DX:HEATPUMPWATERHEATER
7242 : // Jun 2007, L. Gu, FSEC. Add new coil type COIL:DX:MULTISPEED:COOLING and HEATING
7243 : // Jan 2011, B. Griffithn, NREL. add EMS overrides for autosized fields
7244 : // Aug 2013, D. Kang. add component sizing table entries
7245 : // May 2014, R. Raustad, FSEC. moved sizing calculations to common routine
7246 : // Aug 2015, R. Zhang, LBNL. Add new coil types for VRF_FluidTCtrl
7247 : // RE-ENGINEERED na
7248 :
7249 : // PURPOSE OF THIS SUBROUTINE:
7250 : // This subroutine is for sizing DX Coil components for which nominal capacity and air flow rate
7251 : // have not been specified in the input.
7252 :
7253 : // METHODOLOGY EMPLOYED:
7254 : // Obtains cooling capacities and air flow rates from the zone or system sizing arrays.
7255 :
7256 : // Using/Aliasing
7257 : using namespace DataSizing;
7258 : using Curve::CurveValue;
7259 :
7260 : using namespace OutputReportPredefined;
7261 : using StandardRatings::CalcDXCoilStandardRating;
7262 :
7263 : // SUBROUTINE PARAMETER DEFINITIONS:
7264 : static constexpr std::string_view RoutineName("SizeDXCoil");
7265 :
7266 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7267 : Real64 CoilInTemp; // DX coil inlet temperature
7268 : int CapacityStageNum; // Loop index for 1,Number of capacity stages
7269 : int DehumidModeNum; // Loop index for 1,Number of enhanced dehumidification modes
7270 : int Mode; // Operating mode for MultiMode DX coil; Always 1 for other coil types
7271 : int NumOfSpeedCompanion; // Number of speed for a companion cooling coil (Multispeed HO heating coil only
7272 992 : std::string equipName;
7273 : Real64 RatedAirVolFlowRateDes; // Design rated air volume flow for reporting
7274 : Real64 RatedAirVolFlowRateUser; // Hard-sized rated air volume flow for reporting
7275 : Real64 RatedAirVolFlowRate2Des; // Design rated low speed air volume flow for reporting
7276 : Real64 RatedAirVolFlowRate2User; // Hard-sized rated low speed air volume flow for reporting
7277 : Real64 RatedTotCapDes; // Design rated total capacity for reproting
7278 : Real64 RatedTotCapUser; // Hard-sized rated total capacity for reproting
7279 : Real64 RatedTotCap2Des; // Design rated low speed total capacity for reproting
7280 : Real64 RatedTotCap2User; // Hard-sized rated low speed total capacity for reproting
7281 : Real64 RatedSHRDes; // Design ratd SHR for reporting
7282 : Real64 RatedSHRUser; // Hard-sized ratd SHR for reporting
7283 : Real64 RatedSHR2Des; // Design ratd low speed SHR for reporting
7284 : Real64 RatedSHR2User; // Hard-sized ratd low speed SHR for reporting
7285 : Real64 EvapCondAirFlowDes; // Design evaporative condenser air flow for reporting
7286 : Real64 EvapCondAirFlowUser; // Hard-sized evaporative condenser air flow for reporting
7287 : Real64 EvapCondAirFlow2Des; // Design low speed evaporative condenser air flow for reporting
7288 : Real64 EvapCondAirFlow2User; // Hard-sized low speed evaporative condenser air flow for reporting
7289 : Real64 EvapCondPumpElecNomPowerDes; // Design evaporative condenser pump rated power consumption for reporting
7290 : Real64 EvapCondPumpElecNomPowerUser; // Hard-sized evaporative condenser pump rated power consumption for reporting
7291 : Real64 EvapCondPumpElecNomPower2Des; // Design low speed condenser pump rated power consumption for reporting
7292 : Real64 EvapCondPumpElecNomPower2User; // Hard-sized low speed condenser pump rated power consumption for reporting
7293 : Real64 DefrostCapacityDes; // Design defrost heater capacity for reporting
7294 : Real64 DefrostCapacityUser; // Hard-sized defrost heater capacity for reporting
7295 : Real64 MSRatedAirVolFlowRateDes; // Design multispeed rated air volume flow rate for reporting
7296 : Real64 MSRatedAirVolFlowRateUser; // Hard-sized multispeed rated air volume flow rate for reporting
7297 : Real64 MSRatedTotCapDesAtMaxSpeed; // Design multispeed rated total capacity for reporting (at maximum speed)
7298 : Real64 MSRatedTotCapUser; // Hard-sized multispeed rated total capacity for reporting
7299 : Real64 MSRatedSHRDes; // Design multispeed rated SHR for reporting
7300 : Real64 MSRatedSHRUser; // Hard-sized multispeed rated SHR for reporting
7301 : Real64 MSEvapCondAirFlowDes; // Design evaporative condenser air flow for reporting
7302 : Real64 MSEvapCondAirFlowUser; // Hard-sized evaporative condenser air flow for reporting
7303 : Real64 MSEvapCondAirFlow2Des; // Design low speed evaporative condenser air flow for reporting
7304 : Real64 MSEvapCondAirFlow2User; // Hard-sized low speed evaporative condenser air flow for reporting
7305 : Real64 MSEvapCondPumpElecNomPowerDes; // Design evaporative condenser pump rated power consumption for reporting
7306 : Real64 MSEvapCondPumpElecNomPowerUser; // Hard-sized evaporative condenser pump rated power consumption for reporting
7307 : Real64 MSEvapCondPumpElecNomPower2Des; // Design low speed condenser pump rated power consumption for reporting
7308 : Real64 MSEvapCondPumpElecNomPower2User; // Hard-sized low speed condenser pump rated power consumption for reporting
7309 : Real64 MSDefrostCapacityDes; // Design defrost heater capacity for reporting
7310 : Real64 MSDefrostCapacityUser; // Hard-sized defrost heater capacity for reporting
7311 : bool HardSizeNoDesRun; // Indicator to a hard-sized field with no design sizing data
7312 : bool IsAutoSize; // Indicator to autosize for reporting
7313 : bool IsCoolCoilCapAutoSize; // Indicator to cooling capacity autosize for reporting
7314 : bool SizingDesRunThisAirSys; // true if a particular air system had a Sizing:System object and system sizing done
7315 : bool SizingDesRunThisZone; // true if a particular zone had a Sizing:Zone object and zone sizing was done
7316 992 : std::string CompName; // component name
7317 992 : std::string CompType; // component type
7318 992 : std::string SizingString; // input field sizing description (e.g., Nominal Capacity)
7319 992 : bool bPRINT = true; // TRUE if sizing is reported to output (eio)
7320 : Real64 TempSize; // autosized value of coil input field
7321 992 : int FieldNum = 2; // IDD numeric field number where input field description is found
7322 : int SizingMethod; // Integer representation of sizing method (e.g., CoolingAirflowSizing, HeatingCapacitySizing, etc.)
7323 : bool PrintFlag; // TRUE when sizing information is reported in the eio file
7324 : bool SizeSecDXCoil; // if true do sizing calculation for secondary coil
7325 : Real64 SecCoilAirFlowDes; // Design secondary DX coil air flow for reporting
7326 : Real64 SecCoilAirFlowUser; // Hard-sized secondary DX coil air flow for reporting
7327 :
7328 : // Initiate all reporting variables
7329 992 : if (state.dataSize->SysSizingRunDone || state.dataSize->ZoneSizingRunDone) {
7330 858 : HardSizeNoDesRun = false;
7331 : } else {
7332 134 : HardSizeNoDesRun = true;
7333 : }
7334 :
7335 992 : if (state.dataSize->CurSysNum > 0) {
7336 617 : CheckThisAirSystemForSizing(state, state.dataSize->CurSysNum, SizingDesRunThisAirSys);
7337 : } else {
7338 375 : SizingDesRunThisAirSys = false;
7339 : }
7340 992 : if (state.dataSize->CurZoneEqNum > 0) {
7341 351 : CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
7342 : } else {
7343 641 : SizingDesRunThisZone = false;
7344 : }
7345 :
7346 992 : IsAutoSize = false;
7347 992 : IsCoolCoilCapAutoSize = false;
7348 992 : SizeSecDXCoil = false;
7349 992 : RatedAirVolFlowRateDes = 0.0;
7350 992 : RatedAirVolFlowRateUser = 0.0;
7351 992 : RatedAirVolFlowRate2Des = 0.0;
7352 992 : RatedAirVolFlowRate2User = 0.0;
7353 992 : RatedTotCapDes = 0.0;
7354 992 : RatedTotCapUser = 0.0;
7355 992 : RatedTotCap2Des = 0.0;
7356 992 : RatedTotCap2User = 0.0;
7357 992 : MSRatedTotCapDesAtMaxSpeed = 0.0;
7358 992 : RatedSHRDes = 0.0;
7359 992 : RatedSHRUser = 0.0;
7360 992 : RatedSHR2Des = 0.0;
7361 992 : RatedSHR2User = 0.0;
7362 992 : EvapCondAirFlowDes = 0.0;
7363 992 : EvapCondAirFlowUser = 0.0;
7364 992 : EvapCondAirFlow2Des = 0.0;
7365 992 : EvapCondAirFlow2User = 0.0;
7366 992 : EvapCondPumpElecNomPowerDes = 0.0;
7367 992 : EvapCondPumpElecNomPowerUser = 0.0;
7368 992 : EvapCondPumpElecNomPower2Des = 0.0;
7369 992 : EvapCondPumpElecNomPower2User = 0.0;
7370 992 : DefrostCapacityDes = 0.0;
7371 992 : DefrostCapacityUser = 0.0;
7372 992 : MSRatedAirVolFlowRateDes = 0.0;
7373 992 : MSRatedAirVolFlowRateUser = 0.0;
7374 : // MSRatedTotCapDes = 0.0;
7375 992 : MSRatedTotCapUser = 0.0;
7376 992 : MSRatedSHRDes = 0.0;
7377 992 : MSRatedSHRUser = 0.0;
7378 992 : MSEvapCondAirFlowDes = 0.0;
7379 992 : MSEvapCondAirFlowUser = 0.0;
7380 992 : MSEvapCondAirFlow2Des = 0.0;
7381 992 : MSEvapCondAirFlow2User = 0.0;
7382 992 : MSEvapCondPumpElecNomPowerDes = 0.0;
7383 992 : MSEvapCondPumpElecNomPowerUser = 0.0;
7384 992 : MSEvapCondPumpElecNomPower2Des = 0.0;
7385 992 : MSEvapCondPumpElecNomPower2User = 0.0;
7386 992 : MSDefrostCapacityDes = 0.0;
7387 992 : MSDefrostCapacityUser = 0.0;
7388 992 : SecCoilAirFlowDes = 0.0;
7389 992 : SecCoilAirFlowUser = 0.0;
7390 :
7391 : // Sizer classes
7392 992 : CoolingSHRSizer sizerCoolingSHR;
7393 992 : bool ErrorsFound = false;
7394 :
7395 992 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
7396 :
7397 : // NOTE: we are sizing COIL:DX:HeatingEmpirical on the COOLING load. Thus the cooling and
7398 : // and heating capacities of a DX heat pump system will be identical. In real life the AHRI
7399 : // heating and cooling capacities are close but not identical.
7400 1991 : for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
7401 2015 : for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
7402 1016 : Mode = DehumidModeNum * 2 + CapacityStageNum;
7403 1016 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
7404 990 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
7405 32 : if (thisDXCoil.RatedAirVolFlowRate(1) == Constant::AutoCalculate) {
7406 : // report autocalculated sizing
7407 6 : PrintFlag = true;
7408 6 : CompName = thisDXCoil.Name;
7409 6 : CompType = thisDXCoil.DXCoilType;
7410 : // DXCoil( DXCoilNum ).RatedAirVolFlowRate( 1 ) = DXCoil( DXCoilNum ).RatedTotCap2 * 0.00005035
7411 6 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap2;
7412 6 : state.dataSize->DataFractionUsedForSizing = 0.00005035;
7413 6 : TempSize = AutoSize;
7414 6 : AutoCalculateSizer sizerHPRatedAirVolFlow;
7415 6 : std::string stringOverride = "Rated Evaporator Air Flow Rate [m3/s]";
7416 6 : if (state.dataGlobal->isEpJSON) stringOverride = "rated_evaporator_air_flow_rate [m3/s]";
7417 6 : sizerHPRatedAirVolFlow.overrideSizingString(stringOverride);
7418 6 : sizerHPRatedAirVolFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7419 6 : thisDXCoil.RatedAirVolFlowRate(1) = sizerHPRatedAirVolFlow.size(state, TempSize, ErrorsFound);
7420 6 : PrintFlag = false;
7421 6 : }
7422 :
7423 32 : if (thisDXCoil.RatedHPWHCondWaterFlow == Constant::AutoCalculate) {
7424 : // report autocalculated sizing
7425 6 : PrintFlag = true;
7426 6 : CompName = thisDXCoil.Name;
7427 6 : CompType = thisDXCoil.DXCoilType;
7428 : // DXCoil( DXCoilNum ).RatedAirVolFlowRate( 1 ) = DXCoil( DXCoilNum ).RatedTotCap2 * 0.00000004487
7429 6 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap2;
7430 6 : state.dataSize->DataFractionUsedForSizing = 0.00000004487;
7431 6 : TempSize = AutoSize;
7432 6 : AutoCalculateSizer sizerHPWHCondWaterFlow;
7433 6 : std::string stringOverride = "Rated Condenser Water Flow Rate [m3/s]";
7434 6 : if (state.dataGlobal->isEpJSON) stringOverride = "rated_condenser_water_flow_rate [m3/s]";
7435 6 : sizerHPWHCondWaterFlow.overrideSizingString(stringOverride);
7436 6 : sizerHPWHCondWaterFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7437 6 : thisDXCoil.RatedHPWHCondWaterFlow = sizerHPWHCondWaterFlow.size(state, TempSize, ErrorsFound);
7438 6 : PrintFlag = false;
7439 6 : }
7440 32 : } else {
7441 984 : PrintFlag = true;
7442 984 : FieldNum = 0;
7443 984 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7444 35 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7445 35 : FieldNum = 4;
7446 35 : state.dataSize->DataBypassFrac = thisDXCoil.BypassedFlowFrac(Mode);
7447 949 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
7448 75 : CompName = thisDXCoil.Name;
7449 75 : FieldNum = 3;
7450 : // doesn't look like this is needed for air flow sizing, only for heating capacity sizing
7451 150 : state.dataSize->DataCoolCoilCap =
7452 75 : state.dataSize->DXCoolCap; // pass global variable used only for heat pumps (i.e., DX cooling and heating coils)
7453 76 : if ((thisDXCoil.IsSecondaryDXCoilInZone) &&
7454 1 : (thisDXCoil.CondenserType(1) ==
7455 : DataHeatBalance::RefrigCondenserType::Air)) { // seconday DX coil in secondary zone is specified
7456 1 : SizeSecDXCoil = true;
7457 : }
7458 874 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
7459 46 : CompName = thisDXCoil.Name;
7460 46 : FieldNum = 2;
7461 828 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
7462 46 : CompName = thisDXCoil.Name;
7463 46 : FieldNum = 3;
7464 782 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7465 16 : CompName = thisDXCoil.Name;
7466 766 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7467 16 : CompName = thisDXCoil.Name;
7468 750 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7469 49 : thisDXCoil.RatedAirVolFlowRate(Mode) = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
7470 49 : CompName = thisDXCoil.Name;
7471 49 : PrintFlag = false;
7472 701 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7473 22 : thisDXCoil.RatedAirVolFlowRate(Mode) = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
7474 22 : CompName = thisDXCoil.Name;
7475 22 : PrintFlag = false;
7476 : } else {
7477 679 : CompName = thisDXCoil.Name;
7478 679 : FieldNum = 4;
7479 : }
7480 :
7481 984 : TempSize = thisDXCoil.RatedAirVolFlowRate(Mode);
7482 984 : if (FieldNum > 0) {
7483 881 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [m3/s]";
7484 : } else {
7485 103 : SizingString = "Rated Air Flow Rate [m3/s]";
7486 : }
7487 984 : CompType = thisDXCoil.DXCoilType;
7488 984 : state.dataSize->DataIsDXCoil = true;
7489 984 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
7490 984 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
7491 984 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating ||
7492 946 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
7493 159 : bool errorsFound = false;
7494 159 : HeatingAirFlowSizer sizingHeatingAirFlow;
7495 159 : sizingHeatingAirFlow.overrideSizingString(SizingString);
7496 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7497 159 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7498 159 : thisDXCoil.RatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
7499 159 : } else {
7500 825 : bool errorsFound = false;
7501 825 : CoolingAirFlowSizer sizingCoolingAirFlow;
7502 825 : sizingCoolingAirFlow.overrideSizingString(SizingString);
7503 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7504 825 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7505 825 : thisDXCoil.RatedAirVolFlowRate(Mode) = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7506 825 : }
7507 984 : state.dataSize->DataIsDXCoil = false;
7508 984 : state.dataSize->DataEMSOverrideON = false;
7509 984 : state.dataSize->DataEMSOverride = 0.0;
7510 984 : state.dataSize->DataBypassFrac = 0.0;
7511 : }
7512 :
7513 1016 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
7514 : // get autosized air flow for capacity calc's if capacity is not autosized
7515 : // *** RAR this if block is a last minute addition to correct capacity reporting when not autosized and a sizing run is done. Test
7516 : // suite was not run with this code included. *** The question here is if the autosized air flow rate or the user specified air flow
7517 : // rate should be used to calculate capacity removing this for now until more is known
7518 : // if ( DXCoil( DXCoilNum ).RatedTotCap( Mode ) != AutoSize && ( ( SysSizingRunDone && CurSysNum > 0 ) ||
7519 : //( ZoneSizingRunDone && CurZoneEqNum > 0 ) ) ) { if ( DXCoil( DXCoilNum ).DXCoilType_Num ==
7520 : // HVAC::CoilDX_CoolingTwoStageWHumControl ) { SizingMethod = CoolingAirflowSizing;
7521 : // DataBypassFrac = DXCoil ( DXCoilNum ).BypassedFlowFrac ( Mode );
7522 : // } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical ) {
7523 : // SizingMethod = HeatingAirflowSizing;
7524 : //// DataCoolCoilCap = DXCoolCap; // pass global variable used only for heat pumps (i.e.,
7525 : /// DX cooling and heating coils)
7526 : // } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilVRF_Heating ) {
7527 : // SizingMethod = HeatingAirflowSizing;
7528 : // } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilVRF_Cooling ) {
7529 : // SizingMethod = CoolingAirflowSizing;
7530 : // } else {
7531 : // SizingMethod = CoolingAirflowSizing;
7532 : // }
7533 : // CompName = DXCoil( DXCoilNum ).Name;
7534 : // TempSize = AutoSize;
7535 : // SizingString.clear(); // don't care
7536 : // CompType = DXCoil( DXCoilNum ).DXCoilType;
7537 : // DataIsDXCoil = true;
7538 : // DataEMSOverrideON = DXCoil ( DXCoilNum ).RatedAirVolFlowRateEMSOverrideON ( Mode );
7539 : // DataEMSOverride = DXCoil( DXCoilNum ).RatedAirVolFlowRateEMSOverrideValue( Mode );
7540 : // CoolingAirFlowSizer sizingCoolingAirFlow;
7541 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7542 : // sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
7543 : // DataAirFlowUsedForSizing = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7544 : // DataIsDXCoil = false; // don't need this and next 2, they are just overwritten below. Delete
7545 : // on next pass so testing will show problems if any. DataEMSOverrideON = false;
7546 : // DataEMSOverride = 0.0;
7547 : // DataBypassFrac = 0.0;
7548 : // }
7549 1016 : PrintFlag = true;
7550 1016 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.CCapFTemp(Mode);
7551 1016 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7552 35 : SizingMethod = HVAC::CoolingCapacitySizing;
7553 35 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7554 35 : FieldNum = 1;
7555 35 : TempSize = thisDXCoil.RatedTotCap(Mode);
7556 35 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7557 981 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating ||
7558 860 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7559 137 : SizingMethod = HVAC::HeatingCapacitySizing;
7560 137 : CompName = thisDXCoil.Name;
7561 137 : FieldNum = 1;
7562 137 : TempSize = thisDXCoil.RatedTotCap(Mode);
7563 137 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7564 137 : state.dataSize->DataCoolCoilCap = state.dataSize->DXCoolCap;
7565 844 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
7566 818 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
7567 32 : SizingMethod = HVAC::CoolingCapacitySizing;
7568 32 : CompName = thisDXCoil.Name;
7569 32 : FieldNum = 1;
7570 32 : TempSize = thisDXCoil.RatedTotCap(Mode);
7571 32 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7572 32 : PrintFlag = false;
7573 32 : state.dataLoopNodes->Node(thisDXCoil.WaterInNode).Temp =
7574 32 : thisDXCoil.RatedInletWaterTemp; // set the rated water inlet node for HPWHs for use in CalcHPWHDXCoil
7575 812 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7576 16 : SizingMethod = HVAC::CoolingCapacitySizing;
7577 16 : CompName = thisDXCoil.Name;
7578 16 : FieldNum = 1;
7579 16 : TempSize = thisDXCoil.RatedTotCap(Mode);
7580 16 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7581 16 : if (state.dataSize->CurZoneEqNum > 0) {
7582 16 : CoilInTemp =
7583 16 : state.dataSize->ZoneSizingRunDone ? state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp : 26;
7584 : } else {
7585 0 : if (state.dataSize->CurOASysNum > 0) {
7586 0 : CoilInTemp =
7587 0 : state.dataSize->SysSizingRunDone ? state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).OutTempAtCoolPeak : 32;
7588 : } else {
7589 0 : CoilInTemp =
7590 0 : state.dataSize->SysSizingRunDone ? state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).MixTempAtCoolPeak : 26;
7591 : }
7592 : }
7593 16 : CalcVRFCoilCapModFac(state, 0, _, CompName, CoilInTemp, _, _, _, state.dataSize->DataTotCapCurveValue);
7594 796 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7595 49 : SizingMethod = HVAC::CoolingCapacitySizing;
7596 49 : CompName = thisDXCoil.Name;
7597 49 : FieldNum = 7 + (thisDXCoil.NumOfSpeeds - 1) * 13;
7598 49 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(thisDXCoil.NumOfSpeeds);
7599 49 : TempSize = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
7600 49 : PrintFlag = false;
7601 49 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7602 747 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7603 22 : SizingMethod = HVAC::HeatingCapacitySizing;
7604 22 : CompName = thisDXCoil.Name;
7605 22 : FieldNum = 10 + (thisDXCoil.NumOfSpeeds - 1) * 5;
7606 22 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(thisDXCoil.NumOfSpeeds);
7607 22 : TempSize = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
7608 22 : PrintFlag = false;
7609 22 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7610 : } else {
7611 725 : SizingMethod = HVAC::CoolingCapacitySizing;
7612 725 : CompName = thisDXCoil.Name;
7613 725 : FieldNum = 1;
7614 725 : TempSize = thisDXCoil.RatedTotCap(Mode);
7615 725 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7616 : }
7617 1016 : CompType = thisDXCoil.DXCoilType;
7618 1016 : state.dataSize->DataIsDXCoil = true;
7619 1016 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
7620 1016 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
7621 1016 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical ||
7622 919 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7623 159 : HeatingCapacitySizer sizerHeatingCapacity;
7624 159 : sizerHeatingCapacity.overrideSizingString(SizingString);
7625 159 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7626 159 : thisDXCoil.RatedTotCap(Mode) = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
7627 159 : } else {
7628 857 : CoolingCapacitySizer sizerCoolingCapacity;
7629 857 : sizerCoolingCapacity.overrideSizingString(SizingString);
7630 857 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7631 857 : thisDXCoil.RatedTotCap(Mode) = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
7632 857 : }
7633 1016 : state.dataSize->DataIsDXCoil = false;
7634 1016 : state.dataSize->DataFlowUsedForSizing = 0.0;
7635 1016 : state.dataSize->DataCoolCoilCap = 0.0;
7636 1016 : state.dataSize->DataTotCapCurveIndex = 0;
7637 1016 : state.dataSize->DataEMSOverrideON = false;
7638 1016 : state.dataSize->DataEMSOverride = 0.0;
7639 1016 : state.dataSize->DataConstantUsedForSizing = 0.0;
7640 1016 : state.dataSize->DataFractionUsedForSizing = 0.0;
7641 1016 : state.dataSize->DataTotCapCurveValue = 0.0;
7642 :
7643 : // Cooling coil capacity
7644 1016 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7645 337 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling ||
7646 256 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7647 776 : state.dataSize->DXCoolCap = thisDXCoil.RatedTotCap(Mode);
7648 : }
7649 :
7650 : // Sizing DX cooling coil SHR
7651 1016 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7652 337 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling ||
7653 256 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7654 :
7655 776 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7656 35 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7657 : } else {
7658 741 : CompName = thisDXCoil.Name;
7659 : }
7660 776 : CompType = thisDXCoil.DXCoilType;
7661 776 : TempSize = thisDXCoil.RatedSHR(Mode);
7662 776 : state.dataSize->DataDXSpeedNum = Mode;
7663 776 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
7664 776 : state.dataSize->DataCapacityUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7665 776 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedSHREMSOverrideOn(Mode);
7666 776 : state.dataSize->DataEMSOverride = thisDXCoil.RatedSHREMSOverrideValue(Mode);
7667 776 : bool ErrorsFound = false;
7668 776 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7669 776 : thisDXCoil.RatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
7670 776 : state.dataSize->DataDXSpeedNum = 0;
7671 776 : state.dataSize->DataFlowUsedForSizing = 0.0;
7672 776 : state.dataSize->DataCapacityUsedForSizing = 0.0;
7673 776 : state.dataSize->DataEMSOverrideON = false;
7674 776 : state.dataSize->DataEMSOverride = 0.0;
7675 :
7676 : } // End of Rated SHR
7677 :
7678 : // Sizing evaporator condenser air flow
7679 1016 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondAirFlow(Mode) != 0.0 &&
7680 0 : (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7681 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
7682 :
7683 0 : AutoCalculateSizer sizerEvapCondAirFlow;
7684 0 : std::string stringOverride = "Evaporative Condenser Air Flow Rate [m3/s]";
7685 0 : if (state.dataGlobal->isEpJSON) stringOverride = "evaporative_condenser_air_flow_rate [m3/s]";
7686 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7687 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7688 : } else {
7689 0 : CompName = thisDXCoil.Name;
7690 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7691 0 : stringOverride = "High Speed Evaporative Condenser Air Flow Rate [m3/s]";
7692 0 : if (state.dataGlobal->isEpJSON) stringOverride = "high_speed_evaporative_condenser_air_flow_rate [m3/s]";
7693 : } else {
7694 0 : stringOverride = "Evaporative Condenser Air Flow Rate [m3/s]";
7695 0 : if (state.dataGlobal->isEpJSON) stringOverride = "evaporative_condenser_air_flow_rate [m3/s]";
7696 : }
7697 : }
7698 0 : CompType = thisDXCoil.DXCoilType;
7699 : // Auto-size condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
7700 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7701 0 : state.dataSize->DataFractionUsedForSizing = 0.000114;
7702 0 : TempSize = thisDXCoil.EvapCondAirFlow(Mode);
7703 0 : sizerEvapCondAirFlow.overrideSizingString(stringOverride);
7704 0 : sizerEvapCondAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7705 0 : thisDXCoil.EvapCondAirFlow(Mode) = sizerEvapCondAirFlow.size(state, TempSize, ErrorsFound);
7706 0 : }
7707 :
7708 1016 : if (SizeSecDXCoil) { // autosize secondary coil air flow rate for AirCooled condenser type
7709 1 : IsAutoSize = false;
7710 1 : if (thisDXCoil.SecCoilAirFlow == AutoSize) {
7711 1 : IsAutoSize = true;
7712 : }
7713 : // Autosize Primary Coil Air Flow * Secondary Coil Scaling Factor
7714 1 : SecCoilAirFlowDes = thisDXCoil.RatedAirVolFlowRate(1) * thisDXCoil.SecCoilAirFlowScalingFactor;
7715 1 : if (IsAutoSize) {
7716 1 : thisDXCoil.SecCoilAirFlow = SecCoilAirFlowDes;
7717 1 : BaseSizer::reportSizerOutput(
7718 : state, thisDXCoil.DXCoilType, thisDXCoil.Name, "Design Size Secondary Coil Air Flow Rate [m3/s]", SecCoilAirFlowDes);
7719 : } else {
7720 0 : if (thisDXCoil.SecCoilAirFlow > 0.0 && SecCoilAirFlowDes > 0.0 && !HardSizeNoDesRun) {
7721 0 : SecCoilAirFlowUser = thisDXCoil.SecCoilAirFlow;
7722 0 : BaseSizer::reportSizerOutput(state,
7723 : thisDXCoil.DXCoilType,
7724 : thisDXCoil.Name,
7725 : "Design Size Secondary Coil Air Flow Rate [m3/s]",
7726 : SecCoilAirFlowDes,
7727 : "User-Specified Secondary Coil Air Flow Rate [m3/s]",
7728 : SecCoilAirFlowUser);
7729 0 : if (state.dataGlobal->DisplayExtraWarnings) {
7730 0 : if ((std::abs(SecCoilAirFlowDes - SecCoilAirFlowUser) / SecCoilAirFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
7731 0 : ShowMessage(
7732 : state,
7733 0 : format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
7734 0 : ShowContinueError(state, format("User-Specified Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowUser));
7735 0 : ShowContinueError(
7736 0 : state, format("differs from Design Size Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowDes));
7737 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
7738 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
7739 : }
7740 : }
7741 : }
7742 : }
7743 : }
7744 :
7745 : // Sizing evaporative condenser air flow 2
7746 1016 : PrintFlag = true;
7747 1016 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondAirFlow2 != 0.0 &&
7748 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7749 0 : CompName = thisDXCoil.Name;
7750 0 : FieldNum = 15; // Low Speed Evaporative Condenser Air Flow Rate
7751 0 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [m3/s]";
7752 0 : SizingMethod = HVAC::AutoCalculateSizing;
7753 0 : CompType = thisDXCoil.DXCoilType;
7754 : // Autosize low speed condenser air flow to 1/3 Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
7755 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7756 0 : state.dataSize->DataFractionUsedForSizing = 0.000114 * 0.3333;
7757 0 : TempSize = thisDXCoil.EvapCondAirFlow2;
7758 0 : AutoCalculateSizer sizerEvapCondAirFlow2;
7759 0 : std::string stringOverride = "Low Speed Evaporative Condenser Air Flow Rate [m3/s]";
7760 0 : if (state.dataGlobal->isEpJSON) stringOverride = "low_speed_evaporative_condenser_air_flow_rate [m3/s]";
7761 0 : sizerEvapCondAirFlow2.overrideSizingString(stringOverride);
7762 0 : sizerEvapCondAirFlow2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7763 0 : thisDXCoil.EvapCondAirFlow2 = sizerEvapCondAirFlow2.size(state, TempSize, ErrorsFound);
7764 0 : }
7765 :
7766 : // Sizing evaporative condenser pump electric nominal power
7767 1016 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondPumpElecNomPower(Mode) != 0.0 &&
7768 0 : (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7769 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
7770 :
7771 0 : AutoCalculateSizer sizerEvapCondPumpPower;
7772 0 : std::string stringOverride = "Evaporative Condenser Pump Rated Power Consumption [W]";
7773 0 : if (state.dataGlobal->isEpJSON) stringOverride = "evaporative_condenser_pump_rated_power_consumption [W]";
7774 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7775 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7776 : } else {
7777 0 : CompName = thisDXCoil.Name;
7778 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7779 0 : stringOverride = "High Speed Evaporative Condenser Pump Rated Power Consumption [W]";
7780 0 : if (state.dataGlobal->isEpJSON) stringOverride = "high_speed_evaporative_condenser_pump_rated_power_consumption [W]";
7781 : } else {
7782 0 : stringOverride = "Evaporative Condenser Pump Rated Power Consumption [W]";
7783 0 : if (state.dataGlobal->isEpJSON) stringOverride = "evaporative_condenser_pump_rated_power_consumption [W]";
7784 : }
7785 : }
7786 0 : SizingMethod = HVAC::AutoCalculateSizing;
7787 0 : CompType = thisDXCoil.DXCoilType;
7788 : // Autosize high speed evap condenser pump power to Total Capacity * 0.004266 w/w (15 w/ton)
7789 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7790 0 : state.dataSize->DataFractionUsedForSizing = 0.004266;
7791 0 : TempSize = thisDXCoil.EvapCondPumpElecNomPower(Mode);
7792 0 : sizerEvapCondPumpPower.overrideSizingString(stringOverride);
7793 0 : sizerEvapCondPumpPower.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7794 0 : thisDXCoil.EvapCondPumpElecNomPower(Mode) = sizerEvapCondPumpPower.size(state, TempSize, ErrorsFound);
7795 0 : }
7796 :
7797 : // Sizing low speed evaporative condenser pump electric nominal power
7798 1016 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondPumpElecNomPower2 != 0.0 &&
7799 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7800 0 : CompName = thisDXCoil.Name;
7801 0 : CompType = thisDXCoil.DXCoilType;
7802 : // Autosize low speed evap condenser pump power to 1/3 Total Capacity * 0.004266 w/w (15 w/ton)
7803 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7804 0 : state.dataSize->DataFractionUsedForSizing = 0.004266 * 0.3333;
7805 0 : TempSize = thisDXCoil.EvapCondPumpElecNomPower2;
7806 0 : AutoCalculateSizer sizerEvapCondPumpPower2;
7807 0 : std::string stringOverride = "Low Speed Evaporative Condenser Pump Rated Power Consumption [W]";
7808 0 : if (state.dataGlobal->isEpJSON) stringOverride = "low_speed_evaporative_condenser_pump_rated_power_consumption [W]";
7809 0 : sizerEvapCondPumpPower2.overrideSizingString(stringOverride);
7810 0 : sizerEvapCondPumpPower2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7811 0 : thisDXCoil.EvapCondPumpElecNomPower2 = sizerEvapCondPumpPower2.size(state, TempSize, ErrorsFound);
7812 0 : }
7813 :
7814 : // // Sizing rated low speed air flow rate
7815 1016 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7816 67 : CompName = thisDXCoil.Name;
7817 67 : CompType = thisDXCoil.DXCoilType;
7818 : // Autosize low speed air flow rate to 1/3 high speed air flow rate
7819 67 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
7820 67 : state.dataSize->DataFractionUsedForSizing = 0.3333;
7821 67 : TempSize = thisDXCoil.RatedAirVolFlowRate2;
7822 67 : AutoCalculateSizer sizerLowSpdAirFlow;
7823 67 : std::string stringOverride = "Low Speed Rated Air Flow Rate [m3/s]";
7824 67 : if (state.dataGlobal->isEpJSON) stringOverride = "low_speed_rated_air_flow_rate [m3/s]";
7825 67 : sizerLowSpdAirFlow.overrideSizingString(stringOverride);
7826 67 : sizerLowSpdAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7827 67 : thisDXCoil.RatedAirVolFlowRate2 = sizerLowSpdAirFlow.size(state, TempSize, ErrorsFound);
7828 67 : }
7829 :
7830 : // // Sizing rated low speed total cooling capacity
7831 1016 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7832 67 : CompName = thisDXCoil.Name;
7833 67 : CompType = thisDXCoil.DXCoilType;
7834 : // Autosize low speed capacity to 1/3 high speed capacity
7835 67 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7836 67 : state.dataSize->DataFractionUsedForSizing = 0.3333;
7837 67 : TempSize = thisDXCoil.RatedTotCap2;
7838 67 : AutoCalculateSizer sizerLowSpdCap;
7839 67 : std::string stringOverride = "Low Speed Gross Rated Total Cooling Capacity [W]";
7840 67 : if (state.dataGlobal->isEpJSON) stringOverride = "low_speed_gross_rated_total_cooling_capacity [W]";
7841 67 : sizerLowSpdCap.overrideSizingString(stringOverride);
7842 67 : sizerLowSpdCap.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7843 67 : thisDXCoil.RatedTotCap2 = sizerLowSpdCap.size(state, TempSize, ErrorsFound);
7844 67 : }
7845 :
7846 1016 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7847 67 : if (thisDXCoil.EvapCondAirFlow2 > thisDXCoil.EvapCondAirFlow(Mode)) {
7848 0 : ShowSevereError(
7849 : state,
7850 0 : format("SizeDXCoil: {} {}, Evaporative Condenser low speed air flow must be less than or equal to high speed air flow.",
7851 0 : thisDXCoil.DXCoilType,
7852 0 : thisDXCoil.Name));
7853 0 : ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.EvapCondAirFlow2, thisDXCoil.EvapCondAirFlow(Mode)));
7854 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7855 : }
7856 :
7857 67 : if (thisDXCoil.EvapCondPumpElecNomPower2 > thisDXCoil.EvapCondPumpElecNomPower(Mode)) {
7858 0 : ShowSevereError(
7859 : state,
7860 0 : format("SizeDXCoil: {} {}, Evaporative Condenser low speed pump power must be less than or equal to high speed pump power.",
7861 0 : thisDXCoil.DXCoilType,
7862 0 : thisDXCoil.Name));
7863 0 : ShowContinueError(
7864 0 : state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.EvapCondPumpElecNomPower2, thisDXCoil.EvapCondPumpElecNomPower(Mode)));
7865 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7866 : }
7867 :
7868 67 : if (thisDXCoil.RatedTotCap2 > thisDXCoil.RatedTotCap(Mode)) {
7869 0 : ShowSevereError(state,
7870 0 : format("SizeDXCoil: {} {}, Rated Total Cooling Capacity, Low Speed must be less than or equal to Rated Total "
7871 : "Cooling Capacity, High Speed.",
7872 0 : thisDXCoil.DXCoilType,
7873 0 : thisDXCoil.Name));
7874 0 : ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.RatedTotCap2, thisDXCoil.RatedTotCap(Mode)));
7875 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7876 : }
7877 :
7878 67 : if (thisDXCoil.RatedAirVolFlowRate2 > thisDXCoil.RatedAirVolFlowRate(Mode)) {
7879 0 : ShowFatalError(state,
7880 0 : format("SizeDXCoil: {} {}, Rated Air Volume Flow Rate, low speed must be less than or equal to Rated Air Volume "
7881 : "Flow Rate, high speed.",
7882 0 : thisDXCoil.DXCoilType,
7883 0 : thisDXCoil.Name));
7884 0 : ShowContinueError(state,
7885 0 : format("Instead, {:.2R} > {:.2R}", thisDXCoil.RatedAirVolFlowRate2, thisDXCoil.RatedAirVolFlowRate(Mode)));
7886 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7887 : }
7888 : }
7889 :
7890 : // // Sizing rated low speed SHR2
7891 1016 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7892 67 : CompName = thisDXCoil.Name;
7893 67 : FieldNum = 7;
7894 67 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum);
7895 67 : SizingMethod = HVAC::AutoCalculateSizing;
7896 67 : CompType = thisDXCoil.DXCoilType;
7897 : // Autosize low speed SHR to be the same as high speed SHR
7898 67 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedSHR(Mode);
7899 67 : state.dataSize->DataFractionUsedForSizing = 1.0;
7900 67 : state.dataSize->DataDXSpeedNum = 2; // refers to low speed in sizer
7901 67 : bool ErrorsFound = false;
7902 67 : TempSize = thisDXCoil.RatedSHR2;
7903 67 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7904 67 : thisDXCoil.RatedSHR2 = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
7905 67 : state.dataSize->DataConstantUsedForSizing = 0.0;
7906 67 : state.dataSize->DataFractionUsedForSizing = 0.0;
7907 67 : state.dataSize->DataDXSpeedNum = 0;
7908 : }
7909 :
7910 : // // Sizing resistive defrost heater capacity
7911 1016 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating &&
7912 954 : thisDXCoil.DXCoilType_Num != HVAC::CoilDX_MultiSpeedHeating) {
7913 : // IF (DXCoil(DXCoilNum)%DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating .OR. &
7914 : // DXCoil(DXCoilNum)%DXCoilType_Num == Coil_HeatingAirToAirVariableSpeed) THEN
7915 932 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
7916 48 : CompName = thisDXCoil.Name;
7917 48 : CompType = thisDXCoil.DXCoilType;
7918 : // Autosize low speed capacity to 1/3 high speed capacity
7919 48 : state.dataSize->DataConstantUsedForSizing = state.dataSize->DXCoolCap;
7920 48 : state.dataSize->DataFractionUsedForSizing = 1.0;
7921 48 : TempSize = thisDXCoil.DefrostCapacity;
7922 48 : AutoCalculateSizer sizerResDefCap;
7923 48 : std::string stringOverride = "Resistive Defrost Heater Capacity [W]";
7924 48 : if (state.dataGlobal->isEpJSON) stringOverride = "resistive_defrost_heater_capacity [W]";
7925 48 : sizerResDefCap.overrideSizingString(stringOverride);
7926 48 : sizerResDefCap.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7927 48 : thisDXCoil.DefrostCapacity = sizerResDefCap.size(state, TempSize, ErrorsFound);
7928 48 : } else {
7929 884 : thisDXCoil.DefrostCapacity = 0.0;
7930 : }
7931 : }
7932 :
7933 : } // End capacity stages loop
7934 : } // End dehumidification modes loop
7935 :
7936 : // Autosizing for multispeed cooling coil
7937 992 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7938 : // flow rate autosize
7939 162 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
7940 : // Sizing multispeed air volume flow rate
7941 113 : IsAutoSize = false;
7942 113 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) == AutoSize) {
7943 7 : IsAutoSize = true;
7944 : }
7945 113 : state.dataSize->DataIsDXCoil = true;
7946 113 : CompName = thisDXCoil.Name;
7947 113 : CompType = thisDXCoil.DXCoilType;
7948 113 : if (Mode == thisDXCoil.NumOfSpeeds) {
7949 49 : FieldNum = 10 + (Mode - 1) * 14;
7950 49 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
7951 49 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
7952 49 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
7953 49 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
7954 49 : bool errorsFound = false;
7955 49 : CoolingAirFlowSizer sizingCoolingAirFlow;
7956 49 : sizingCoolingAirFlow.overrideSizingString(SizingString);
7957 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7958 49 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7959 49 : TempSize = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7960 49 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = TempSize;
7961 49 : state.dataSize->DataEMSOverrideON = false;
7962 49 : state.dataSize->DataEMSOverride = 0.0;
7963 49 : if (!IsAutoSize && !HardSizeNoDesRun) {
7964 36 : TempSize = AutoSize;
7965 36 : bPRINT = false;
7966 36 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
7967 36 : MSRatedAirVolFlowRateDes = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7968 36 : bPRINT = true;
7969 : }
7970 49 : if (IsAutoSize) {
7971 2 : MSRatedAirVolFlowRateDes = TempSize;
7972 : }
7973 49 : } else {
7974 64 : FieldNum = 10 + (Mode - 1) * 14;
7975 64 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
7976 64 : if (IsAutoSize || !HardSizeNoDesRun) {
7977 41 : SizingMethod = HVAC::AutoCalculateSizing;
7978 : // Autosize low speed flow to fraction of the highest speed flow
7979 41 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
7980 41 : if (!IsAutoSize && !HardSizeNoDesRun) state.dataSize->DataConstantUsedForSizing = MSRatedAirVolFlowRateDes;
7981 41 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
7982 : }
7983 64 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
7984 64 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
7985 64 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
7986 64 : bool errorsFound = false;
7987 64 : CoolingAirFlowSizer sizingCoolingAirFlow;
7988 64 : sizingCoolingAirFlow.overrideSizingString(SizingString);
7989 64 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
7990 64 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7991 64 : }
7992 113 : state.dataSize->DataEMSOverride = 0.0;
7993 113 : state.dataSize->DataEMSOverrideON = false;
7994 113 : state.dataSize->DataIsDXCoil = false;
7995 113 : state.dataSize->DataTotCapCurveIndex = 0;
7996 113 : state.dataSize->DataConstantUsedForSizing = 0.0;
7997 113 : state.dataSize->DataFractionUsedForSizing = 0.0;
7998 : }
7999 :
8000 : // Ensure flow rate at lower speed must be lower or equal to the flow rate at higher speed. Otherwise, a severe error is isssued.
8001 113 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8002 64 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) > thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)) {
8003 0 : ShowWarningError(state,
8004 0 : format("SizeDXCoil: {} {}, Speed {} Rated Air Flow Rate must be less than or equal to Speed {} Rated Air Flow Rate.",
8005 0 : thisDXCoil.DXCoilType,
8006 0 : thisDXCoil.Name,
8007 : Mode,
8008 0 : Mode + 1));
8009 0 : ShowContinueError(
8010 0 : state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedAirVolFlowRate(Mode), thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)));
8011 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8012 : }
8013 : }
8014 :
8015 : // Sizing multispeed rated total cooling capacity
8016 162 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8017 113 : IsAutoSize = false;
8018 113 : if (thisDXCoil.MSRatedTotCap(Mode) == AutoSize) {
8019 7 : IsAutoSize = true;
8020 : }
8021 113 : CompName = thisDXCoil.Name;
8022 113 : CompType = thisDXCoil.DXCoilType;
8023 113 : state.dataSize->DataIsDXCoil = true;
8024 113 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(Mode);
8025 113 : if (Mode == thisDXCoil.NumOfSpeeds) {
8026 49 : PrintFlag = true;
8027 49 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8028 49 : SizingMethod = HVAC::CoolingCapacitySizing;
8029 49 : FieldNum = 7 + (Mode - 1) * 14;
8030 49 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8031 49 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8032 49 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8033 49 : MSRatedTotCapDesAtMaxSpeed = thisDXCoil.MSRatedTotCap(Mode);
8034 49 : if (!HardSizeNoDesRun) {
8035 38 : PrintFlag = false;
8036 38 : TempSize = DataSizing::AutoSize;
8037 : // Auto-size capacity at the highest speed
8038 38 : CoolingCapacitySizer sizerCoolingCapacity;
8039 38 : sizerCoolingCapacity.overrideSizingString(SizingString);
8040 38 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8041 38 : TempSize = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
8042 38 : SizingMethod = HVAC::AutoCalculateSizing;
8043 38 : state.dataSize->DataConstantUsedForSizing = TempSize;
8044 38 : state.dataSize->DataFractionUsedForSizing = 1.0;
8045 38 : MSRatedTotCapDesAtMaxSpeed = TempSize;
8046 38 : thisDXCoil.MSRatedTotCapDes(Mode) = TempSize;
8047 38 : PrintFlag = true;
8048 38 : }
8049 49 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8050 49 : CoolingCapacitySizer sizerCoolingCapacity2;
8051 49 : sizerCoolingCapacity2.overrideSizingString(SizingString);
8052 49 : sizerCoolingCapacity2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8053 49 : TempSize = sizerCoolingCapacity2.size(state, TempSize, ErrorsFound);
8054 49 : thisDXCoil.MSRatedTotCap(Mode) = TempSize;
8055 49 : if (IsAutoSize) {
8056 2 : MSRatedTotCapDesAtMaxSpeed = TempSize;
8057 2 : thisDXCoil.MSRatedTotCapDes(Mode) = TempSize;
8058 : }
8059 49 : } else {
8060 : // cooling capacity at lower speeds
8061 64 : PrintFlag = true;
8062 64 : SizingMethod = HVAC::CoolingCapacitySizing;
8063 64 : FieldNum = 7 + (Mode - 1) * 14;
8064 64 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8065 64 : if (IsAutoSize || !HardSizeNoDesRun) {
8066 41 : SizingMethod = HVAC::AutoCalculateSizing;
8067 : // autosize low speed capacity to fraction of the highest speed capacity
8068 41 : if (!HardSizeNoDesRun) {
8069 41 : state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8070 : } else {
8071 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
8072 : }
8073 41 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8074 41 : thisDXCoil.MSRatedTotCapDes(Mode) = state.dataSize->DataConstantUsedForSizing * state.dataSize->DataFractionUsedForSizing;
8075 : }
8076 64 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8077 64 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8078 64 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8079 64 : CoolingCapacitySizer sizerCoolingCapacity;
8080 64 : sizerCoolingCapacity.overrideSizingString(SizingString);
8081 64 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8082 64 : thisDXCoil.MSRatedTotCap(Mode) = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
8083 64 : }
8084 113 : state.dataSize->DataEMSOverride = 0.0;
8085 113 : state.dataSize->DataEMSOverrideON = false;
8086 113 : state.dataSize->DataIsDXCoil = false;
8087 113 : state.dataSize->DataCoolCoilCap = 0.0;
8088 113 : state.dataSize->DataTotCapCurveIndex = 0;
8089 113 : state.dataSize->DataConstantUsedForSizing = 0.0;
8090 113 : state.dataSize->DataFractionUsedForSizing = 0.0;
8091 : }
8092 :
8093 : // Ensure capacity at lower speed must be lower or equal to the capacity at higher speed.
8094 113 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8095 64 : if (thisDXCoil.MSRatedTotCap(Mode) > thisDXCoil.MSRatedTotCap(Mode + 1)) {
8096 0 : ShowWarningError(state,
8097 0 : format("SizeDXCoil: {} {}, Speed {} Rated Total Cooling Capacity must be less than or equal to Speed {} Rated "
8098 : "Total Cooling Capacity.",
8099 0 : thisDXCoil.DXCoilType,
8100 0 : thisDXCoil.Name,
8101 : Mode,
8102 0 : Mode + 1));
8103 0 : ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedTotCap(Mode), thisDXCoil.MSRatedTotCap(Mode + 1)));
8104 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8105 : }
8106 : }
8107 :
8108 : // Rated SHR
8109 162 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8110 113 : IsAutoSize = false;
8111 113 : if (thisDXCoil.MSRatedSHR(Mode) == AutoSize) {
8112 7 : IsAutoSize = true;
8113 : }
8114 113 : if (Mode == thisDXCoil.NumOfSpeeds) {
8115 49 : CompType = thisDXCoil.DXCoilType;
8116 49 : CompName = thisDXCoil.Name;
8117 49 : TempSize = thisDXCoil.MSRatedSHR(Mode);
8118 49 : state.dataSize->DataFlowUsedForSizing = MSRatedAirVolFlowRateDes;
8119 49 : state.dataSize->DataCapacityUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8120 49 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedSHREMSOverrideOn(Mode);
8121 49 : state.dataSize->DataEMSOverride = thisDXCoil.RatedSHREMSOverrideValue(Mode);
8122 49 : bool ErrorsFound = false;
8123 49 : state.dataSize->DataDXSpeedNum = Mode;
8124 49 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8125 49 : thisDXCoil.MSRatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
8126 : // added for rated sensible cooling capacity estimate for html reporting, issue #7381
8127 49 : thisDXCoil.RatedSHR(1) = thisDXCoil.MSRatedSHR(Mode);
8128 : // design SHR value at the maxiumum speed calculated above was supposed to be used for all speeds
8129 : // Now user specified SHR value is used when the SHR field is not autosized and design day run is
8130 : // set to yes unless the code below is commented out
8131 49 : MSRatedSHRDes = thisDXCoil.MSRatedSHR(Mode);
8132 : } else {
8133 64 : TempSize = thisDXCoil.MSRatedSHR(Mode);
8134 64 : bool ErrorsFound = false;
8135 64 : state.dataSize->DataDXSpeedNum = Mode;
8136 64 : state.dataSize->DataFractionUsedForSizing = MSRatedSHRDes;
8137 64 : state.dataSize->DataConstantUsedForSizing = 1.0;
8138 64 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8139 64 : thisDXCoil.MSRatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
8140 : }
8141 : }
8142 49 : state.dataSize->DataFlowUsedForSizing = 0.0;
8143 49 : state.dataSize->DataCapacityUsedForSizing = 0.0;
8144 49 : state.dataSize->DataEMSOverrideON = false;
8145 49 : state.dataSize->DataEMSOverride = 0.0;
8146 49 : state.dataSize->DataDXSpeedNum = 0;
8147 49 : state.dataSize->DataFractionUsedForSizing = 0.0;
8148 49 : state.dataSize->DataConstantUsedForSizing = 0.0;
8149 :
8150 : // Rated Evapovative condenser airflow rates
8151 162 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8152 113 : IsAutoSize = false;
8153 113 : if (thisDXCoil.MSEvapCondAirFlow(Mode) == AutoSize) {
8154 0 : IsAutoSize = true;
8155 : }
8156 113 : if (IsAutoSize || !HardSizeNoDesRun) {
8157 : // Autosize condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
8158 79 : MSEvapCondAirFlowDes = ((float)Mode / thisDXCoil.NumOfSpeeds) * MSRatedTotCapDesAtMaxSpeed * 0.000114;
8159 : } else {
8160 : // this is done to duplicate any existing calc method
8161 34 : MSEvapCondAirFlowDes = thisDXCoil.MSRatedTotCap(Mode) * 0.000114;
8162 : }
8163 113 : if (IsAutoSize) {
8164 0 : thisDXCoil.MSEvapCondAirFlow(Mode) = MSEvapCondAirFlowDes;
8165 0 : BaseSizer::reportSizerOutput(state,
8166 : thisDXCoil.DXCoilType,
8167 : thisDXCoil.Name,
8168 0 : format("Design Size Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
8169 : MSEvapCondAirFlowDes);
8170 : } else {
8171 113 : if (thisDXCoil.MSEvapCondAirFlow(Mode) > 0.0 && MSEvapCondAirFlowDes > 0.0 && !HardSizeNoDesRun) {
8172 8 : MSEvapCondAirFlowUser = thisDXCoil.MSEvapCondAirFlow(Mode);
8173 24 : BaseSizer::reportSizerOutput(state,
8174 : thisDXCoil.DXCoilType,
8175 : thisDXCoil.Name,
8176 16 : format("Design Size Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
8177 : MSEvapCondAirFlowDes,
8178 16 : format("User-Specified Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
8179 : MSEvapCondAirFlowUser);
8180 8 : if (state.dataGlobal->DisplayExtraWarnings) {
8181 0 : if ((std::abs(MSEvapCondAirFlowDes - MSEvapCondAirFlowUser) / MSEvapCondAirFlowUser) >
8182 0 : state.dataSize->AutoVsHardSizingThreshold) {
8183 0 : ShowMessage(
8184 0 : state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
8185 0 : ShowContinueError(state,
8186 0 : format("User-Specified Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", MSEvapCondAirFlowUser));
8187 0 : ShowContinueError(
8188 0 : state, format("differs from Design Size Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", MSEvapCondAirFlowDes));
8189 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8190 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8191 : }
8192 : }
8193 : }
8194 : }
8195 : }
8196 :
8197 : // Ensure evaporative condenser airflow rate at lower speed must be lower or equal to one at higher speed.
8198 113 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8199 64 : if (thisDXCoil.MSEvapCondAirFlow(Mode) > thisDXCoil.MSEvapCondAirFlow(Mode + 1)) {
8200 0 : ShowWarningError(state,
8201 0 : format("SizeDXCoil: {} {}, Speed {} Evaporative Condenser Air Flow Rate must be less than or equal to Speed {} "
8202 : "Evaporative Condenser Air Flow Rate.",
8203 0 : thisDXCoil.DXCoilType,
8204 0 : thisDXCoil.Name,
8205 : Mode,
8206 0 : Mode + 1));
8207 0 : ShowContinueError(state,
8208 0 : format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSEvapCondAirFlow(Mode), thisDXCoil.MSEvapCondAirFlow(Mode + 1)));
8209 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8210 : }
8211 : }
8212 :
8213 : // Sizing multispeed rated evapovative condenser pump power
8214 162 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8215 113 : IsAutoSize = false;
8216 113 : if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) == AutoSize) {
8217 0 : IsAutoSize = true;
8218 : }
8219 :
8220 113 : if (IsAutoSize || !HardSizeNoDesRun) {
8221 : // Autosize low speed evap condenser pump power to 1/3 Total Capacity * 0.004266 w/w (15 w/ton)
8222 79 : MSEvapCondPumpElecNomPowerDes = ((float)Mode / thisDXCoil.NumOfSpeeds) * MSRatedTotCapDesAtMaxSpeed * 0.004266;
8223 : } else {
8224 : // this is done to duplicate any existing calc method
8225 34 : MSEvapCondPumpElecNomPowerDes = thisDXCoil.MSRatedTotCap(Mode) * 0.004266;
8226 : }
8227 : // Design Size data is always available
8228 113 : if (IsAutoSize) {
8229 0 : thisDXCoil.MSEvapCondPumpElecNomPower(Mode) = MSEvapCondPumpElecNomPowerDes;
8230 0 : BaseSizer::reportSizerOutput(state,
8231 : thisDXCoil.DXCoilType,
8232 : thisDXCoil.Name,
8233 0 : format("Design Size Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
8234 : MSEvapCondPumpElecNomPowerDes);
8235 : } else {
8236 113 : if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) > 0.0 && MSEvapCondPumpElecNomPowerDes > 0.0 && !HardSizeNoDesRun) {
8237 8 : MSEvapCondPumpElecNomPowerUser = thisDXCoil.MSEvapCondPumpElecNomPower(Mode);
8238 24 : BaseSizer::reportSizerOutput(state,
8239 : thisDXCoil.DXCoilType,
8240 : thisDXCoil.Name,
8241 16 : format("Design Size Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
8242 : MSEvapCondPumpElecNomPowerDes,
8243 16 : format("User-Specified Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
8244 : MSEvapCondPumpElecNomPowerUser);
8245 8 : if (state.dataGlobal->DisplayExtraWarnings) {
8246 0 : if ((std::abs(MSEvapCondPumpElecNomPowerDes - MSEvapCondPumpElecNomPowerUser) / MSEvapCondPumpElecNomPowerUser) >
8247 0 : state.dataSize->AutoVsHardSizingThreshold) {
8248 0 : ShowMessage(
8249 0 : state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
8250 0 : ShowContinueError(state,
8251 0 : format("User-Specified Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]",
8252 : MSEvapCondPumpElecNomPowerUser));
8253 0 : ShowContinueError(state,
8254 0 : format("differs from Design Size Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]",
8255 : MSEvapCondPumpElecNomPowerDes));
8256 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8257 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8258 : }
8259 : }
8260 : }
8261 : }
8262 : }
8263 :
8264 : // Ensure evaporative condesner pump power at lower speed must be lower or equal to one at higher speed.
8265 113 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8266 64 : if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) > thisDXCoil.MSEvapCondPumpElecNomPower(Mode + 1)) {
8267 0 : ShowWarningError(state,
8268 0 : format("SizeDXCoil: {} {}, Speed {} Rated Evaporative Condenser Pump Power Consumption must be less than or "
8269 : "equal to Speed {} Rated Evaporative Condenser Pump Power Consumption.",
8270 0 : thisDXCoil.DXCoilType,
8271 0 : thisDXCoil.Name,
8272 : Mode,
8273 0 : Mode + 1));
8274 0 : ShowContinueError(
8275 : state,
8276 0 : format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSEvapCondPumpElecNomPower(Mode), thisDXCoil.MSEvapCondPumpElecNomPower(Mode + 1)));
8277 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8278 : }
8279 : }
8280 : }
8281 :
8282 : // Autosizing for multispeed heating coil
8283 992 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
8284 : // flow rate autosize
8285 92 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8286 70 : IsAutoSize = false;
8287 70 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) == AutoSize) {
8288 32 : IsAutoSize = true;
8289 : }
8290 70 : state.dataSize->DataIsDXCoil = true;
8291 70 : CompName = thisDXCoil.Name;
8292 70 : CompType = thisDXCoil.DXCoilType;
8293 : // Sizing rated air flow rate
8294 70 : if (Mode == thisDXCoil.NumOfSpeeds) {
8295 22 : FieldNum = 12 + (Mode - 1) * 6;
8296 22 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
8297 22 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8298 22 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
8299 22 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
8300 22 : bool errorsFound = false;
8301 22 : HeatingAirFlowSizer sizingHeatingAirFlow;
8302 22 : sizingHeatingAirFlow.overrideSizingString(SizingString);
8303 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8304 22 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8305 22 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
8306 22 : if (!IsAutoSize && !HardSizeNoDesRun) {
8307 5 : TempSize = AutoSize;
8308 5 : bPRINT = false;
8309 5 : errorsFound = false;
8310 5 : HeatingAirFlowSizer sizingHeatingAirFlow2;
8311 5 : sizingHeatingAirFlow2.overrideSizingString(SizingString);
8312 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8313 5 : sizingHeatingAirFlow2.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8314 5 : MSRatedAirVolFlowRateDes = sizingHeatingAirFlow2.size(state, TempSize, errorsFound);
8315 5 : bPRINT = true;
8316 5 : }
8317 22 : } else {
8318 48 : FieldNum = 12 + (Mode - 1) * 6;
8319 48 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
8320 48 : if (IsAutoSize || !HardSizeNoDesRun) {
8321 31 : SizingMethod = HVAC::AutoCalculateSizing;
8322 : // Auto-size low speed flow to fraction of the highest speed capacity
8323 31 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
8324 31 : if (!IsAutoSize && !HardSizeNoDesRun) state.dataSize->DataConstantUsedForSizing = MSRatedAirVolFlowRateDes;
8325 31 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8326 : }
8327 48 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8328 48 : bool errorsFound = false;
8329 48 : HeatingAirFlowSizer sizingHeatingAirFlow;
8330 48 : sizingHeatingAirFlow.overrideSizingString(SizingString);
8331 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8332 48 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8333 48 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
8334 48 : }
8335 70 : state.dataSize->DataEMSOverride = 0.0;
8336 70 : state.dataSize->DataEMSOverrideON = false;
8337 70 : state.dataSize->DataIsDXCoil = false;
8338 70 : state.dataSize->DataTotCapCurveIndex = 0;
8339 70 : state.dataSize->DataConstantUsedForSizing = 0.0;
8340 70 : state.dataSize->DataFractionUsedForSizing = 0.0;
8341 : }
8342 :
8343 : // Ensure flow rate at lower speed must be lower or equal to the flow rate at higher speed. Otherwise, a severe error is isssued.
8344 70 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8345 48 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) > thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)) {
8346 0 : ShowWarningError(state,
8347 0 : format("SizeDXCoil: {} {}, Speed {} Rated Air Flow Rate must be less than or equal to Speed {} Rated Air Flow Rate.",
8348 0 : thisDXCoil.DXCoilType,
8349 0 : thisDXCoil.Name,
8350 : Mode,
8351 0 : Mode + 1));
8352 0 : ShowContinueError(
8353 0 : state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedAirVolFlowRate(Mode), thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)));
8354 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8355 : }
8356 : }
8357 : // Rated Secondary Coil Airflow Rates for AirCooled condenser type
8358 22 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
8359 0 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8360 0 : IsAutoSize = false;
8361 0 : if (thisDXCoil.MSSecCoilAirFlow(Mode) == AutoSize) {
8362 0 : IsAutoSize = true;
8363 : }
8364 : // Autosize Primary Coil air flow * Secondary Coil Scaling Factor
8365 0 : SecCoilAirFlowDes = thisDXCoil.MSRatedAirVolFlowRate(Mode) * thisDXCoil.MSSecCoilAirFlowScalingFactor(Mode);
8366 0 : if (IsAutoSize) {
8367 0 : thisDXCoil.MSSecCoilAirFlow(Mode) = SecCoilAirFlowDes;
8368 0 : BaseSizer::reportSizerOutput(state,
8369 : thisDXCoil.DXCoilType,
8370 : thisDXCoil.Name,
8371 0 : format("Design Size Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
8372 : SecCoilAirFlowDes);
8373 : } else {
8374 0 : if (thisDXCoil.MSSecCoilAirFlow(Mode) > 0.0 && SecCoilAirFlowDes > 0.0 && !HardSizeNoDesRun) {
8375 0 : SecCoilAirFlowUser = thisDXCoil.MSSecCoilAirFlow(Mode);
8376 0 : BaseSizer::reportSizerOutput(state,
8377 : thisDXCoil.DXCoilType,
8378 : thisDXCoil.Name,
8379 0 : format("Design Size Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
8380 : SecCoilAirFlowDes,
8381 0 : format("User-Specified Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
8382 : SecCoilAirFlowUser);
8383 0 : if (state.dataGlobal->DisplayExtraWarnings) {
8384 0 : if ((std::abs(SecCoilAirFlowDes - SecCoilAirFlowUser) / SecCoilAirFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
8385 0 : ShowMessage(
8386 : state,
8387 0 : format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
8388 0 : ShowContinueError(state, format("User-Specified Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowUser));
8389 0 : ShowContinueError(
8390 0 : state, format("differs from Design Size Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowDes));
8391 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8392 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8393 : }
8394 : }
8395 : }
8396 : }
8397 : }
8398 : }
8399 :
8400 : // Sizing rated total heating capacity
8401 92 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8402 70 : IsAutoSize = false;
8403 70 : if (thisDXCoil.MSRatedTotCap(Mode) == AutoSize) {
8404 36 : IsAutoSize = true;
8405 : }
8406 70 : state.dataSize->DataIsDXCoil = true;
8407 70 : CompName = thisDXCoil.Name;
8408 70 : CompType = thisDXCoil.DXCoilType;
8409 70 : if (Mode == thisDXCoil.NumOfSpeeds) {
8410 22 : SizingMethod = HVAC::HeatingCapacitySizing;
8411 22 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8412 22 : FieldNum = 10 + (Mode - 1) * 6;
8413 22 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8414 22 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(Mode);
8415 22 : if (IsAutoSize || !HardSizeNoDesRun) {
8416 : // Heating capacity is assumed to be equal to the cooling capacity
8417 13 : PrintFlag = false;
8418 13 : SizingMethod = HVAC::AutoCalculateSizing;
8419 13 : state.dataSize->DataFractionUsedForSizing = 1.0;
8420 13 : if (thisDXCoil.CompanionUpstreamDXCoil > 0) {
8421 5 : NumOfSpeedCompanion = state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).NumOfSpeeds;
8422 5 : state.dataSize->DataConstantUsedForSizing =
8423 5 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).MSRatedTotCapDes(NumOfSpeedCompanion);
8424 : } else {
8425 8 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(1); // sized above
8426 : }
8427 13 : TempSize = DataSizing::AutoSize;
8428 13 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8429 13 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8430 13 : HeatingCapacitySizer sizerHeatingCapacity;
8431 13 : sizerHeatingCapacity.overrideSizingString(SizingString);
8432 13 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8433 13 : MSRatedTotCapDesAtMaxSpeed = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
8434 13 : SizingMethod = HVAC::AutoCalculateSizing;
8435 13 : state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8436 13 : state.dataSize->DataFractionUsedForSizing = 1.0;
8437 13 : }
8438 22 : PrintFlag = true;
8439 22 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8440 22 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8441 22 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8442 22 : HeatingCapacitySizer sizerHeatingCapacity;
8443 22 : sizerHeatingCapacity.overrideSizingString(SizingString);
8444 22 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8445 22 : TempSize = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
8446 22 : thisDXCoil.MSRatedTotCap(Mode) = TempSize;
8447 22 : if (IsAutoSize) {
8448 10 : MSRatedTotCapDesAtMaxSpeed = TempSize;
8449 : }
8450 22 : } else {
8451 48 : PrintFlag = true;
8452 48 : SizingMethod = HVAC::HeatingCapacitySizing;
8453 48 : FieldNum = 10 + (Mode - 1) * 6;
8454 48 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8455 48 : if (IsAutoSize || !HardSizeNoDesRun) {
8456 31 : SizingMethod = HVAC::AutoCalculateSizing;
8457 : // autosize low speed capacity to fraction of the highest speed capacity
8458 31 : if (!HardSizeNoDesRun) {
8459 31 : state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8460 : } else {
8461 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
8462 : }
8463 31 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8464 : }
8465 48 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8466 48 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8467 48 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8468 48 : HeatingCapacitySizer sizerHeatingCapacity;
8469 48 : sizerHeatingCapacity.overrideSizingString(SizingString);
8470 48 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8471 48 : TempSize = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
8472 48 : thisDXCoil.MSRatedTotCap(Mode) = TempSize;
8473 48 : }
8474 70 : PrintFlag = false;
8475 70 : state.dataSize->DataEMSOverrideON = false;
8476 70 : state.dataSize->DataEMSOverride = 0.0;
8477 70 : state.dataSize->DataIsDXCoil = false;
8478 70 : state.dataSize->DataFlowUsedForSizing = 0.0;
8479 70 : state.dataSize->DataCoolCoilCap = 0.0;
8480 70 : state.dataSize->DataTotCapCurveIndex = 0;
8481 70 : state.dataSize->DataConstantUsedForSizing = 0.0;
8482 70 : state.dataSize->DataFractionUsedForSizing = 0.0;
8483 : }
8484 : // Ensure capacity at lower speed must be lower or equal to the capacity at higher speed.
8485 70 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8486 48 : if (thisDXCoil.MSRatedTotCap(Mode) > thisDXCoil.MSRatedTotCap(Mode + 1)) {
8487 0 : ShowWarningError(state,
8488 0 : format("SizeDXCoil: {} {}, Speed {} Rated Total Heating Capacity must be less than or equal to Speed {} Rated "
8489 : "Total Heating Capacity.",
8490 0 : thisDXCoil.DXCoilType,
8491 0 : thisDXCoil.Name,
8492 : Mode,
8493 0 : Mode + 1));
8494 0 : ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedTotCap(Mode), thisDXCoil.MSRatedTotCap(Mode + 1)));
8495 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8496 : }
8497 : }
8498 :
8499 : // Resistive Defrost Heater Capacity = capacity at the first stage
8500 : // Sizing defrost heater capacity
8501 22 : IsAutoSize = false;
8502 22 : if (thisDXCoil.DefrostCapacity == AutoSize) {
8503 8 : IsAutoSize = true;
8504 : }
8505 22 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
8506 0 : DefrostCapacityDes = thisDXCoil.MSRatedTotCap(1);
8507 : } else {
8508 22 : DefrostCapacityDes = 0.0;
8509 : }
8510 22 : if (IsAutoSize) {
8511 8 : thisDXCoil.DefrostCapacity = DefrostCapacityDes;
8512 8 : BaseSizer::reportSizerOutput(
8513 : state, thisDXCoil.DXCoilType, thisDXCoil.Name, "Design Size Resistive Defrost Heater Capacity", DefrostCapacityDes);
8514 : } else {
8515 14 : if (thisDXCoil.DefrostCapacity > 0.0 && DefrostCapacityDes > 0.0 && !HardSizeNoDesRun) {
8516 0 : DefrostCapacityUser = thisDXCoil.DefrostCapacity;
8517 0 : BaseSizer::reportSizerOutput(state,
8518 : thisDXCoil.DXCoilType,
8519 : thisDXCoil.Name,
8520 : "Design Size Resistive Defrost Heater Capacity",
8521 : DefrostCapacityDes,
8522 : "User-Specified Resistive Defrost Heater Capacity",
8523 : DefrostCapacityUser);
8524 0 : if (state.dataGlobal->DisplayExtraWarnings) {
8525 0 : if ((std::abs(DefrostCapacityDes - DefrostCapacityUser) / DefrostCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8526 0 : ShowWarningMessage(
8527 0 : state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
8528 0 : ShowContinueError(state, format("User-Specified Resistive Defrost Heater Capacity of {:.2R}[W]", DefrostCapacityUser));
8529 0 : ShowContinueError(state,
8530 0 : format("differs from Design Size Resistive Defrost Heater Capacity of {:.2R}[W]", DefrostCapacityDes));
8531 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8532 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8533 : }
8534 : }
8535 : }
8536 : }
8537 : }
8538 :
8539 : // Call routine that computes AHRI certified rating for single-speed DX Coils
8540 2596 : if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed &&
8541 612 : (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air ||
8542 1984 : thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap)) ||
8543 380 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
8544 1374 : CalcDXCoilStandardRating(state,
8545 687 : thisDXCoil.Name,
8546 687 : thisDXCoil.DXCoilType,
8547 : thisDXCoil.DXCoilType_Num,
8548 : 1,
8549 687 : thisDXCoil.RatedTotCap(1),
8550 687 : thisDXCoil.RatedCOP(1),
8551 687 : thisDXCoil.CCapFFlow(1),
8552 687 : thisDXCoil.CCapFTemp(1),
8553 687 : thisDXCoil.EIRFFlow(1),
8554 687 : thisDXCoil.EIRFTemp(1),
8555 687 : thisDXCoil.PLFFPLR(1),
8556 687 : thisDXCoil.RatedAirVolFlowRate(1),
8557 687 : thisDXCoil.FanPowerPerEvapAirFlowRate(1),
8558 687 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1),
8559 687 : thisDXCoil.CondenserType,
8560 687 : thisDXCoil.RegionNum,
8561 687 : thisDXCoil.MinOATCompressor,
8562 687 : thisDXCoil.OATempCompressorOn,
8563 687 : thisDXCoil.OATempCompressorOnOffBlank,
8564 687 : thisDXCoil.DefrostControl,
8565 687 : thisDXCoil.ASHRAE127StdRprt);
8566 : }
8567 : // Call routine that computes AHRI certified rating for multi-speed DX cooling Coils
8568 992 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
8569 284 : CalcDXCoilStandardRating(state,
8570 71 : thisDXCoil.Name,
8571 71 : thisDXCoil.DXCoilType,
8572 : thisDXCoil.DXCoilType_Num,
8573 : thisDXCoil.NumOfSpeeds,
8574 : thisDXCoil.MSRatedTotCap,
8575 : thisDXCoil.MSRatedCOP,
8576 : thisDXCoil.MSCCapFFlow,
8577 : thisDXCoil.MSCCapFTemp,
8578 : thisDXCoil.MSEIRFFlow,
8579 : thisDXCoil.MSEIRFTemp,
8580 : thisDXCoil.MSPLFFPLR,
8581 : thisDXCoil.MSRatedAirVolFlowRate,
8582 : thisDXCoil.MSFanPowerPerEvapAirFlowRate,
8583 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023,
8584 71 : thisDXCoil.CondenserType,
8585 71 : thisDXCoil.RegionNum,
8586 71 : thisDXCoil.MinOATCompressor,
8587 71 : thisDXCoil.OATempCompressorOn,
8588 71 : thisDXCoil.OATempCompressorOnOffBlank,
8589 71 : thisDXCoil.DefrostControl,
8590 142 : ObjexxFCL::Optional_bool_const());
8591 : }
8592 :
8593 993 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed && (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air ||
8594 1 : thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap)) {
8595 134 : StandardRatings::CalcTwoSpeedDXCoilRating(state,
8596 67 : thisDXCoil.Name,
8597 67 : thisDXCoil.DXCoilType,
8598 : thisDXCoil.DXCoilType_Num,
8599 : thisDXCoil.RatedTotCap,
8600 : thisDXCoil.RatedTotCap2,
8601 : thisDXCoil.RatedCOP,
8602 : thisDXCoil.RatedCOP2,
8603 : thisDXCoil.CCapFFlow, // High Speed
8604 : thisDXCoil.CCapFTemp,
8605 : thisDXCoil.CCapFTemp2,
8606 : thisDXCoil.EIRFFlow, // High Speed
8607 : thisDXCoil.EIRFTemp,
8608 : thisDXCoil.EIRFTemp2,
8609 : thisDXCoil.RatedAirVolFlowRate,
8610 : thisDXCoil.RatedAirVolFlowRate2,
8611 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023,
8612 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023_LowSpeed,
8613 67 : thisDXCoil.CondenserType,
8614 67 : thisDXCoil.PLFFPLR(1));
8615 : }
8616 :
8617 : // create predefined report entries
8618 992 : equipName = thisDXCoil.Name;
8619 : // put tables for cooling and heating separate
8620 992 : switch (thisDXCoil.DXCoilType_Num) {
8621 739 : case HVAC::CoilDX_CoolingSingleSpeed:
8622 : case HVAC::CoilDX_CoolingTwoSpeed:
8623 : case HVAC::CoilDX_CoolingTwoStageWHumControl:
8624 : case HVAC::CoilDX_MultiSpeedCooling: {
8625 739 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilType, equipName, thisDXCoil.DXCoilType);
8626 739 : if (thisDXCoil.NumOfSpeeds == 0) {
8627 690 : if (thisDXCoil.NumCapacityStages == 1) {
8628 680 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.RatedTotCap(1));
8629 1360 : PreDefTableEntry(
8630 680 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1));
8631 1360 : PreDefTableEntry(state,
8632 680 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
8633 : equipName,
8634 680 : thisDXCoil.RatedTotCap(1) - thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1));
8635 680 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.RatedSHR(1));
8636 680 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.RatedCOP(1));
8637 : } else {
8638 10 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.RatedTotCap(2));
8639 20 : PreDefTableEntry(
8640 10 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.RatedTotCap(2) * thisDXCoil.RatedSHR(2));
8641 20 : PreDefTableEntry(state,
8642 10 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
8643 : equipName,
8644 10 : thisDXCoil.RatedTotCap(2) - thisDXCoil.RatedTotCap(2) * thisDXCoil.RatedSHR(2));
8645 10 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.RatedSHR(2));
8646 10 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.RatedCOP(2));
8647 : }
8648 : } else {
8649 162 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8650 113 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.MSRatedTotCap(Mode));
8651 226 : PreDefTableEntry(
8652 113 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.MSRatedTotCap(Mode) * thisDXCoil.MSRatedSHR(Mode));
8653 226 : PreDefTableEntry(state,
8654 113 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
8655 : equipName,
8656 113 : thisDXCoil.MSRatedTotCap(Mode) - thisDXCoil.MSRatedTotCap(Mode) * thisDXCoil.MSRatedSHR(Mode));
8657 113 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.MSRatedSHR(Mode));
8658 113 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.MSRatedCOP(Mode));
8659 : }
8660 : }
8661 1478 : addFootNoteSubTable(state,
8662 739 : state.dataOutRptPredefined->pdstCoolCoil,
8663 : "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
8664 739 : } break;
8665 129 : case HVAC::CoilDX_HeatingEmpirical:
8666 : case HVAC::CoilDX_MultiSpeedHeating:
8667 : case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
8668 : case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
8669 129 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilType, equipName, thisDXCoil.DXCoilType);
8670 129 : if (thisDXCoil.NumOfSpeeds == 0) {
8671 107 : if (thisDXCoil.NumCapacityStages == 1) {
8672 107 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.RatedTotCap(1));
8673 107 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.RatedCOP(1));
8674 : } else {
8675 0 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.RatedTotCap(2));
8676 0 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.RatedCOP(2));
8677 : }
8678 : } else {
8679 92 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8680 70 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.MSRatedTotCap(Mode));
8681 70 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.MSRatedCOP(Mode));
8682 : }
8683 : }
8684 258 : addFootNoteSubTable(state,
8685 129 : state.dataOutRptPredefined->pdstHeatCoil,
8686 : "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
8687 :
8688 : // std 229 existing table DX Heating coil new reporting variables
8689 258 : OutputReportPredefined::PreDefTableEntry(
8690 129 : state, state.dataOutRptPredefined->pdchDXHeatCoilMinOADBTforCompOp, equipName, thisDXCoil.MinOATCompressor);
8691 258 : OutputReportPredefined::PreDefTableEntry(state,
8692 129 : state.dataOutRptPredefined->pdchDXHeatCoilAirloopName,
8693 : equipName,
8694 258 : thisDXCoil.AirLoopNum > 0 ? state.dataAirSystemsData->PrimaryAirSystems(thisDXCoil.AirLoopNum).Name
8695 : : "N/A");
8696 : // std 229 existing table DX Heating coil 2023 AHRI new reporting variables
8697 258 : OutputReportPredefined::PreDefTableEntry(
8698 129 : state, state.dataOutRptPredefined->pdchDXHeatCoilMinOADBTforCompOp_2023, equipName, thisDXCoil.MinOATCompressor);
8699 258 : OutputReportPredefined::PreDefTableEntry(state,
8700 129 : state.dataOutRptPredefined->pdchDXHeatCoilAirloopName_2023,
8701 : equipName,
8702 258 : thisDXCoil.AirLoopNum > 0 ? state.dataAirSystemsData->PrimaryAirSystems(thisDXCoil.AirLoopNum).Name
8703 : : "N/A");
8704 129 : } break;
8705 124 : default:
8706 124 : break;
8707 : }
8708 992 : }
8709 :
8710 1098657 : void CalcHPWHDXCoil(EnergyPlusData &state,
8711 : int const DXCoilNum, // the number of the DX coil to be simulated
8712 : Real64 const PartLoadRatio // sensible water heating load / full load sensible water heating capacity
8713 : )
8714 : {
8715 :
8716 : // SUBROUTINE INFORMATION:
8717 : // AUTHOR Richard Raustad
8718 : // DATE WRITTEN May 2005
8719 :
8720 : // PURPOSE OF THIS SUBROUTINE:
8721 : // Calculates the gross cooling capacity of a heat pump water heater evaporator and
8722 : // heating capacity of the condenser coil given the rated heating capacity and COP.
8723 :
8724 : // METHODOLOGY EMPLOYED:
8725 : // The routine requires the user to enter the total heating capacity and COP for the
8726 : // heat pump water heater along with logicals defining if fan and condenser pump are included.
8727 : // Since manufacturer's can rate their HPWH equipment with or without including condenser
8728 : // pump heat, this information is required to accurately determine the condenser's leaving
8729 : // water temperature. In addition, knowledge of the fan heat is required to back into
8730 : // a compressor COP.
8731 :
8732 : // Using/Aliasing
8733 : using Curve::CurveValue;
8734 :
8735 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8736 : Real64 RatedHeatingCapacity; // Water heating rated capacity with or without condenser water pump heat (W)
8737 : Real64 RatedHeatingCOP; // Water heating rated COP with or without evap fan and cond water pump heat (W/W)
8738 : Real64 OperatingHeatingCapacity; // Water heating operating capacity including the impact of capacity and COP curves (W)
8739 : Real64 OperatingHeatingCOP; // Water heating operating COP including the impact of capacity and COP curves (W/W)
8740 : Real64 OperatingHeatingPower; // Water heating operating Power (W)
8741 : Real64 CompressorPower; // Power consumed by compressor only (W)
8742 :
8743 : Real64 TotalTankHeatingCapacity; // Water heating capacity corrected for condenser water pump heat (W)
8744 : Real64 TankHeatingCOP; // Water heating COP corrected for fan and condenser water pump power (W/W)
8745 : // (these previous 2 variables also include the impact of capacity and COP curves)
8746 : Real64 EvapCoolingCapacity; // Air cooling capacity corrected for evap fan and cond water pump heat (W)
8747 : Real64 InletWaterTemp; // Condenser water inlet temperature (C)
8748 : Real64 OutletWaterTemp; // Condenser water outlet temperature (C)
8749 : Real64 EvapInletMassFlowRate; // Evaporator air inlet mass flow rate (m3/s)
8750 : Real64 CondInletMassFlowRate; // Condenser water inlet mass flow rate (m3/s)
8751 : Real64 CpWater; // Specific heat of condenser inlet water (J/Kg/k)
8752 : Real64 InletAirTemp; // HPWH inlet air temperature (dry-bulb or wet-bulb) (C)
8753 : Real64 HeatCapFTemp; // Output of HPWH Heating Capacity as a Function of Temperature curve
8754 : Real64 HeatCapFAirFlow; // Output of HPWH Heating Capacity as a Function of Air Flow Rate Ratio curve
8755 : Real64 HeatCapFWaterFlow; // Output of HPWH Heating Capacity as a Function of Water Flow Rate Ratio curve
8756 : Real64 HeatCOPFTemp; // Output of HPWH COP as a Function of Temperature curve
8757 : Real64 HeatCOPFAirFlow; // Output of HPWH COP as a Function of Air Flow Rate Ratio curve
8758 : Real64 HeatCOPFWaterFlow; // Output of HPWH COP as a Function of Water Flow Rate Ratio curve
8759 : Real64 AirFlowRateRatio; // Ratio of evaporator inlet air mass flow rate to rated mass flow rate
8760 : Real64 WaterFlowRateRatio; // Ratio of evaporator inlet water mass flow rate to rated mass flow rate
8761 : Real64 PartLoadFraction; // Output of Part Load Fraction as a Function of Part Load Ratio curve
8762 : Real64 PumpHeatToWater; // Amount of pump heat attributed to heating water
8763 : Real64 HPRTF; // Heat pump run time fraction
8764 :
8765 : // References to Coil and Node struct
8766 1098657 : DXCoilData &Coil = state.dataDXCoils->DXCoil(DXCoilNum);
8767 1098657 : NodeData &AirInletNode = state.dataLoopNodes->Node(Coil.AirInNode);
8768 1098657 : NodeData &WaterInletNode = state.dataLoopNodes->Node(Coil.WaterInNode);
8769 1098657 : NodeData &WaterOutletNode = state.dataLoopNodes->Node(Coil.WaterOutNode);
8770 :
8771 : // If heat pump water heater is OFF, set outlet to inlet and RETURN
8772 : // Also set the heating energy rate to zero
8773 1098657 : if (PartLoadRatio == 0.0) {
8774 358458 : WaterOutletNode = WaterInletNode;
8775 358458 : Coil.TotalHeatingEnergyRate = 0.0;
8776 358458 : return;
8777 : } else {
8778 740199 : RatedHeatingCapacity = Coil.RatedTotCap2;
8779 740199 : RatedHeatingCOP = Coil.RatedCOP(1);
8780 740199 : InletWaterTemp = WaterInletNode.Temp;
8781 740199 : CondInletMassFlowRate = WaterInletNode.MassFlowRate / PartLoadRatio;
8782 740199 : EvapInletMassFlowRate = AirInletNode.MassFlowRate / PartLoadRatio;
8783 740199 : CpWater = CPHW(InletWaterTemp);
8784 740199 : CompressorPower = 0.0;
8785 740199 : OperatingHeatingPower = 0.0;
8786 740199 : TankHeatingCOP = 0.0;
8787 : }
8788 :
8789 : // determine inlet air temperature type for curve objects
8790 740199 : if (Coil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
8791 740199 : InletAirTemp = state.dataHVACGlobal->HPWHInletWBTemp;
8792 : } else {
8793 0 : InletAirTemp = state.dataHVACGlobal->HPWHInletDBTemp;
8794 : }
8795 :
8796 : // get output of Heating Capacity and Heating COP curves (curves default to 1 if user has not specified curve name)
8797 740199 : if (Coil.HCapFTemp > 0) {
8798 740199 : if (state.dataCurveManager->PerfCurve(Coil.HCapFTemp)->numDims == 1) {
8799 0 : HeatCapFTemp = CurveValue(state, Coil.HCapFTemp, InletAirTemp);
8800 : } else {
8801 740199 : HeatCapFTemp = CurveValue(state, Coil.HCapFTemp, InletAirTemp, InletWaterTemp);
8802 : }
8803 : // Warn user if curve output goes negative
8804 740199 : if (HeatCapFTemp < 0.0) {
8805 0 : if (Coil.HCapFTempErrorIndex == 0) {
8806 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8807 0 : ShowContinueError(
8808 0 : state, format(" HPWH Heating Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", HeatCapFTemp));
8809 0 : if (state.dataCurveManager->PerfCurve(Coil.HCapFTemp)->numDims == 2) {
8810 0 : ShowContinueError(
8811 : state,
8812 0 : format(" Negative value occurs using an inlet air temperature of {:.1T} and an inlet water temperature of {:.1T}.",
8813 : InletAirTemp,
8814 : InletWaterTemp));
8815 : } else {
8816 0 : ShowContinueError(state, format(" Negative value occurs using an inlet air temperature of {:.1T}.", InletAirTemp));
8817 : }
8818 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8819 : }
8820 0 : ShowRecurringWarningErrorAtEnd(
8821 : state,
8822 0 : Coil.DXCoilType + " \"" + Coil.Name +
8823 : "\": HPWH Heating Capacity Modifier curve (function of temperature) output is negative warning continues...",
8824 0 : Coil.HCapFTempErrorIndex,
8825 : HeatCapFTemp,
8826 : HeatCapFTemp,
8827 : _,
8828 : "[C]",
8829 : "[C]");
8830 0 : HeatCapFTemp = 0.0;
8831 : }
8832 : } else {
8833 0 : HeatCapFTemp = 1.0;
8834 : }
8835 :
8836 740199 : if (Coil.HCOPFTemp > 0) {
8837 740199 : if (state.dataCurveManager->PerfCurve(Coil.HCOPFTemp)->numDims == 1) {
8838 0 : HeatCOPFTemp = CurveValue(state, Coil.HCOPFTemp, InletAirTemp);
8839 : } else {
8840 740199 : HeatCOPFTemp = CurveValue(state, Coil.HCOPFTemp, InletAirTemp, InletWaterTemp);
8841 : }
8842 : // Warn user if curve output goes negative
8843 740199 : if (HeatCOPFTemp < 0.0) {
8844 0 : if (Coil.HCOPFTempErrorIndex == 0) {
8845 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8846 0 : ShowContinueError(state,
8847 0 : format(" HPWH Heating COP Modifier curve (function of temperature) output is negative ({:.3T}).", HeatCOPFTemp));
8848 0 : if (state.dataCurveManager->PerfCurve(Coil.HCOPFTemp)->numDims == 2) {
8849 0 : ShowContinueError(
8850 : state,
8851 0 : format(" Negative value occurs using an inlet air temperature of {:.1T} and an inlet water temperature of {:.1T}.",
8852 : InletAirTemp,
8853 : InletWaterTemp));
8854 : } else {
8855 0 : ShowContinueError(state, format(" Negative value occurs using an inlet air temperature of {:.1T}.", InletAirTemp));
8856 : }
8857 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8858 : }
8859 0 : ShowRecurringWarningErrorAtEnd(
8860 : state,
8861 0 : Coil.DXCoilType + " \"" + Coil.Name +
8862 : "\": HPWH Heating COP Modifier curve (function of temperature) output is negative warning continues...",
8863 0 : Coil.HCOPFTempErrorIndex,
8864 : HeatCOPFTemp,
8865 : HeatCOPFTemp,
8866 : _,
8867 : "[C]",
8868 : "[C]");
8869 0 : HeatCOPFTemp = 0.0;
8870 : }
8871 : } else {
8872 0 : HeatCOPFTemp = 1.0;
8873 : }
8874 :
8875 740199 : if (Coil.HCapFAirFlow > 0) {
8876 0 : AirFlowRateRatio = EvapInletMassFlowRate / (Coil.RatedAirMassFlowRate(1));
8877 0 : HeatCapFAirFlow = CurveValue(state, Coil.HCapFAirFlow, AirFlowRateRatio);
8878 : // Warn user if curve output goes negative
8879 0 : if (HeatCapFAirFlow < 0.0) {
8880 0 : if (Coil.HCapFAirFlowErrorIndex == 0) {
8881 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8882 0 : ShowContinueError(
8883 : state,
8884 0 : format(" HPWH Heating Capacity Modifier curve (function of air flow fraction) output is negative ({:.3T}).", HeatCapFAirFlow));
8885 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirFlowRateRatio));
8886 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8887 : }
8888 0 : ShowRecurringWarningErrorAtEnd(
8889 : state,
8890 0 : Coil.DXCoilType + " \"" + Coil.Name +
8891 : "\": HPWH Heating Capacity Modifier curve (function of air flow fraction) output is negative warning continues...",
8892 0 : Coil.HCapFAirFlowErrorIndex,
8893 : HeatCapFAirFlow,
8894 : HeatCapFAirFlow);
8895 0 : HeatCapFAirFlow = 0.0;
8896 : }
8897 : } else {
8898 740199 : HeatCapFAirFlow = 1.0;
8899 : }
8900 :
8901 740199 : if (Coil.HCOPFAirFlow > 0) {
8902 0 : AirFlowRateRatio = EvapInletMassFlowRate / (Coil.RatedAirMassFlowRate(1));
8903 0 : HeatCOPFAirFlow = CurveValue(state, Coil.HCOPFAirFlow, AirFlowRateRatio);
8904 : // Warn user if curve output goes negative
8905 0 : if (HeatCOPFAirFlow < 0.0) {
8906 0 : if (Coil.HCOPFAirFlowErrorIndex == 0) {
8907 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8908 0 : ShowContinueError(
8909 0 : state, format(" HPWH Heating COP Modifier curve (function of air flow fraction) output is negative ({:.3T}).", HeatCOPFAirFlow));
8910 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirFlowRateRatio));
8911 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8912 : }
8913 0 : ShowRecurringWarningErrorAtEnd(
8914 : state,
8915 0 : Coil.DXCoilType + " \"" + Coil.Name +
8916 : "\": HPWH Heating COP Modifier curve (function of air flow fraction) output is negative warning continues...",
8917 0 : Coil.HCOPFAirFlowErrorIndex,
8918 : HeatCOPFAirFlow,
8919 : HeatCOPFAirFlow);
8920 0 : HeatCOPFAirFlow = 0.0;
8921 : }
8922 : } else {
8923 740199 : HeatCOPFAirFlow = 1.0;
8924 : }
8925 :
8926 740199 : if (Coil.HCapFWaterFlow > 0) {
8927 0 : WaterFlowRateRatio = CondInletMassFlowRate / (Coil.RatedHPWHCondWaterFlow * RhoH2O(InletWaterTemp));
8928 0 : HeatCapFWaterFlow = CurveValue(state, Coil.HCapFWaterFlow, WaterFlowRateRatio);
8929 : // Warn user if curve output goes negative
8930 0 : if (HeatCapFWaterFlow < 0.0) {
8931 0 : if (Coil.HCapFWaterFlowErrorIndex == 0) {
8932 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8933 0 : ShowContinueError(state,
8934 0 : format(" HPWH Heating Capacity Modifier curve (function of water flow fraction) output is negative ({:.3T}).",
8935 : HeatCapFWaterFlow));
8936 0 : ShowContinueError(state, format(" Negative value occurs using a water flow fraction of {:.3T}.", WaterFlowRateRatio));
8937 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8938 : }
8939 0 : ShowRecurringWarningErrorAtEnd(
8940 : state,
8941 0 : Coil.DXCoilType + " \"" + Coil.Name +
8942 : "\": HPWH Heating Capacity Modifier curve (function of water flow fraction) output is negative warning continues...",
8943 0 : Coil.HCapFWaterFlowErrorIndex,
8944 : HeatCapFWaterFlow,
8945 : HeatCapFWaterFlow);
8946 0 : HeatCapFWaterFlow = 0.0;
8947 : }
8948 : } else {
8949 740199 : HeatCapFWaterFlow = 1.0;
8950 : }
8951 :
8952 740199 : if (Coil.HCOPFWaterFlow > 0) {
8953 0 : WaterFlowRateRatio = CondInletMassFlowRate / (Coil.RatedHPWHCondWaterFlow * RhoH2O(InletWaterTemp));
8954 0 : HeatCOPFWaterFlow = CurveValue(state, Coil.HCOPFWaterFlow, WaterFlowRateRatio);
8955 : // Warn user if curve output goes negative
8956 0 : if (HeatCOPFWaterFlow < 0.0) {
8957 0 : if (Coil.HCOPFWaterFlowErrorIndex == 0) {
8958 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8959 0 : ShowContinueError(
8960 : state,
8961 0 : format(" HPWH Heating COP Modifier curve (function of water flow fraction) output is negative ({:.3T}).", HeatCOPFWaterFlow));
8962 0 : ShowContinueError(state, format(" Negative value occurs using a water flow fraction of {:.3T}.", WaterFlowRateRatio));
8963 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8964 : }
8965 0 : ShowRecurringWarningErrorAtEnd(
8966 : state,
8967 0 : Coil.DXCoilType + " \"" + Coil.Name +
8968 : "\": HPWH Heating COP Modifier curve (function of water flow fraction) output is negative warning continues...",
8969 0 : Coil.HCOPFWaterFlowErrorIndex,
8970 : HeatCOPFWaterFlow,
8971 : HeatCOPFWaterFlow);
8972 0 : HeatCOPFWaterFlow = 0.0;
8973 : }
8974 : } else {
8975 740199 : HeatCOPFWaterFlow = 1.0;
8976 : }
8977 :
8978 : // adjust Heating Capacity and COP for off-design conditions
8979 740199 : OperatingHeatingCapacity = RatedHeatingCapacity * HeatCapFTemp * HeatCapFAirFlow * HeatCapFWaterFlow;
8980 740199 : OperatingHeatingCOP = RatedHeatingCOP * HeatCOPFTemp * HeatCOPFAirFlow * HeatCOPFWaterFlow;
8981 :
8982 740199 : if (OperatingHeatingCOP > 0.0) OperatingHeatingPower = OperatingHeatingCapacity / OperatingHeatingCOP;
8983 :
8984 740199 : PumpHeatToWater = Coil.HPWHCondPumpElecNomPower * Coil.HPWHCondPumpFracToWater;
8985 740199 : TankHeatingCOP = OperatingHeatingCOP;
8986 :
8987 : // account for pump heat if not included in total water heating capacity
8988 740199 : if (Coil.CondPumpHeatInCapacity) {
8989 0 : TotalTankHeatingCapacity = OperatingHeatingCapacity;
8990 : } else {
8991 740199 : TotalTankHeatingCapacity = OperatingHeatingCapacity + PumpHeatToWater;
8992 : }
8993 :
8994 : // find part load fraction to calculate RTF
8995 740199 : if (Coil.PLFFPLR(1) > 0) {
8996 740199 : PartLoadFraction = max(0.7, CurveValue(state, Coil.PLFFPLR(1), PartLoadRatio));
8997 : } else {
8998 0 : PartLoadFraction = 1.0;
8999 : }
9000 :
9001 740199 : HPRTF = min(1.0, (PartLoadRatio / PartLoadFraction));
9002 :
9003 740199 : Real64 locFanElecPower = state.dataFans->fans(Coil.SupplyFanIndex)->totalPower;
9004 :
9005 : // calculate evaporator total cooling capacity
9006 740199 : if (HPRTF > 0.0) {
9007 740199 : if (Coil.FanPowerIncludedInCOP) {
9008 420988 : if (Coil.CondPumpPowerInCOP) {
9009 : // make sure fan power is full load fan power
9010 0 : CompressorPower = OperatingHeatingPower - locFanElecPower / HPRTF - Coil.HPWHCondPumpElecNomPower;
9011 0 : if (OperatingHeatingPower > 0.0) TankHeatingCOP = TotalTankHeatingCapacity / OperatingHeatingPower;
9012 : } else {
9013 420988 : CompressorPower = OperatingHeatingPower - locFanElecPower / HPRTF;
9014 420988 : if ((OperatingHeatingPower + Coil.HPWHCondPumpElecNomPower) > 0.0)
9015 420988 : TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + Coil.HPWHCondPumpElecNomPower);
9016 : }
9017 : } else {
9018 319211 : if (Coil.CondPumpPowerInCOP) {
9019 : // make sure fan power is full load fan power
9020 0 : CompressorPower = OperatingHeatingPower - Coil.HPWHCondPumpElecNomPower;
9021 0 : if ((OperatingHeatingPower + locFanElecPower / HPRTF) > 0.0)
9022 0 : TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + locFanElecPower / HPRTF);
9023 : } else {
9024 319211 : CompressorPower = OperatingHeatingPower;
9025 319211 : if ((OperatingHeatingPower + locFanElecPower / HPRTF + Coil.HPWHCondPumpElecNomPower) > 0.0)
9026 319211 : TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + locFanElecPower / HPRTF + Coil.HPWHCondPumpElecNomPower);
9027 : }
9028 : }
9029 : }
9030 :
9031 740199 : if (Coil.CondPumpHeatInCapacity) {
9032 0 : EvapCoolingCapacity = TotalTankHeatingCapacity - PumpHeatToWater - CompressorPower;
9033 : } else {
9034 740199 : EvapCoolingCapacity = TotalTankHeatingCapacity - CompressorPower;
9035 : }
9036 :
9037 : // set evaporator total cooling capacity prior to CalcDOE2DXCoil subroutine
9038 740199 : Coil.RatedTotCap(1) = EvapCoolingCapacity;
9039 :
9040 : // determine condenser water inlet/outlet condition at full capacity
9041 740199 : if (CondInletMassFlowRate == 0.0) {
9042 418529 : OutletWaterTemp = InletWaterTemp;
9043 : } else {
9044 321670 : OutletWaterTemp = InletWaterTemp + TotalTankHeatingCapacity / (CpWater * CondInletMassFlowRate);
9045 : }
9046 :
9047 740199 : WaterOutletNode.Temp = OutletWaterTemp;
9048 :
9049 740199 : WaterOutletNode.MassFlowRate = WaterInletNode.MassFlowRate;
9050 :
9051 : // send heating capacity and COP to water heater module for standards rating calculation
9052 : // total heating capacity including condenser pump
9053 740199 : state.dataDXCoils->HPWHHeatingCapacity = TotalTankHeatingCapacity;
9054 : // total heating COP including compressor, fan, and condenser pump
9055 740199 : state.dataDXCoils->HPWHHeatingCOP = TankHeatingCOP;
9056 :
9057 : // send DX coil total cooling capacity to HPWH for reporting
9058 740199 : state.dataHVACGlobal->DXCoilTotalCapacity = EvapCoolingCapacity;
9059 :
9060 740199 : Coil.TotalHeatingEnergyRate = TotalTankHeatingCapacity * PartLoadRatio;
9061 :
9062 : // calculate total compressor plus condenser pump power, fan power reported in fan module
9063 740199 : Coil.ElecWaterHeatingPower = (CompressorPower + Coil.HPWHCondPumpElecNomPower) * HPRTF;
9064 : }
9065 :
9066 39594393 : void CalcDoe2DXCoil(EnergyPlusData &state,
9067 : int const DXCoilNum, // the number of the DX coil to be simulated
9068 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
9069 : bool const FirstHVACIteration, // true if this is the first iteration of HVAC
9070 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
9071 : HVAC::FanOp const fanOp, // Allows parent object to control fan operation
9072 : ObjexxFCL::Optional_int_const PerfMode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
9073 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
9074 : ObjexxFCL::Optional<Real64 const> CoolingHeatingPLR // used for cycling fan RH control
9075 : )
9076 : {
9077 :
9078 : // SUBROUTINE INFORMATION:
9079 : // AUTHOR Fred Buhl
9080 : // DATE WRITTEN May 2000
9081 : // MODIFIED Shirey, Feb/October 2001, Feb/Mar 2004
9082 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
9083 : // Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
9084 : // April 2010 Chandan Sharma, FSEC, Added basin heater
9085 : // RE-ENGINEERED Don Shirey, Aug/Sept 2000
9086 :
9087 : // PURPOSE OF THIS SUBROUTINE:
9088 : // Calculates the air-side performance and electrical energy use of a direct-
9089 : // expansion, air-cooled cooling unit.
9090 :
9091 : // METHODOLOGY EMPLOYED:
9092 : // This routine simulates the performance of air-cooled DX cooling equipment.
9093 : // The routine requires the user to enter the total cooling capacity, sensible heat ratio,
9094 : // and COP for the unit at ARI 210/240 rating conditions (26.67C [80F] dry-bulb, 19.44C [67F]
9095 : // wet-bulb air entering the cooling coil, 35C [95F] dry-bulb air entering the outdoor
9096 : // condenser. Since different manufacturer's rate their equipment at different air flow rates,
9097 : // the supply air flow rate corresponding to the rated capacities and rated COP must also be
9098 : // entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information entered by
9099 : // the user should NOT include the thermal or electrical impacts of the supply air fan, as
9100 : // this is addressed by another module.
9101 :
9102 : // With the rated performance data entered by the user, the model employs some of the
9103 : // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
9104 : // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
9105 : // does NOT employ the exact same methodology to calculate performance as DOE-2, although
9106 : // some of the DOE-2 curve fits are employed by this model.
9107 :
9108 : // The model checks for coil dryout conditions, and adjusts the calculated performance
9109 : // appropriately.
9110 :
9111 : // REFERENCES:
9112 : // ASHRAE HVAC 2 Toolkit page 4-81.
9113 : // Henderson, H.I. Jr., K. Rengarajan and D.B. Shirey, III. 1992.The impact of comfort
9114 : // control on air conditioner energy use in humid climates. ASHRAE Transactions 98(2):
9115 : // 104-113.
9116 : // Henderson, H.I. Jr., Danny Parker and Y.J. Huang. 2000.Improving DOE-2's RESYS routine:
9117 : // User Defined Functions to Provide More Accurate Part Load Energy Use and Humidity
9118 : // Predictions. Proceedings of ACEEE Conference.
9119 :
9120 : // Using/Aliasing
9121 : using Curve::CurveValue;
9122 39594393 : Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
9123 39594393 : Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
9124 : using General::CreateSysTimeIntervalString;
9125 :
9126 : // SUBROUTINE PARAMETER DEFINITIONS:
9127 : static constexpr std::string_view RoutineName("CalcDoe2DXCoil: ");
9128 : static constexpr std::string_view calcDoe2DXCoil("CalcDoe2DXCoil");
9129 :
9130 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9131 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
9132 : Real64 AirMassFlowRatio; // Ratio of actual air mass flow to rated air mass flow (adjusted for bypass if any)
9133 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
9134 : // (average flow if cycling fan, full flow if constant fan)
9135 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
9136 : Real64 BypassFlowFraction; // Fraction of total flow which is bypassed around the cooling coil
9137 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
9138 : Real64 TotCapTempModFac; // Total capacity modifier (function of entering wetbulb, outside drybulb)
9139 : Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs rated flow)
9140 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
9141 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
9142 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
9143 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
9144 : Real64 InletAirHumRatTemp; // inlet air humidity ratio used in ADP/BF loop [kg/kg]
9145 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9146 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
9147 : Real64 RatedCBF; // coil bypass factor at rated conditions
9148 : Real64 SHR; // Sensible Heat Ratio (sensible/total) of the cooling coil
9149 : Real64 CBF; // coil bypass factor at off rated conditions
9150 : Real64 A0; // NTU * air mass flow rate, used in CBF calculation
9151 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
9152 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
9153 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
9154 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
9155 : Real64 tADP; // Apparatus dew point temperature [C]
9156 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
9157 : Real64 FullLoadOutAirEnth; // outlet full load enthalpy [J/kg]
9158 : Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
9159 : Real64 FullLoadOutAirTemp; // outlet air temperature at full load [C]
9160 : Real64 EIRTempModFac; // EIR modifier (function of entering wetbulb, outside drybulb)
9161 : Real64 EIRFlowModFac; // EIR modifier (function of actual supply air flow vs rated flow)
9162 : Real64 EIR; // EIR at part load and off rated conditions
9163 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
9164 : Real64 QLatActual; // operating latent capacity of DX coil
9165 : Real64 QLatRated; // Rated latent capacity of DX coil
9166 : Real64 SHRUnadjusted; // SHR prior to latent degradation effective SHR calculation
9167 : int Counter; // Counter for dry evaporator iterations
9168 : int MaxIter; // Maximum number of iterations for dry evaporator calculations
9169 : Real64 RF; // Relaxation factor for dry evaporator iterations
9170 : Real64 Tolerance; // Error tolerance for dry evaporator iterations
9171 : Real64 werror; // Deviation of humidity ratio in dry evaporator iteration loop
9172 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
9173 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
9174 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
9175 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
9176 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
9177 : Real64 RhoAir; // Density of air [kg/m3]
9178 : Real64 RhoWater; // Density of water [kg/m3]
9179 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
9180 39594393 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
9181 : Real64 AirFlowRatio; // ratio of compressor on airflow to average timestep airflow
9182 : // used when constant fan mode yields different air flow rates when compressor is ON and OFF
9183 : // (e.g. Packaged Terminal Heat Pump)
9184 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
9185 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
9186 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
9187 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
9188 :
9189 : int Mode; // Performance mode for Multimode DX coil; Always 1 for other coil types
9190 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
9191 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
9192 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
9193 : Real64 ADiff; // Used for exponential
9194 : Real64 DXcoolToHeatPLRRatio; // ratio of cooling PLR to heating PLR, used for cycling fan RH control
9195 : Real64 HeatRTF; // heating coil part-load ratio, used for cycling fan RH control
9196 : Real64 HeatingCoilPLF; // heating coil PLF (function of PLR), used for cycling fan RH control
9197 :
9198 39594393 : auto &DXCT = state.dataHVACGlobal->DXCT;
9199 :
9200 : // If Performance mode not present, then set to 1. Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
9201 39594393 : if (present(PerfMode)) {
9202 280657 : Mode = PerfMode;
9203 : } else {
9204 39313736 : Mode = 1;
9205 : }
9206 :
9207 : // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
9208 : // during cooling and when no cooling is required (constant fan, fan speed changes)
9209 39594393 : if (present(OnOffAirFlowRatio)) {
9210 36196796 : AirFlowRatio = OnOffAirFlowRatio;
9211 : } else {
9212 3397597 : AirFlowRatio = 1.0;
9213 : }
9214 :
9215 : // If CoolingHeatingPLR not present, then set to 1. Used for cycling fan systems where
9216 : // heating PLR is greater than cooling PLR, otherwise CoolingHeatingPLR = 1.
9217 39594393 : if (present(CoolingHeatingPLR)) {
9218 30229503 : DXcoolToHeatPLRRatio = CoolingHeatingPLR;
9219 : } else {
9220 9364890 : DXcoolToHeatPLRRatio = 1.0;
9221 : }
9222 :
9223 39594393 : MaxIter = 30;
9224 39594393 : RF = 0.4;
9225 39594393 : Counter = 0;
9226 39594393 : Tolerance = 0.01;
9227 39594393 : CondInletTemp = 0.0;
9228 39594393 : CondInletHumRat = 0.0;
9229 :
9230 39594393 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
9231 :
9232 39594393 : BypassFlowFraction = thisDXCoil.BypassedFlowFrac(Mode);
9233 39594393 : AirMassFlow = thisDXCoil.InletAirMassFlowRate * (1.0 - BypassFlowFraction);
9234 39594393 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
9235 39594393 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
9236 39594393 : InletAirHumRat = thisDXCoil.InletAirHumRat;
9237 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9238 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
9239 39594393 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
9240 39594393 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
9241 39594393 : thisDXCoil.PartLoadRatio = 0.0;
9242 39594393 : thisDXCoil.BasinHeaterPower = 0.0;
9243 :
9244 39594393 : if (thisDXCoil.CondenserType(Mode) != DataHeatBalance::RefrigCondenserType::WaterHeater) {
9245 38962549 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
9246 8600936 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
9247 : // If node is not connected to anything, pressure = default, use weather data
9248 8600936 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
9249 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
9250 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
9251 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9252 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
9253 : } else {
9254 8600936 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
9255 8600936 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
9256 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
9257 8600936 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
9258 : }
9259 : } else {
9260 30361613 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
9261 30361613 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
9262 30361613 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9263 30361613 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
9264 : }
9265 38962549 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
9266 81926 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
9267 81926 : OutdoorDryBulb = secZoneHB.ZT;
9268 81926 : OutdoorHumRat = secZoneHB.airHumRat;
9269 81926 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
9270 81926 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9271 : }
9272 : } else {
9273 631844 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
9274 631844 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
9275 : // If node is not connected to anything, pressure = default, use weather data
9276 631844 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press)
9277 390 : OutdoorPressure = state.dataEnvrn->OutBaroPress; // node not connected
9278 : } else {
9279 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9280 : }
9281 : }
9282 :
9283 39594393 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
9284 38850193 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
9285 38850193 : CompAmbTemp = OutdoorDryBulb;
9286 38850193 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
9287 81926 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
9288 81926 : CondInletTemp = secZoneHB.ZT;
9289 81926 : CompAmbTemp = CondInletTemp; // assumes compressor is in same location as secondary coil
9290 81926 : OutdoorDryBulb = CondInletTemp;
9291 81926 : OutdoorHumRat = secZoneHB.airHumRat;
9292 81926 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
9293 81926 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9294 : }
9295 744200 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
9296 112356 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
9297 112356 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
9298 : // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
9299 112356 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
9300 112356 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
9301 112356 : CompAmbTemp = OutdoorDryBulb;
9302 631844 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::WaterHeater) {
9303 631844 : CompAmbTemp = state.dataHVACGlobal->HPWHCrankcaseDBTemp; // Temperature at HP water heater compressor
9304 631844 : CondInletTemp = state.dataHVACGlobal->HPWHCrankcaseDBTemp; // Temperature at HP water heater compressor
9305 : }
9306 :
9307 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
9308 : // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
9309 39594393 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
9310 15293395 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
9311 15293395 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
9312 56165 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
9313 : }
9314 : } else {
9315 24300998 : CrankcaseHeatingPower = 0.0;
9316 : }
9317 :
9318 : // calculate end time of current time step to determine if error messages should be printed
9319 39594393 : state.dataDXCoils->CurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
9320 :
9321 : // Print warning messages only when valid and only for the first ocurrance. Let summary provide statistics.
9322 : // Wait for next time step to print warnings. If simulation iterates, print out
9323 : // the warning for the last iteration only. Must wait for next time step to accomplish this.
9324 : // If a warning occurs and the simulation down shifts, the warning is not valid.
9325 :
9326 39594393 : if (thisDXCoil.PrintLowAmbMessage) { // .AND. &
9327 5852 : if (state.dataDXCoils->CurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
9328 650 : if (thisDXCoil.LowAmbErrIndex == 0) {
9329 10 : ShowWarningMessage(state, format("{}{}", RoutineName, thisDXCoil.LowAmbBuffer1));
9330 10 : ShowContinueError(state, thisDXCoil.LowAmbBuffer2);
9331 10 : ShowContinueError(state, "... Operation at low ambient temperatures may require special performance curves.");
9332 : }
9333 650 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
9334 1950 : ShowRecurringWarningErrorAtEnd(state,
9335 1300 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9336 : "\" - Low condenser dry-bulb temperature error continues...",
9337 650 : thisDXCoil.LowAmbErrIndex,
9338 650 : thisDXCoil.LowTempLast,
9339 650 : thisDXCoil.LowTempLast,
9340 : _,
9341 : "[C]",
9342 : "[C]");
9343 : } else {
9344 0 : ShowRecurringWarningErrorAtEnd(state,
9345 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9346 : "\" - Low condenser wet-bulb temperature error continues...",
9347 0 : thisDXCoil.LowAmbErrIndex,
9348 0 : thisDXCoil.LowTempLast,
9349 0 : thisDXCoil.LowTempLast,
9350 : _,
9351 : "[C]",
9352 : "[C]");
9353 : }
9354 : }
9355 : }
9356 :
9357 39594393 : if (thisDXCoil.PrintLowOutTempMessage) {
9358 4402 : if (state.dataDXCoils->CurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
9359 727 : if (thisDXCoil.LowOutletTempIndex == 0) {
9360 10 : ShowWarningMessage(state, format("{}{}", RoutineName, thisDXCoil.LowOutTempBuffer1));
9361 10 : ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
9362 10 : ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
9363 20 : ShowContinueError(state,
9364 20 : format(" 1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
9365 10 : thisDXCoil.FullLoadInletAirTempLast));
9366 10 : ShowContinueError(state, " 2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
9367 10 : ShowContinueError(state,
9368 : " 3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
9369 : }
9370 2181 : ShowRecurringWarningErrorAtEnd(state,
9371 1454 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9372 : "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
9373 : "Outlet air temperature statistics follow:",
9374 727 : thisDXCoil.LowOutletTempIndex,
9375 727 : thisDXCoil.FullLoadOutAirTempLast,
9376 727 : thisDXCoil.FullLoadOutAirTempLast);
9377 : }
9378 : }
9379 :
9380 : // save last system time step and last end time of current time step (used to determine if warning is valid)
9381 39594393 : thisDXCoil.TimeStepSysLast = TimeStepSys;
9382 39594393 : thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CurrentEndTime;
9383 39594393 : thisDXCoil.PrintLowAmbMessage = false;
9384 39594393 : thisDXCoil.PrintLowOutTempMessage = false;
9385 :
9386 71191939 : if ((AirMassFlow > 0.0) &&
9387 31597546 : (GetCurrentScheduleValue(state, thisDXCoil.SchedPtr) > 0.0 || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9388 309974 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
9389 86177814 : (PartLoadRatio > 0.0) && (compressorOp == HVAC::CompressorOp::On) &&
9390 14985875 : CompAmbTemp > thisDXCoil.MinOATCompressor) { // criteria for coil operation
9391 14985875 : if (fanOp == HVAC::FanOp::Cycling) {
9392 7430004 : AirMassFlow /= (PartLoadRatio / DXcoolToHeatPLRRatio);
9393 7555871 : } else if (fanOp == HVAC::FanOp::Continuous && thisDXCoil.DXCoilType_Num != HVAC::CoilDX_CoolingTwoSpeed) {
9394 7555871 : AirMassFlow *= AirFlowRatio;
9395 : } else {
9396 0 : AirMassFlow = thisDXCoil.RatedAirMassFlowRate(Mode);
9397 : }
9398 :
9399 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton)
9400 :
9401 : // for some reason there are diff's when using coil inlet air pressure
9402 : // these lines (more to follow) are commented out for the time being
9403 :
9404 14985875 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
9405 14985875 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
9406 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9407 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
9408 : // AirVolumeFlowRate = AirMassFlow/ PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
9409 14985875 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
9410 0 : ShowFatalError(
9411 0 : state, format("{}{}=\"{}\" - Rated total cooling capacity is zero or less.", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9412 : }
9413 14985875 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9414 14863772 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9415 273402 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap2;
9416 : } else {
9417 14712473 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
9418 : }
9419 9789732 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag && thisDXCoil.DXCoilType_Num != HVAC::CoilDX_HeatPumpWaterHeaterPumped &&
9420 26111713 : thisDXCoil.DXCoilType_Num != HVAC::CoilDX_HeatPumpWaterHeaterWrapped &&
9421 1336106 : ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
9422 1333620 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
9423 2486 : if (thisDXCoil.ErrIndex1 == 0) {
9424 6 : ShowWarningMessage(
9425 : state,
9426 6 : format("{}{}=\"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at {:.3R} m3/s/W.",
9427 : RoutineName,
9428 3 : thisDXCoil.DXCoilType,
9429 3 : thisDXCoil.Name,
9430 : VolFlowperRatedTotCap));
9431 3 : ShowContinueErrorTimeStamp(state, "");
9432 6 : ShowContinueError(state,
9433 6 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
9434 3 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
9435 3 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
9436 3 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components,");
9437 3 : ShowContinueError(state, "or variable air volume [VAV] system using incorrect coil type.");
9438 : }
9439 7458 : ShowRecurringWarningErrorAtEnd(
9440 : state,
9441 4972 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9442 : "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
9443 2486 : thisDXCoil.ErrIndex1,
9444 : VolFlowperRatedTotCap,
9445 : VolFlowperRatedTotCap);
9446 14983389 : } else if (!state.dataGlobal->WarmupFlag &&
9447 2140886 : (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9448 17164443 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
9449 58882 : ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
9450 58882 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
9451 29016 : if (thisDXCoil.ErrIndex1 == 0) {
9452 2 : ShowWarningMessage(
9453 : state,
9454 2 : format("{}{}=\"{}\" - Air volume flow rate per watt of rated total water heating capacity is out of range at {:.2R} m3/s/W.",
9455 : RoutineName,
9456 1 : thisDXCoil.DXCoilType,
9457 1 : thisDXCoil.Name,
9458 : VolFlowperRatedTotCap));
9459 1 : ShowContinueErrorTimeStamp(state, "");
9460 2 : ShowContinueError(state,
9461 2 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
9462 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
9463 1 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
9464 1 : ShowContinueError(state,
9465 : "Possible causes may be that the parent object is calling for an actual supply air flow rate that is much "
9466 : "higher or lower than the DX coil rated supply air flow rate.");
9467 : }
9468 87048 : ShowRecurringWarningErrorAtEnd(
9469 : state,
9470 58032 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9471 : "\" - Air volume flow rate per watt of rated total water heating capacity is out of range error continues...",
9472 29016 : thisDXCoil.ErrIndex1,
9473 : VolFlowperRatedTotCap,
9474 : VolFlowperRatedTotCap);
9475 : }
9476 : // Adjust coil bypass factor for actual air flow rate. Use relation CBF = exp(-NTU) where
9477 : // NTU = A0/(m*cp). Relationship models the cooling coil as a heat exchanger with Cmin/Cmax = 0.
9478 :
9479 14985875 : RatedCBF = thisDXCoil.RatedCBF(Mode);
9480 14985875 : if (RatedCBF > 0.0) {
9481 14985875 : A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
9482 : } else {
9483 0 : A0 = 0.0;
9484 : }
9485 14985875 : ADiff = -A0 / AirMassFlow;
9486 14985875 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
9487 14963247 : CBF = std::exp(ADiff);
9488 : } else {
9489 22628 : CBF = 0.0;
9490 : }
9491 :
9492 : // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
9493 14985875 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
9494 14667487 : if (OutdoorDryBulb < 0.0 && !state.dataGlobal->WarmupFlag) { // Same threshold as for air-cooled electric chiller
9495 5852 : thisDXCoil.PrintLowAmbMessage = true;
9496 5852 : thisDXCoil.LowTempLast = OutdoorDryBulb;
9497 5852 : if (thisDXCoil.LowAmbErrIndex == 0) {
9498 : thisDXCoil.LowAmbBuffer1 =
9499 244 : format("{} \"{}\" - Air-cooled condenser inlet dry-bulb temperature below 0 C. Outdoor dry-bulb temperature = {:.2R}",
9500 122 : thisDXCoil.DXCoilType,
9501 122 : thisDXCoil.Name,
9502 122 : OutdoorDryBulb);
9503 244 : thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
9504 366 : CreateSysTimeIntervalString(state);
9505 : }
9506 : }
9507 318388 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
9508 44986 : if (OutdoorWetBulb < 10.0 && !state.dataGlobal->WarmupFlag) { // Same threshold as for evap-cooled electric chiller
9509 0 : thisDXCoil.PrintLowAmbMessage = true;
9510 0 : thisDXCoil.LowTempLast = OutdoorWetBulb;
9511 0 : if (thisDXCoil.LowAmbErrIndex == 0) {
9512 : thisDXCoil.LowAmbBuffer1 =
9513 0 : format("{} \"{}\" - Evap-cooled condenser inlet wet-bulb temperature below 10 C. Outdoor wet-bulb temperature = {:.2R}",
9514 0 : thisDXCoil.DXCoilType,
9515 0 : thisDXCoil.Name,
9516 0 : OutdoorWetBulb);
9517 0 : thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
9518 0 : CreateSysTimeIntervalString(state);
9519 : }
9520 : }
9521 : }
9522 :
9523 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
9524 : // InletAirHumRat may be modified in this ADP/BF loop, use temporary varible for calculations
9525 14985875 : InletAirHumRatTemp = InletAirHumRat;
9526 14985875 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
9527 : while (true) {
9528 23920519 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9529 23798416 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9530 : // Coil:DX:HeatPumpWaterHeater does not have total cooling capacity as a function of temp or flow curve
9531 547615 : TotCapTempModFac = 1.0;
9532 547615 : TotCapFlowModFac = 1.0;
9533 : } else {
9534 23372904 : if (state.dataCurveManager->PerfCurve(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
9535 23372904 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC, CondInletTemp);
9536 : } else {
9537 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), CondInletTemp);
9538 : }
9539 :
9540 : // Warn user if curve output goes negative
9541 23372904 : if (TotCapTempModFac < 0.0) {
9542 0 : if (thisDXCoil.CCapFTempErrorIndex == 0) {
9543 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9544 0 : ShowContinueError(state,
9545 0 : format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).",
9546 : TotCapTempModFac));
9547 0 : if (state.dataCurveManager->PerfCurve(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
9548 0 : ShowContinueError(state,
9549 0 : format(" Negative value occurs using a condenser inlet air temperature of {:.1T} and an inlet air "
9550 : "wet-bulb temperature of {:.1T}.",
9551 : CondInletTemp,
9552 : InletAirWetBulbC));
9553 : } else {
9554 0 : ShowContinueError(state,
9555 0 : format(" Negative value occurs using a condenser inlet air temperature of {:.1T}.", CondInletTemp));
9556 : }
9557 0 : if (Mode > 1) {
9558 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
9559 : }
9560 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
9561 : }
9562 0 : ShowRecurringWarningErrorAtEnd(
9563 : state,
9564 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
9565 : "\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
9566 0 : thisDXCoil.CCapFTempErrorIndex,
9567 : TotCapTempModFac,
9568 : TotCapTempModFac);
9569 0 : TotCapTempModFac = 0.0;
9570 : }
9571 :
9572 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
9573 23372904 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
9574 : // Warn user if curve output goes negative
9575 23372904 : if (TotCapFlowModFac < 0.0) {
9576 0 : if (thisDXCoil.CCapFFlowErrorIndex == 0) {
9577 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9578 0 : ShowContinueError(state,
9579 0 : format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).",
9580 : TotCapFlowModFac));
9581 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
9582 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
9583 0 : if (Mode > 1) {
9584 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
9585 : }
9586 : }
9587 0 : ShowRecurringWarningErrorAtEnd(
9588 : state,
9589 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
9590 : "\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
9591 0 : thisDXCoil.CCapFFlowErrorIndex,
9592 : TotCapFlowModFac,
9593 : TotCapFlowModFac);
9594 0 : TotCapFlowModFac = 0.0;
9595 : }
9596 : }
9597 23920519 : TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
9598 : // if user specified SHR modifier curves are available calculate the SHR as follows:
9599 23920519 : if (thisDXCoil.UserSHRCurveExists) {
9600 0 : SHR = CalcSHRUserDefinedCurves(state,
9601 : InletAirDryBulbTemp,
9602 : InletAirWetBulbC,
9603 : AirMassFlowRatio,
9604 0 : thisDXCoil.SHRFTemp(Mode),
9605 0 : thisDXCoil.SHRFFlow(Mode),
9606 0 : thisDXCoil.RatedSHR(Mode));
9607 0 : hDelta = TotCap / AirMassFlow;
9608 0 : break;
9609 : } else {
9610 : // Calculate apparatus dew point conditions using TotCap and CBF
9611 23920519 : hDelta = TotCap / AirMassFlow;
9612 23920519 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
9613 23920519 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, calcDoe2DXCoil);
9614 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9615 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
9616 23920519 : wADP = PsyWFnTdbH(state, tADP, hADP, calcDoe2DXCoil);
9617 23920519 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
9618 23920519 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
9619 23920519 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
9620 : } else {
9621 0 : SHR = 1.0;
9622 : }
9623 : // Check for dry evaporator conditions (win < wadp)
9624 23920519 : if (wADP > InletAirHumRatTemp || (Counter >= 1 && Counter < MaxIter)) {
9625 11211526 : if (InletAirHumRatTemp == 0.0) InletAirHumRatTemp = 0.00001;
9626 11211526 : werror = (InletAirHumRatTemp - wADP) / InletAirHumRatTemp;
9627 : // Increase InletAirHumRatTemp at constant InletAirTemp to find coil dry-out point. Then use the
9628 : // capacity at the dry-out point to determine exiting conditions from coil. This is required
9629 : // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
9630 11211526 : InletAirHumRatTemp = RF * wADP + (1.0 - RF) * InletAirHumRatTemp;
9631 11211526 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRatTemp, OutdoorPressure);
9632 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment
9633 : // line InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRatTemp,InletAirPressure)
9634 11211526 : ++Counter;
9635 11211526 : if (std::abs(werror) > Tolerance) continue; // Recalculate with modified inlet conditions
9636 2276882 : break;
9637 : } else {
9638 : break;
9639 : }
9640 : }
9641 : } // end of DO iteration loop
9642 :
9643 14985875 : if (thisDXCoil.PLFFPLR(Mode) > 0) {
9644 14985875 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PartLoadRatio); // Calculate part-load factor
9645 : } else {
9646 0 : PLF = 1.0;
9647 : }
9648 :
9649 14985875 : if (PLF < 0.7) {
9650 0 : if (thisDXCoil.ErrIndex2 == 0) {
9651 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9652 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9653 0 : ShowWarningMessage(state, format("{}{}=\"{}\", PLF curve value", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9654 0 : ShowContinueError(state, format("The PLF curve value = {:.3T} for part-load ratio = {:.3T}", PLF, PartLoadRatio));
9655 0 : ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
9656 0 : ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
9657 : } else {
9658 0 : ShowWarningMessage(state, format("{}{}=\"{}\", PLF curve value", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9659 0 : ShowContinueError(state, format("The PLF curve value = {:.3T} for part-load ratio = {:.3T}", PLF, PartLoadRatio));
9660 0 : ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
9661 0 : ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
9662 : }
9663 : }
9664 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9665 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9666 0 : ShowRecurringWarningErrorAtEnd(
9667 0 : state, thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
9668 : } else {
9669 0 : ShowRecurringWarningErrorAtEnd(
9670 0 : state, thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
9671 : }
9672 0 : PLF = 0.7;
9673 : }
9674 :
9675 14985875 : thisDXCoil.PartLoadRatio = PartLoadRatio;
9676 14985875 : thisDXCoil.CoolingCoilRuntimeFraction = PartLoadRatio / PLF;
9677 14985875 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
9678 0 : if (thisDXCoil.ErrIndex3 == 0) {
9679 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9680 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9681 0 : ShowWarningMessage(state, format("{}{}=\"{}\", runtime fraction", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9682 0 : ShowWarningMessage(state, format("The runtime fraction exceeded 1.0. [{:.4R}].", thisDXCoil.CoolingCoilRuntimeFraction));
9683 0 : ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
9684 0 : ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
9685 0 : ShowContinueErrorTimeStamp(state, "");
9686 : } else {
9687 0 : ShowWarningMessage(state, format("{}{}=\"{}\", runtime fraction", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9688 0 : ShowWarningMessage(state, format("The runtime fraction exceeded 1.0. [{:.4R}].", thisDXCoil.CoolingCoilRuntimeFraction));
9689 0 : ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
9690 0 : ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
9691 0 : ShowContinueErrorTimeStamp(state, "");
9692 : }
9693 : }
9694 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9695 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9696 0 : ShowRecurringWarningErrorAtEnd(state,
9697 0 : thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " runtime fraction > 1.0 warning continues...",
9698 0 : thisDXCoil.ErrIndex3,
9699 0 : thisDXCoil.CoolingCoilRuntimeFraction,
9700 0 : thisDXCoil.CoolingCoilRuntimeFraction);
9701 : } else {
9702 0 : ShowRecurringWarningErrorAtEnd(state,
9703 0 : thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " runtime fraction > 1.0 warning continues...",
9704 0 : thisDXCoil.ErrIndex3,
9705 0 : thisDXCoil.CoolingCoilRuntimeFraction,
9706 0 : thisDXCoil.CoolingCoilRuntimeFraction);
9707 : }
9708 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
9709 14985875 : } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
9710 747051 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
9711 : }
9712 :
9713 : // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
9714 14985875 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
9715 :
9716 : // Calculate full load output conditions
9717 14985875 : if (thisDXCoil.UserSHRCurveExists) {
9718 0 : FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
9719 0 : if (SHR < 1.0) {
9720 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9721 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9722 0 : if (FullLoadOutAirHumRat <= 0.0) {
9723 0 : FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
9724 : }
9725 : } else {
9726 0 : SHR = 1.0;
9727 0 : FullLoadOutAirHumRat = InletAirHumRat;
9728 : }
9729 : } else {
9730 14985875 : if (SHR > 1.0 || Counter > 0) SHR = 1.0;
9731 14985875 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
9732 14985875 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9733 14985875 : if (SHR < 1.0) {
9734 12708993 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9735 : } else {
9736 2276882 : FullLoadOutAirHumRat = InletAirHumRat;
9737 : }
9738 : }
9739 14985875 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
9740 :
9741 : // Check for saturation error and modify temperature at constant enthalpy
9742 14985875 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure)) {
9743 225993 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
9744 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9745 : // IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
9746 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
9747 225993 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
9748 : }
9749 :
9750 : // Store actual outlet conditions when DX coil is ON for use in heat recovery module
9751 14985875 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = FullLoadOutAirTemp;
9752 14985875 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = FullLoadOutAirHumRat;
9753 :
9754 : // Add warning message for cold cooling coil (FullLoadOutAirTemp < 2 C)
9755 14985875 : if (FullLoadOutAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
9756 4406 : thisDXCoil.PrintLowOutTempMessage = true;
9757 4406 : thisDXCoil.FullLoadOutAirTempLast = FullLoadOutAirTemp;
9758 4406 : if (thisDXCoil.LowOutletTempIndex == 0) {
9759 75 : thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
9760 150 : thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
9761 : "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
9762 75 : thisDXCoil.DXCoilType,
9763 75 : thisDXCoil.Name,
9764 75 : FullLoadOutAirTemp);
9765 150 : thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
9766 225 : CreateSysTimeIntervalString(state);
9767 : }
9768 : }
9769 :
9770 : // If constant fan with cycling compressor, call function to determine "effective SHR"
9771 : // which includes the part-load degradation on latent capacity
9772 14985875 : if (fanOp == HVAC::FanOp::Continuous) {
9773 7555871 : QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode));
9774 7555871 : QLatActual = TotCap * (1.0 - SHR);
9775 7555871 : SHRUnadjusted = SHR;
9776 7555871 : SHR = CalcEffectiveSHR(
9777 : state, DXCoilNum, SHR, thisDXCoil.CoolingCoilRuntimeFraction, QLatRated, QLatActual, InletAirDryBulbTemp, InletAirWetBulbC, Mode);
9778 : // For multimode coil, if stage-2 operation (modes 2 or 4), adjust Stage1&2 SHR to account for
9779 : // Stage 1 operating at full load, so there is no degradation for that portion
9780 : // Use the stage 1 bypass fraction to allocate
9781 7555871 : if (Mode == 2 || Mode == 4) {
9782 98314 : SHR = SHRUnadjusted * (1.0 - thisDXCoil.BypassedFlowFrac(Mode - 1)) + SHR * thisDXCoil.BypassedFlowFrac(Mode - 1);
9783 : }
9784 :
9785 : // Calculate full load output conditions
9786 7555871 : if (thisDXCoil.UserSHRCurveExists) {
9787 0 : FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
9788 0 : if (SHR < 1.0) {
9789 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9790 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9791 0 : if (FullLoadOutAirHumRat <= 0.0) {
9792 0 : FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
9793 : }
9794 : } else {
9795 0 : SHR = 1.0;
9796 0 : FullLoadOutAirHumRat = InletAirHumRat;
9797 : }
9798 : } else {
9799 7555871 : if (SHR > 1.0 || Counter > 0) SHR = 1.0;
9800 7555871 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
9801 7555871 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9802 7555871 : if (SHR < 1.0) {
9803 6302920 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9804 : } else {
9805 1252951 : FullLoadOutAirHumRat = InletAirHumRat;
9806 : }
9807 : }
9808 7555871 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
9809 :
9810 : // apply latent degradation model to cycling fan when RH control is desired and heating coil operates
9811 : // longer than the cooling coil. DXcoolToHeatPLRRatio = Cooling coil PLR / Heating coil PLR.
9812 7430004 : } else if (fanOp == HVAC::FanOp::Cycling) {
9813 7430004 : if (DXcoolToHeatPLRRatio < 1.0) {
9814 0 : QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode));
9815 0 : QLatActual = TotCap * (1.0 - SHR);
9816 0 : HeatRTF = PartLoadRatio / DXcoolToHeatPLRRatio;
9817 0 : if (thisDXCoil.HeatingCoilPLFCurvePTR > 0) {
9818 0 : HeatingCoilPLF = CurveValue(state, thisDXCoil.HeatingCoilPLFCurvePTR, HeatRTF);
9819 0 : if (HeatingCoilPLF > 0) HeatRTF /= HeatingCoilPLF;
9820 : }
9821 0 : SHRUnadjusted = SHR;
9822 0 : SHR = CalcEffectiveSHR(state,
9823 : DXCoilNum,
9824 : SHR,
9825 : thisDXCoil.CoolingCoilRuntimeFraction,
9826 : QLatRated,
9827 : QLatActual,
9828 : InletAirDryBulbTemp,
9829 : InletAirWetBulbC,
9830 : Mode,
9831 : HeatRTF);
9832 : // Calculate full load output conditions
9833 0 : if (thisDXCoil.UserSHRCurveExists) {
9834 0 : FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
9835 0 : if (SHR < 1.0) {
9836 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9837 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9838 0 : if (FullLoadOutAirHumRat <= 0.0) {
9839 0 : FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
9840 : }
9841 : } else {
9842 0 : SHR = 1.0;
9843 0 : FullLoadOutAirHumRat = InletAirHumRat;
9844 : }
9845 : } else {
9846 0 : if (SHR > 1.0 || Counter > 0) SHR = 1.0;
9847 0 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
9848 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9849 0 : if (SHR < 1.0) {
9850 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9851 : } else {
9852 0 : FullLoadOutAirHumRat = InletAirHumRat;
9853 : }
9854 : }
9855 0 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
9856 : }
9857 : }
9858 :
9859 : // Calculate actual outlet conditions for the input part load ratio
9860 : // Actual outlet conditions are "average" for time step
9861 :
9862 : // For multimode coil, if stage-2 operation (modes 2 or 4), return "full load" outlet conditions
9863 14985875 : if (((fanOp == HVAC::FanOp::Continuous) && (Mode == 1)) || (Mode == 3)) {
9864 : // Continuous fan, cycling compressor
9865 7457557 : OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
9866 7457557 : OutletAirHumRat = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirHumRat + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirHumRat);
9867 7457557 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
9868 : } else {
9869 : // Default to cycling fan, cycling compressor
9870 : // Also return this result for stage 2 operation of multimode coil
9871 : // Cycling fan typically provides full outlet conditions. When RH control is used, account for additional
9872 : // heating run time by using cooing/heating ratio the same as constant fan (otherwise PLRRatio = 1).
9873 7528318 : OutletAirEnthalpy = FullLoadOutAirEnth * DXcoolToHeatPLRRatio + InletAirEnthalpy * (1.0 - DXcoolToHeatPLRRatio);
9874 7528318 : OutletAirHumRat = FullLoadOutAirHumRat * DXcoolToHeatPLRRatio + InletAirHumRat * (1.0 - DXcoolToHeatPLRRatio);
9875 7528318 : OutletAirTemp = FullLoadOutAirTemp * DXcoolToHeatPLRRatio + InletAirDryBulbTemp * (1.0 - DXcoolToHeatPLRRatio);
9876 : }
9877 :
9878 : // Check for saturation error and modify temperature at constant enthalpy
9879 14985875 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, calcDoe2DXCoil)) {
9880 153073 : OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
9881 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9882 : // IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
9883 : // OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
9884 153073 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
9885 : }
9886 :
9887 : // Mix with air that was bypassed around coil, if any
9888 14985875 : if (BypassFlowFraction > 0.0) {
9889 103788 : OutletAirEnthalpy = (1.0 - BypassFlowFraction) * OutletAirEnthalpy + BypassFlowFraction * InletAirEnthalpy;
9890 103788 : OutletAirHumRat = (1.0 - BypassFlowFraction) * OutletAirHumRat + BypassFlowFraction * InletAirHumRat;
9891 103788 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
9892 : // Check for saturation error and modify temperature at constant enthalpy
9893 103788 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) {
9894 0 : OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
9895 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9896 : // IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
9897 : // OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
9898 0 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
9899 : }
9900 : }
9901 :
9902 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
9903 14985875 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9904 14863772 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9905 : // Coil:DX:HeatPumpWaterHeater does not have EIR temp or flow curves
9906 273402 : EIRTempModFac = 1.0;
9907 273402 : EIRFlowModFac = 1.0;
9908 : } else {
9909 14712473 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirWetBulbC, CondInletTemp);
9910 :
9911 : // Warn user if curve output goes negative
9912 14712473 : if (EIRTempModFac < 0.0) {
9913 0 : if (thisDXCoil.EIRFTempErrorIndex == 0) {
9914 0 : ShowWarningMessage(state, format("{}{}=\"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9915 0 : ShowContinueError(
9916 0 : state, format(" Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).", EIRTempModFac));
9917 0 : if (state.dataCurveManager->PerfCurve(thisDXCoil.EIRFTemp(Mode))->numDims == 2) {
9918 0 : ShowContinueError(state,
9919 0 : format(" Negative value occurs using a condenser inlet air temperature of {:.1T} and an inlet air "
9920 : "wet-bulb temperature of {:.1T}.",
9921 : CondInletTemp,
9922 : InletAirWetBulbC));
9923 : } else {
9924 0 : ShowContinueError(state, format(" Negative value occurs using a condenser inlet air temperature of {:.1T}.", CondInletTemp));
9925 : }
9926 0 : if (Mode > 1) {
9927 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
9928 : }
9929 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
9930 : }
9931 0 : ShowRecurringWarningErrorAtEnd(
9932 : state,
9933 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9934 : "\": Energy Input Ratio Modifier curve (function of temperature) output is negative warning continues...",
9935 0 : thisDXCoil.EIRFTempErrorIndex,
9936 : EIRTempModFac,
9937 : EIRTempModFac);
9938 0 : EIRTempModFac = 0.0;
9939 : }
9940 :
9941 14712473 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
9942 :
9943 : // Warn user if curve output goes negative
9944 14712473 : if (EIRFlowModFac < 0.0) {
9945 0 : if (thisDXCoil.EIRFFlowErrorIndex == 0) {
9946 0 : ShowWarningMessage(state, format("{}{}=\"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9947 0 : ShowContinueError(
9948 0 : state, format(" Energy Input Ratio Modifier curve (function of flow fraction) output is negative ({:.3T}).", EIRFlowModFac));
9949 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
9950 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
9951 0 : if (Mode > 1) {
9952 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
9953 : }
9954 : }
9955 0 : ShowRecurringWarningErrorAtEnd(
9956 : state,
9957 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9958 : "\": Energy Input Ratio Modifier curve (function of flow fraction) output is negative warning continues...",
9959 0 : thisDXCoil.EIRFFlowErrorIndex,
9960 : EIRFlowModFac,
9961 : EIRFlowModFac);
9962 0 : EIRFlowModFac = 0.0;
9963 : }
9964 : }
9965 :
9966 14985875 : EIR = thisDXCoil.RatedEIR(Mode) * EIRFlowModFac * EIRTempModFac;
9967 :
9968 : // For multimode coil, if stage-2 operation (Modes 2 or 4), return "full load" power adjusted for PLF
9969 14985875 : if (Mode == 1 || Mode == 3) {
9970 14887561 : thisDXCoil.ElecCoolingPower = TotCap * EIR * thisDXCoil.CoolingCoilRuntimeFraction;
9971 : } else {
9972 98314 : thisDXCoil.ElecCoolingPower = TotCap * EIR * thisDXCoil.CoolingCoilRuntimeFraction / PartLoadRatio;
9973 : }
9974 :
9975 : // Reset AirMassFlow to inlet node air mass flow for final total, sensible and latent calculations
9976 : // since AirMassFlow might have been modified above (in this subroutine):
9977 : // IF (FanOpMode .EQ. FanOp::Cycling) AirMassFlow = AirMassFlow / PartLoadRatio
9978 : // For multimode coil, this should be full flow including bypassed fraction
9979 14985875 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
9980 14985875 : CalcComponentSensibleLatentOutput(AirMassFlow,
9981 : InletAirDryBulbTemp,
9982 : InletAirHumRat,
9983 : OutletAirTemp,
9984 : OutletAirHumRat,
9985 14985875 : thisDXCoil.SensCoolingEnergyRate,
9986 14985875 : thisDXCoil.LatCoolingEnergyRate,
9987 14985875 : thisDXCoil.TotalCoolingEnergyRate);
9988 :
9989 : // Set DataHeatGlobal heat reclaim variable for use by heat reclaim coil (part load ratio is accounted for)
9990 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
9991 14985875 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
9992 :
9993 : // Calculate crankcase heater power using the runtime fraction for this DX cooling coil only if there is no companion DX coil.
9994 : // Else use the largest runtime fraction of this DX cooling coil and the companion DX heating coil.
9995 14985875 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
9996 14985875 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
9997 : } else {
9998 0 : thisDXCoil.CrankcaseHeaterPower =
9999 0 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.CoolingCoilRuntimeFraction,
10000 0 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction));
10001 : }
10002 :
10003 14985875 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
10004 : //******************
10005 : // WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
10006 : // H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
10007 : // /RhoWater [kgWater/m3]
10008 : //******************
10009 44986 : RhoWater = RhoH2O(OutdoorDryBulb);
10010 44986 : thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater * thisDXCoil.CoolingCoilRuntimeFraction;
10011 44986 : thisDXCoil.EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower(Mode) * thisDXCoil.CoolingCoilRuntimeFraction;
10012 : // Calculate basin heater power
10013 44986 : CalcBasinHeaterPower(state,
10014 : thisDXCoil.BasinHeaterPowerFTempDiff,
10015 : thisDXCoil.BasinHeaterSchedulePtr,
10016 : thisDXCoil.BasinHeaterSetPointTemp,
10017 44986 : thisDXCoil.BasinHeaterPower);
10018 44986 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
10019 44986 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
10020 : }
10021 : }
10022 :
10023 14985875 : thisDXCoil.OutletAirTemp = OutletAirTemp;
10024 14985875 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
10025 14985875 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
10026 :
10027 : } else {
10028 :
10029 : // DX coil is off; just pass through conditions
10030 24608518 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10031 24608518 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
10032 24608518 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
10033 :
10034 24608518 : thisDXCoil.ElecCoolingPower = 0.0;
10035 24608518 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
10036 24608518 : thisDXCoil.SensCoolingEnergyRate = 0.0;
10037 24608518 : thisDXCoil.LatCoolingEnergyRate = 0.0;
10038 24608518 : thisDXCoil.EvapCondPumpElecPower = 0.0;
10039 24608518 : thisDXCoil.EvapWaterConsumpRate = 0.0;
10040 :
10041 : // Reset globals when DX coil is OFF for use in heat recovery module
10042 24608518 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
10043 24608518 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
10044 :
10045 : // Calculate crankcase heater power using the runtime fraction for this DX cooling coil (here DXCoolingCoilRTF=0) if
10046 : // there is no companion DX coil, or the runtime fraction of the companion DX heating coil (here DXHeatingCoilRTF>=0).
10047 24608518 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
10048 24608518 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
10049 : } else {
10050 0 : thisDXCoil.CrankcaseHeaterPower =
10051 0 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction);
10052 : }
10053 :
10054 : // Calculate basin heater power
10055 24608518 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
10056 75255 : if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
10057 0 : CalcBasinHeaterPower(state,
10058 : thisDXCoil.BasinHeaterPowerFTempDiff,
10059 : thisDXCoil.BasinHeaterSchedulePtr,
10060 : thisDXCoil.BasinHeaterSetPointTemp,
10061 0 : thisDXCoil.BasinHeaterPower);
10062 : }
10063 : } else {
10064 24533263 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
10065 67370 : CalcBasinHeaterPower(state,
10066 : thisDXCoil.BasinHeaterPowerFTempDiff,
10067 : thisDXCoil.BasinHeaterSchedulePtr,
10068 : thisDXCoil.BasinHeaterSetPointTemp,
10069 67370 : thisDXCoil.BasinHeaterPower);
10070 : }
10071 : }
10072 :
10073 : } // end of on/off if - else
10074 :
10075 : // set water system demand request (if needed)
10076 39594393 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
10077 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
10078 0 : thisDXCoil.EvapWaterConsumpRate;
10079 : }
10080 :
10081 39594393 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
10082 39594393 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
10083 39594393 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
10084 39594393 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
10085 39594393 : thisDXCoil.CondInletTemp = CondInletTemp;
10086 :
10087 : // set outlet node conditions
10088 39594393 : int airOutletNode = thisDXCoil.AirOutNode;
10089 39594393 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
10090 39594393 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
10091 :
10092 : // calc secondary coil if specified
10093 39594393 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
10094 81926 : CalcSecondaryDXCoils(state, DXCoilNum);
10095 : }
10096 39594393 : }
10097 :
10098 1704105 : void CalcVRFCoolingCoil(EnergyPlusData &state,
10099 : int const DXCoilNum, // the number of the DX coil to be simulated
10100 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
10101 : bool const FirstHVACIteration, // true if this is the first iteration of HVAC
10102 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
10103 : HVAC::FanOp const fanOp, // Allows parent object to control fan operation
10104 : Real64 const CompCycRatio, // cycling ratio of VRF condenser
10105 : ObjexxFCL::Optional_int_const PerfMode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
10106 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
10107 : ObjexxFCL::Optional<Real64 const> MaxCoolCap // maximum capacity of DX coil
10108 : )
10109 : {
10110 :
10111 : // SUBROUTINE INFORMATION:
10112 : // AUTHOR Richard Raustad
10113 : // DATE WRITTEN August 2010
10114 :
10115 : // PURPOSE OF THIS SUBROUTINE:
10116 : // Calculates the air-side performance of a direct-expansion, air-cooled
10117 : // VRF terminal unit cooling coil.
10118 : // A new subroutine was created in case this DX coil model is significantly
10119 : // different from the existing CalcDoe2DXCoil subroutine. The VRF heating coil
10120 : // uses the existing DX heating coil subroutine (CalcDXHeatingCoil).
10121 :
10122 : // METHODOLOGY EMPLOYED:
10123 : // This routine simulates the performance of a variable refrigerant flow cooling coil.
10124 : // The routine requires the user to enter the total cooling capacity and sensible heat ratio.
10125 : // Since different manufacturer's rate their equipment at different air flow rates,
10126 : // the supply air flow rate corresponding to the rated capacities must also be
10127 : // entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information entered by
10128 : // the user should NOT include the thermal or electrical impacts of the supply air fan, as
10129 : // this is addressed by another module.
10130 :
10131 : // With the rated performance data entered by the user, the model employs some of the
10132 : // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
10133 : // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
10134 : // does NOT employ the exact same methodology to calculate performance as DOE-2.
10135 : // This VRF cooling coil model adjusts the rated total cooling capacity by the CAPFT
10136 : // and CAP funciton of flow curve/model currently used by the existing DX coil model.
10137 : // The part-load ratio is then applied to the total operating capacity to find the capacity
10138 : // required to meet the load. This VRF model then uses the ADP/bypass method to find the
10139 : // SHR and resulting outlet conditions given that total capacity (or delta H).
10140 :
10141 : // The model checks for coil dryout conditions, and adjusts the calculated performance
10142 : // appropriately.
10143 :
10144 : // Using/Aliasing
10145 : using Curve::CurveValue;
10146 1704105 : Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
10147 1704105 : Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
10148 : using General::CreateSysTimeIntervalString;
10149 :
10150 : // SUBROUTINE ARGUMENT DEFINITIONS:
10151 : // REAL(r64), INTENT(IN), OPTIONAL :: CoolingHeatingPLR ! used for cycling fan RH control
10152 :
10153 : // SUBROUTINE PARAMETER DEFINITIONS:
10154 : static constexpr std::string_view RoutineName("CalcVRFCoolingCoil");
10155 :
10156 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10157 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
10158 : Real64 AirMassFlowRatio; // Ratio of actual air mass flow to rated air mass flow (adjusted for bypass if any)
10159 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
10160 : // (average flow if cycling fan, full flow if constant fan)
10161 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
10162 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
10163 : Real64 TotCapTempModFac; // Total capacity modifier (function of entering wetbulb, outside drybulb)
10164 : Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs rated flow)
10165 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
10166 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
10167 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
10168 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
10169 : Real64 InletAirHumRatTemp; // inlet air humidity ratio used in ADP/BF loop [kg/kg]
10170 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10171 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
10172 : Real64 RatedCBF; // coil bypass factor at rated conditions
10173 : Real64 SHR; // Sensible Heat Ratio (sensible/total) of the cooling coil
10174 : Real64 CBF; // coil bypass factor at off rated conditions
10175 : Real64 A0; // NTU * air mass flow rate, used in CBF calculation
10176 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
10177 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
10178 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
10179 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
10180 : Real64 tADP; // Apparatus dew point temperature [C]
10181 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
10182 : Real64 FullLoadOutAirEnth; // outlet full load enthalpy [J/kg]
10183 : Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
10184 : Real64 FullLoadOutAirTemp; // outlet air temperature at full load [C]
10185 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
10186 : Real64 QLatActual; // operating latent capacity of DX coil
10187 : Real64 QLatRated; // Rated latent capacity of DX coil
10188 : Real64 SHRUnadjusted; // SHR prior to latent degradation effective SHR calculation
10189 : int Counter; // Counter for dry evaporator iterations
10190 : int MaxIter; // Maximum number of iterations for dry evaporator calculations
10191 : Real64 RF; // Relaxation factor for dry evaporator iterations
10192 : Real64 Tolerance; // Error tolerance for dry evaporator iterations
10193 : Real64 werror; // Deviation of humidity ratio in dry evaporator iteration loop
10194 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
10195 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
10196 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
10197 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
10198 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
10199 : Real64 RhoAir; // Density of air [kg/m3]
10200 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
10201 1704105 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
10202 : Real64 AirFlowRatio; // ratio of compressor on airflow to average timestep airflow
10203 : // used when constant fan mode yields different air flow rates when compressor is ON and OFF
10204 : // (e.g. Packaged Terminal Heat Pump)
10205 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
10206 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
10207 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
10208 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
10209 :
10210 : int Mode; // Performance mode for Multimode DX coil; Always 1 for other coil types
10211 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
10212 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
10213 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
10214 : Real64 ADiff; // Used for exponential
10215 :
10216 : // If Performance mode not present, then set to 1. Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
10217 1704105 : if (present(PerfMode)) {
10218 0 : Mode = PerfMode;
10219 : } else {
10220 1704105 : Mode = 1;
10221 : }
10222 :
10223 : // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
10224 : // during cooling and when no cooling is required (constant fan, fan speed changes)
10225 1704105 : if (present(OnOffAirFlowRatio)) {
10226 1704059 : AirFlowRatio = OnOffAirFlowRatio;
10227 : } else {
10228 46 : AirFlowRatio = 1.0;
10229 : }
10230 :
10231 1704105 : auto &DXCT = state.dataHVACGlobal->DXCT;
10232 :
10233 1704105 : MaxIter = 30;
10234 1704105 : RF = 0.4;
10235 1704105 : Counter = 0;
10236 1704105 : Tolerance = 0.01;
10237 1704105 : CondInletTemp = 0.0;
10238 1704105 : CondInletHumRat = 0.0;
10239 :
10240 1704105 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
10241 :
10242 1704105 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10243 1704105 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
10244 1704105 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10245 1704105 : InletAirHumRat = thisDXCoil.InletAirHumRat;
10246 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10247 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
10248 1704105 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
10249 1704105 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
10250 1704105 : thisDXCoil.PartLoadRatio = 0.0;
10251 1704105 : thisDXCoil.BasinHeaterPower = 0.0;
10252 :
10253 1704105 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
10254 1704105 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
10255 1704105 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
10256 156109 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10257 156109 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10258 156109 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10259 : } else {
10260 1547996 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
10261 : // If node is not connected to anything, pressure = default, use weather data
10262 1547996 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
10263 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10264 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10265 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10266 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10267 : } else {
10268 1547996 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
10269 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
10270 1547996 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
10271 : }
10272 : }
10273 : } else {
10274 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10275 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10276 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10277 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10278 : }
10279 :
10280 1704105 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
10281 0 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
10282 0 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
10283 : // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
10284 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
10285 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
10286 0 : CompAmbTemp = OutdoorDryBulb;
10287 : } else { // for air or water-cooled, inlet temp is stored in OutdoorDryBulb temp
10288 1704105 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp or water inlet temp
10289 1704105 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
10290 156109 : CompAmbTemp = state.dataEnvrn->OutDryBulbTemp; // for crankcase heater use actual outdoor temp for water-cooled
10291 : } else {
10292 1547996 : CompAmbTemp = OutdoorDryBulb;
10293 : }
10294 : }
10295 :
10296 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
10297 : // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
10298 1704105 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
10299 90229 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
10300 90229 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
10301 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
10302 : }
10303 : } else {
10304 1613876 : CrankcaseHeatingPower = 0.0;
10305 : }
10306 :
10307 : // calculate end time of current time step to determine if error messages should be printed
10308 1704105 : state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
10309 :
10310 : // Print warning messages only when valid and only for the first ocurrance. Let summary provide statistics.
10311 : // Wait for next time step to print warnings. If simulation iterates, print out
10312 : // the warning for the last iteration only. Must wait for next time step to accomplish this.
10313 : // If a warning occurs and the simulation down shifts, the warning is not valid.
10314 1704105 : if (thisDXCoil.PrintLowAmbMessage) { // .AND. &
10315 0 : if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
10316 0 : if (thisDXCoil.LowAmbErrIndex == 0) {
10317 0 : ShowWarningMessage(state, thisDXCoil.LowAmbBuffer1);
10318 0 : ShowContinueError(state, thisDXCoil.LowAmbBuffer2);
10319 0 : ShowContinueError(state, "... Operation at low inlet temperatures may require special performance curves.");
10320 : }
10321 0 : ShowRecurringWarningErrorAtEnd(state,
10322 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10323 : "\" - Low condenser inlet temperature error continues...",
10324 0 : thisDXCoil.LowAmbErrIndex,
10325 0 : thisDXCoil.LowTempLast,
10326 0 : thisDXCoil.LowTempLast,
10327 : _,
10328 : "[C]",
10329 : "[C]");
10330 : }
10331 : }
10332 :
10333 1704105 : if (thisDXCoil.PrintHighAmbMessage) { // .AND. &
10334 0 : if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
10335 0 : if (thisDXCoil.HighAmbErrIndex == 0) {
10336 0 : ShowWarningMessage(state, thisDXCoil.HighAmbBuffer1);
10337 0 : ShowContinueError(state, thisDXCoil.HighAmbBuffer2);
10338 0 : ShowContinueError(state, "... Operation at high inlet temperatures may require special performance curves.");
10339 : }
10340 0 : ShowRecurringWarningErrorAtEnd(state,
10341 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10342 : "\" - High condenser inlet temperature error continues...",
10343 0 : thisDXCoil.HighAmbErrIndex,
10344 0 : thisDXCoil.HighTempLast,
10345 0 : thisDXCoil.HighTempLast,
10346 : _,
10347 : "[C]",
10348 : "[C]");
10349 : }
10350 : }
10351 :
10352 1704105 : if (thisDXCoil.PrintLowOutTempMessage) {
10353 0 : if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
10354 0 : if (thisDXCoil.LowOutletTempIndex == 0) {
10355 0 : ShowWarningMessage(state, thisDXCoil.LowOutTempBuffer1);
10356 0 : ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
10357 0 : ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
10358 0 : ShowContinueError(state,
10359 0 : format(" 1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
10360 0 : thisDXCoil.FullLoadInletAirTempLast));
10361 0 : ShowContinueError(state, " 2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
10362 0 : ShowContinueError(state,
10363 : " 3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
10364 : }
10365 0 : ShowRecurringWarningErrorAtEnd(state,
10366 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10367 : "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
10368 : "Outlet air temperature statistics follow:",
10369 0 : thisDXCoil.LowOutletTempIndex,
10370 0 : thisDXCoil.FullLoadOutAirTempLast,
10371 0 : thisDXCoil.FullLoadOutAirTempLast);
10372 : }
10373 : }
10374 :
10375 : // save last system time step and last end time of current time step (used to determine if warning is valid)
10376 1704105 : thisDXCoil.TimeStepSysLast = TimeStepSys;
10377 1704105 : thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime;
10378 1704105 : thisDXCoil.PrintLowAmbMessage = false;
10379 1704105 : thisDXCoil.PrintLowOutTempMessage = false;
10380 :
10381 1704105 : if ((AirMassFlow > 0.0) && (GetCurrentScheduleValue(state, thisDXCoil.SchedPtr) > 0.0) && (PartLoadRatio > 0.0) &&
10382 : (compressorOp == HVAC::CompressorOp::On)) { // for cycling fan, reset mass flow to full on rate
10383 933576 : if (fanOp == HVAC::FanOp::Cycling) {
10384 252614 : AirMassFlow /= PartLoadRatio;
10385 680962 : } else if (fanOp == HVAC::FanOp::Continuous) {
10386 680962 : AirMassFlow *= AirFlowRatio;
10387 : } else {
10388 0 : AirMassFlow = thisDXCoil.RatedAirMassFlowRate(Mode);
10389 : }
10390 :
10391 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton)
10392 :
10393 : // for some reason there are diff's when using coil inlet air pressure
10394 : // these lines (more to follow) are commented out for the time being
10395 :
10396 933576 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
10397 933576 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
10398 933576 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
10399 :
10400 933576 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
10401 0 : ShowFatalError(state, format("{} \"{}\" - Rated total cooling capacity is zero or less.", thisDXCoil.DXCoilType, thisDXCoil.Name));
10402 : }
10403 :
10404 999607 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag &&
10405 66031 : ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
10406 65703 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
10407 328 : if (thisDXCoil.ErrIndex1 == 0) {
10408 2 : ShowWarningMessage(
10409 : state,
10410 2 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at {:.3R} m3/s/W.",
10411 1 : thisDXCoil.DXCoilType,
10412 1 : thisDXCoil.Name,
10413 : VolFlowperRatedTotCap));
10414 1 : ShowContinueErrorTimeStamp(state, "");
10415 2 : ShowContinueError(state,
10416 2 : format("...Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
10417 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
10418 1 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
10419 1 : ShowContinueError(state, "...Possible causes include inconsistent air flow rates in system components,");
10420 1 : ShowContinueError(state, "...or mixing manual inputs with autosize inputs. Also check the following values and calculations.");
10421 1 : ShowContinueError(state, "...Volume Flow Rate per Rated Total Capacity = Volume Flow Rate / Rated Total Capacity");
10422 1 : ShowContinueError(state, "...Volume Flow Rate = Air Mass Flow Rate / Air Density");
10423 1 : ShowContinueError(state, "...Data used for calculations:");
10424 1 : ShowContinueError(state, format("...Rated Total Capacity = {:.2R} W.", thisDXCoil.RatedTotCap(Mode)));
10425 1 : ShowContinueError(state, "...Volume Flow Rate = Air Mass Flow Rate / Air Density");
10426 1 : ShowContinueError(state, format("...Volume Flow Rate = {:.8R} m3/s.", AirVolumeFlowRate));
10427 1 : ShowContinueError(state, format("...Air Mass Flow Rate = {:.8R} kg/s.", AirMassFlow));
10428 2 : ShowContinueError(
10429 : state,
10430 2 : format("...Air Density = {:.8R} kg/m3.", PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat)));
10431 1 : ShowContinueError(state, "...Data used for air density calculation:");
10432 1 : ShowContinueError(state, format("...Outdoor Air Pressure = {:.3R} Pa.", OutdoorPressure));
10433 1 : ShowContinueError(state, format("...Inlet Air Dry-Bulb Temp = {:.3R} C.", InletAirDryBulbTemp));
10434 1 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.8R} kgWater/kgDryAir.", InletAirHumRat));
10435 : }
10436 984 : ShowRecurringWarningErrorAtEnd(
10437 : state,
10438 656 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10439 : "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
10440 328 : thisDXCoil.ErrIndex1,
10441 : VolFlowperRatedTotCap,
10442 : VolFlowperRatedTotCap);
10443 : }
10444 : // Adjust coil bypass factor for actual air flow rate. Use relation CBF = exp(-NTU) where
10445 : // NTU = A0/(m*cp). Relationship models the cooling coil as a heat exchanger with Cmin/Cmax = 0.
10446 :
10447 933576 : RatedCBF = thisDXCoil.RatedCBF(Mode);
10448 933576 : if (RatedCBF > 0.0) {
10449 933576 : A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
10450 : } else {
10451 0 : A0 = 0.0;
10452 : }
10453 933576 : ADiff = -A0 / AirMassFlow;
10454 933576 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
10455 933576 : CBF = std::exp(ADiff);
10456 : } else {
10457 0 : CBF = 0.0;
10458 : }
10459 :
10460 : // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
10461 933576 : if (OutdoorDryBulb < thisDXCoil.MinOATCompressor && !state.dataGlobal->WarmupFlag) {
10462 0 : thisDXCoil.PrintLowAmbMessage = true;
10463 0 : thisDXCoil.LowTempLast = OutdoorDryBulb;
10464 0 : if (thisDXCoil.LowAmbErrIndex == 0) {
10465 0 : thisDXCoil.LowAmbBuffer1 = format("{} \"{}\" - Condenser inlet temperature below {:.2R} C. Condenser inlet temperature = {:.2R}",
10466 0 : thisDXCoil.DXCoilType,
10467 0 : thisDXCoil.Name,
10468 0 : thisDXCoil.MinOATCompressor,
10469 0 : OutdoorDryBulb);
10470 0 : thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
10471 0 : CreateSysTimeIntervalString(state);
10472 : }
10473 : }
10474 :
10475 : // check boundary for high ambient temperature and post warnings to individual DX coil buffers to print at end of time step
10476 933576 : if (OutdoorDryBulb > thisDXCoil.MaxOATCompressor && !state.dataGlobal->WarmupFlag) {
10477 0 : thisDXCoil.PrintHighAmbMessage = true;
10478 0 : thisDXCoil.HighTempLast = OutdoorDryBulb;
10479 0 : if (thisDXCoil.HighAmbErrIndex == 0) {
10480 0 : thisDXCoil.HighAmbBuffer1 = format("{} \"{}\" - Condenser inlet temperature above {:.2R} C. Condenser temperature = {:.2R}",
10481 0 : thisDXCoil.DXCoilType,
10482 0 : thisDXCoil.Name,
10483 0 : thisDXCoil.MaxOATCompressor,
10484 0 : OutdoorDryBulb);
10485 0 : thisDXCoil.HighAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
10486 0 : CreateSysTimeIntervalString(state);
10487 : }
10488 : }
10489 :
10490 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
10491 : // InletAirHumRat may be modified in this ADP/BF loop, use temporary varible for calculations
10492 933576 : InletAirHumRatTemp = InletAirHumRat;
10493 :
10494 933576 : Label50:;
10495 933576 : switch (state.dataCurveManager->PerfCurve(thisDXCoil.CCapFTemp(Mode))->numDims) {
10496 693423 : case 1:
10497 693423 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC);
10498 693423 : break;
10499 240153 : case 2:
10500 : default: // this default allows the simulation to continue, but will issue a warning, should be removed eventually
10501 240153 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC, CondInletTemp);
10502 240153 : break;
10503 : }
10504 :
10505 : // Warn user if curve output goes negative
10506 933576 : if (TotCapTempModFac < 0.0) {
10507 0 : if (thisDXCoil.CCapFTempErrorIndex == 0) {
10508 0 : ShowWarningMessage(state, format("{} \"{}\":", thisDXCoil.DXCoilType, thisDXCoil.Name));
10509 0 : ShowContinueError(
10510 0 : state, format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
10511 0 : ShowContinueError(
10512 : state,
10513 0 : format(" Negative value occurs using a condenser inlet temperature of {:.1T} and an inlet air wet-bulb temperature of {:.1T}.",
10514 : CondInletTemp,
10515 : InletAirWetBulbC));
10516 0 : if (Mode > 1) {
10517 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
10518 : }
10519 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
10520 : }
10521 0 : ShowRecurringWarningErrorAtEnd(
10522 : state,
10523 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10524 : "\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
10525 0 : thisDXCoil.CCapFTempErrorIndex,
10526 : TotCapTempModFac,
10527 : TotCapTempModFac);
10528 0 : TotCapTempModFac = 0.0;
10529 : }
10530 :
10531 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
10532 933576 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
10533 933576 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
10534 :
10535 : // Warn user if curve output goes negative
10536 933576 : if (TotCapFlowModFac < 0.0) {
10537 0 : if (thisDXCoil.CCapFFlowErrorIndex == 0) {
10538 0 : ShowWarningMessage(state, format("{} \"{}\":", thisDXCoil.DXCoilType, thisDXCoil.Name));
10539 0 : ShowContinueError(
10540 : state,
10541 0 : format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).", TotCapFlowModFac));
10542 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
10543 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
10544 0 : if (Mode > 1) {
10545 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
10546 : }
10547 : }
10548 0 : ShowRecurringWarningErrorAtEnd(
10549 : state,
10550 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10551 : "\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
10552 0 : thisDXCoil.CCapFFlowErrorIndex,
10553 : TotCapFlowModFac,
10554 : TotCapFlowModFac);
10555 0 : TotCapFlowModFac = 0.0;
10556 : }
10557 :
10558 933576 : if (present(MaxCoolCap)) {
10559 933530 : TotCap = min(MaxCoolCap, thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac);
10560 : } else {
10561 46 : TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
10562 : }
10563 :
10564 933576 : TotCap *= PartLoadRatio;
10565 :
10566 : // Calculate apparatus dew point conditions using TotCap and CBF
10567 933576 : hDelta = TotCap / AirMassFlow;
10568 : // there is an issue here with using CBF to calculate the ADP enthalpy.
10569 : // at low loads the bypass factor increases significantly.
10570 933576 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
10571 933576 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
10572 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10573 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
10574 933576 : wADP = min(InletAirHumRat, PsyWFnTdbH(state, tADP, hADP, RoutineName));
10575 933576 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
10576 933576 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
10577 853825 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
10578 : } else {
10579 79751 : SHR = 1.0;
10580 : }
10581 : // Check for dry evaporator conditions (win < wadp)
10582 933576 : if (wADP > InletAirHumRatTemp || (Counter >= 1 && Counter < MaxIter)) {
10583 0 : if (InletAirHumRatTemp == 0.0) InletAirHumRatTemp = 0.00001;
10584 0 : werror = (InletAirHumRatTemp - wADP) / InletAirHumRatTemp;
10585 : // Increase InletAirHumRatTemp at constant InletAirTemp to find coil dry-out point. Then use the
10586 : // capacity at the dry-out point to determine exiting conditions from coil. This is required
10587 : // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
10588 0 : InletAirHumRatTemp = RF * wADP + (1.0 - RF) * InletAirHumRatTemp;
10589 0 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRatTemp, OutdoorPressure);
10590 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10591 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRatTemp,InletAirPressure)
10592 0 : ++Counter;
10593 0 : if (std::abs(werror) > Tolerance) goto Label50; // Recalculate with modified inlet conditions
10594 : }
10595 :
10596 933576 : if (thisDXCoil.PLFFPLR(Mode) > 0 && CompCycRatio < 1.0) {
10597 0 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CompCycRatio); // Calculate part-load factor
10598 : } else {
10599 933576 : PLF = 1.0;
10600 : }
10601 :
10602 933576 : if (PLF < 0.7) {
10603 0 : if (thisDXCoil.ErrIndex2 == 0) {
10604 0 : ShowWarningMessage(
10605 : state,
10606 0 : format(
10607 0 : "The PLF curve value for the DX cooling coil {} ={:.3R} for part-load ratio ={:.3R}", thisDXCoil.Name, PLF, PartLoadRatio));
10608 0 : ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
10609 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
10610 : }
10611 0 : ShowRecurringWarningErrorAtEnd(
10612 0 : state, thisDXCoil.Name + ", DX cooling coil PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
10613 0 : PLF = 0.7;
10614 : }
10615 :
10616 933576 : thisDXCoil.PartLoadRatio = PartLoadRatio;
10617 933576 : thisDXCoil.CoolingCoilRuntimeFraction = CompCycRatio / PLF;
10618 933576 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
10619 0 : if (thisDXCoil.ErrIndex3 == 0) {
10620 0 : ShowWarningMessage(state,
10621 0 : format("The runtime fraction for DX cooling coil {} exceeded 1.0. [{:.4R}].",
10622 0 : thisDXCoil.Name,
10623 0 : thisDXCoil.CoolingCoilRuntimeFraction));
10624 0 : ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
10625 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
10626 0 : ShowContinueErrorTimeStamp(state, "");
10627 : }
10628 0 : ShowRecurringWarningErrorAtEnd(state,
10629 0 : thisDXCoil.Name + ", DX cooling coil runtime fraction > 1.0 warning continues...",
10630 0 : thisDXCoil.ErrIndex3,
10631 0 : thisDXCoil.CoolingCoilRuntimeFraction,
10632 0 : thisDXCoil.CoolingCoilRuntimeFraction);
10633 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
10634 933576 : } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
10635 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
10636 : }
10637 :
10638 : // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
10639 933576 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
10640 :
10641 : // Calculate full load output conditions
10642 : // if ( SHR > 1.0 || Counter > 0 ) SHR = 1.0;
10643 933576 : if (SHR > 1.0) SHR = 1.0;
10644 933576 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
10645 933576 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
10646 933576 : if (SHR < 1.0) {
10647 603302 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
10648 : } else {
10649 330274 : FullLoadOutAirHumRat = InletAirHumRat;
10650 : }
10651 933576 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
10652 :
10653 : // Check for saturation error and modify temperature at constant enthalpy
10654 933576 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure)) {
10655 765 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
10656 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10657 : // IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
10658 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
10659 765 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
10660 : }
10661 :
10662 : // Store actual outlet conditions when DX coil is ON for use in heat recovery module
10663 933576 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = FullLoadOutAirTemp;
10664 933576 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = FullLoadOutAirHumRat;
10665 :
10666 : // Add warning message for cold cooling coil (FullLoadOutAirTemp < 2 C)
10667 933576 : if (FullLoadOutAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
10668 0 : thisDXCoil.PrintLowOutTempMessage = true;
10669 0 : thisDXCoil.FullLoadOutAirTempLast = FullLoadOutAirTemp;
10670 0 : if (thisDXCoil.LowOutletTempIndex == 0) {
10671 0 : thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
10672 0 : thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
10673 : "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
10674 0 : thisDXCoil.DXCoilType,
10675 0 : thisDXCoil.Name,
10676 0 : FullLoadOutAirTemp);
10677 0 : thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
10678 0 : CreateSysTimeIntervalString(state);
10679 : }
10680 : }
10681 :
10682 : // If constant fan with cycling compressor, call function to determine "effective SHR"
10683 : // which includes the part-load degradation on latent capacity
10684 933576 : if (fanOp == HVAC::FanOp::Continuous && CompCycRatio < 1.0) {
10685 284079 : QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode)); // always the same number
10686 284079 : QLatActual = TotCap * (1.0 - SHR);
10687 284079 : SHRUnadjusted = SHR;
10688 284079 : SHR = CalcEffectiveSHR(
10689 : state, DXCoilNum, SHR, thisDXCoil.CoolingCoilRuntimeFraction, QLatRated, QLatActual, InletAirDryBulbTemp, InletAirWetBulbC, Mode);
10690 :
10691 : // Calculate full load output conditions
10692 : // if ( SHR > 1.0 || Counter > 0 ) SHR = 1.0;
10693 284079 : if (SHR > 1.0) SHR = 1.0;
10694 284079 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
10695 284079 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
10696 284079 : if (SHR < 1.0) {
10697 183279 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
10698 : } else {
10699 100800 : FullLoadOutAirHumRat = InletAirHumRat;
10700 : }
10701 284079 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
10702 : }
10703 :
10704 : // Calculate actual outlet conditions for the input part load ratio
10705 : // Actual outlet conditions are "average" for time step when compressor cycles
10706 :
10707 933576 : if (fanOp == HVAC::FanOp::Continuous && CompCycRatio < 1.0) {
10708 : // Continuous fan, cycling compressor
10709 : // hmmm ... this seems wrong. PLR * AirFlowRatio = 1. So we get FullLoadOutAirEnth all this time. This is OK since above TotCap *=
10710 : // PLR.
10711 284079 : OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
10712 284079 : OutletAirHumRat = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirHumRat + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirHumRat);
10713 284079 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
10714 : } else {
10715 : // Default to cycling fan, cycling compressor
10716 649497 : OutletAirEnthalpy = FullLoadOutAirEnth;
10717 649497 : OutletAirHumRat = FullLoadOutAirHumRat;
10718 649497 : OutletAirTemp = FullLoadOutAirTemp;
10719 : }
10720 :
10721 : // Check for saturation error and modify temperature at constant enthalpy
10722 933576 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, RoutineName)) {
10723 3982 : OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
10724 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10725 : // IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
10726 : // OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
10727 3982 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
10728 : }
10729 :
10730 : // Reset AirMassFlow to inlet node air mass flow for final total, sensible and latent calculations
10731 : // since AirMassFlow might have been modified above (in this subroutine):
10732 : // IF (FanOpMode .EQ. FanOp::Cycling) AirMassFlow = AirMassFlow / PartLoadRatio
10733 : // For multimode coil, this should be full flow including bypassed fraction
10734 933576 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10735 :
10736 : // Coil total/sensible/latent cooling rates
10737 933576 : CalcComponentSensibleLatentOutput(AirMassFlow,
10738 : InletAirDryBulbTemp,
10739 : InletAirHumRat,
10740 : OutletAirTemp,
10741 : OutletAirHumRat,
10742 933576 : thisDXCoil.SensCoolingEnergyRate,
10743 933576 : thisDXCoil.LatCoolingEnergyRate,
10744 933576 : thisDXCoil.TotalCoolingEnergyRate);
10745 :
10746 933576 : thisDXCoil.OutletAirTemp = OutletAirTemp;
10747 933576 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
10748 933576 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
10749 :
10750 : } else {
10751 :
10752 : // DX coil is off; just pass through conditions
10753 770529 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10754 770529 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
10755 770529 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
10756 :
10757 770529 : thisDXCoil.ElecCoolingPower = 0.0;
10758 770529 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
10759 770529 : thisDXCoil.SensCoolingEnergyRate = 0.0;
10760 770529 : thisDXCoil.LatCoolingEnergyRate = 0.0;
10761 770529 : thisDXCoil.EvapCondPumpElecPower = 0.0;
10762 770529 : thisDXCoil.EvapWaterConsumpRate = 0.0;
10763 :
10764 : // Reset globals when DX coil is OFF for use in heat recovery module
10765 770529 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
10766 770529 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
10767 :
10768 : } // end of on/off if - else
10769 :
10770 : // set water system demand request (if needed)
10771 1704105 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
10772 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
10773 0 : thisDXCoil.EvapWaterConsumpRate;
10774 : }
10775 :
10776 1704105 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
10777 1704105 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
10778 1704105 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
10779 1704105 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
10780 1704105 : thisDXCoil.CondInletTemp = CondInletTemp;
10781 1704105 : state.dataDXCoils->DXCoilTotalCooling(DXCoilNum) = thisDXCoil.TotalCoolingEnergyRate;
10782 1704105 : state.dataDXCoils->DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
10783 :
10784 : // set outlet node conditions
10785 1704105 : int airOutletNode = thisDXCoil.AirOutNode;
10786 1704105 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
10787 1704105 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
10788 1704105 : }
10789 :
10790 7591276 : void CalcDXHeatingCoil(EnergyPlusData &state,
10791 : int const DXCoilNum, // the number of the DX heating coil to be simulated
10792 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
10793 : HVAC::FanOp const fanOp, // Allows parent object to control fan mode
10794 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
10795 : ObjexxFCL::Optional<Real64 const> MaxHeatCap // maximum allowed heating capacity
10796 : )
10797 : {
10798 :
10799 : // SUBROUTINE INFORMATION:
10800 : // AUTHOR Richard Raustad
10801 : // DATE WRITTEN October 2001
10802 : // MODIFIED Raustad/Shirey Mar 2004
10803 : // Kenneth Tang 2004 (Sensitivity of TotCapTempModFac & EIRTempModFac to indoor dry bulb temp)
10804 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
10805 : // Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
10806 :
10807 : // PURPOSE OF THIS SUBROUTINE:
10808 : // Calculates the air-side heating performance and electrical heating energy
10809 : // use of a direct-expansion, air-cooled heat pump unit.
10810 :
10811 : // METHODOLOGY EMPLOYED:
10812 : // This routine simulates the performance of air-cooled DX heating equipment.
10813 : // The routine requires the user to enter the total heating capacity
10814 : // and COP for the unit at ARI 210/240 rating conditions (21.11C [70F] dry-bulb,
10815 : // 15.55C [60F] wet-bulb air entering the heating coil, 8.33C [47F] dry-bulb,
10816 : // 6.11C [43F] wet-bulb air entering the outdoor condenser. Since different
10817 : // manufacturer's rate their equipment at different air flow rates, the supply
10818 : // air flow rate corresponding to the rated capacities and rated COP must also
10819 : // be entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information
10820 : // entered by the user should NOT include the thermal or electrical impacts of the
10821 : // supply air fan, as this is addressed by another module.
10822 :
10823 : // With the rated performance data entered by the user, the model employs some of the
10824 : // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
10825 : // of outdoor air temperatures and supply air flow rate (actual vs rated flow). The
10826 : // model does NOT employ the exact same methodology to calculate performance as DOE-2,
10827 : // although some of the DOE-2 curve fits are employed by this model.
10828 :
10829 : // REFERENCES:
10830 : // Winkelmann, F.C., Birdsall, B.E., Buhl W.F., Ellington, K.L., Erdem, A.E. 1993.
10831 : // DOE-2 Supplement Version 2.1E. Energy and Environment Division, Larwence Berkely
10832 : // Laboratory.
10833 : // Henderson, H.I. Jr., Y.J. Huang and Danny Parker. 1999. Residential Equipment Part
10834 : // Load Curves for Use in DOE-2. Environmental Energy Technologies Division, Ernest
10835 : // Orlando Lawrence Berkeley National Laboratory.
10836 :
10837 : // Using/Aliasing
10838 : using Curve::CurveValue;
10839 :
10840 : // SUBROUTINE PARAMETER DEFINITIONS:
10841 : static constexpr std::string_view RoutineNameFullLoad("CalcDXHeatingCoil:fullload");
10842 :
10843 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10844 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
10845 : Real64 AirMassFlowRatio; // Ratio of actual air mass flow to rated air mass flow
10846 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s]
10847 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W]
10848 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
10849 : Real64 TotCapAdj; // adjusted total cooling capacity at off-rated conditions [W]
10850 : Real64 TotCapTempModFac; // Total capacity modifier (function of entering drybulb, outside drybulb) depending
10851 : // on the type of curve
10852 : Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs rated flow)
10853 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
10854 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
10855 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
10856 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
10857 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10858 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
10859 : Real64 FullLoadOutAirEnth; // outlet full load enthalpy [J/kg]
10860 : Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
10861 : Real64 FullLoadOutAirTemp; // outlet air temperature at full load [C]
10862 : Real64 FullLoadOutAirRH; // outlet air relative humidity at full load
10863 7591276 : Real64 EIRTempModFac(0.0); // EIR modifier (function of entering drybulb, outside drybulb) depending on the
10864 : // type of curve
10865 : Real64 DefrostEIRTempModFac; // EIR modifier for defrost (function of entering wetbulb, outside drybulb)
10866 : Real64 EIRFlowModFac; // EIR modifier (function of actual supply air flow vs rated flow)
10867 : Real64 EIR; // EIR at part load and off rated conditions
10868 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup
10869 : Real64 PLRHeating; // PartLoadRatio in heating
10870 : Real64 OutdoorCoilT; // Outdoor coil temperature (C)
10871 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
10872 : Real64 FractionalDefrostTime; // Fraction of time step system is in defrost
10873 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
10874 : Real64 InputPowerMultiplier; // Multiplier for power when system is in defrost
10875 : Real64 LoadDueToDefrost; // Additional load due to defrost
10876 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
10877 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
10878 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
10879 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
10880 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
10881 7591276 : constexpr int Mode(1); // Performance mode for MultiMode DX coil; Always 1 for other coil types
10882 : Real64 AirFlowRatio; // Ratio of compressor on airflow to average timestep airflow
10883 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
10884 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
10885 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
10886 7591276 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
10887 :
10888 7591276 : if (present(OnOffAirFlowRatio)) {
10889 7591230 : AirFlowRatio = OnOffAirFlowRatio;
10890 : } else {
10891 46 : AirFlowRatio = 1.0;
10892 : }
10893 :
10894 7591276 : auto &DXCT = state.dataHVACGlobal->DXCT;
10895 :
10896 7591276 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
10897 :
10898 : // Get condenser outdoor node info from DX Heating Coil
10899 7591276 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
10900 2431409 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp;
10901 2431409 : CompAmbTemp = OutdoorDryBulb;
10902 2431409 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
10903 156109 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10904 156109 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10905 156109 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10906 156109 : CompAmbTemp = state.dataEnvrn->OutDryBulbTemp;
10907 : } else {
10908 2275300 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press;
10909 : // If node is not connected to anything, pressure = default, use weather data
10910 2275300 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
10911 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10912 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10913 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10914 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10915 : } else {
10916 2275300 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat;
10917 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
10918 2275300 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb;
10919 : }
10920 2275300 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
10921 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
10922 0 : OutdoorDryBulb = secZoneHB.ZT;
10923 0 : OutdoorHumRat = secZoneHB.airHumRat;
10924 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
10925 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10926 0 : CompAmbTemp = OutdoorDryBulb;
10927 : }
10928 : }
10929 5159867 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
10930 81925 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
10931 81925 : OutdoorDryBulb = secZoneHB.ZT;
10932 81925 : OutdoorHumRat = secZoneHB.airHumRat;
10933 81925 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
10934 81925 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10935 81925 : CompAmbTemp = OutdoorDryBulb;
10936 : } else {
10937 5077942 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10938 5077942 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10939 5077942 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10940 5077942 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10941 5077942 : CompAmbTemp = OutdoorDryBulb;
10942 : }
10943 :
10944 7591276 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10945 7591276 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
10946 7591276 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10947 7591276 : InletAirHumRat = thisDXCoil.InletAirHumRat;
10948 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10949 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
10950 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
10951 7591276 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
10952 7591276 : PLRHeating = 0.0;
10953 7591276 : thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
10954 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
10955 7591276 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
10956 1960774 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
10957 1960774 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
10958 56165 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
10959 : }
10960 : } else {
10961 5630502 : CrankcaseHeatingPower = 0.0;
10962 : }
10963 :
10964 8826166 : if ((AirMassFlow > 0.0) && (GetCurrentScheduleValue(state, thisDXCoil.SchedPtr) > 0.0) && (PartLoadRatio > 0.0) &&
10965 1234890 : OutdoorDryBulb > thisDXCoil.MinOATCompressor) {
10966 : // for cycling fan, reset mass flow to full on rate
10967 605359 : if (fanOp == HVAC::FanOp::Cycling) AirMassFlow /= PartLoadRatio;
10968 605359 : if (fanOp == HVAC::FanOp::Continuous) AirMassFlow *= AirFlowRatio;
10969 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton)
10970 605359 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
10971 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10972 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
10973 605359 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
10974 :
10975 1207638 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
10976 602279 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
10977 3080 : if (thisDXCoil.ErrIndex1 == 0) {
10978 2 : ShowWarningMessage(
10979 : state,
10980 2 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at {:.3R} m3/s/W.",
10981 1 : thisDXCoil.DXCoilType,
10982 1 : thisDXCoil.Name,
10983 : VolFlowperRatedTotCap));
10984 1 : ShowContinueErrorTimeStamp(state, "");
10985 2 : ShowContinueError(state,
10986 2 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
10987 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
10988 1 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
10989 1 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
10990 1 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
10991 : }
10992 9240 : ShowRecurringWarningErrorAtEnd(
10993 : state,
10994 6160 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10995 : "\" - Air volume flow rate per watt of rated total heating capacity is out of range error continues...",
10996 3080 : thisDXCoil.ErrIndex1,
10997 : VolFlowperRatedTotCap,
10998 : VolFlowperRatedTotCap);
10999 : }
11000 :
11001 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
11002 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
11003 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
11004 : // advised to use the bi-quaratic curve if sufficient manufacturer data is available.
11005 605359 : if (state.dataCurveManager->PerfCurve(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
11006 56682 : switch (thisDXCoil.HeatingPerformanceOATType) {
11007 1 : case HVAC::OATType::DryBulb: {
11008 1 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
11009 1 : } break;
11010 56681 : case HVAC::OATType::WetBulb: {
11011 56681 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp, OutdoorWetBulb);
11012 56681 : } break;
11013 0 : default: {
11014 0 : TotCapTempModFac = 1.0;
11015 0 : } break;
11016 : }
11017 : } else {
11018 548677 : switch (thisDXCoil.HeatingPerformanceOATType) {
11019 312950 : case HVAC::OATType::DryBulb: {
11020 312950 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
11021 289170 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), OutdoorDryBulb);
11022 : } else {
11023 23780 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp);
11024 : }
11025 312950 : } break;
11026 235727 : case HVAC::OATType::WetBulb: {
11027 235727 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
11028 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), OutdoorWetBulb);
11029 : } else {
11030 235727 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp);
11031 : }
11032 235727 : } break;
11033 0 : default: {
11034 0 : TotCapTempModFac = 1.0;
11035 0 : } break;
11036 : }
11037 : }
11038 :
11039 605359 : if (TotCapTempModFac < 0.0) {
11040 0 : if (thisDXCoil.CAPFTErrIndex == 0) {
11041 0 : ShowWarningMessage(state,
11042 0 : format("The TotCapTempModFac curve value for DX heating coil {} ={:.2R}", thisDXCoil.Name, TotCapTempModFac));
11043 0 : ShowContinueError(state,
11044 : "TotCapTempModFac curve value must be > 0. TotCapTempModFac curve value has been reset to 0.0 and "
11045 : "simulation is continuing.");
11046 0 : ShowContinueError(state, format("Check the IO reference manual for TotCapTempModFac curve guidance [ {} ].", thisDXCoil.DXCoilType));
11047 0 : ShowContinueErrorTimeStamp(state, "");
11048 : }
11049 0 : ShowRecurringWarningErrorAtEnd(state,
11050 : "DX heating coil TotCapTempModFac curve value < 0 warning continues... ",
11051 0 : thisDXCoil.CAPFTErrIndex,
11052 : TotCapTempModFac,
11053 : TotCapTempModFac);
11054 0 : TotCapTempModFac = 0.0;
11055 : }
11056 :
11057 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
11058 605359 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
11059 605359 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
11060 :
11061 : // Calculate total heating capacity for off-rated conditions
11062 605359 : TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
11063 :
11064 : // Calculating adjustment factors for defrost
11065 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
11066 605359 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
11067 605359 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
11068 :
11069 : // Initializing defrost adjustment factors
11070 605359 : LoadDueToDefrost = 0.0;
11071 605359 : HeatingCapacityMultiplier = 1.0;
11072 605359 : FractionalDefrostTime = 0.0;
11073 605359 : InputPowerMultiplier = 1.0;
11074 :
11075 : // Check outdoor temperature to determine of defrost is active
11076 605359 : if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost && thisDXCoil.CondenserType(Mode) != DataHeatBalance::RefrigCondenserType::Water) {
11077 : // Calculate defrost adjustment factors depending on defrost control type
11078 88366 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
11079 87823 : FractionalDefrostTime = thisDXCoil.DefrostTime;
11080 87823 : if (FractionalDefrostTime > 0.0) {
11081 87823 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
11082 87823 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
11083 : }
11084 : } else { // else defrost control is on-demand
11085 543 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
11086 543 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
11087 543 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
11088 : }
11089 :
11090 88366 : if (FractionalDefrostTime > 0.0) {
11091 : // Calculate defrost adjustment factors depending on defrost control strategy
11092 88366 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
11093 543 : LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.RatedTotCap(Mode) / 1.01667);
11094 543 : DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
11095 543 : thisDXCoil.DefrostPower = DefrostEIRTempModFac * (thisDXCoil.RatedTotCap(Mode) / 1.01667) * FractionalDefrostTime;
11096 : } else { // Defrost strategy is resistive
11097 87823 : thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
11098 : }
11099 : } else { // Defrost is not active because (FractionalDefrostTime .EQ. 0.0)
11100 0 : thisDXCoil.DefrostPower = 0.0;
11101 : }
11102 : }
11103 :
11104 : // Modify total heating capacity based on defrost heating capacity multiplier
11105 : // MaxHeatCap passed from parent object VRF Condenser and is used to limit capacity of TU's to that available from condenser
11106 605359 : if (present(MaxHeatCap)) {
11107 316142 : TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
11108 316142 : TotCap = min(MaxHeatCap, TotCap);
11109 : } else {
11110 289217 : TotCapAdj = TotCap * HeatingCapacityMultiplier;
11111 : }
11112 :
11113 : // Calculate full load outlet conditions
11114 605359 : FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
11115 605359 : FullLoadOutAirHumRat = InletAirHumRat;
11116 605359 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
11117 605359 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
11118 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11119 : // FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
11120 605359 : if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
11121 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
11122 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11123 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
11124 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
11125 : }
11126 :
11127 : // Calculate actual outlet conditions for the input part load ratio
11128 : // Actual outlet conditions are "average" for time step
11129 605359 : if (fanOp == HVAC::FanOp::Continuous) {
11130 : // continuous fan, cycling compressor
11131 352749 : OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
11132 352749 : OutletAirHumRat = (PartLoadRatio * FullLoadOutAirHumRat + (1.0 - PartLoadRatio) * InletAirHumRat);
11133 352749 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11134 : } else {
11135 : // default to cycling fan, cycling compressor
11136 252610 : OutletAirEnthalpy = FullLoadOutAirEnth;
11137 252610 : OutletAirHumRat = FullLoadOutAirHumRat;
11138 252610 : OutletAirTemp = FullLoadOutAirTemp;
11139 : }
11140 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
11141 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
11142 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
11143 : // advised to use the bi-quaratic curve if sufficient manufacturer data is available.
11144 605359 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
11145 289171 : if (state.dataCurveManager->PerfCurve(thisDXCoil.EIRFTemp(Mode))->numDims == 1) {
11146 289170 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), OutdoorDryBulb);
11147 : } else {
11148 1 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
11149 : }
11150 289171 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
11151 : } else {
11152 316188 : EIRTempModFac = 1.0;
11153 316188 : EIRFlowModFac = 1.0;
11154 : }
11155 :
11156 605359 : if (EIRTempModFac < 0.0) {
11157 0 : if (thisDXCoil.EIRFTErrIndex == 0) {
11158 0 : ShowWarningMessage(state, format("The EIRTempModFac curve value for DX heating coil {} ={:.2R}", thisDXCoil.Name, EIRTempModFac));
11159 0 : ShowContinueError(
11160 : state, "EIRTempModFac curve value must be > 0. EIRTempModFac curve value has been reset to 0.0 and simulation is continuing.");
11161 0 : ShowContinueError(state, format("Check the IO reference manual for EIRTempModFac curve guidance [ {} ].", thisDXCoil.DXCoilType));
11162 0 : ShowContinueErrorTimeStamp(state, "");
11163 : }
11164 0 : ShowRecurringWarningErrorAtEnd(state,
11165 : "DX heating coil EIRTempModFac curve value < 0.0 warning continues... ",
11166 0 : thisDXCoil.EIRFTErrIndex,
11167 : EIRTempModFac,
11168 : EIRTempModFac);
11169 0 : EIRTempModFac = 0.0;
11170 : }
11171 :
11172 605359 : EIR = thisDXCoil.RatedEIR(Mode) * EIRTempModFac * EIRFlowModFac;
11173 : // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
11174 605359 : if (TotCapAdj > 0.0) {
11175 605302 : PLRHeating = min(1.0, (PartLoadRatio + (LoadDueToDefrost * PartLoadRatio) / TotCapAdj));
11176 : } else {
11177 57 : PLRHeating = 0.0;
11178 : }
11179 605359 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating) {
11180 289171 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PLRHeating); // Calculate part-load factor
11181 : } else {
11182 316188 : PLF = 1.0;
11183 : }
11184 :
11185 605359 : if (PLF < 0.7) {
11186 0 : if (thisDXCoil.PLRErrIndex == 0) {
11187 0 : ShowWarningMessage(
11188 : state,
11189 0 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
11190 0 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
11191 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
11192 0 : ShowContinueErrorTimeStamp(state, "");
11193 : }
11194 0 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
11195 0 : PLF = 0.7;
11196 : }
11197 :
11198 605359 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
11199 605359 : if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
11200 0 : if (thisDXCoil.ErrIndex4 == 0) {
11201 0 : ShowWarningMessage(state,
11202 0 : format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
11203 0 : thisDXCoil.Name,
11204 0 : thisDXCoil.HeatingCoilRuntimeFraction));
11205 0 : ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
11206 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
11207 0 : ShowContinueErrorTimeStamp(state, "");
11208 : }
11209 0 : ShowRecurringWarningErrorAtEnd(state,
11210 0 : thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
11211 0 : thisDXCoil.ErrIndex4,
11212 0 : thisDXCoil.HeatingCoilRuntimeFraction,
11213 0 : thisDXCoil.HeatingCoilRuntimeFraction);
11214 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
11215 605359 : } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
11216 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
11217 : }
11218 : // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
11219 605359 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
11220 605359 : thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
11221 :
11222 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
11223 : // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
11224 :
11225 605359 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
11226 316211 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
11227 : } else {
11228 289148 : thisDXCoil.CrankcaseHeaterPower =
11229 289148 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
11230 289148 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
11231 : }
11232 :
11233 605359 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
11234 605359 : thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy);
11235 : // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
11236 : // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
11237 605359 : thisDXCoil.DefrostPower *= thisDXCoil.HeatingCoilRuntimeFraction;
11238 :
11239 605359 : thisDXCoil.OutletAirTemp = OutletAirTemp;
11240 605359 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
11241 605359 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
11242 605359 : thisDXCoil.CompressorPartLoadRatio = PartLoadRatio;
11243 :
11244 : } else {
11245 :
11246 : // DX coil is off; just pass through conditions
11247 6985917 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
11248 6985917 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
11249 6985917 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
11250 :
11251 6985917 : thisDXCoil.ElecHeatingPower = 0.0;
11252 6985917 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
11253 6985917 : thisDXCoil.DefrostPower = 0.0;
11254 :
11255 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
11256 : // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
11257 6985917 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
11258 2520848 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
11259 : } else {
11260 4465069 : thisDXCoil.CrankcaseHeaterPower =
11261 4465069 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
11262 : }
11263 6985917 : thisDXCoil.CompressorPartLoadRatio = 0.0;
11264 :
11265 : } // end of on/off if - else
11266 :
11267 7591276 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
11268 7591276 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
11269 7591276 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
11270 7591276 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
11271 7591276 : state.dataDXCoils->DXCoilTotalHeating(DXCoilNum) = thisDXCoil.TotalHeatingEnergyRate;
11272 7591276 : state.dataDXCoils->DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
11273 7591276 : state.dataDXCoils->DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;
11274 :
11275 : // set outlet node conditions
11276 7591276 : int airOutletNode = thisDXCoil.AirOutNode;
11277 7591276 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
11278 7591276 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
11279 :
11280 : // calc secondary coil if specified
11281 7591276 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
11282 81925 : CalcSecondaryDXCoils(state, DXCoilNum);
11283 : }
11284 7591276 : }
11285 :
11286 4143600 : void CalcMultiSpeedDXCoil(EnergyPlusData &state,
11287 : int const DXCoilNum, // the number of the DX heating coil to be simulated
11288 : Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
11289 : Real64 const CycRatio, // cycling part load ratio
11290 : ObjexxFCL::Optional_bool_const ForceOn)
11291 : {
11292 :
11293 : // SUBROUTINE INFORMATION:
11294 : // AUTHOR Fred Buhl
11295 : // DATE WRITTEN September 2002
11296 : // MODIFIED Raustad/Shirey, Feb 2004
11297 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
11298 : // Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
11299 : // April 2010, Chandan sharma, FSEC, added basin heater
11300 :
11301 : // PURPOSE OF THIS SUBROUTINE:
11302 : // Calculates the air-side performance and electrical energy use of a direct-
11303 : // expansion, air-cooled cooling unit with a 2 speed or variable speed compressor.
11304 :
11305 : // METHODOLOGY EMPLOYED:
11306 : // Uses the same methodology as the single speed DX unit model (SUBROUTINE CalcDoe2DXCoil).
11307 : // In addition it assumes that the unit performance is obtained by interpolating between
11308 : // the performance at high speed and that at low speed. If the output needed is below
11309 : // that produced at low speed, the compressor cycles between off and low speed.
11310 :
11311 : // Using/Aliasing
11312 : using Curve::CurveValue;
11313 :
11314 : // SUBROUTINE ARGUMENT DEFINITIONS:
11315 : // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
11316 :
11317 : // SUBROUTINE PARAMETER DEFINITIONS:
11318 : static constexpr std::string_view RoutineNameHighSpeedOutlet("CalcMultiSpeedDXCoil:highspeedoutlet");
11319 : static constexpr std::string_view RoutineNameLowSpeedOutlet("CalcMultiSpeedDXCoil:lowspeedoutlet");
11320 : static constexpr std::string_view RoutineNameNewDewPointConditions("CalcMultiSpeedDXCoil:newdewpointconditions");
11321 :
11322 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11323 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
11324 : Real64 AirMassFlowRatio; // Ratio of max air mass flow to rated air mass flow
11325 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
11326 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
11327 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
11328 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
11329 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11330 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
11331 : Real64 OutletAirDryBulbTemp; // outlet air dry bulb temperature [C]
11332 : Real64 OutletAirEnthalpy; // outlet air enthalpy [J/kg]
11333 : Real64 OutletAirHumRat; // outlet air humidity ratio [kg/kg]
11334 : Real64 OutletAirDryBulbTempSat; // outlet air dry bulb temp at saturation at the outlet enthalpy [C]
11335 : Real64 LSOutletAirDryBulbTemp; // low speed outlet air dry bulb temperature [C]
11336 : Real64 LSOutletAirEnthalpy; // low speed outlet air enthalpy [J/kg]
11337 : Real64 LSOutletAirHumRat; // low speed outlet air humidity ratio [kg/kg]
11338 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
11339 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
11340 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
11341 : Real64 tADP; // Apparatus dew point temperature [C]
11342 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
11343 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
11344 : Real64 RatedCBFHS; // coil bypass factor at rated conditions (high speed)
11345 : Real64 CBFHS; // coil bypass factor at max flow (high speed)
11346 : Real64 TotCapHS; // total capacity at high speed [W]
11347 : Real64 SHRHS; // sensible heat ratio at high speed
11348 : Real64 TotCapLS; // total capacity at low speed [W]
11349 : Real64 SHRLS; // sensible heat ratio at low speed
11350 : Real64 EIRTempModFacHS; // EIR modifier (function of entering wetbulb, outside drybulb) (high speed)
11351 : Real64 EIRFlowModFacHS; // EIR modifier (function of actual supply air flow vs rated flow) (high speed)
11352 : Real64 EIRHS; // EIR at off rated conditions (high speed)
11353 : Real64 EIRTempModFacLS; // EIR modifier (function of entering wetbulb, outside drybulb) (low speed)
11354 : Real64 EIRLS; // EIR at off rated conditions (low speed)
11355 : Real64 TotCap; // total capacity at current speed [W]
11356 : Real64 SHR; // sensible heat ratio at current speed
11357 : Real64 EIR; // EIR at current speed
11358 : Real64 AirMassFlowNom; // speed ratio weighted average of high and low speed air mass flow rates [kg/s]
11359 : Real64 CBFNom; // coil bypass factor corresponding to AirMassFlowNom and SpeedRatio
11360 : Real64 CBF; // CBFNom adjusted for actual air mass flow rate
11361 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in
11362 : // power calculation
11363 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
11364 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
11365 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
11366 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
11367 : Real64 RhoAir; // Density of air [kg/m3]
11368 : Real64 RhoWater; // Density of water [kg/m3]
11369 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
11370 : Real64 EvapCondPumpElecPower; // Evaporative condenser electric pump power [W]
11371 4143600 : constexpr int Mode(1); // Performance mode for MultiMode DX coil; Always 1 for other coil types
11372 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
11373 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
11374 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
11375 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
11376 : bool LocalForceOn;
11377 : Real64 AirMassFlowRatio2; // Ratio of low speed air mass flow to rated air mass flow
11378 4143600 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
11379 :
11380 4143600 : if (present(ForceOn)) {
11381 55368 : LocalForceOn = true;
11382 : } else {
11383 4088232 : LocalForceOn = false;
11384 : }
11385 :
11386 4143600 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
11387 :
11388 4143600 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
11389 332756 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
11390 : // If node is not connected to anything, pressure = default, use weather data
11391 332756 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
11392 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
11393 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
11394 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11395 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
11396 : } else {
11397 332756 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
11398 332756 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
11399 332756 : OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure);
11400 : }
11401 332756 : CompAmbTemp = OutdoorDryBulb;
11402 332756 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
11403 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
11404 0 : OutdoorDryBulb = secZoneHB.ZT;
11405 0 : OutdoorHumRat = secZoneHB.airHumRat;
11406 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
11407 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11408 0 : CompAmbTemp = OutdoorDryBulb;
11409 : }
11410 3810844 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
11411 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
11412 0 : OutdoorDryBulb = secZoneHB.ZT;
11413 0 : OutdoorHumRat = secZoneHB.airHumRat;
11414 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
11415 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11416 0 : CompAmbTemp = OutdoorDryBulb;
11417 : } else {
11418 3810844 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
11419 3810844 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
11420 3810844 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11421 3810844 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
11422 3810844 : CompAmbTemp = OutdoorDryBulb;
11423 : }
11424 :
11425 4143600 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
11426 4143600 : AirMassFlowRatio = thisDXCoil.InletAirMassFlowRateMax / thisDXCoil.RatedAirMassFlowRate(Mode);
11427 4143600 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
11428 4143600 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
11429 4143600 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
11430 4143600 : InletAirHumRat = thisDXCoil.InletAirHumRat;
11431 4143600 : AirMassFlowRatio2 = 1.0; // DXCoil(DXCoilNum)%RatedAirMassFlowRate2 / DXCoil(DXCoilNum)%RatedAirMassFlowRate(Mode)
11432 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11433 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
11434 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
11435 4143600 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
11436 4143600 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
11437 4120107 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
11438 23493 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11439 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
11440 23493 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
11441 23493 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
11442 : }
11443 :
11444 3965651 : if ((AirMassFlow > 0.0 && CompAmbTemp >= thisDXCoil.MinOATCompressor) &&
11445 8109251 : ((GetCurrentScheduleValue(state, thisDXCoil.SchedPtr) > 0.0) || (LocalForceOn)) && (SpeedRatio > 0.0 || CycRatio > 0.0)) {
11446 :
11447 3061183 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
11448 3061183 : if (SpeedRatio > 0.0) {
11449 : // Adjust high speed coil bypass factor for actual maximum air flow rate.
11450 2201122 : RatedCBFHS = thisDXCoil.RatedCBF(Mode);
11451 2201122 : CBFHS = AdjustCBF(RatedCBFHS, thisDXCoil.RatedAirMassFlowRate(Mode), thisDXCoil.InletAirMassFlowRateMax);
11452 : // get high speed total capacity and SHR at current conditions
11453 6603366 : CalcTotCapSHR(state,
11454 : InletAirDryBulbTemp,
11455 : InletAirHumRat,
11456 : InletAirEnthalpy,
11457 : InletAirWetBulbC,
11458 : AirMassFlowRatio,
11459 : thisDXCoil.InletAirMassFlowRateMax,
11460 2201122 : thisDXCoil.RatedTotCap(Mode),
11461 : CBFHS,
11462 2201122 : thisDXCoil.CCapFTemp(Mode),
11463 2201122 : thisDXCoil.CCapFFlow(Mode),
11464 : TotCapHS,
11465 : SHRHS,
11466 : CondInletTemp,
11467 : OutdoorPressure,
11468 2201122 : thisDXCoil.capModFacTotal);
11469 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11470 : // CondInletTemp, Node(DXCoil(DXCoilNum)%AirInNode)%Press)
11471 : // get the high speed SHR from user specified SHR modifier curves
11472 2201122 : if (thisDXCoil.UserSHRCurveExists) {
11473 3662 : SHRHS = CalcSHRUserDefinedCurves(state,
11474 : InletAirDryBulbTemp,
11475 : InletAirWetBulbC,
11476 : AirMassFlowRatio,
11477 3662 : thisDXCoil.SHRFTemp(Mode),
11478 3662 : thisDXCoil.SHRFFlow(Mode),
11479 3662 : thisDXCoil.RatedSHR(Mode));
11480 : }
11481 : // get low speed total capacity and SHR at current conditions
11482 2201122 : CalcTotCapSHR(state,
11483 : InletAirDryBulbTemp,
11484 : InletAirHumRat,
11485 : InletAirEnthalpy,
11486 : InletAirWetBulbC,
11487 : 1.0,
11488 : thisDXCoil.RatedAirMassFlowRate2,
11489 : thisDXCoil.RatedTotCap2,
11490 : thisDXCoil.RatedCBF2,
11491 : thisDXCoil.CCapFTemp2,
11492 2201122 : thisDXCoil.CCapFFlow(Mode),
11493 : TotCapLS,
11494 : SHRLS,
11495 : CondInletTemp,
11496 : OutdoorPressure,
11497 2201122 : thisDXCoil.capModFacTotal);
11498 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11499 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)
11500 : // get the low speed SHR from user specified SHR modifier curves
11501 2201122 : if (thisDXCoil.UserSHRCurveExists) {
11502 3662 : SHRLS = CalcSHRUserDefinedCurves(state,
11503 : InletAirDryBulbTemp,
11504 : InletAirWetBulbC,
11505 : AirMassFlowRatio2,
11506 : thisDXCoil.SHRFTemp2,
11507 : thisDXCoil.SHRFFlow2,
11508 : thisDXCoil.RatedSHR2);
11509 : }
11510 : // get high speed EIR at current conditions
11511 2201122 : EIRTempModFacHS = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirWetBulbC, CondInletTemp);
11512 2201122 : EIRFlowModFacHS = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
11513 2201122 : EIRHS = thisDXCoil.RatedEIR(Mode) * EIRFlowModFacHS * EIRTempModFacHS;
11514 : // get low speed EIR at current conditions
11515 : // EIRTempModFacLS = CurveValue(state, DXCoil(DXCoilNum)%EIRFTemp(Mode),InletAirWetBulbC,CondInletTemp)
11516 : // CR7307 changed EIRTempModFacLS calculation to that shown below.
11517 2201122 : EIRTempModFacLS = CurveValue(state, thisDXCoil.EIRFTemp2, InletAirWetBulbC, CondInletTemp);
11518 2201122 : EIRLS = thisDXCoil.RatedEIR2 * EIRTempModFacLS;
11519 :
11520 : // get current total capacity, SHR, EIR
11521 2201122 : if (SpeedRatio >= 1.0) {
11522 703252 : TotCap = TotCapHS;
11523 703252 : SHR = SHRHS;
11524 703252 : EIR = EIRHS;
11525 703252 : CBFNom = CBFHS;
11526 703252 : AirMassFlowNom = thisDXCoil.InletAirMassFlowRateMax;
11527 703252 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
11528 703252 : EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower(Mode);
11529 : } else {
11530 1497870 : TotCap = SpeedRatio * TotCapHS + (1.0 - SpeedRatio) * TotCapLS;
11531 1497870 : EIR = SpeedRatio * EIRHS + (1.0 - SpeedRatio) * EIRLS;
11532 1497870 : CBFNom = SpeedRatio * CBFHS + (1.0 - SpeedRatio) * thisDXCoil.RatedCBF2;
11533 1497870 : AirMassFlowNom = SpeedRatio * thisDXCoil.InletAirMassFlowRateMax + (1.0 - SpeedRatio) * thisDXCoil.RatedAirMassFlowRate2;
11534 1497870 : CondAirMassFlow = RhoAir * (SpeedRatio * thisDXCoil.EvapCondAirFlow(Mode) + (1.0 - SpeedRatio) * thisDXCoil.EvapCondAirFlow2);
11535 1497870 : EvapCondPumpElecPower =
11536 1497870 : SpeedRatio * thisDXCoil.EvapCondPumpElecNomPower(Mode) + (1.0 - SpeedRatio) * thisDXCoil.EvapCondPumpElecNomPower2;
11537 : }
11538 2201122 : hDelta = TotCap / AirMassFlow;
11539 2201122 : if (thisDXCoil.UserSHRCurveExists) {
11540 3662 : if (SpeedRatio >= 1.0) {
11541 2939 : SHR = SHRHS;
11542 : } else {
11543 723 : SHR = min(SpeedRatio * SHRHS + (1.0 - SpeedRatio) * SHRLS, 1.0);
11544 : }
11545 3662 : OutletAirEnthalpy = InletAirEnthalpy - hDelta;
11546 3662 : if (SHR < 1.0) {
11547 3662 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11548 3662 : OutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11549 3662 : if (OutletAirHumRat <= 0.0) {
11550 0 : OutletAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
11551 : }
11552 : } else {
11553 0 : SHR = 1.0;
11554 0 : OutletAirHumRat = InletAirHumRat;
11555 : }
11556 3662 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11557 3662 : OutletAirDryBulbTempSat = PsyTdpFnWPb(state, OutletAirHumRat, OutdoorPressure, RoutineNameHighSpeedOutlet);
11558 3662 : if (OutletAirDryBulbTempSat > OutletAirDryBulbTemp) {
11559 3635 : OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11560 3635 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy, RoutineNameHighSpeedOutlet);
11561 : }
11562 :
11563 : } else {
11564 : // Adjust CBF for off-nominal flow
11565 2197460 : CBF = AdjustCBF(CBFNom, AirMassFlowNom, AirMassFlow);
11566 : // Calculate new apparatus dew point conditions
11567 2197460 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
11568 2197460 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure);
11569 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11570 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
11571 2197460 : wADP = PsyWFnTdbH(state, tADP, hADP);
11572 2197460 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
11573 : // get corresponding SHR
11574 2197460 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
11575 2197460 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
11576 : } else {
11577 0 : SHR = 1.0;
11578 : }
11579 :
11580 : // cr8918 SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
11581 2197460 : OutletAirEnthalpy = InletAirEnthalpy - hDelta;
11582 : // get outlet conditions
11583 2197460 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11584 2197460 : OutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11585 :
11586 2197460 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11587 2197460 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
11588 2197460 : if (OutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
11589 383753 : OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11590 383753 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy);
11591 : }
11592 : }
11593 : // Coil total/sensible/latent cooling rates and electrical power
11594 2201122 : CalcComponentSensibleLatentOutput(AirMassFlow,
11595 : InletAirDryBulbTemp,
11596 : InletAirHumRat,
11597 : OutletAirDryBulbTemp,
11598 : OutletAirHumRat,
11599 2201122 : thisDXCoil.SensCoolingEnergyRate,
11600 2201122 : thisDXCoil.LatCoolingEnergyRate,
11601 2201122 : thisDXCoil.TotalCoolingEnergyRate);
11602 2201122 : thisDXCoil.ElecCoolingPower = TotCap * EIR;
11603 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
11604 2201122 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
11605 2201122 : thisDXCoil.PartLoadRatio = 1.0;
11606 2201122 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0;
11607 :
11608 2201122 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
11609 2201122 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
11610 2201122 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
11611 :
11612 860061 : } else if (CycRatio > 0.0) {
11613 :
11614 860061 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11615 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
11616 6143 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect2);
11617 6143 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
11618 : }
11619 :
11620 : // Adjust low speed coil bypass factor for actual flow rate.
11621 : // CBF = AdjustCBF(DXCoil(DXCoilNum)%RatedCBF2,DXCoil(DXCoilNum)%RatedAirMassFlowRate2,AirMassFlow)
11622 : // get low speed total capacity and SHR at current conditions
11623 860061 : CalcTotCapSHR(state,
11624 : InletAirDryBulbTemp,
11625 : InletAirHumRat,
11626 : InletAirEnthalpy,
11627 : InletAirWetBulbC,
11628 : 1.0,
11629 : thisDXCoil.RatedAirMassFlowRate2,
11630 : thisDXCoil.RatedTotCap2,
11631 : thisDXCoil.RatedCBF2,
11632 : thisDXCoil.CCapFTemp2,
11633 860061 : thisDXCoil.CCapFFlow(Mode),
11634 : TotCapLS,
11635 : SHRLS,
11636 : CondInletTemp,
11637 : OutdoorPressure,
11638 860061 : thisDXCoil.capModFacTotal);
11639 : // get the low speed SHR from user specified SHR modifier curves
11640 860061 : if (thisDXCoil.UserSHRCurveExists) {
11641 1886 : SHRLS = CalcSHRUserDefinedCurves(
11642 : state, InletAirDryBulbTemp, InletAirWetBulbC, 1.0, thisDXCoil.SHRFTemp2, thisDXCoil.SHRFFlow2, thisDXCoil.RatedSHR2);
11643 : }
11644 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11645 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)
11646 860061 : hDelta = TotCapLS / AirMassFlow;
11647 860061 : if (thisDXCoil.UserSHRCurveExists) {
11648 1886 : SHR = SHRLS;
11649 1886 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
11650 1886 : if (SHR < 1.0) {
11651 1886 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11652 1886 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11653 1886 : if (LSOutletAirHumRat <= 0.0) {
11654 0 : LSOutletAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
11655 : }
11656 : } else {
11657 0 : SHR = 1.0;
11658 0 : LSOutletAirHumRat = InletAirHumRat;
11659 : }
11660 1886 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
11661 1886 : OutletAirDryBulbTempSat = PsyTdpFnWPb(state, LSOutletAirHumRat, OutdoorPressure, RoutineNameLowSpeedOutlet);
11662 1886 : if (OutletAirDryBulbTempSat > LSOutletAirDryBulbTemp) {
11663 1 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11664 1 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineNameLowSpeedOutlet);
11665 : }
11666 :
11667 : } else {
11668 : // Adjust CBF for off-nominal flow
11669 858175 : CBF = AdjustCBF(thisDXCoil.RatedCBF2, thisDXCoil.RatedAirMassFlowRate2, AirMassFlow);
11670 : // Calculate new apparatus dew point conditions
11671 858175 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
11672 858175 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineNameNewDewPointConditions);
11673 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11674 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
11675 858175 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineNameNewDewPointConditions);
11676 858175 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
11677 : // get corresponding SHR
11678 858175 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
11679 858175 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
11680 : } else {
11681 0 : SHR = 1.0;
11682 : }
11683 : // cr8918 SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
11684 : // get low speed outlet conditions
11685 858175 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
11686 858175 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11687 858175 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11688 858175 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
11689 858175 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineNameLowSpeedOutlet);
11690 858175 : if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
11691 84351 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11692 84351 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineNameLowSpeedOutlet);
11693 : }
11694 : }
11695 : // outlet conditions are average of inlet and low speed weighted by CycRatio
11696 860061 : OutletAirEnthalpy = CycRatio * LSOutletAirEnthalpy + (1.0 - CycRatio) * InletAirEnthalpy;
11697 860061 : OutletAirHumRat = CycRatio * LSOutletAirHumRat + (1.0 - CycRatio) * InletAirHumRat;
11698 860061 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11699 : // get low speed EIR at current conditions
11700 : // EIRTempModFacLS = CurveValue(state, DXCoil(DXCoilNum)%EIRFTemp(Mode),InletAirWetBulbC,CondInletTemp)
11701 : // CR7307 changed EIRTempModFacLS calculation to that shown below.
11702 860061 : EIRTempModFacLS = CurveValue(state, thisDXCoil.EIRFTemp2, InletAirWetBulbC, CondInletTemp);
11703 860061 : EIRLS = thisDXCoil.RatedEIR2 * EIRTempModFacLS;
11704 : // get the part load factor that will account for cycling losses
11705 860061 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CycRatio);
11706 860061 : if (PLF < 0.7) {
11707 0 : PLF = 0.7;
11708 : }
11709 : // calculate the run time fraction
11710 860061 : thisDXCoil.CoolingCoilRuntimeFraction = CycRatio / PLF;
11711 860061 : thisDXCoil.PartLoadRatio = CycRatio;
11712 860061 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
11713 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
11714 : }
11715 : // get the eletrical power consumption
11716 860061 : thisDXCoil.ElecCoolingPower = TotCapLS * EIRLS * thisDXCoil.CoolingCoilRuntimeFraction;
11717 :
11718 : // Coil total/sensible/latent cooling rates and electrical power
11719 860061 : CalcComponentSensibleLatentOutput(AirMassFlow,
11720 : InletAirDryBulbTemp,
11721 : InletAirHumRat,
11722 : OutletAirDryBulbTemp,
11723 : OutletAirHumRat,
11724 860061 : thisDXCoil.SensCoolingEnergyRate,
11725 860061 : thisDXCoil.LatCoolingEnergyRate,
11726 860061 : thisDXCoil.TotalCoolingEnergyRate);
11727 860061 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
11728 860061 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
11729 860061 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
11730 860061 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
11731 860061 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow2 * thisDXCoil.CoolingCoilRuntimeFraction;
11732 860061 : EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower2 * thisDXCoil.CoolingCoilRuntimeFraction;
11733 : }
11734 :
11735 3061183 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11736 : //******************
11737 : // WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
11738 : // H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
11739 : // /RhoWater [kgWater/m3]
11740 : //******************
11741 19013 : RhoWater = RhoH2O(OutdoorDryBulb);
11742 19013 : thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater;
11743 19013 : thisDXCoil.EvapCondPumpElecPower = EvapCondPumpElecPower;
11744 : // set water system demand request (if needed)
11745 19013 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
11746 :
11747 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
11748 0 : thisDXCoil.EvapWaterConsumpRate;
11749 : }
11750 :
11751 : // Calculate basin heater power
11752 19013 : CalcBasinHeaterPower(state,
11753 : thisDXCoil.BasinHeaterPowerFTempDiff,
11754 : thisDXCoil.BasinHeaterSchedulePtr,
11755 : thisDXCoil.BasinHeaterSetPointTemp,
11756 19013 : thisDXCoil.BasinHeaterPower);
11757 19013 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
11758 : }
11759 :
11760 : } else {
11761 :
11762 : // DX coil is off; just pass through conditions
11763 1082417 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
11764 1082417 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
11765 1082417 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
11766 :
11767 1082417 : thisDXCoil.ElecCoolingPower = 0.0;
11768 1082417 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
11769 1082417 : thisDXCoil.SensCoolingEnergyRate = 0.0;
11770 1082417 : thisDXCoil.LatCoolingEnergyRate = 0.0;
11771 1082417 : thisDXCoil.EvapCondPumpElecPower = 0.0;
11772 1082417 : thisDXCoil.EvapWaterConsumpRate = 0.0;
11773 :
11774 : // Calculate basin heater power
11775 1082417 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11776 4480 : CalcBasinHeaterPower(state,
11777 : thisDXCoil.BasinHeaterPowerFTempDiff,
11778 : thisDXCoil.BasinHeaterSchedulePtr,
11779 : thisDXCoil.BasinHeaterSetPointTemp,
11780 4480 : thisDXCoil.BasinHeaterPower);
11781 : }
11782 : }
11783 :
11784 4143600 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
11785 4143600 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
11786 4143600 : thisDXCoil.CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure
11787 :
11788 : // set outlet node conditions
11789 4143600 : int airOutletNode = thisDXCoil.AirOutNode;
11790 4143600 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
11791 4143600 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
11792 :
11793 : // calc secondary coil if specified
11794 4143600 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
11795 0 : CalcSecondaryDXCoils(state, DXCoilNum);
11796 : }
11797 4143600 : }
11798 :
11799 130449 : void CalcBasinHeaterPowerForMultiModeDXCoil(EnergyPlusData &state,
11800 : int const DXCoilNum, // Index of coil being simulated
11801 : HVAC::CoilMode const DehumidMode // Dehumidification mode (0=normal, 1=enhanced)
11802 : )
11803 : {
11804 :
11805 : // SUBROUTINE INFORMATION:
11806 : // AUTHOR Chandan Sharma, FSEC
11807 : // DATE WRITTEN May 2010
11808 :
11809 : // PURPOSE OF THIS SUBROUTINE:
11810 : // To calculate the basin heater power for multi mode DX cooling coil
11811 :
11812 : // METHODOLOGY EMPLOYED:
11813 : // The methodology employed is as follows:
11814 : // 1) If the number of capacity stages is equal to 1 and the CondenserType for stage 1
11815 : // is EvapCooled, then the basin heater power is calculated for (1-runtimefractionstage1) of DX coil
11816 : // 2) If the number of capacity stages is greater than 1, then
11817 : // a) If the CondenserType for stage 1 is EvapCooled, then the basin heater power is calculated for
11818 : // (1-runtimefractionofstage1) of DX coil
11819 : // b) Elseif the CondenserType for stage 2 is EvapCooled, then the basin heater power is calculated for
11820 : // (1-runtimefractionofstage2) of DX coil
11821 :
11822 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11823 : int PerfMode; // Performance mode for MultiMode DX coil; Always 1 for other coil types
11824 : // 1-2=normal mode: 1=stage 1 only, 2=stage 1&2
11825 : // 3-4=enhanced dehumidification mode: 3=stage 1 only, 4=stage 1&2
11826 :
11827 130449 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
11828 :
11829 130449 : if (thisDXCoil.NumCapacityStages == 1) {
11830 11265 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
11831 : } else {
11832 119184 : PerfMode = (int)DehumidMode * 2 + 1;
11833 119184 : if (thisDXCoil.CondenserType(PerfMode) == DataHeatBalance::RefrigCondenserType::Evap) {
11834 0 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
11835 119184 : } else if (thisDXCoil.CondenserType(PerfMode + 1) == DataHeatBalance::RefrigCondenserType::Evap) {
11836 0 : CalcBasinHeaterPower(state,
11837 : thisDXCoil.BasinHeaterPowerFTempDiff,
11838 : thisDXCoil.BasinHeaterSchedulePtr,
11839 : thisDXCoil.BasinHeaterSetPointTemp,
11840 0 : thisDXCoil.BasinHeaterPower);
11841 0 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilStg2RuntimeFrac);
11842 : }
11843 : }
11844 130449 : }
11845 :
11846 53239294 : Real64 AdjustCBF(Real64 const CBFNom, // nominal coil bypass factor
11847 : Real64 const AirMassFlowRateNom, // nominal air mass flow rate [kg/s]
11848 : Real64 const AirMassFlowRate // actual air mass flow rate [kg/s]
11849 : )
11850 : {
11851 :
11852 : // FUNCTION INFORMATION:
11853 : // AUTHOR Fred Buhl using Don Shirey's code
11854 : // DATE WRITTEN September 2002
11855 :
11856 : // PURPOSE OF THIS FUNCTION:
11857 : // Adjust coil bypass factor for actual air flow rate.
11858 :
11859 : // METHODOLOGY EMPLOYED:
11860 : // Uses relation CBF = exp(-NTU) whereNTU = A0/(m*cp). Relationship models the cooling coil
11861 : // as a heat exchanger with Cmin/Cmax = 0.
11862 :
11863 : // Return value
11864 : Real64 CBFAdj; // the result - the adjusted coil bypass factor
11865 :
11866 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
11867 : Real64 A0; // intermediate variable
11868 : Real64 ADiff; // intermediate variable
11869 :
11870 53239294 : if (CBFNom > 0.0) {
11871 53239294 : A0 = -std::log(CBFNom) * AirMassFlowRateNom;
11872 : } else {
11873 0 : A0 = 0.0;
11874 : }
11875 53239294 : ADiff = -A0 / AirMassFlowRate;
11876 53239294 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
11877 53212495 : CBFAdj = std::exp(ADiff);
11878 : } else {
11879 26799 : CBFAdj = 1.0e-6;
11880 : }
11881 :
11882 53239294 : return CBFAdj;
11883 : }
11884 :
11885 26335 : Real64 CalcCBF(EnergyPlusData &state,
11886 : std::string const &UnitType,
11887 : std::string const &UnitName,
11888 : Real64 const InletAirTemp, // inlet air temperature [C]
11889 : Real64 const InletAirHumRat, // inlet air humidity ratio [kg water / kg dry air]
11890 : Real64 const TotCap, // total cooling capacity [Watts]
11891 : Real64 const AirVolFlowRate, // the air volume flow rate at the given capacity [m3/s]
11892 : Real64 const SHR, // sensible heat ratio at the given capacity and flow rate
11893 : bool const PrintFlag // flag used to print warnings if desired
11894 : )
11895 : {
11896 :
11897 : // FUNCTION INFORMATION:
11898 : // AUTHOR Fred Buhl using Don Shirey's code
11899 : // DATE WRITTEN September 2002
11900 :
11901 : // PURPOSE OF THIS FUNCTION:
11902 : // Calculate the coil bypass factor for a coil given the total capacity at the entering conditions,
11903 : // air mass flow rate at the entering conditions, and the sensible heat ratio (SHR) at the
11904 : // entering conditions. Standard barometric pressure is used for this model parameter.
11905 :
11906 : // METHODOLOGY EMPLOYED:
11907 : // calculate SlopeRated (deltahumrat/deltaT) using rated unit information provided by
11908 : // user. Then hunt along saturation curve of psychrometric chart until the slope of the line
11909 : // between the saturation point and rated inlet air humidity ratio and T is the same as SlopeRated.
11910 : // When the slopes are equal, then we have located the apparatus dewpoint of the coil at rated
11911 : // conditions. From this information, coil bypass factor is calculated.
11912 :
11913 : // Using/Aliasing
11914 :
11915 : // Return value
11916 26335 : Real64 CBF(0.0); // the result - the coil bypass factor
11917 :
11918 : // FUNCTION PARAMETER DEFINITIONS:
11919 : static constexpr std::string_view RoutineName("CalcCBF");
11920 26335 : constexpr Real64 SmallDifferenceTest(0.00000001);
11921 :
11922 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
11923 : Real64 InletAirEnthalpy; // Enthalpy of inlet air to evaporator at given conditions [J/kg]
11924 26335 : Real64 DeltaH(0.0); // Enthalpy drop across evaporator at given conditions [J/kg]
11925 26335 : Real64 DeltaT(0.0); // Temperature drop across evaporator at given conditions [C]
11926 26335 : Real64 DeltaHumRat(0.0); // Humidity ratio drop across evaporator at given conditions [kg/kg]
11927 26335 : Real64 OutletAirTemp(InletAirTemp); // Outlet dry-bulb temperature from evaporator at given conditions [C]
11928 26335 : Real64 OutletAirTempSat(InletAirTemp); // Saturation dry-bulb temperature from evaporator at outlet air enthalpy [C]
11929 : Real64 OutletAirEnthalpy; // Enthalpy of outlet air at given conditions [J/kg]
11930 26335 : Real64 OutletAirHumRat(InletAirHumRat); // Outlet humidity ratio from evaporator at given conditions [kg/kg]
11931 : Real64 OutletAirRH; // relative humidity of the outlet air
11932 : Real64 Error; // Error term used in given coil bypass factor (CBF) calculations
11933 : Real64 ErrorLast; // Error term, from previous iteration
11934 : int Iter; // Iteration loop counter in CBF calculations
11935 26335 : int IterMax(50); // Maximum number of iterations in CBF calculations
11936 : Real64 ADPTemp; // Apparatus dewpoint temperature used in CBF calculations [C]
11937 : Real64 ADPHumRat; // Apparatus dewpoint humidity used in CBF calculations [kg/kg]
11938 : Real64 ADPEnthalpy; // Air enthalpy at apparatus dew point [J/kg]
11939 : Real64 DeltaADPTemp; // Change in Apparatus Dew Point used in CBF calculations [C]
11940 26335 : Real64 SlopeAtConds(0.0); // Slope (DeltaHumRat/DeltaT) at given conditions
11941 26335 : Real64 Slope(0.0); // Calculated Slope used while hunting for Tadp
11942 : Real64 Tolerance; // Convergence tolerance for CBF calculations
11943 : Real64 HTinHumRatOut; // Air enthalpy at inlet air temp and outlet air humidity ratio [J/kg]
11944 : Real64 AirMassFlowRate; // the standard air mass flow rate at the given capacity [kg/s]
11945 : Real64 adjustedSHR; // SHR calculated using adjusted outlet air properties []
11946 26335 : bool CBFErrors(false); // Set to true if errors in CBF calculation, fatal at end of routine
11947 :
11948 26335 : auto &DXCT = state.dataHVACGlobal->DXCT;
11949 :
11950 26335 : if (AirVolFlowRate <= 0.0 || TotCap <= 0.0) { // Coil not running or has no capacity, don't calculate CBF
11951 0 : return CBF;
11952 : }
11953 :
11954 26335 : AirMassFlowRate = AirVolFlowRate * PsyRhoAirFnPbTdbW(state, DataEnvironment::StdPressureSeaLevel, InletAirTemp, InletAirHumRat, RoutineName);
11955 26335 : DeltaH = TotCap / AirMassFlowRate;
11956 26335 : InletAirEnthalpy = PsyHFnTdbW(InletAirTemp, InletAirHumRat);
11957 26335 : HTinHumRatOut = InletAirEnthalpy - (1.0 - SHR) * DeltaH;
11958 26335 : OutletAirHumRat = PsyWFnTdbH(state, InletAirTemp, HTinHumRatOut);
11959 26335 : DeltaHumRat = InletAirHumRat - OutletAirHumRat;
11960 26335 : OutletAirEnthalpy = InletAirEnthalpy - DeltaH;
11961 26335 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11962 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11963 : // Pressure will have to be pass into this subroutine to fix this one
11964 26335 : OutletAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
11965 26335 : if (OutletAirRH >= 1.0 && PrintFlag) {
11966 10 : ShowWarningError(state, format("For object = {}, name = \"{}\"", UnitType, UnitName));
11967 10 : ShowContinueError(state, "Calculated outlet air relative humidity greater than 1. The combination of");
11968 10 : ShowContinueError(state, "rated air volume flow rate, total cooling capacity and sensible heat ratio yields coil exiting");
11969 10 : ShowContinueError(state, "air conditions above the saturation curve. Possible fixes are to reduce the rated total cooling");
11970 10 : ShowContinueError(state, "capacity, increase the rated air volume flow rate, or reduce the rated sensible heat ratio for this coil.");
11971 10 : ShowContinueError(state, "If autosizing, it is recommended that all three of these values be autosized.");
11972 10 : ShowContinueError(state, "...Inputs used for calculating cooling coil bypass factor.");
11973 10 : ShowContinueError(state, format("...Inlet Air Temperature = {:.2R} C", InletAirTemp));
11974 10 : ShowContinueError(state, format("...Outlet Air Temperature = {:.2R} C", OutletAirTemp));
11975 10 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", InletAirHumRat));
11976 10 : ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
11977 10 : ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
11978 10 : ShowContinueError(state, format("...Air Mass Flow Rate used in calculation = {:.6R} kg/s", AirMassFlowRate));
11979 10 : ShowContinueError(state, format("...Air Volume Flow Rate used in calculation = {:.6R} m3/s", AirVolFlowRate));
11980 10 : if (TotCap > 0.0) {
11981 20 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
11982 10 : ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
11983 0 : ShowContinueError(state,
11984 0 : format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
11985 0 : AirVolFlowRate / TotCap));
11986 : }
11987 : }
11988 10 : ShowContinueErrorTimeStamp(state, "");
11989 10 : OutletAirTempSat = PsyTsatFnHPb(state, OutletAirEnthalpy, DataEnvironment::StdPressureSeaLevel, RoutineName);
11990 10 : if (OutletAirTemp < OutletAirTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
11991 10 : OutletAirTemp = OutletAirTempSat + 0.005;
11992 10 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy, RoutineName);
11993 10 : DeltaHumRat = InletAirHumRat - OutletAirHumRat;
11994 10 : HTinHumRatOut = PsyHFnTdbW(InletAirTemp, OutletAirHumRat);
11995 10 : adjustedSHR = (HTinHumRatOut - OutletAirEnthalpy) / DeltaH;
11996 10 : ShowContinueError(state, "CalcCBF: SHR adjusted to achieve valid outlet air properties and the simulation continues.");
11997 10 : ShowContinueError(state, format("CalcCBF: initial SHR = {:.5R}", SHR));
11998 10 : ShowContinueError(state, format("CalcCBF: adjusted SHR = {:.5R}", adjustedSHR));
11999 : }
12000 : }
12001 26335 : DeltaT = InletAirTemp - OutletAirTemp;
12002 26335 : if (DeltaT <= 0.0) {
12003 0 : ShowSevereError(state, format("For object = {}, name = \"{}\"", UnitType, UnitName));
12004 0 : ShowContinueError(state, "Calculated coil delta T is less than or equal to 0. The combination of");
12005 0 : ShowContinueError(state, "rated air volume flow rate, total cooling capacity and sensible heat ratio yields coil exiting");
12006 0 : ShowContinueError(state, "air conditions that are not reasonable. Possible fixes are to adjust the rated total cooling");
12007 0 : ShowContinueError(state, "capacity, rated air volume flow rate, or rated sensible heat ratio for this coil.");
12008 0 : ShowContinueError(state, "If autosizing, it is recommended that all three of these values be autosized.");
12009 0 : ShowContinueError(state, "...Inputs used for calculating cooling coil bypass factor.");
12010 0 : ShowContinueError(state, format("...Inlet Air Temperature = {:.2R} C", InletAirTemp));
12011 0 : ShowContinueError(state, format("...Outlet Air Temperature = {:.2R} C", OutletAirTemp));
12012 0 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", InletAirHumRat));
12013 0 : ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
12014 0 : ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
12015 0 : ShowContinueError(state, format("...Air Mass Flow Rate used in calculation = {:.6R} kg/s", AirMassFlowRate));
12016 0 : ShowContinueError(state, format("...Air Volume Flow Rate used in calculation = {:.6R} m3/s", AirVolFlowRate));
12017 0 : if (TotCap > 0.0) {
12018 0 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
12019 0 : ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
12020 0 : ShowContinueError(state,
12021 0 : format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
12022 0 : AirVolFlowRate / TotCap));
12023 : }
12024 : }
12025 0 : ShowContinueErrorTimeStamp(state, "");
12026 0 : ShowFatalError(state, "Check and revise the input data for this coil before rerunning the simulation.");
12027 : }
12028 : // Calculate slope at given conditions
12029 26335 : if (DeltaT > 0.0) SlopeAtConds = DeltaHumRat / DeltaT;
12030 :
12031 : // IF (SlopeAtConds .le. .0000001d0 .or. OutletAirHumRat .le. 0.0d0) THEN
12032 26335 : if (SlopeAtConds < 0.0 || OutletAirHumRat <= 0.0) {
12033 : // Invalid conditions, slope can't be less than zero (SHR > 1) or
12034 : // outlet air humidity ratio can't be less than zero.
12035 0 : ShowSevereError(state, format("{} \"{}\"", UnitType, UnitName));
12036 0 : ShowContinueError(state, "...Invalid slope or outlet air condition when calculating cooling coil bypass factor.");
12037 0 : ShowContinueError(state, format("...Slope = {:.8R}", SlopeAtConds));
12038 0 : ShowContinueError(state, format("...Inlet Air Temperature = {:.2R} C", InletAirTemp));
12039 0 : ShowContinueError(state, format("...Outlet Air Temperature = {:.2R} C", OutletAirTemp));
12040 0 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", InletAirHumRat));
12041 0 : ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
12042 0 : ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
12043 0 : ShowContinueError(state, format("...Air Mass Flow Rate used in calculation = {:.6R} kg/s", AirMassFlowRate));
12044 0 : ShowContinueError(state, format("...Air Volume Flow Rate used in calculation = {:.6R} m3/s", AirVolFlowRate));
12045 0 : if (TotCap > 0.0) {
12046 0 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
12047 0 : ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
12048 0 : ShowContinueError(state,
12049 0 : format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
12050 0 : AirVolFlowRate / TotCap));
12051 : }
12052 : }
12053 0 : ShowContinueErrorTimeStamp(state, "");
12054 0 : CBFErrors = true;
12055 0 : CBF = 0.0; //? Added: Is this what should be returned
12056 : } else {
12057 :
12058 : // First guess for Tadp is outlet air dew point
12059 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12060 : // Pressure will have to be pass into this subroutine to fix this one
12061 26335 : ADPTemp = PsyTdpFnWPb(state, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel);
12062 :
12063 26335 : Tolerance = 1.0; // initial conditions for iteration
12064 26335 : ErrorLast = 100.0;
12065 26335 : Iter = 0;
12066 26335 : DeltaADPTemp = 5.0;
12067 356445 : while ((Iter <= IterMax) && (Tolerance > 0.001)) {
12068 : // Do for IterMax iterations or until the error gets below .1%
12069 330110 : if (Iter > 0) ADPTemp += DeltaADPTemp;
12070 330110 : ++Iter;
12071 :
12072 : // Find new slope using guessed Tadp
12073 :
12074 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12075 : // Pressure will have to be pass into this subroutine to fix this one
12076 330110 : ADPHumRat = min(OutletAirHumRat, PsyWFnTdpPb(state, ADPTemp, DataEnvironment::StdPressureSeaLevel));
12077 330110 : Slope = (InletAirHumRat - ADPHumRat) / max(0.001, (InletAirTemp - ADPTemp));
12078 :
12079 : // check for convergence (slopes are equal to within error tolerance)
12080 :
12081 330110 : Error = (Slope - SlopeAtConds) / SlopeAtConds;
12082 330110 : if ((Error > 0.0) && (ErrorLast < 0.0)) {
12083 106468 : DeltaADPTemp = -DeltaADPTemp / 2.0;
12084 223642 : } else if ((Error < 0.0) && (ErrorLast > 0.0)) {
12085 120651 : DeltaADPTemp = -DeltaADPTemp / 2.0;
12086 102991 : } else if (std::abs(Error) > std::abs(ErrorLast)) {
12087 543 : DeltaADPTemp = -DeltaADPTemp / 2.0;
12088 : }
12089 330110 : ErrorLast = Error;
12090 :
12091 330110 : Tolerance = std::abs(Error);
12092 : }
12093 :
12094 : // Calculate Bypass Factor from Enthalpies
12095 :
12096 26335 : InletAirEnthalpy = PsyHFnTdbW(InletAirTemp, InletAirHumRat);
12097 26335 : OutletAirEnthalpy = PsyHFnTdbW(OutletAirTemp, OutletAirHumRat);
12098 26335 : ADPEnthalpy = PsyHFnTdbW(ADPTemp, ADPHumRat);
12099 26335 : CBF = min(1.0, (OutletAirEnthalpy - ADPEnthalpy) / (InletAirEnthalpy - ADPEnthalpy));
12100 26335 : if (Iter > IterMax && PrintFlag) {
12101 0 : ShowSevereError(state, format("{} \"{}\" -- coil bypass factor calculation did not converge after max iterations.", UnitType, UnitName));
12102 0 : ShowContinueError(state, format("The RatedSHR of [{:.3R}], entered by the user or autosized (see *.eio file),", SHR));
12103 0 : ShowContinueError(state, "may be causing this. The line defined by the coil rated inlet air conditions");
12104 0 : ShowContinueError(state, "(26.7C drybulb and 19.4C wetbulb) and the RatedSHR (i.e., slope of the line) must intersect");
12105 0 : ShowContinueError(state, "the saturation curve of the psychrometric chart. If the RatedSHR is too low, then this");
12106 0 : ShowContinueError(state, "intersection may not occur and the coil bypass factor calculation will not converge.");
12107 0 : ShowContinueError(state, "If autosizing the SHR, recheck the design supply air humidity ratio and design supply air");
12108 0 : ShowContinueError(state, "temperature values in the Sizing:System and Sizing:Zone objects. In general, the temperatures");
12109 0 : ShowContinueError(state, "and humidity ratios specified in these two objects should be the same for each system");
12110 0 : ShowContinueError(state, "and the zones that it serves.");
12111 0 : ShowContinueErrorTimeStamp(state, "");
12112 0 : CBFErrors = true; // Didn't converge within MaxIter iterations
12113 : }
12114 26335 : if (CBF < 0.0 && PrintFlag) {
12115 0 : ShowSevereError(state, format("{} \"{}\" -- negative coil bypass factor calculated.", UnitType, UnitName));
12116 0 : ShowContinueErrorTimeStamp(state, "");
12117 0 : CBFErrors = true; // Negative CBF not valid
12118 : }
12119 : }
12120 :
12121 : // Show fatal error for specific coil that caused a CBF error
12122 26335 : if (CBFErrors) {
12123 0 : ShowFatalError(state, format("{} \"{}\" Errors found in calculating coil bypass factors", UnitType, UnitName));
12124 : }
12125 :
12126 26335 : return CBF;
12127 : }
12128 :
12129 843 : Real64 ValidateADP(EnergyPlusData &state,
12130 : std::string const &UnitType, // component name
12131 : std::string const &UnitName, // component type
12132 : Real64 const RatedInletAirTemp, // coil inlet air temperature [C]
12133 : Real64 const RatedInletAirHumRat, // coil inlet air humidity ratio [kg/kg]
12134 : Real64 const TotCap, // coil total capacity [W]
12135 : Real64 const AirVolFlowRate, // coil air volume flow rate [m3/s]
12136 : Real64 const InitialSHR, // coil sensible heat ratio []
12137 : std::string const &CallingRoutine // function name calling this routine
12138 : )
12139 : {
12140 :
12141 : // FUNCTION INFORMATION:
12142 : // AUTHOR Richard Raustad, FSEC
12143 : // DATE WRITTEN December 2015
12144 :
12145 : // PURPOSE OF THIS FUNCTION:
12146 : // Validates that the calcualted bypass factor represents valid SHR based on total capacity and air mass flow rate.
12147 :
12148 : // METHODOLOGY EMPLOYED:
12149 : // With model parameters autosized by the user, the SHR is selected based on an empirical model.
12150 : // This can sometimes lead to an SHR that does not cross the saturation curve, or one that crosses excessively where
12151 : // the coil outlet air conditions exceed the saturation curve (i.e., RH > 1).
12152 : // This function checks to see if the ADP based on coil delta T and calculated bypass factor and the ADP based
12153 : // on coil delta W and calculated bypass factor land on the saturation curve at the same place within a tolerance.
12154 : // The result is passed back to the sizing routine as the new value for SHR.
12155 : // If the SHR is not autosized, this routine will still adjust the design SHR appropriately, however, the hard-sized SHR will not
12156 : // change.
12157 :
12158 : // Return value
12159 843 : Real64 SHR(0.0); // the result - the adjusted design SHR
12160 :
12161 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
12162 843 : Real64 CBF_calculated(0.0); // coil bypass factor based on TotCap, AirFlow, SHR, and BaroPress
12163 843 : Real64 InletAirEnthalpy(0.0); // Enthalpy of inlet air to evaporator at given conditions [J/kg]
12164 843 : Real64 DeltaH(0.0); // Enthalpy drop across evaporator at given conditions [J/kg]
12165 843 : Real64 HTinHumRatOut(0.0); // Air enthalpy at inlet air temp and outlet air humidity ratio [J/kg]
12166 843 : Real64 DeltaHumRat(0.0); // Humidity ratio drop across evaporator at given conditions [kg/kg]
12167 843 : Real64 OutletAirTemp(0.0); // Outlet dry-bulb temperature from evaporator at given conditions [C]
12168 843 : Real64 OutletAirEnthalpy(0.0); // Enthalpy of outlet air at given conditions [J/kg]
12169 843 : Real64 OutletAirHumRat(0.0); // Outlet humidity ratio from evaporator at given conditions [kg/kg]
12170 843 : Real64 OutletAirRH(0.0); // relative humidity of the outlet air
12171 843 : Real64 CalcADPTemp(0.0); // actual ADP temperature based on bypass factor [C]
12172 843 : Real64 CalcADPHumRat(0.0); // actual ADP humidity ratio based on bypass factor [kg/kg]
12173 843 : Real64 CalcADPTempFnHR(0.0); // actual ADP temperature as a function of humidity ratio based on bypass factor [C]
12174 843 : Real64 ADPerror(0.0); // difference between ADP function of temperature and humidity ratio [deltaC]
12175 843 : Real64 AirMassFlow(0.0); // air mass flow rate based on standard barometric pressure [kg/s]
12176 843 : bool bStillValidating(true); // while loop flag
12177 843 : bool bNoReporting(false); // don't report specific warnings in calcCBF while iterating on result
12178 843 : bool bReversePerturb(false); // identifies when SHR is being lowered based on outlet air RH
12179 :
12180 843 : SHR = InitialSHR;
12181 843 : AirMassFlow =
12182 843 : AirVolFlowRate * PsyRhoAirFnPbTdbW(state, DataEnvironment::StdPressureSeaLevel, RatedInletAirTemp, RatedInletAirHumRat, CallingRoutine);
12183 25706 : while (bStillValidating) {
12184 24863 : CBF_calculated = max(0.0, CalcCBF(state, UnitType, UnitName, RatedInletAirTemp, RatedInletAirHumRat, TotCap, AirMassFlow, SHR, bNoReporting));
12185 24863 : DeltaH = TotCap / AirMassFlow;
12186 24863 : InletAirEnthalpy = PsyHFnTdbW(RatedInletAirTemp, RatedInletAirHumRat);
12187 24863 : HTinHumRatOut = InletAirEnthalpy - (1.0 - SHR) * DeltaH;
12188 24863 : OutletAirHumRat = PsyWFnTdbH(state, RatedInletAirTemp, HTinHumRatOut, CallingRoutine);
12189 24863 : DeltaHumRat = RatedInletAirHumRat - OutletAirHumRat;
12190 24863 : OutletAirEnthalpy = InletAirEnthalpy - DeltaH;
12191 24863 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
12192 24863 : OutletAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, CallingRoutine);
12193 24863 : if (CBF_calculated < 1) {
12194 24863 : CalcADPTemp = RatedInletAirTemp - ((RatedInletAirTemp - OutletAirTemp) / (1 - CBF_calculated));
12195 24863 : CalcADPHumRat = RatedInletAirHumRat - ((DeltaHumRat) / (1 - CBF_calculated));
12196 24863 : CalcADPTempFnHR = PsyTdpFnWPb(state, CalcADPHumRat, DataEnvironment::StdPressureSeaLevel, CallingRoutine);
12197 24863 : ADPerror = CalcADPTemp - CalcADPTempFnHR;
12198 : } else {
12199 0 : ADPerror = 0; // might be able to check for RH >= 1 and reduce SHR, need defect file for that since can't create one
12200 : }
12201 :
12202 24863 : if (std::abs(ADPerror) > 0.012) {
12203 24863 : if (OutletAirRH >= 1.0) { // if RH > 1, reduce SHR until it crosses the saturation curve
12204 606 : SHR -= 0.001;
12205 606 : bReversePerturb = true;
12206 606 : if (SHR < 0.5)
12207 0 : bStillValidating = false; // have to stop somewhere, this is lower than the lower limit of SHR empirical model (see
12208 : // Autosizing/CoolingSHRSizing)
12209 : } else {
12210 24257 : if (bReversePerturb) {
12211 602 : bStillValidating = false; // stop iterating once SHR causes ADP to cross back under saturation curve, take what you get
12212 : } else {
12213 23655 : SHR += 0.001; // increase SHR slowly until ADP temps are resolved
12214 : }
12215 : }
12216 24863 : if (SHR > 0.8)
12217 241 : bStillValidating = false; // have to stop somewhere, this is the upper limit of SHR empirical model (see Autosizing/CoolingSHRSizing)
12218 : } else {
12219 0 : bStillValidating = false; // ADP temps are close enough. Normal input files hit this on first pass
12220 : }
12221 : }
12222 :
12223 843 : return SHR;
12224 : }
12225 :
12226 8188828 : Real64 CalcEffectiveSHR(EnergyPlusData &state,
12227 : int const DXCoilNum, // Index number for cooling coil
12228 : Real64 const SHRss, // Steady-state sensible heat ratio
12229 : Real64 const RTF, // Compressor run-time fraction
12230 : Real64 const QLatRated, // Rated latent capacity
12231 : Real64 const QLatActual, // Actual latent capacity
12232 : Real64 const EnteringDB, // Entering air dry-bulb temperature
12233 : Real64 const EnteringWB, // Entering air wet-bulb temperature
12234 : ObjexxFCL::Optional_int_const Mode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
12235 : ObjexxFCL::Optional<Real64 const> HeatingRTF // Used to recalculate Toff for cycling fan systems
12236 : )
12237 : {
12238 :
12239 : // FUNCTION INFORMATION:
12240 : // AUTHOR Richard Raustad, FSEC
12241 : // DATE WRITTEN September 2003
12242 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
12243 : // Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
12244 : // Nov 2008 R. Raustad, FSEC
12245 : // Modified to allow latent degradation with cycling fan
12246 :
12247 : // PURPOSE OF THIS FUNCTION:
12248 : // Adjust sensible heat ratio to account for degradation of DX coil latent
12249 : // capacity at part-load (cycling) conditions.
12250 :
12251 : // METHODOLOGY EMPLOYED:
12252 : // With model parameters entered by the user, the part-load latent performance
12253 : // of a DX cooling coil is determined for a constant air flow system with
12254 : // a cooling coil that cycles on/off. The model calculates the time
12255 : // required for condensate to begin falling from the cooling coil.
12256 : // Runtimes greater than this are integrated to a "part-load" latent
12257 : // capacity which is used to determine the "part-load" sensible heat ratio.
12258 : // See reference below for additional details (linear decay model, Eq. 8b).
12259 : // REFERENCES:
12260 : // "A Model to Predict the Latent Capacity of Air Conditioners and
12261 : // Heat Pumps at Part-Load Conditions with Constant Fan Operation"
12262 : // 1996 ASHRAE Transactions, Volume 102, Part 1, Pp. 266 - 274,
12263 : // Hugh I. Henderson, Jr., P.E., Kannan Rengarajan, P.E.
12264 :
12265 : // Return value
12266 : Real64 SHReff; // Effective sensible heat ratio, includes degradation due to cycling effects
12267 :
12268 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
12269 : Real64 Twet; // Nominal time for condensate to begin leaving the coil's condensate drain line
12270 : // at the current operating conditions (sec)
12271 : Real64 Gamma; // Initial moisture evaporation rate divided by steady-state AC latent capacity
12272 : // at the current operating conditions
12273 : Real64 Twet_Rated; // Twet at rated conditions (coil air flow rate and air temperatures), sec
12274 : Real64 Gamma_Rated; // Gamma at rated conditions (coil air flow rate and air temperatures)
12275 : Real64 Twet_max; // Maximum allowed value for Twet
12276 : Real64 Nmax; // Maximum ON/OFF cycles per hour for the compressor (cycles/hr)
12277 : Real64 Tcl; // Time constant for latent capacity to reach steady state after startup (sec)
12278 : Real64 Ton; // Coil on time (sec)
12279 : Real64 Toff; // Coil off time (sec)
12280 : Real64 Toffa; // Actual coil off time (sec). Equations valid for Toff <= (2.0 * Twet/Gamma)
12281 : Real64 aa; // Intermediate variable
12282 : Real64 To1; // Intermediate variable (first guess at To). To = time to the start of moisture removal
12283 : Real64 To2; // Intermediate variable (second guess at To). To = time to the start of moisture removal
12284 : Real64 Error; // Error for iteration (DO) loop
12285 : Real64 LHRmult; // Latent Heat Ratio (LHR) multiplier. The effective latent heat ratio LHR = (1-SHRss)*LHRmult
12286 : Real64 Ton_heating;
12287 : Real64 Toff_heating;
12288 :
12289 8188828 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
12290 :
12291 8188828 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilDX_MultiSpeedCooling) {
12292 7839950 : Twet_Rated = thisDXCoil.Twet_Rated(Mode);
12293 7839950 : Gamma_Rated = thisDXCoil.Gamma_Rated(Mode);
12294 7839950 : Nmax = thisDXCoil.MaxONOFFCyclesperHour(Mode);
12295 7839950 : Tcl = thisDXCoil.LatentCapacityTimeConstant(Mode);
12296 : } else {
12297 348878 : Twet_Rated = thisDXCoil.MSTwet_Rated(Mode);
12298 348878 : Gamma_Rated = thisDXCoil.MSGamma_Rated(Mode);
12299 348878 : Nmax = thisDXCoil.MSMaxONOFFCyclesperHour(Mode);
12300 348878 : Tcl = thisDXCoil.MSLatentCapacityTimeConstant(Mode);
12301 : }
12302 :
12303 : // No moisture evaporation (latent degradation) occurs for runtime fraction of 1.0
12304 : // All latent degradation model parameters cause divide by 0.0 if not greater than 0.0
12305 : // Latent degradation model parameters initialize to 0.0 meaning no evaporation model used.
12306 8188828 : if (RTF >= 1.0 || Twet_Rated <= 0.0 || Gamma_Rated <= 0.0 || Nmax <= 0.0 || Tcl <= 0.0) {
12307 7271442 : SHReff = SHRss;
12308 7271442 : return SHReff;
12309 : }
12310 :
12311 917386 : Twet_max = 9999.0; // high limit for Twet
12312 :
12313 : // Calculate the model parameters at the actual operating conditions
12314 917386 : Twet = min(Twet_Rated * QLatRated / (QLatActual + 1.e-10), Twet_max);
12315 917386 : Gamma = Gamma_Rated * QLatRated * (EnteringDB - EnteringWB) / ((26.7 - 19.4) * QLatActual + 1.e-10);
12316 :
12317 : // Calculate the compressor on and off times using a converntional thermostat curve
12318 917386 : Ton = 3600.0 / (4.0 * Nmax * (1.0 - RTF)); // duration of cooling coil on-cycle (sec)
12319 917386 : Toff = 3600.0 / (4.0 * Nmax * RTF); // duration of cooling coil off-cycle (sec)
12320 :
12321 : // Cap Toff to meet the equation restriction
12322 917386 : if (Gamma > 0.0) {
12323 917386 : Toffa = min(Toff, 2.0 * Twet / Gamma);
12324 : } else {
12325 0 : Toffa = Toff;
12326 : }
12327 :
12328 : // Need to include the reheat coil operation to account for actual fan run time. E+ uses a
12329 : // separate heating coil for heating and reheat (to separate the heating and reheat loads)
12330 : // and real world applications would use a single heating coil for both purposes, the actual
12331 : // fan operation is based on HeatingPLR + ReheatPLR. For cycling fan RH control, latent
12332 : // degradation only occurs when a heating load exists, in this case the reheat load is
12333 : // equal to and oposite in magnitude to the cooling coil sensible output but the reheat
12334 : // coil is not always active. This additional fan run time has not been accounted for at this time.
12335 : // Recalculate Toff for cycling fan systems when heating is active
12336 917386 : if (present(HeatingRTF)) {
12337 0 : if (HeatingRTF < 1.0 && HeatingRTF > RTF) {
12338 0 : Ton_heating = 3600.0 / (4.0 * Nmax * (1.0 - HeatingRTF));
12339 0 : Toff_heating = 3600.0 / (4.0 * Nmax * HeatingRTF);
12340 : // add additional heating coil operation during cooling coil off cycle (due to cycling rate difference of coils)
12341 0 : Ton_heating += max(0.0, min(Ton_heating, (Ton + Toffa) - (Ton_heating + Toff_heating)));
12342 0 : Toffa = min(Toffa, Ton_heating - Ton);
12343 : }
12344 : }
12345 :
12346 : // Use sucessive substitution to solve for To
12347 917386 : aa = (Gamma * Toffa) - (0.25 / Twet) * pow_2(Gamma) * pow_2(Toffa);
12348 917386 : To1 = aa + Tcl;
12349 917386 : Error = 1.0;
12350 1903934 : while (Error > 0.001) {
12351 986548 : To2 = aa - Tcl * (std::exp(-To1 / Tcl) - 1.0);
12352 986548 : Error = std::abs((To2 - To1) / To1);
12353 986548 : To1 = To2;
12354 : }
12355 :
12356 : // Adjust Sensible Heat Ratio (SHR) using Latent Heat Ratio (LHR) multiplier
12357 : // Floating underflow errors occur when -Ton/Tcl is a large negative number.
12358 : // Cap lower limit at -700 to avoid the underflow errors.
12359 917386 : aa = std::exp(max(-700.0, -Ton / Tcl));
12360 : // Calculate latent heat ratio multiplier
12361 917386 : LHRmult = max(((Ton - To2) / (Ton + Tcl * (aa - 1.0))), 0.0);
12362 :
12363 : // Calculate part-load or "effective" sensible heat ratio
12364 917386 : SHReff = 1.0 - (1.0 - SHRss) * LHRmult;
12365 :
12366 917386 : if (SHReff < SHRss) SHReff = SHRss; // Effective SHR can be less than the steady-state SHR
12367 917386 : if (SHReff > 1.0) SHReff = 1.0; // Effective sensible heat ratio can't be greater than 1.0
12368 :
12369 917386 : return SHReff;
12370 : }
12371 :
12372 8635964 : void CalcTotCapSHR(EnergyPlusData &state,
12373 : Real64 const InletDryBulb, // inlet air dry bulb temperature [C]
12374 : Real64 const InletHumRat, // inlet air humidity ratio [kg water / kg dry air]
12375 : Real64 const InletEnthalpy, // inlet air specific enthalpy [J/kg]
12376 : Real64 const InletWetBulb, // inlet air wet bulb temperature [C]
12377 : Real64 const AirMassFlowRatio, // Ratio of actual air mass flow to nominal air mass flow
12378 : Real64 const AirMassFlow, // actual mass flow for capacity and SHR calculation
12379 : Real64 const TotCapNom, // nominal total capacity [W]
12380 : Real64 const CBF, // coil bypass factor
12381 : int const CCapFTemp, // capacity modifier curve index, function of entering wetbulb
12382 : int const CCapFFlow, // capacity modifier curve, function of actual flow vs rated flow
12383 : Real64 &TotCap, // total capacity at the given conditions [W]
12384 : Real64 &SHR, // sensible heat ratio at the given conditions
12385 : Real64 const CondInletTemp, // Condenser inlet temperature [C]
12386 : Real64 const Pressure, // air pressure [Pa]
12387 : Real64 &TotCapModFac // capacity modification factor, func of temp and func of flow
12388 : )
12389 : {
12390 :
12391 : // SUBROUTINE INFORMATION:
12392 : // AUTHOR Fred Buhl using Don Shirey's code
12393 : // DATE WRITTEN September 2002
12394 :
12395 : // PURPOSE OF THIS SUBROUTINE:
12396 : // Calculates total capacity and sensible heat ratio of a DX coil at the specified conditions
12397 :
12398 : // METHODOLOGY EMPLOYED:
12399 : // With the rated performance data entered by the user, the model employs some of the
12400 : // DOE-2.1E curve fits to adjust the capacity and SHR of the unit as a function
12401 : // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
12402 : // does NOT employ the exact same methodology to calculate performance as DOE-2, although
12403 : // some of the DOE-2 curve fits are employed by this model.
12404 :
12405 : // The model checks for coil dryout conditions, and adjusts the calculated performance
12406 : // appropriately.
12407 :
12408 : // REFERENCES:
12409 : // ASHRAE HVAC 2 Toolkit page 4-81.
12410 : // Henderson, H.I. Jr., K. Rengarajan and D.B. Shirey, III. 1992.The impact of comfort
12411 : // control on air conditioner energy use in humid climates. ASHRAE Transactions 98(2):
12412 : // 104-113.
12413 : // Henderson, H.I. Jr., Danny Parker and Y.J. Huang. 2000.Improving DOE-2's RESYS routine:
12414 : // User Defined Functions to Provide More Accurate Part Load Energy Use and Humidity
12415 : // Predictions. Proceedings of ACEEE Conference.
12416 :
12417 : // Using/Aliasing
12418 : using Curve::CurveValue;
12419 :
12420 : // Locals
12421 : // SUBROUTINE ARGUMENT DEFINITIONS:
12422 : // and outside drybulb
12423 :
12424 : // SUBROUTINE PARAMETER DEFINITIONS:
12425 8635964 : constexpr int MaxIter(30); // Maximum number of iterations for dry evaporator calculations
12426 8635964 : constexpr Real64 RF(0.4); // Relaxation factor for dry evaporator iterations
12427 8635964 : constexpr Real64 Tolerance(0.01); // Error tolerance for dry evaporator iterations
12428 8635964 : constexpr Real64 MinHumRatCalc(0.00001); // Error tolerance for dry evaporator iterations
12429 :
12430 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12431 : Real64 InletWetBulbCalc; // calculated inlet wetbulb temperature used for finding dry coil point [C]
12432 : Real64 InletHumRatCalc; // calculated inlet humidity ratio used for finding dry coil point [kg water / kg dry air]
12433 : Real64 TotCapTempModFac; // Total capacity modifier (function of entering wetbulb, outside drybulb)
12434 : Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs nominal flow)
12435 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
12436 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
12437 : Real64 tADP; // Apparatus dew point temperature [C]
12438 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
12439 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
12440 : Real64 SHRCalc; // temporary calculated value of SHR
12441 : Real64 TotCapCalc; // temporary calculated value of total capacity [W]
12442 : int Counter; // Counter for dry evaporator iterations
12443 : Real64 werror; // Deviation of humidity ratio in dry evaporator iteration loop
12444 :
12445 : // MaxIter = 30
12446 : // RF = 0.4d0
12447 8635964 : Counter = 0;
12448 : // Tolerance = 0.01d0
12449 8635964 : werror = 0.0;
12450 :
12451 8635964 : InletWetBulbCalc = InletWetBulb;
12452 8635964 : InletHumRatCalc = InletHumRat;
12453 :
12454 8635964 : if (AirMassFlow <= 0.00001) {
12455 61 : TotCap = 0.0;
12456 61 : SHR = 0.0;
12457 61 : return;
12458 : }
12459 :
12460 : // DO WHILE (ABS(werror) .gt. Tolerance .OR. Counter == 0)
12461 : // Get capacity modifying factor (function of inlet wetbulb & outside drybulb) for off-rated conditions
12462 : while (true) {
12463 13245937 : TotCapTempModFac = CurveValue(state, CCapFTemp, InletWetBulbCalc, CondInletTemp);
12464 : // Get capacity modifying factor (function of mass flow) for off-rated conditions
12465 13245937 : TotCapFlowModFac = CurveValue(state, CCapFFlow, AirMassFlowRatio);
12466 : // Get total capacity
12467 13245937 : TotCapCalc = TotCapNom * TotCapFlowModFac * TotCapTempModFac;
12468 :
12469 : // Calculate apparatus dew point conditions using TotCap and CBF
12470 13245937 : hDelta = TotCapCalc / AirMassFlow;
12471 13245937 : hADP = InletEnthalpy - hDelta / (1.0 - CBF);
12472 13245937 : tADP = PsyTsatFnHPb(state, hADP, Pressure);
12473 13245937 : wADP = PsyWFnTdbH(state, tADP, hADP);
12474 13245937 : hTinwADP = PsyHFnTdbW(InletDryBulb, wADP);
12475 13245937 : if ((InletEnthalpy - hADP) > 1.e-10) {
12476 13245937 : SHRCalc = min((hTinwADP - hADP) / (InletEnthalpy - hADP), 1.0);
12477 : } else {
12478 0 : SHRCalc = 1.0;
12479 : }
12480 : // Check for dry evaporator conditions (win < wadp)
12481 13245937 : if (wADP > InletHumRatCalc || (Counter >= 1 && Counter < MaxIter)) {
12482 5806652 : if (InletHumRatCalc == 0.0) InletHumRatCalc = MinHumRatCalc;
12483 : // InletHumRatCalc=MAX(InletHumRatCalc,MinHumRatCalc) ! proposed.
12484 :
12485 5806652 : werror = (InletHumRatCalc - wADP) / InletHumRatCalc;
12486 : // Increase InletHumRatCalc at constant inlet air temp to find coil dry-out point. Then use the
12487 : // capacity at the dry-out point to determine exiting conditions from coil. This is required
12488 : // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
12489 5806652 : InletHumRatCalc = RF * wADP + (1.0 - RF) * InletHumRatCalc;
12490 5806652 : InletWetBulbCalc = PsyTwbFnTdbWPb(state, InletDryBulb, InletHumRatCalc, Pressure);
12491 5806652 : ++Counter;
12492 5806652 : if (std::abs(werror) > Tolerance) continue; // Recalculate with modified inlet conditions
12493 1196618 : break; // conditions are satisfied
12494 : } else {
12495 : break; // conditions are satisfied
12496 : }
12497 : }
12498 :
12499 : // END DO
12500 :
12501 : // Calculate full load output conditions
12502 8635903 : if (SHRCalc > 1.0 || Counter > 0) SHRCalc = 1.0;
12503 :
12504 8635903 : SHR = SHRCalc;
12505 8635903 : TotCap = TotCapCalc;
12506 8635903 : TotCapModFac = TotCapTempModFac * TotCapFlowModFac;
12507 : }
12508 :
12509 6868538 : void CalcMultiSpeedDXCoilCooling(EnergyPlusData &state,
12510 : int const DXCoilNum, // the number of the DX heating coil to be simulated
12511 : Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
12512 : Real64 const CycRatio, // cycling part load ratio
12513 : int const SpeedNum, // Speed number
12514 : HVAC::FanOp const fanOp, // Sets fan control to FanOp::Cycling or FanOp::Continuous
12515 : HVAC::CompressorOp const compressorOp, // Compressor on/off; 1=on, 0=off
12516 : int const SingleMode // Single mode operation Yes/No; 1=Yes, 0=No
12517 : )
12518 : {
12519 :
12520 : // SUBROUTINE INFORMATION:
12521 : // AUTHOR Lixing Gu, FSEC
12522 : // DATE WRITTEN June 2007
12523 : // MODIFIED April 2010, Chandan sharma, FSEC, added basin heater
12524 : // RE-ENGINEERED Revised based on CalcMultiSpeedDXCoil
12525 :
12526 : // PURPOSE OF THIS SUBROUTINE:
12527 : // Calculates the air-side performance and electrical energy use of a direct-
12528 : // expansion, air-cooled cooling unit with a multispeed compressor.
12529 :
12530 : // METHODOLOGY EMPLOYED:
12531 : // Uses the same methodology as the single speed DX unit model (SUBROUTINE CalcDoe2DXCoil).
12532 : // In addition it assumes that the unit performance is obtained by interpolating between
12533 : // the performance at high speed and that at low speed. If the output needed is below
12534 : // that produced at low speed, the compressor cycles between off and low speed.
12535 :
12536 : // Using/Aliasing
12537 : using Curve::CurveValue;
12538 6868538 : Real64 MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
12539 6868538 : Real64 MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
12540 6868538 : auto &MSHPWasteHeat = state.dataHVACGlobal->MSHPWasteHeat;
12541 :
12542 : // Locals
12543 : // SUBROUTINE ARGUMENT DEFINITIONS:
12544 : // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
12545 :
12546 : // SUBROUTINE PARAMETER DEFINITIONS:
12547 : static constexpr std::string_view RoutineName("CalcMultiSpeedDXCoilCooling");
12548 : static constexpr std::string_view RoutineNameHighSpeedAlt("CalcMultiSpeedDXCoilCooling highspeed");
12549 :
12550 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12551 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
12552 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
12553 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
12554 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
12555 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
12556 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12557 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
12558 : Real64 OutletAirDryBulbTemp; // outlet air dry bulb temperature [C]
12559 : Real64 OutletAirEnthalpy; // outlet air enthalpy [J/kg]
12560 : Real64 OutletAirHumRat; // outlet air humidity ratio [kg/kg]
12561 : Real64 OutletAirDryBulbTempSat; // outlet air dry bulb temp at saturation at the outlet enthalpy [C]
12562 : Real64 LSOutletAirDryBulbTemp; // low speed outlet air dry bulb temperature [C]
12563 : Real64 LSOutletAirEnthalpy; // low speed outlet air enthalpy [J/kg]
12564 : Real64 LSOutletAirHumRat; // low speed outlet air humidity ratio [kg/kg]
12565 : Real64 HSOutletAirDryBulbTemp; // hihg speed outlet air dry bulb temperature [C]
12566 : Real64 HSOutletAirEnthalpy; // high speed outlet air enthalpy [J/kg]
12567 : Real64 HSOutletAirHumRat; // high speed outlet air humidity ratio [kg/kg]
12568 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
12569 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
12570 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
12571 : Real64 tADP; // Apparatus dew point temperature [C]
12572 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
12573 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
12574 : Real64 RatedCBFHS; // coil bypass factor at rated conditions (high speed)
12575 : Real64 CBFHS; // coil bypass factor at max flow (high speed)
12576 : Real64 RatedCBFLS; // coil bypass factor at rated conditions (low speed)
12577 : Real64 CBFLS; // coil bypass factor at max flow (low speed)
12578 : Real64 TotCapHS; // total capacity at high speed [W]
12579 : Real64 SHRHS; // sensible heat ratio at high speed
12580 : Real64 TotCapLS; // total capacity at low speed [W]
12581 : Real64 SHRLS; // sensible heat ratio at low speed
12582 : Real64 EIRTempModFacHS; // EIR modifier (function of entering wetbulb, outside drybulb) (high speed)
12583 : Real64 EIRFlowModFacHS; // EIR modifier (function of actual supply air flow vs rated flow) (high speed)
12584 : Real64 EIRHS; // EIR at off rated conditions (high speed)
12585 : Real64 EIRTempModFacLS; // EIR modifier (function of entering wetbulb, outside drybulb) (low speed)
12586 : Real64 EIRFlowModFacLS; // EIR modifier (function of actual supply air flow vs rated flow) (low speed)
12587 : Real64 EIRLS; // EIR at off rated conditions (low speed)
12588 : Real64 SHR; // sensible heat ratio at current speed
12589 : Real64 EIR; // EIR at current speed
12590 : Real64 CBF; // CBFNom adjusted for actual air mass flow rate
12591 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in
12592 : // power calculation
12593 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
12594 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
12595 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
12596 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
12597 : Real64 RhoAir; // Density of air [kg/m3]
12598 : Real64 RhoWater; // Density of water [kg/m3]
12599 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
12600 : Real64 EvapCondPumpElecPower; // Evaporative condenser electric pump power [W]
12601 6868538 : constexpr int DXMode(1); // Performance mode for MultiMode DX coil; Always 1 for other coil types
12602 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
12603 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
12604 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
12605 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
12606 : int SpeedNumHS; // High speed number
12607 : int SpeedNumLS; // Low speed number
12608 : Real64 SHRUnadjusted; // Temp SHR
12609 : Real64 QLatRated; // Qlatent at rated conditions of indoor(TDB,TWB)=(26.7C,19.4C)
12610 : Real64 QLatActual; // Qlatent at actual operating conditions
12611 : Real64 AirMassFlowRatioLS; // airflow ratio at low speed
12612 : Real64 AirMassFlowRatioHS; // airflow ratio at high speed
12613 : Real64 WasteHeatLS; // Waste heat at low speed
12614 : Real64 WasteHeatHS; // Waste heat at high speed
12615 : Real64 LSElecCoolingPower; // low speed power [W]
12616 : Real64 HSElecCoolingPower; // high speed power [W]
12617 : Real64 CrankcaseHeatingPower; // Power due to crank case heater
12618 : Real64 AirVolumeFlowRate; // Air volume flow rate across the heating coil
12619 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total heating capacity
12620 :
12621 6868538 : auto &DXCT = state.dataHVACGlobal->DXCT;
12622 :
12623 6868538 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
12624 :
12625 6868538 : if (thisDXCoil.CondenserInletNodeNum(DXMode) != 0) {
12626 3430422 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).Press;
12627 : // If node is not connected to anything, pressure = default, use weather data
12628 3430422 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
12629 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12630 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
12631 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12632 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
12633 : } else {
12634 3430422 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).Temp;
12635 3430422 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).HumRat;
12636 3430422 : OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, RoutineName);
12637 : }
12638 3430422 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
12639 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
12640 0 : OutdoorDryBulb = secZoneHB.ZT;
12641 0 : OutdoorHumRat = secZoneHB.airHumRat;
12642 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
12643 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12644 : }
12645 3438116 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
12646 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
12647 0 : OutdoorDryBulb = secZoneHB.ZT;
12648 0 : OutdoorHumRat = secZoneHB.airHumRat;
12649 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
12650 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12651 : } else {
12652 3438116 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12653 3438116 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
12654 3438116 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12655 3438116 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
12656 : }
12657 :
12658 6868538 : if (SpeedNum > 1) {
12659 1809618 : SpeedNumLS = SpeedNum - 1;
12660 1809618 : SpeedNumHS = SpeedNum;
12661 1809618 : if (SpeedNum > thisDXCoil.NumOfSpeeds) {
12662 0 : SpeedNumLS = thisDXCoil.NumOfSpeeds - 1;
12663 0 : SpeedNumHS = thisDXCoil.NumOfSpeeds;
12664 : }
12665 : } else {
12666 5058920 : SpeedNumLS = 1;
12667 5058920 : SpeedNumHS = 1;
12668 : }
12669 :
12670 6868538 : MSHPWasteHeat = 0.0;
12671 6868538 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
12672 6868538 : AirMassFlowRatioLS = MSHPMassFlowRateLow / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS);
12673 6868538 : AirMassFlowRatioHS = MSHPMassFlowRateHigh / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS);
12674 6868538 : if ((AirMassFlow > 0.0) && (CycRatio > 0.0) && (MSHPMassFlowRateHigh == 0.0)) {
12675 0 : ShowSevereError(
12676 : state,
12677 0 : format("CalcMultiSpeedDXCoilCooling: {} \"{} Developer error - inconsistent airflow rates.", thisDXCoil.DXCoilType, thisDXCoil.Name));
12678 0 : if (MSHPMassFlowRateLow == 0.0 && SpeedNum > 1) {
12679 0 : ShowContinueError(state,
12680 : "When AirMassFlow > 0.0 and CycRatio > 0.0 and SpeedNum > 1, then MSHPMassFlowRateLow and MSHPMassFlowRateHigh "
12681 : "must also be > 0.0");
12682 0 : ShowContinueErrorTimeStamp(state, "");
12683 0 : ShowContinueError(state,
12684 0 : format("AirMassFlow={:.3R},CycRatio={:.3R},SpeedNum={:.0R}, MSHPMassFlowRateLow={:.3R}, MSHPMassFlowRateHigh={:.3R}",
12685 : AirMassFlow,
12686 0 : double(SpeedNum),
12687 : CycRatio,
12688 : MSHPMassFlowRateLow,
12689 : MSHPMassFlowRateHigh));
12690 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
12691 : } else {
12692 0 : ShowContinueError(state, "When AirMassFlow > 0.0 and CycRatio > 0.0, then MSHPMassFlowRateHigh must also be > 0.0");
12693 0 : ShowContinueErrorTimeStamp(state, "");
12694 0 : ShowContinueError(state,
12695 0 : format("AirMassFlow={:.3R},CycRatio={:.3R}, MSHPMassFlowRateHigh={:.3R}", AirMassFlow, CycRatio, MSHPMassFlowRateHigh));
12696 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
12697 : }
12698 6868538 : } else if (CycRatio > 1.0 || SpeedRatio > 1.0) {
12699 0 : ShowSevereError(
12700 : state,
12701 0 : format("CalcMultiSpeedDXCoilCooling: {} \"{} Developer error - inconsistent speed ratios.", thisDXCoil.DXCoilType, thisDXCoil.Name));
12702 0 : ShowContinueError(state, "CycRatio and SpeedRatio must be between 0.0 and 1.0");
12703 0 : ShowContinueErrorTimeStamp(state, "");
12704 0 : ShowContinueError(state, format("CycRatio={:.1R}, SpeedRatio = {:.1R}", CycRatio, SpeedRatio));
12705 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
12706 : }
12707 :
12708 6868538 : thisDXCoil.PartLoadRatio = 0.0;
12709 6868538 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
12710 6868538 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
12711 6868538 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
12712 6868538 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
12713 6868538 : InletAirHumRat = thisDXCoil.InletAirHumRat;
12714 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12715 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
12716 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
12717 6868538 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure, RoutineName);
12718 6868538 : if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Air) {
12719 6868538 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
12720 0 : } else if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
12721 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
12722 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.MSEvapCondEffect(SpeedNumHS));
12723 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure, RoutineName);
12724 : }
12725 6868538 : if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
12726 3430633 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
12727 3430633 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
12728 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
12729 : }
12730 : } else {
12731 3437905 : CrankcaseHeatingPower = 0.0;
12732 : }
12733 :
12734 5796844 : if ((AirMassFlow > 0.0 && CondInletTemp >= thisDXCoil.MinOATCompressor) && (GetCurrentScheduleValue(state, thisDXCoil.SchedPtr) > 0.0) &&
12735 12665382 : ((SpeedRatio > 0.0 && SingleMode == 0) || CycRatio > 0.0) && (compressorOp == HVAC::CompressorOp::On)) {
12736 :
12737 2104426 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat, RoutineName);
12738 2104426 : if (SpeedNum > 1 && SingleMode == 0) {
12739 :
12740 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at low speed
12741 1269233 : AirVolumeFlowRate = MSHPMassFlowRateLow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
12742 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12743 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
12744 1269233 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumLS);
12745 1269233 : if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
12746 1759167 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
12747 489934 : state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
12748 489934 : if (thisDXCoil.MSErrIndex(SpeedNumLS) == 0) {
12749 64 : ShowWarningMessage(
12750 : state,
12751 64 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
12752 32 : thisDXCoil.DXCoilType,
12753 32 : thisDXCoil.Name,
12754 : SpeedNumLS));
12755 32 : ShowContinueErrorTimeStamp(state, "");
12756 64 : ShowContinueError(state,
12757 64 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
12758 32 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12759 32 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12760 : VolFlowperRatedTotCap));
12761 32 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
12762 32 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
12763 : }
12764 1469802 : ShowRecurringWarningErrorAtEnd(state,
12765 979868 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
12766 : "at speed {} error continues...",
12767 489934 : thisDXCoil.DXCoilType,
12768 489934 : thisDXCoil.Name,
12769 : SpeedNumLS),
12770 : thisDXCoil.MSErrIndex(SpeedNumLS),
12771 : VolFlowperRatedTotCap,
12772 : VolFlowperRatedTotCap);
12773 : }
12774 :
12775 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at high speed
12776 1269233 : AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
12777 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12778 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
12779 1269233 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumHS);
12780 1269233 : if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
12781 1390534 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
12782 121301 : state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
12783 121301 : if (thisDXCoil.MSErrIndex(SpeedNumHS) == 0) {
12784 32 : ShowWarningMessage(
12785 : state,
12786 32 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
12787 16 : thisDXCoil.DXCoilType,
12788 16 : thisDXCoil.Name,
12789 : SpeedNumHS));
12790 16 : ShowContinueErrorTimeStamp(state, "");
12791 32 : ShowContinueError(state,
12792 32 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
12793 16 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12794 16 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12795 : VolFlowperRatedTotCap));
12796 16 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
12797 16 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
12798 : }
12799 363903 : ShowRecurringWarningErrorAtEnd(state,
12800 242602 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
12801 : "at speed {} error continues...",
12802 121301 : thisDXCoil.DXCoilType,
12803 121301 : thisDXCoil.Name,
12804 : SpeedNumHS),
12805 : thisDXCoil.MSErrIndex(SpeedNumHS),
12806 : VolFlowperRatedTotCap,
12807 : VolFlowperRatedTotCap);
12808 : }
12809 :
12810 : // Adjust high speed coil bypass factor for actual maximum air flow rate.
12811 1269233 : RatedCBFHS = thisDXCoil.MSRatedCBF(SpeedNumHS);
12812 1269233 : CBFHS = AdjustCBF(RatedCBFHS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS), MSHPMassFlowRateHigh);
12813 1269233 : RatedCBFLS = thisDXCoil.MSRatedCBF(SpeedNumLS);
12814 1269233 : CBFLS = AdjustCBF(RatedCBFLS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS), MSHPMassFlowRateLow);
12815 : // get low speed total capacity and SHR at current conditions
12816 3807699 : CalcTotCapSHR(state,
12817 : InletAirDryBulbTemp,
12818 : InletAirHumRat,
12819 : InletAirEnthalpy,
12820 : InletAirWetBulbC,
12821 : AirMassFlowRatioLS,
12822 : MSHPMassFlowRateLow,
12823 1269233 : thisDXCoil.MSRatedTotCap(SpeedNumLS),
12824 : CBFLS,
12825 1269233 : thisDXCoil.MSCCapFTemp(SpeedNumLS),
12826 1269233 : thisDXCoil.MSCCapFFlow(SpeedNumLS),
12827 : TotCapLS,
12828 : SHRLS,
12829 : CondInletTemp,
12830 : OutdoorPressure,
12831 1269233 : thisDXCoil.capModFacTotal);
12832 : // get low speed outlet conditions
12833 1269233 : hDelta = TotCapLS / MSHPMassFlowRateLow;
12834 : // Calculate new apparatus dew point conditions
12835 1269233 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBFLS);
12836 1269233 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineNameHighSpeedAlt);
12837 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12838 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
12839 1269233 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
12840 1269233 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
12841 : // get corresponding SHR
12842 1269233 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
12843 1269233 : SHRLS = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
12844 : } else {
12845 0 : SHRLS = 1.0;
12846 : }
12847 : // cr8918 SHRLS = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
12848 : // get low speed outlet conditions
12849 1269233 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
12850 1269233 : hTinwout = InletAirEnthalpy - (1.0 - SHRLS) * hDelta;
12851 1269233 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
12852 1269233 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
12853 1269233 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineName);
12854 1269233 : if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
12855 630 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
12856 630 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineName);
12857 : }
12858 :
12859 : // get high speed total capacity and SHR at current conditions
12860 :
12861 3807699 : CalcTotCapSHR(state,
12862 : InletAirDryBulbTemp,
12863 : InletAirHumRat,
12864 : InletAirEnthalpy,
12865 : InletAirWetBulbC,
12866 : AirMassFlowRatioHS,
12867 : MSHPMassFlowRateHigh,
12868 1269233 : thisDXCoil.MSRatedTotCap(SpeedNumHS),
12869 : CBFHS,
12870 1269233 : thisDXCoil.MSCCapFTemp(SpeedNumHS),
12871 1269233 : thisDXCoil.MSCCapFFlow(SpeedNumHS),
12872 : TotCapHS,
12873 : SHRHS,
12874 : CondInletTemp,
12875 : OutdoorPressure,
12876 1269233 : thisDXCoil.capModFacTotal);
12877 1269233 : hDelta = TotCapHS / MSHPMassFlowRateHigh;
12878 : // Calculate new apparatus dew point conditions
12879 1269233 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBFHS);
12880 1269233 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
12881 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12882 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
12883 1269233 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
12884 1269233 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
12885 : // get corresponding SHR
12886 1269233 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
12887 1269233 : SHRHS = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
12888 : } else {
12889 0 : SHRHS = 1.0;
12890 : }
12891 : // cr8918 SHRHS = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
12892 : // get the part load factor that will account for cycling losses
12893 1269233 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNumHS), SpeedRatio);
12894 1269233 : if (PLF < 0.7) {
12895 0 : PLF = 0.7;
12896 : }
12897 : // calculate the run time fraction
12898 1269233 : thisDXCoil.CoolingCoilRuntimeFraction = SpeedRatio / PLF;
12899 1269233 : thisDXCoil.PartLoadRatio = SpeedRatio;
12900 :
12901 1269233 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
12902 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
12903 : }
12904 :
12905 : // get high speed outlet conditions
12906 1269233 : HSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
12907 1269233 : hTinwout = InletAirEnthalpy - (1.0 - SHRHS) * hDelta;
12908 1269233 : HSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
12909 1269233 : HSOutletAirDryBulbTemp = PsyTdbFnHW(HSOutletAirEnthalpy, HSOutletAirHumRat);
12910 1269233 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, HSOutletAirEnthalpy, OutdoorPressure, RoutineName);
12911 1269233 : if (HSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
12912 634 : HSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
12913 634 : HSOutletAirHumRat = PsyWFnTdbH(state, HSOutletAirDryBulbTemp, HSOutletAirEnthalpy, RoutineName);
12914 : }
12915 :
12916 : // If constant fan with cycling compressor, call function to determine "effective SHR"
12917 : // which includes the part-load degradation on latent capacity
12918 1269233 : if (thisDXCoil.LatentImpact && fanOp == HVAC::FanOp::Continuous && SpeedRatio > 0.0) {
12919 0 : QLatRated = thisDXCoil.MSRatedTotCap(SpeedNumHS) * (1.0 - thisDXCoil.MSRatedSHR(SpeedNumHS));
12920 0 : QLatActual = TotCapHS * (1.0 - SHRHS);
12921 0 : SHRUnadjusted = SHRHS;
12922 0 : SHR = CalcEffectiveSHR(state,
12923 : DXCoilNum,
12924 : SHRHS,
12925 : thisDXCoil.CoolingCoilRuntimeFraction,
12926 : QLatRated,
12927 : QLatActual,
12928 : InletAirDryBulbTemp,
12929 : InletAirWetBulbC,
12930 : SpeedNumHS);
12931 : // Calculate full load output conditions
12932 0 : if (SHR > 1.0) SHR = 1.0;
12933 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
12934 0 : if (SHR < 1.0) {
12935 0 : HSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
12936 : } else {
12937 0 : HSOutletAirHumRat = InletAirHumRat;
12938 : }
12939 0 : HSOutletAirDryBulbTemp = PsyTdbFnHW(HSOutletAirEnthalpy, HSOutletAirHumRat);
12940 : }
12941 :
12942 : // get high speed EIR at current conditions
12943 1269233 : EIRTempModFacHS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), InletAirWetBulbC, CondInletTemp);
12944 1269233 : EIRFlowModFacHS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumHS), AirMassFlowRatioHS);
12945 1269233 : EIRHS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumHS) * EIRFlowModFacHS * EIRTempModFacHS;
12946 : // get low speed EIR at current conditions
12947 1269233 : EIRTempModFacLS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), InletAirWetBulbC, CondInletTemp);
12948 1269233 : EIRFlowModFacLS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumLS), AirMassFlowRatioLS);
12949 1269233 : EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumLS) * EIRTempModFacLS * EIRFlowModFacLS;
12950 :
12951 : // get current total capacity, SHR, EIR
12952 1269233 : if (SpeedRatio >= 1.0) {
12953 702041 : SHR = SHRHS;
12954 702041 : EIR = EIRHS;
12955 702041 : CondAirMassFlow = RhoAir * thisDXCoil.MSEvapCondAirFlow(SpeedNumHS);
12956 702041 : EvapCondPumpElecPower = thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumHS);
12957 : } else {
12958 567192 : EIR = SpeedRatio * EIRHS + (1.0 - SpeedRatio) * EIRLS;
12959 567192 : SHR = SpeedRatio * SHRHS + (1.0 - SpeedRatio) * SHRLS;
12960 567192 : CondAirMassFlow =
12961 567192 : RhoAir * (SpeedRatio * thisDXCoil.MSEvapCondAirFlow(SpeedNumHS) + (1.0 - SpeedRatio) * thisDXCoil.MSEvapCondAirFlow(SpeedNumLS));
12962 567192 : EvapCondPumpElecPower = SpeedRatio * thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumHS) +
12963 567192 : (1.0 - SpeedRatio) * thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumLS);
12964 : }
12965 :
12966 : // Outlet calculation
12967 1269233 : Real64 SensibleOutputLS(0.0); // low speed sensible output rate
12968 1269233 : Real64 LatentOutputLS(0.0); // low speed latent output rate
12969 1269233 : Real64 TotalOutputLS(0.0); // low speed total output rate
12970 1269233 : Real64 SensibleOutputHS(0.0); // high speed sensible output rate
12971 1269233 : Real64 LatentOutputHS(0.0); // high speed latent output rate
12972 1269233 : Real64 TotalOutputHS(0.0); // high speed total output rate
12973 1269233 : CalcComponentSensibleLatentOutput(MSHPMassFlowRateLow,
12974 : InletAirDryBulbTemp,
12975 : InletAirHumRat,
12976 : LSOutletAirDryBulbTemp,
12977 : LSOutletAirHumRat,
12978 : SensibleOutputLS,
12979 : LatentOutputLS,
12980 : TotalOutputLS);
12981 1269233 : CalcComponentSensibleLatentOutput(MSHPMassFlowRateHigh,
12982 : InletAirDryBulbTemp,
12983 : InletAirHumRat,
12984 : HSOutletAirDryBulbTemp,
12985 : HSOutletAirHumRat,
12986 : SensibleOutputHS,
12987 : LatentOutputHS,
12988 : TotalOutputHS);
12989 1269233 : thisDXCoil.TotalCoolingEnergyRate = TotalOutputHS * SpeedRatio + TotalOutputLS * (1.0 - SpeedRatio);
12990 1269233 : thisDXCoil.SensCoolingEnergyRate = SensibleOutputHS * SpeedRatio + SensibleOutputLS * (1.0 - SpeedRatio);
12991 1269233 : thisDXCoil.LatCoolingEnergyRate = LatentOutputHS * SpeedRatio + LatentOutputLS * (1.0 - SpeedRatio);
12992 : // Average outlet enthalpy
12993 1269233 : OutletAirEnthalpy = InletAirEnthalpy - thisDXCoil.TotalCoolingEnergyRate / thisDXCoil.InletAirMassFlowRate;
12994 :
12995 1269233 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
12996 : // Update outlet conditions
12997 1269233 : if (SpeedRatio == 0.0 && fanOp == HVAC::FanOp::Cycling) {
12998 6743 : OutletAirEnthalpy = LSOutletAirEnthalpy;
12999 6743 : OutletAirHumRat = LSOutletAirHumRat;
13000 6743 : OutletAirDryBulbTemp = LSOutletAirDryBulbTemp;
13001 1262490 : } else if (SpeedRatio >= 1.0 && fanOp == HVAC::FanOp::Cycling) {
13002 152102 : OutletAirEnthalpy = HSOutletAirEnthalpy;
13003 152102 : OutletAirHumRat = HSOutletAirHumRat;
13004 152102 : OutletAirDryBulbTemp = HSOutletAirDryBulbTemp;
13005 : } else {
13006 1110388 : OutletAirHumRat =
13007 1110388 : ((HSOutletAirHumRat * SpeedRatio * MSHPMassFlowRateHigh) + (LSOutletAirHumRat * (1.0 - SpeedRatio) * MSHPMassFlowRateLow)) /
13008 1110388 : thisDXCoil.InletAirMassFlowRate;
13009 1110388 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
13010 1110388 : if (OutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
13011 9005 : OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
13012 9005 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy, RoutineName);
13013 9005 : CalcComponentSensibleLatentOutput(AirMassFlow,
13014 : InletAirDryBulbTemp,
13015 : InletAirHumRat,
13016 : OutletAirDryBulbTemp,
13017 : OutletAirHumRat,
13018 9005 : thisDXCoil.SensCoolingEnergyRate,
13019 9005 : thisDXCoil.LatCoolingEnergyRate,
13020 9005 : thisDXCoil.TotalCoolingEnergyRate);
13021 : }
13022 : }
13023 :
13024 1269233 : LSElecCoolingPower = TotCapLS * EIRLS;
13025 1269233 : HSElecCoolingPower = TotCapHS * EIRHS;
13026 :
13027 : // Power calculation
13028 1269233 : if (!thisDXCoil.PLRImpact) {
13029 1269233 : thisDXCoil.ElecCoolingPower = SpeedRatio * HSElecCoolingPower + (1.0 - SpeedRatio) * LSElecCoolingPower;
13030 : } else {
13031 0 : thisDXCoil.ElecCoolingPower =
13032 0 : thisDXCoil.CoolingCoilRuntimeFraction * HSElecCoolingPower + (1.0 - thisDXCoil.CoolingCoilRuntimeFraction) * LSElecCoolingPower;
13033 : }
13034 : // Now reset runtime fraction to 1.0 (because LS is running the full timestep)
13035 1269233 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0;
13036 :
13037 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
13038 1269233 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
13039 :
13040 : // Waste heat calculation
13041 : // TODO: waste heat not considered even if defined in Cooling:DX:MultiSpeed, N16, \field Speed 1 Rated Waste Heat Fraction of
13042 : // Power Input
13043 1269233 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13044 317468 : if (thisDXCoil.MSWasteHeat(SpeedNumLS) == 0) {
13045 0 : WasteHeatLS = thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13046 : } else {
13047 317468 : WasteHeatLS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumLS), OutdoorDryBulb, InletAirDryBulbTemp) *
13048 317468 : thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13049 : }
13050 317468 : if (thisDXCoil.MSWasteHeat(SpeedNumHS) == 0) {
13051 0 : WasteHeatHS = thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13052 : } else {
13053 317468 : WasteHeatHS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumHS), OutdoorDryBulb, InletAirDryBulbTemp) *
13054 317468 : thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13055 : }
13056 317468 : thisDXCoil.MSFuelWasteHeat = (SpeedRatio * WasteHeatHS + (1.0 - SpeedRatio) * WasteHeatLS) * thisDXCoil.ElecCoolingPower;
13057 317468 : if (thisDXCoil.MSHPHeatRecActive) {
13058 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
13059 : }
13060 : }
13061 :
13062 : // Energy use for other fuel types
13063 1269233 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13064 317468 : thisDXCoil.FuelUsed = thisDXCoil.ElecCoolingPower;
13065 317468 : thisDXCoil.ElecCoolingPower = 0.0;
13066 : }
13067 :
13068 1269233 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
13069 1269233 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
13070 1269233 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
13071 1269233 : thisDXCoil.CrankcaseHeaterPower = 0.0;
13072 :
13073 2104426 : } else if (CycRatio > 0.0) {
13074 :
13075 835193 : if (fanOp == HVAC::FanOp::Cycling) AirMassFlow /= CycRatio;
13076 835193 : if (fanOp == HVAC::FanOp::Continuous) AirMassFlow = MSHPMassFlowRateHigh;
13077 :
13078 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at low speed
13079 835193 : AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
13080 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13081 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
13082 835193 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNum);
13083 835193 : if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13084 1158066 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
13085 322873 : state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
13086 310293 : if (thisDXCoil.MSErrIndex(SpeedNum) == 0) {
13087 2 : ShowWarningMessage(
13088 : state,
13089 2 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
13090 1 : thisDXCoil.DXCoilType,
13091 1 : thisDXCoil.Name,
13092 : SpeedNum));
13093 1 : ShowContinueErrorTimeStamp(state, "");
13094 2 : ShowContinueError(state,
13095 2 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13096 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13097 1 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13098 : VolFlowperRatedTotCap));
13099 1 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13100 1 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13101 : }
13102 930879 : ShowRecurringWarningErrorAtEnd(state,
13103 620586 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
13104 : "at speed {} error continues...",
13105 310293 : thisDXCoil.DXCoilType,
13106 310293 : thisDXCoil.Name,
13107 : SpeedNumHS),
13108 : thisDXCoil.MSErrIndex(SpeedNumHS),
13109 : VolFlowperRatedTotCap,
13110 : VolFlowperRatedTotCap);
13111 : }
13112 :
13113 835193 : if (thisDXCoil.CondenserType(SpeedNum) == DataHeatBalance::RefrigCondenserType::Evap) {
13114 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
13115 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.MSEvapCondEffect(SpeedNum));
13116 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure, RoutineName);
13117 : }
13118 :
13119 835193 : RatedCBFLS = thisDXCoil.MSRatedCBF(SpeedNum);
13120 835193 : CBFLS = AdjustCBF(RatedCBFLS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNum), MSHPMassFlowRateHigh);
13121 :
13122 : // Adjust low speed coil bypass factor for actual flow rate.
13123 : // CBF = AdjustCBF(DXCoil(DXCoilNum)%RatedCBF2,DXCoil(DXCoilNum)%RatedAirMassFlowRate2,AirMassFlow)
13124 : // get low speed total capacity and SHR at current conditions
13125 2505579 : CalcTotCapSHR(state,
13126 : InletAirDryBulbTemp,
13127 : InletAirHumRat,
13128 : InletAirEnthalpy,
13129 : InletAirWetBulbC,
13130 : AirMassFlowRatioLS,
13131 : MSHPMassFlowRateHigh,
13132 835193 : thisDXCoil.MSRatedTotCap(SpeedNum),
13133 : CBFLS,
13134 835193 : thisDXCoil.MSCCapFTemp(SpeedNum),
13135 835193 : thisDXCoil.MSCCapFFlow(SpeedNum),
13136 : TotCapLS,
13137 : SHRLS,
13138 : CondInletTemp,
13139 : OutdoorPressure,
13140 835193 : thisDXCoil.capModFacTotal);
13141 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13142 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)
13143 835193 : hDelta = TotCapLS / AirMassFlow;
13144 : // Adjust CBF for off-nominal flow
13145 835193 : CBF = AdjustCBF(thisDXCoil.MSRatedCBF(SpeedNum), thisDXCoil.MSRatedAirMassFlowRate(SpeedNum), AirMassFlow);
13146 : // Calculate new apparatus dew point conditions
13147 835193 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
13148 835193 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
13149 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13150 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
13151 835193 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
13152 835193 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
13153 : // get corresponding SHR
13154 835193 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
13155 835193 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
13156 : } else {
13157 0 : SHR = 1.0;
13158 : }
13159 : // cr8918 SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
13160 :
13161 : // get the part load factor that will account for cycling losses
13162 835193 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNum), CycRatio);
13163 835193 : if (fanOp == HVAC::FanOp::Cycling && CycRatio == 1.0 && PLF != 1.0) {
13164 0 : if (thisDXCoil.PLFErrIndex == 0) {
13165 0 : ShowWarningMessage(state,
13166 0 : format("The PLF curve value for DX cooling coil {} ={:.2R} for part-load ratio = 1", thisDXCoil.Name, PLF));
13167 0 : ShowContinueError(state, "PLF curve value must be = 1.0 and has been reset to 1.0. Simulation is continuing.");
13168 0 : ShowContinueErrorTimeStamp(state, "");
13169 : }
13170 0 : ShowRecurringWarningErrorAtEnd(
13171 0 : state, thisDXCoil.Name + "\": DX cooling coil PLF curve value <> 1.0 warning continues...", thisDXCoil.PLFErrIndex, PLF, PLF);
13172 0 : PLF = 1.0;
13173 : }
13174 :
13175 835193 : if (PLF < 0.7) {
13176 0 : PLF = 0.7;
13177 : }
13178 : // calculate the run time fraction
13179 835193 : thisDXCoil.CoolingCoilRuntimeFraction = CycRatio / PLF;
13180 835193 : thisDXCoil.PartLoadRatio = CycRatio;
13181 :
13182 835193 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
13183 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
13184 : }
13185 :
13186 : // get low speed outlet conditions
13187 835193 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
13188 835193 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
13189 835193 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
13190 835193 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
13191 835193 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineName);
13192 835193 : if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
13193 321 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
13194 321 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineName);
13195 : }
13196 :
13197 : // If constant fan with cycling compressor, call function to determine "effective SHR"
13198 : // which includes the part-load degradation on latent capacity
13199 835193 : if (fanOp == HVAC::FanOp::Continuous) {
13200 348878 : QLatRated = thisDXCoil.MSRatedTotCap(SpeedNum) * (1.0 - thisDXCoil.MSRatedSHR(SpeedNum));
13201 348878 : QLatActual = TotCapLS * (1.0 - SHR);
13202 348878 : SHRUnadjusted = SHR;
13203 348878 : SHR = CalcEffectiveSHR(state,
13204 : DXCoilNum,
13205 : SHR,
13206 : thisDXCoil.CoolingCoilRuntimeFraction,
13207 : QLatRated,
13208 : QLatActual,
13209 : InletAirDryBulbTemp,
13210 : InletAirWetBulbC,
13211 : SpeedNum);
13212 : // Calculate full load output conditions
13213 348878 : if (SHR > 1.0) SHR = 1.0;
13214 348878 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
13215 348878 : if (SHR < 1.0) {
13216 244591 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
13217 : } else {
13218 104287 : LSOutletAirHumRat = InletAirHumRat;
13219 : }
13220 348878 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
13221 : }
13222 :
13223 835193 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
13224 835193 : if (fanOp == HVAC::FanOp::Continuous) {
13225 : // outlet conditions are average of inlet and low speed weighted by CycRatio
13226 : // Continuous fan, cycling compressor
13227 348878 : Real64 CycAirFlowRatio =
13228 348878 : CycRatio * AirMassFlow / thisDXCoil.InletAirMassFlowRate; // ratio of compressor on airflow to average timestep airflow
13229 348878 : OutletAirEnthalpy = CycAirFlowRatio * LSOutletAirEnthalpy + (1.0 - CycAirFlowRatio) * InletAirEnthalpy;
13230 348878 : OutletAirHumRat = CycAirFlowRatio * LSOutletAirHumRat + (1.0 - CycAirFlowRatio) * InletAirHumRat;
13231 348878 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
13232 : } else {
13233 486315 : OutletAirHumRat = LSOutletAirHumRat;
13234 486315 : OutletAirDryBulbTemp = LSOutletAirDryBulbTemp;
13235 486315 : OutletAirEnthalpy = LSOutletAirEnthalpy;
13236 : }
13237 :
13238 : // get low speed EIR at current conditions
13239 835193 : EIRTempModFacLS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNum), InletAirWetBulbC, CondInletTemp);
13240 835193 : EIRFlowModFacLS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNum), AirMassFlowRatioLS);
13241 835193 : EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNum) * EIRTempModFacLS * EIRFlowModFacLS;
13242 :
13243 : // get the eletrical power consumption
13244 835193 : thisDXCoil.ElecCoolingPower = TotCapLS * EIRLS * thisDXCoil.CoolingCoilRuntimeFraction;
13245 : // calculate cooling output power
13246 : // AirMassFlow = DXCoil(DXCoilNum)%InletAirMassFlowRate
13247 835193 : CalcComponentSensibleLatentOutput(AirMassFlow,
13248 : InletAirDryBulbTemp,
13249 : InletAirHumRat,
13250 : LSOutletAirDryBulbTemp,
13251 : LSOutletAirHumRat,
13252 835193 : thisDXCoil.SensCoolingEnergyRate,
13253 835193 : thisDXCoil.LatCoolingEnergyRate,
13254 835193 : thisDXCoil.TotalCoolingEnergyRate);
13255 835193 : thisDXCoil.TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate * CycRatio;
13256 835193 : thisDXCoil.SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate * CycRatio;
13257 835193 : thisDXCoil.LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate * CycRatio;
13258 :
13259 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
13260 835193 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
13261 835193 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
13262 835193 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
13263 835193 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
13264 835193 : CondAirMassFlow = RhoAir * thisDXCoil.MSEvapCondAirFlow(SpeedNum) * thisDXCoil.CoolingCoilRuntimeFraction;
13265 835193 : EvapCondPumpElecPower = thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNum) * thisDXCoil.CoolingCoilRuntimeFraction;
13266 :
13267 : // Waste heat
13268 835193 : if (thisDXCoil.MSHPHeatRecActive) {
13269 0 : if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
13270 0 : thisDXCoil.MSFuelWasteHeat = thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecCoolingPower;
13271 : } else {
13272 0 : thisDXCoil.MSFuelWasteHeat = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNum), OutdoorDryBulb, InletAirDryBulbTemp) *
13273 0 : thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecCoolingPower;
13274 : }
13275 0 : if (thisDXCoil.MSHPHeatRecActive) {
13276 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
13277 : }
13278 : }
13279 : // Energy use for other fuel types
13280 835193 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13281 98244 : thisDXCoil.FuelUsed = thisDXCoil.ElecCoolingPower;
13282 98244 : thisDXCoil.ElecCoolingPower = 0.0;
13283 : }
13284 :
13285 835193 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
13286 835193 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
13287 : } else {
13288 0 : thisDXCoil.CrankcaseHeaterPower =
13289 0 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.CoolingCoilRuntimeFraction,
13290 0 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction));
13291 : }
13292 : }
13293 :
13294 2104426 : if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
13295 : //******************
13296 : // WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
13297 : // H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
13298 : // /RhoWater [kgWater/m3]
13299 : //******************
13300 0 : RhoWater = RhoH2O(OutdoorDryBulb);
13301 0 : thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater;
13302 0 : thisDXCoil.EvapCondPumpElecPower = EvapCondPumpElecPower;
13303 : // set water system demand request (if needed)
13304 0 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
13305 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
13306 0 : thisDXCoil.EvapWaterConsumpRate;
13307 : }
13308 :
13309 : // Calculate basin heater power
13310 0 : CalcBasinHeaterPower(state,
13311 : thisDXCoil.BasinHeaterPowerFTempDiff,
13312 : thisDXCoil.BasinHeaterSchedulePtr,
13313 : thisDXCoil.BasinHeaterSetPointTemp,
13314 0 : thisDXCoil.BasinHeaterPower);
13315 0 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
13316 : }
13317 :
13318 : } else {
13319 :
13320 : // DX coil is off; just pass through conditions
13321 4764112 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
13322 4764112 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
13323 4764112 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
13324 :
13325 4764112 : thisDXCoil.FuelUsed = 0.0;
13326 4764112 : thisDXCoil.ElecCoolingPower = 0.0;
13327 4764112 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
13328 4764112 : thisDXCoil.SensCoolingEnergyRate = 0.0;
13329 4764112 : thisDXCoil.LatCoolingEnergyRate = 0.0;
13330 4764112 : thisDXCoil.EvapCondPumpElecPower = 0.0;
13331 4764112 : thisDXCoil.EvapWaterConsumpRate = 0.0;
13332 :
13333 4764112 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
13334 4764112 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
13335 : } else {
13336 0 : thisDXCoil.CrankcaseHeaterPower =
13337 0 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction);
13338 : }
13339 :
13340 : // Calculate basin heater power
13341 4764112 : if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
13342 0 : CalcBasinHeaterPower(state,
13343 : thisDXCoil.BasinHeaterPowerFTempDiff,
13344 : thisDXCoil.BasinHeaterSchedulePtr,
13345 : thisDXCoil.BasinHeaterSetPointTemp,
13346 0 : thisDXCoil.BasinHeaterPower);
13347 : }
13348 : }
13349 :
13350 6868538 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
13351 6868538 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
13352 6868538 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
13353 6868538 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
13354 6868538 : thisDXCoil.CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure
13355 :
13356 : // set outlet node conditions
13357 6868538 : int airOutletNode = thisDXCoil.AirOutNode;
13358 6868538 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
13359 6868538 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
13360 :
13361 : // calc secondary coil if specified
13362 6868538 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
13363 0 : CalcSecondaryDXCoils(state, DXCoilNum);
13364 : }
13365 6868538 : }
13366 :
13367 6858982 : void CalcMultiSpeedDXCoilHeating(EnergyPlusData &state,
13368 : int const DXCoilNum, // the number of the DX heating coil to be simulated
13369 : Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
13370 : Real64 const CycRatio, // cycling part load ratio
13371 : int const SpeedNum, // Speed number
13372 : HVAC::FanOp const fanOp, // Fan operation mode
13373 : int const SingleMode // Single mode operation Yes/No; 1=Yes, 0=No
13374 : )
13375 : {
13376 :
13377 : // SUBROUTINE INFORMATION:
13378 : // AUTHOR Lixing Gu, FSEC
13379 : // DATE WRITTEN June 2007
13380 : // RE-ENGINEERED Revised based on CalcDXHeatingCoil
13381 :
13382 : // PURPOSE OF THIS SUBROUTINE:
13383 : // Calculates the air-side performance and electrical energy use of a direct-
13384 : // expansion, air-cooled cooling unit with a multispeed compressor.
13385 :
13386 : // METHODOLOGY EMPLOYED:
13387 : // Uses the same methodology as the single speed DX heating unit model (SUBROUTINE CalcDXHeatingCoil).
13388 : // In addition it assumes that the unit performance is obtained by interpolating between
13389 : // the performance at high speed and that at low speed. If the output needed is below
13390 : // that produced at low speed, the compressor cycles between off and low speed.
13391 :
13392 : // Using/Aliasing
13393 : using Curve::CurveValue;
13394 6858982 : Real64 MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
13395 6858982 : Real64 MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
13396 6858982 : auto &MSHPWasteHeat = state.dataHVACGlobal->MSHPWasteHeat;
13397 :
13398 : // SUBROUTINE ARGUMENT DEFINITIONS:
13399 : // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
13400 :
13401 : // SUBROUTINE PARAMETER DEFINITIONS:
13402 : static constexpr std::string_view RoutineName("CalcMultiSpeedDXCoilHeating");
13403 : static constexpr std::string_view RoutineNameAverageLoad("CalcMultiSpeedDXCoilHeating:Averageload");
13404 : static constexpr std::string_view RoutineNameFullLoad("CalcMultiSpeedDXCoilHeating:fullload");
13405 :
13406 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13407 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
13408 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
13409 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
13410 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
13411 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
13412 : Real64 OutletAirEnthalpy; // outlet air enthalpy [J/kg]
13413 : Real64 OutletAirHumRat; // outlet air humidity ratio [kg/kg]
13414 : Real64 TotCapHS; // total capacity at high speed [W]
13415 : Real64 TotCapLS; // total capacity at low speed [W]
13416 : Real64 TotCapHSAdj; // total adjusted capacity at high speed [W]
13417 : Real64 TotCapLSAdj; // total adjusted capacity at low speed [W]
13418 : Real64 EIRHS; // EIR at off rated conditions (high speed)
13419 : Real64 EIRLS; // EIR at off rated conditions (low speed)
13420 : Real64 TotCap; // total capacity at current speed [W]
13421 : Real64 TotCapAdj; // total adjusted capacity at current speed [W]
13422 : Real64 EIR; // EIR at current speed
13423 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in
13424 : // power calculation
13425 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
13426 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
13427 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
13428 : int SpeedNumHS; // High speed number
13429 : int SpeedNumLS; // Low speed number
13430 : Real64 AirMassFlowRatioLS; // airflow ratio at low speed
13431 : Real64 AirMassFlowRatioHS; // airflow ratio at high speed
13432 : Real64 AirFlowRatio; // Airflow ratio
13433 : Real64 PLRHeating; // Part load ratio in heating
13434 : Real64 CrankcaseHeatingPower; // Power due to crank case heater
13435 : Real64 AirVolumeFlowRate; // Air volume flow rate across the heating coil
13436 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total heating capacity
13437 6858982 : Real64 TotCapTempModFac(0.0); // Total capacity modifier as a function ot temperature
13438 : Real64 TotCapFlowModFac; // Total capacity modifier as a function of flow ratio
13439 : Real64 OutdoorCoilT; // Outdoor coil temperature
13440 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temperature of OutdoorCoilT
13441 : Real64 LoadDueToDefrost; // Additonal load due to defrost
13442 : Real64 LoadDueToDefrostLS; // Additonal load due to defrost at low speed
13443 : Real64 LoadDueToDefrostHS; // Additonal load due to defrost at high speed
13444 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
13445 : Real64 FractionalDefrostTime; // Fraction of time step when system is in defrost
13446 : Real64 InputPowerMultiplier; // Multiplier for poer when system is in defrost
13447 : Real64 DefrostEIRTempModFac; // EIR modifier for defrost
13448 : Real64 FullLoadOutAirEnth; // Outlet full load enthalpy
13449 : Real64 FullLoadOutAirHumRat; // Outlet humidity ratio at full load
13450 : Real64 FullLoadOutAirTemp; // Outlet temperature at full load
13451 : Real64 FullLoadOutAirRH; // Outler relative humidity at full load
13452 : Real64 OutletAirTemp; // Supply ari temperature
13453 6858982 : Real64 EIRTempModFac(0.0); // EIR modifier as a function of temperature
13454 : Real64 EIRFlowModFac; // EIR modifier as a function of airflow ratio
13455 : Real64 WasteHeatLS; // Waste heat at low speed
13456 : Real64 WasteHeatHS; // Waste heat at high speed
13457 : Real64 LSFullLoadOutAirEnth; // Outlet full load enthalpy at low speed
13458 : Real64 HSFullLoadOutAirEnth; // Outlet full load enthalpy at high speed
13459 : Real64 LSElecHeatingPower; // Full load power at low speed
13460 : Real64 HSElecHeatingPower; // Full load power at high speed
13461 : Real64 DefrostPowerLS; // Defrost power at low speed [W]
13462 : Real64 DefrostPowerHS; // Defrost power at high speed [W]
13463 :
13464 : // Autodesk:Uninit Initialize variables used uninitialized
13465 6858982 : FullLoadOutAirEnth = 0.0; // Autodesk:Uninit Force default initialization
13466 :
13467 6858982 : auto &DXCT = state.dataHVACGlobal->DXCT;
13468 6858982 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
13469 :
13470 6858982 : if (SpeedNum > 1) {
13471 1207252 : SpeedNumLS = SpeedNum - 1;
13472 1207252 : SpeedNumHS = SpeedNum;
13473 1207252 : if (SpeedNum > thisDXCoil.NumOfSpeeds) {
13474 0 : SpeedNumLS = thisDXCoil.NumOfSpeeds - 1;
13475 0 : SpeedNumHS = thisDXCoil.NumOfSpeeds;
13476 : }
13477 : } else {
13478 5651730 : SpeedNumLS = 1;
13479 5651730 : SpeedNumHS = 1;
13480 : }
13481 :
13482 6858982 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
13483 6858982 : AirMassFlowRatioLS = MSHPMassFlowRateLow / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS);
13484 6858982 : AirMassFlowRatioHS = MSHPMassFlowRateHigh / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS);
13485 6858982 : if ((AirMassFlow > 0.0) && (CycRatio > 0.0) && (MSHPMassFlowRateHigh == 0.0)) {
13486 0 : ShowSevereError(
13487 : state,
13488 0 : format("CalcMultiSpeedDXCoilHeating: {} \"{} Developer error - inconsistent airflow rates.", thisDXCoil.DXCoilType, thisDXCoil.Name));
13489 0 : if (MSHPMassFlowRateLow == 0.0 && SpeedNum > 1) {
13490 0 : ShowContinueError(state,
13491 : "When AirMassFlow > 0.0 and CycRatio > 0.0 and SpeedNum > 1, then MSHPMassFlowRateLow and MSHPMassFlowRateHigh "
13492 : "must also be > 0.0");
13493 0 : ShowContinueErrorTimeStamp(state, "");
13494 0 : ShowContinueError(state,
13495 0 : format("AirMassFlow={:.3R},CycRatio={:.3R},SpeedNum={:.0R}, MSHPMassFlowRateLow={:.3R}, MSHPMassFlowRateHigh={:.3R}",
13496 : AirMassFlow,
13497 0 : double(SpeedNum),
13498 : CycRatio,
13499 : MSHPMassFlowRateLow,
13500 : MSHPMassFlowRateHigh));
13501 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
13502 : } else {
13503 0 : ShowContinueError(state, "When AirMassFlow > 0.0 and CycRatio > 0.0, then MSHPMassFlowRateHigh must also be > 0.0");
13504 0 : ShowContinueErrorTimeStamp(state, "");
13505 0 : ShowContinueError(state,
13506 0 : format("AirMassFlow={:.3R},CycRatio={:.3R}, MSHPMassFlowRateHigh={:.3R}", AirMassFlow, CycRatio, MSHPMassFlowRateHigh));
13507 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
13508 : }
13509 6858982 : } else if (CycRatio > 1.0 || SpeedRatio > 1.0) {
13510 0 : ShowSevereError(
13511 : state,
13512 0 : format("CalcMultiSpeedDXCoilHeating: {} \"{} Developer error - inconsistent speed ratios.", thisDXCoil.DXCoilType, thisDXCoil.Name));
13513 0 : ShowContinueError(state, "CycRatio and SpeedRatio must be between 0.0 and 1.0");
13514 0 : ShowContinueErrorTimeStamp(state, "");
13515 0 : ShowContinueError(state, format("CycRatio={:.1R}, SpeedRatio = {:.1R}", CycRatio, SpeedRatio));
13516 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
13517 : }
13518 :
13519 6858982 : AirFlowRatio = 1.0;
13520 6858982 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) MSHPWasteHeat = 0.0;
13521 :
13522 : // Get condenser outdoor node info from DX Heating Coil
13523 6858982 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
13524 2703794 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press;
13525 : // If node is not connected to anything, pressure = default, use weather data
13526 2703794 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
13527 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13528 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13529 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13530 : } else {
13531 2703794 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp;
13532 2703794 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat;
13533 : }
13534 2703794 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
13535 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
13536 0 : OutdoorDryBulb = secZoneHB.ZT;
13537 0 : OutdoorHumRat = secZoneHB.airHumRat;
13538 : // OutdoorWetBulb = DXCoil( DXCoilNum ).EvapInletWetBulb;
13539 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13540 : }
13541 4155188 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
13542 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
13543 0 : OutdoorDryBulb = secZoneHB.ZT;
13544 0 : OutdoorHumRat = secZoneHB.airHumRat;
13545 : // OutdoorWetBulb = DXCoil( DXCoilNum ).EvapInletWetBulb;
13546 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13547 : } else {
13548 4155188 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13549 4155188 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13550 4155188 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13551 : }
13552 :
13553 6858982 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
13554 6858982 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
13555 6858982 : InletAirHumRat = thisDXCoil.InletAirHumRat;
13556 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13557 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
13558 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
13559 6858982 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure, RoutineName);
13560 6858982 : PLRHeating = 0.0;
13561 6858982 : thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
13562 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
13563 6858982 : if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
13564 2865655 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
13565 2865655 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
13566 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
13567 : }
13568 : } else {
13569 3993327 : CrankcaseHeatingPower = 0.0;
13570 : }
13571 6858982 : thisDXCoil.PartLoadRatio = 0.0;
13572 6858982 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
13573 :
13574 5967060 : if ((AirMassFlow > 0.0) && (GetCurrentScheduleValue(state, thisDXCoil.SchedPtr) > 0.0) &&
13575 12826042 : ((CycRatio > 0.0) || (SpeedRatio > 0.0 && SingleMode == 0)) && OutdoorDryBulb > thisDXCoil.MinOATCompressor) {
13576 :
13577 1014233 : if (SpeedNum > 1 && SingleMode == 0) {
13578 :
13579 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton) at low speed
13580 305149 : AirVolumeFlowRate = MSHPMassFlowRateLow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
13581 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13582 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
13583 305149 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumLS);
13584 610298 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13585 305149 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
13586 283862 : if (thisDXCoil.MSErrIndex(SpeedNumLS) == 0) {
13587 8 : ShowWarningMessage(
13588 : state,
13589 8 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed {}.",
13590 4 : thisDXCoil.DXCoilType,
13591 4 : thisDXCoil.Name,
13592 : SpeedNumLS));
13593 4 : ShowContinueErrorTimeStamp(state, "");
13594 8 : ShowContinueError(state,
13595 8 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13596 4 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13597 4 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13598 : VolFlowperRatedTotCap));
13599 4 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13600 4 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13601 : }
13602 851586 : ShowRecurringWarningErrorAtEnd(state,
13603 567724 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range "
13604 : "at speed {} error continues...",
13605 283862 : thisDXCoil.DXCoilType,
13606 283862 : thisDXCoil.Name,
13607 : SpeedNumLS),
13608 : thisDXCoil.MSErrIndex(SpeedNumLS),
13609 : VolFlowperRatedTotCap,
13610 : VolFlowperRatedTotCap);
13611 : }
13612 :
13613 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton) at high speed
13614 305149 : AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
13615 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13616 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
13617 305149 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumHS);
13618 610298 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13619 305149 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
13620 283646 : if (thisDXCoil.MSErrIndex(SpeedNumHS) == 0) {
13621 4 : ShowWarningMessage(
13622 : state,
13623 4 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed {}.",
13624 2 : thisDXCoil.DXCoilType,
13625 2 : thisDXCoil.Name,
13626 : SpeedNumHS));
13627 2 : ShowContinueErrorTimeStamp(state, "");
13628 4 : ShowContinueError(state,
13629 4 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13630 2 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13631 2 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13632 : VolFlowperRatedTotCap));
13633 2 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13634 2 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13635 : }
13636 850938 : ShowRecurringWarningErrorAtEnd(state,
13637 567292 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range "
13638 : "at speed {} error continues...",
13639 283646 : thisDXCoil.DXCoilType,
13640 283646 : thisDXCoil.Name,
13641 : SpeedNumHS),
13642 : thisDXCoil.MSErrIndex(SpeedNumHS),
13643 : VolFlowperRatedTotCap,
13644 : VolFlowperRatedTotCap);
13645 : }
13646 :
13647 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
13648 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
13649 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
13650 : // advised to use the bi-quaratic curve if sufficient manufacturer data is available.
13651 : // Low speed
13652 305149 : if (state.dataCurveManager->PerfCurve(thisDXCoil.MSCCapFTemp(SpeedNumLS))->numDims == 1) {
13653 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumLS), OutdoorDryBulb);
13654 : } else {
13655 305149 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumLS), InletAirDryBulbTemp, OutdoorDryBulb);
13656 : }
13657 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
13658 305149 : TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNumLS), AirMassFlowRatioLS);
13659 : // Calculate total heating capacity for off-rated conditions
13660 305149 : TotCapLS = thisDXCoil.MSRatedTotCap(SpeedNumLS) * TotCapFlowModFac * TotCapTempModFac;
13661 : // High speed
13662 305149 : if (state.dataCurveManager->PerfCurve(thisDXCoil.MSCCapFTemp(SpeedNumHS))->numDims == 1) {
13663 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumHS), OutdoorDryBulb);
13664 : } else {
13665 305149 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumHS), InletAirDryBulbTemp, OutdoorDryBulb);
13666 : }
13667 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
13668 305149 : TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNumHS), AirMassFlowRatioHS);
13669 : // Calculate total heating capacity for off-rated conditions
13670 305149 : TotCapHS = thisDXCoil.MSRatedTotCap(SpeedNumHS) * TotCapFlowModFac * TotCapTempModFac;
13671 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
13672 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
13673 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
13674 : // advised to use the bi-quaratic curve if sufficient manufacturer data is available.
13675 : // Low Speed
13676 305149 : if (state.dataCurveManager->PerfCurve(thisDXCoil.MSEIRFTemp(SpeedNumLS))->numDims == 1) {
13677 0 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), OutdoorDryBulb);
13678 : } else {
13679 305149 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), InletAirDryBulbTemp, OutdoorDryBulb);
13680 : }
13681 305149 : EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumLS), AirMassFlowRatioLS);
13682 305149 : EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumLS) * EIRTempModFac * EIRFlowModFac;
13683 : // High Speed
13684 305149 : if (state.dataCurveManager->PerfCurve(thisDXCoil.MSEIRFTemp(SpeedNumHS))->numDims == 1) {
13685 0 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), OutdoorDryBulb);
13686 : } else {
13687 305149 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), InletAirDryBulbTemp, OutdoorDryBulb);
13688 : }
13689 305149 : EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumHS), AirMassFlowRatioHS);
13690 305149 : EIRHS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumHS) * EIRTempModFac * EIRFlowModFac;
13691 :
13692 : // Calculating adjustment factors for defrost
13693 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
13694 305149 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
13695 305149 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure, RoutineName)));
13696 :
13697 : // Initializing defrost adjustment factors
13698 305149 : LoadDueToDefrostLS = 0.0;
13699 305149 : LoadDueToDefrostHS = 0.0;
13700 305149 : HeatingCapacityMultiplier = 1.0;
13701 305149 : FractionalDefrostTime = 0.0;
13702 305149 : InputPowerMultiplier = 1.0;
13703 305149 : DefrostPowerLS = 0.0;
13704 305149 : DefrostPowerHS = 0.0;
13705 :
13706 : // Check outdoor temperature to determine if defrost is active
13707 305149 : if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost) {
13708 : // Calculate defrost adjustment factors depending on defrost control type
13709 303898 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
13710 303898 : FractionalDefrostTime = thisDXCoil.DefrostTime;
13711 303898 : if (FractionalDefrostTime > 0.0) {
13712 303898 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
13713 303898 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
13714 : }
13715 : } else { // else defrost control is on-demand
13716 0 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
13717 0 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
13718 0 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
13719 : }
13720 :
13721 303898 : if (FractionalDefrostTime > 0.0) {
13722 : // Calculate defrost adjustment factors depending on defrost control strategy
13723 303898 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
13724 303898 : DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
13725 303898 : LoadDueToDefrostLS =
13726 303898 : (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(SpeedNumLS) / 1.01667);
13727 303898 : DefrostPowerLS = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(SpeedNumLS) / 1.01667) * FractionalDefrostTime;
13728 303898 : LoadDueToDefrostHS =
13729 303898 : (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(SpeedNumHS) / 1.01667);
13730 303898 : DefrostPowerHS = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(SpeedNumHS) / 1.01667) * FractionalDefrostTime;
13731 : } else { // Defrost strategy is resistive
13732 0 : thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
13733 : }
13734 : } else { // Defrost is not active because (OutDryBulbTemp .GT. DXCoil(DXCoilNum)%MaxOATDefrost)
13735 0 : thisDXCoil.DefrostPower = 0.0;
13736 : }
13737 : }
13738 :
13739 305149 : TotCapLSAdj = TotCapLS * HeatingCapacityMultiplier;
13740 305149 : TotCapHSAdj = TotCapHS * HeatingCapacityMultiplier;
13741 :
13742 : // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
13743 305149 : PLRHeating = min(1.0, (SpeedRatio + LoadDueToDefrostHS / TotCapHSAdj));
13744 305149 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNumHS), PLRHeating); // Calculate part-load factor
13745 :
13746 305149 : if (PLF < 0.7) {
13747 0 : if (thisDXCoil.PLRErrIndex == 0) {
13748 0 : ShowWarningMessage(
13749 : state,
13750 0 : format("The PLF curve value at high speed for DX multispeed heating coil {} ={:.2R} for part-load ratio ={:.2R}",
13751 0 : thisDXCoil.Name,
13752 : PLF,
13753 : PLRHeating));
13754 0 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
13755 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:MultiSpeed].");
13756 0 : ShowContinueErrorTimeStamp(state, "");
13757 : }
13758 0 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
13759 0 : PLF = 0.7;
13760 : }
13761 :
13762 305149 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
13763 305149 : if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
13764 0 : if (thisDXCoil.ErrIndex4 == 0) {
13765 0 : ShowWarningMessage(state,
13766 0 : format("The runtime fraction at high speed for DX multispeed heating coil {} exceeded 1.0. [{:.4R}].",
13767 0 : thisDXCoil.Name,
13768 0 : thisDXCoil.HeatingCoilRuntimeFraction));
13769 0 : ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
13770 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
13771 0 : ShowContinueErrorTimeStamp(state, "");
13772 : }
13773 0 : ShowRecurringWarningErrorAtEnd(state,
13774 0 : thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
13775 0 : thisDXCoil.ErrIndex4,
13776 0 : thisDXCoil.HeatingCoilRuntimeFraction,
13777 0 : thisDXCoil.HeatingCoilRuntimeFraction);
13778 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
13779 305149 : } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
13780 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
13781 : }
13782 :
13783 : // Get full load output and power
13784 305149 : LSFullLoadOutAirEnth = InletAirEnthalpy + TotCapLSAdj / MSHPMassFlowRateLow;
13785 305149 : HSFullLoadOutAirEnth = InletAirEnthalpy + TotCapHSAdj / MSHPMassFlowRateHigh;
13786 305149 : LSElecHeatingPower = TotCapLS * EIRLS * InputPowerMultiplier;
13787 305149 : HSElecHeatingPower = TotCapHS * EIRHS * InputPowerMultiplier;
13788 305149 : OutletAirHumRat = InletAirHumRat;
13789 :
13790 : // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
13791 305149 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
13792 :
13793 : // Power calculation
13794 305149 : if (!thisDXCoil.PLRImpact) {
13795 305149 : thisDXCoil.ElecHeatingPower = SpeedRatio * HSElecHeatingPower + (1.0 - SpeedRatio) * LSElecHeatingPower;
13796 : } else {
13797 0 : thisDXCoil.ElecHeatingPower =
13798 0 : thisDXCoil.HeatingCoilRuntimeFraction * HSElecHeatingPower + (1.0 - thisDXCoil.HeatingCoilRuntimeFraction) * LSElecHeatingPower;
13799 : }
13800 :
13801 305149 : thisDXCoil.TotalHeatingEnergyRate = MSHPMassFlowRateHigh * (HSFullLoadOutAirEnth - InletAirEnthalpy) * SpeedRatio +
13802 305149 : MSHPMassFlowRateLow * (LSFullLoadOutAirEnth - InletAirEnthalpy) * (1.0 - SpeedRatio);
13803 305149 : OutletAirEnthalpy = InletAirEnthalpy + thisDXCoil.TotalHeatingEnergyRate / thisDXCoil.InletAirMassFlowRate;
13804 305149 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
13805 305149 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, OutdoorPressure, RoutineNameAverageLoad);
13806 305149 : if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
13807 0 : OutletAirTemp = PsyTsatFnHPb(state,
13808 : FullLoadOutAirEnth,
13809 : OutdoorPressure,
13810 : RoutineName); // Autodesk:Uninit FullLoadOutAirEnth was possibly uninitialized
13811 0 : OutletAirHumRat = PsyWFnTdbH(
13812 : state, OutletAirTemp, FullLoadOutAirEnth, RoutineName); // Autodesk:Uninit FullLoadOutAirEnth was possibly uninitialized
13813 : }
13814 :
13815 : // Waste heat calculation
13816 305149 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13817 0 : if (thisDXCoil.MSWasteHeat(SpeedNumLS) == 0) {
13818 0 : WasteHeatLS = thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13819 : } else {
13820 0 : WasteHeatLS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumLS), OutdoorDryBulb, InletAirDryBulbTemp) *
13821 0 : thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13822 : }
13823 0 : if (thisDXCoil.MSWasteHeat(SpeedNumHS) == 0) {
13824 0 : WasteHeatHS = thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13825 : } else {
13826 0 : WasteHeatHS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumHS), OutdoorDryBulb, InletAirDryBulbTemp) *
13827 0 : thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13828 : }
13829 0 : thisDXCoil.MSFuelWasteHeat = (SpeedRatio * WasteHeatHS + (1.0 - SpeedRatio) * WasteHeatLS) * thisDXCoil.ElecCoolingPower;
13830 0 : if (thisDXCoil.MSHPHeatRecActive) {
13831 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
13832 : }
13833 : }
13834 305149 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13835 :
13836 0 : thisDXCoil.FuelUsed = thisDXCoil.ElecHeatingPower;
13837 0 : thisDXCoil.ElecHeatingPower = 0.0;
13838 : }
13839 :
13840 : // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
13841 : // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
13842 305149 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
13843 305149 : if (!thisDXCoil.PLRImpact) {
13844 305149 : thisDXCoil.DefrostPower = DefrostPowerHS * SpeedRatio + DefrostPowerLS * (1.0 - SpeedRatio);
13845 : } else {
13846 0 : thisDXCoil.DefrostPower =
13847 0 : DefrostPowerHS * thisDXCoil.HeatingCoilRuntimeFraction + DefrostPowerLS * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
13848 : }
13849 : }
13850 305149 : thisDXCoil.OutletAirTemp = OutletAirTemp;
13851 305149 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
13852 305149 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
13853 305149 : thisDXCoil.CrankcaseHeaterPower = 0.0;
13854 :
13855 : // Stage 1
13856 709084 : } else if (CycRatio > 0.0 || (CycRatio > 0.0 && SingleMode == 1)) {
13857 :
13858 : // for cycling fan, reset mass flow to full on rate
13859 709084 : if (fanOp == HVAC::FanOp::Cycling) AirMassFlow /= CycRatio;
13860 709084 : if (fanOp == HVAC::FanOp::Continuous) AirMassFlow = MSHPMassFlowRateHigh;
13861 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton)
13862 709084 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
13863 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13864 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
13865 709084 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNum);
13866 :
13867 1418168 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13868 709084 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
13869 698193 : if (thisDXCoil.ErrIndex1 == 0) {
13870 12 : ShowWarningMessage(state,
13871 12 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed 1.",
13872 6 : thisDXCoil.DXCoilType,
13873 6 : thisDXCoil.Name));
13874 6 : ShowContinueErrorTimeStamp(state, "");
13875 12 : ShowContinueError(state,
13876 12 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13877 6 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13878 6 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13879 : VolFlowperRatedTotCap));
13880 6 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13881 6 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13882 : }
13883 2094579 : ShowRecurringWarningErrorAtEnd(
13884 : state,
13885 1396386 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
13886 : "\" - Air volume flow rate per watt of rated total heating capacity is out of range error continues at speed 1...",
13887 698193 : thisDXCoil.ErrIndex1,
13888 : VolFlowperRatedTotCap,
13889 : VolFlowperRatedTotCap);
13890 : }
13891 :
13892 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
13893 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
13894 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
13895 : // advised to use the bi-quaratic curve if sufficient manufacturer data is available.
13896 709084 : if (state.dataCurveManager->PerfCurve(thisDXCoil.MSCCapFTemp(SpeedNum))->numDims == 1) {
13897 638208 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNum), OutdoorDryBulb);
13898 : } else {
13899 70876 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNum), InletAirDryBulbTemp, OutdoorDryBulb);
13900 : }
13901 :
13902 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
13903 : // AirMassFlowRatio = AirMassFlow/DXCoil(DXCoilNum)%MSRatedAirMassFlowRate(SpeedNumLS)
13904 : // TotCapFlowModFac = CurveValue(state, DXCoil(DXCoilNum)%MSCCapFFlow(SpeedNumLS),AirMassFlowRatio)
13905 709084 : TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNum), AirMassFlowRatioLS);
13906 : // Calculate total heating capacity for off-rated conditions
13907 709084 : TotCap = thisDXCoil.MSRatedTotCap(SpeedNum) * TotCapFlowModFac * TotCapTempModFac;
13908 :
13909 : // Calculating adjustment factors for defrost
13910 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
13911 709084 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
13912 709084 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure, RoutineName)));
13913 :
13914 : // Initializing defrost adjustment factors
13915 709084 : LoadDueToDefrost = 0.0;
13916 709084 : HeatingCapacityMultiplier = 1.0;
13917 709084 : FractionalDefrostTime = 0.0;
13918 709084 : InputPowerMultiplier = 1.0;
13919 :
13920 : // Check outdoor temperature to determine of defrost is active
13921 709084 : if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost) {
13922 : // Calculate defrost adjustment factors depending on defrost control type
13923 449664 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
13924 449664 : FractionalDefrostTime = thisDXCoil.DefrostTime;
13925 449664 : if (FractionalDefrostTime > 0.0) {
13926 449664 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
13927 449664 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
13928 : }
13929 : } else { // else defrost control is on-demand
13930 0 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
13931 0 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
13932 0 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
13933 : }
13934 :
13935 449664 : if (FractionalDefrostTime > 0.0) {
13936 : // Calculate defrost adjustment factors depending on defrost control strategy
13937 449664 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
13938 449664 : LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(1) / 1.01667);
13939 449664 : DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
13940 449664 : thisDXCoil.DefrostPower = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(1) / 1.01667) * FractionalDefrostTime;
13941 : } else { // Defrost strategy is resistive
13942 0 : thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
13943 : }
13944 : } else { // Defrost is not active because (OutDryBulbTemp .GT. DXCoil(DXCoilNum)%MaxOATDefrost)
13945 0 : thisDXCoil.DefrostPower = 0.0;
13946 : }
13947 : }
13948 :
13949 : // Modify total heating capacity based on defrost heating capacity multiplier
13950 709084 : TotCapAdj = TotCap * HeatingCapacityMultiplier;
13951 :
13952 : // Calculate full load outlet conditions
13953 709084 : FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
13954 709084 : FullLoadOutAirHumRat = InletAirHumRat;
13955 709084 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
13956 709084 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
13957 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13958 : // FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
13959 709084 : if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
13960 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure, RoutineName);
13961 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13962 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
13963 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
13964 : }
13965 :
13966 : // Set outlet conditions from the full load calculation
13967 709084 : OutletAirEnthalpy = FullLoadOutAirEnth;
13968 709084 : OutletAirHumRat = FullLoadOutAirHumRat;
13969 709084 : OutletAirTemp = FullLoadOutAirTemp;
13970 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
13971 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
13972 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
13973 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
13974 709084 : if (state.dataCurveManager->PerfCurve(thisDXCoil.MSEIRFTemp(1))->numDims == 1) {
13975 638208 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(1), OutdoorDryBulb);
13976 : } else {
13977 70876 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(1), InletAirDryBulbTemp, OutdoorDryBulb);
13978 : }
13979 709084 : EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(1), AirMassFlowRatioLS);
13980 709084 : EIR = 1.0 / thisDXCoil.MSRatedCOP(1) * EIRTempModFac * EIRFlowModFac;
13981 : // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
13982 709084 : PLRHeating = min(1.0, (CycRatio + LoadDueToDefrost / TotCapAdj));
13983 709084 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(1), PLRHeating); // Calculate part-load factor
13984 709084 : if (fanOp == HVAC::FanOp::Cycling && CycRatio == 1.0 && PLF != 1.0) {
13985 0 : if (thisDXCoil.PLFErrIndex == 0) {
13986 0 : ShowWarningMessage(state,
13987 0 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio = 1", thisDXCoil.Name, PLF));
13988 0 : ShowContinueError(state, "PLF curve value must be = 1.0 and has been reset to 1.0. Simulation is continuing.");
13989 0 : ShowContinueErrorTimeStamp(state, "");
13990 : }
13991 0 : ShowRecurringWarningErrorAtEnd(
13992 0 : state, thisDXCoil.Name + "\": DX heating coil PLF curve value <> 1.0 warning continues...", thisDXCoil.PLFErrIndex, PLF, PLF);
13993 0 : PLF = 1.0;
13994 : }
13995 :
13996 709084 : if (PLF < 0.7) {
13997 0 : if (thisDXCoil.PLRErrIndex == 0) {
13998 0 : ShowWarningMessage(
13999 : state,
14000 0 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
14001 0 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
14002 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
14003 0 : ShowContinueErrorTimeStamp(state, "");
14004 : }
14005 0 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
14006 0 : PLF = 0.7;
14007 : }
14008 :
14009 709084 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
14010 709084 : if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
14011 0 : if (thisDXCoil.ErrIndex4 == 0) {
14012 0 : ShowWarningMessage(state,
14013 0 : format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
14014 0 : thisDXCoil.Name,
14015 0 : thisDXCoil.HeatingCoilRuntimeFraction));
14016 0 : ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
14017 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
14018 0 : ShowContinueErrorTimeStamp(state, "");
14019 : }
14020 0 : ShowRecurringWarningErrorAtEnd(state,
14021 0 : thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
14022 0 : thisDXCoil.ErrIndex4,
14023 0 : thisDXCoil.HeatingCoilRuntimeFraction,
14024 0 : thisDXCoil.HeatingCoilRuntimeFraction);
14025 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
14026 709084 : } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
14027 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
14028 : }
14029 : // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
14030 709084 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
14031 709084 : thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
14032 :
14033 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
14034 : // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
14035 :
14036 709084 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
14037 352687 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
14038 : } else {
14039 356397 : thisDXCoil.CrankcaseHeaterPower =
14040 356397 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
14041 356397 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
14042 : }
14043 :
14044 709084 : thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (FullLoadOutAirEnth - InletAirEnthalpy) * CycRatio;
14045 709084 : if (fanOp == HVAC::FanOp::Continuous) {
14046 590415 : OutletAirEnthalpy = InletAirEnthalpy + thisDXCoil.TotalHeatingEnergyRate / thisDXCoil.InletAirMassFlowRate;
14047 590415 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
14048 : }
14049 709084 : if (thisDXCoil.MSHPHeatRecActive || thisDXCoil.FuelType != Constant::eFuel::Electricity) {
14050 0 : if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
14051 0 : thisDXCoil.MSFuelWasteHeat = thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecHeatingPower;
14052 : } else {
14053 0 : thisDXCoil.MSFuelWasteHeat = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNum), OutdoorDryBulb, InletAirDryBulbTemp) *
14054 0 : thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecHeatingPower;
14055 : }
14056 0 : if (thisDXCoil.MSHPHeatRecActive) {
14057 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
14058 : }
14059 : }
14060 709084 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
14061 :
14062 0 : thisDXCoil.FuelUsed = thisDXCoil.ElecHeatingPower;
14063 0 : thisDXCoil.ElecHeatingPower = 0.0;
14064 : }
14065 : // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
14066 : // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
14067 709084 : thisDXCoil.DefrostPower *= thisDXCoil.HeatingCoilRuntimeFraction;
14068 :
14069 709084 : thisDXCoil.OutletAirTemp = OutletAirTemp;
14070 709084 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
14071 709084 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
14072 : }
14073 :
14074 : } else {
14075 :
14076 : // DX coil is off; just pass through conditions
14077 5844749 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
14078 5844749 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
14079 5844749 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
14080 :
14081 5844749 : thisDXCoil.ElecHeatingPower = 0.0;
14082 5844749 : thisDXCoil.FuelUsed = 0.0;
14083 5844749 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
14084 5844749 : thisDXCoil.DefrostPower = 0.0;
14085 :
14086 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
14087 : // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
14088 5844749 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
14089 2457297 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
14090 : } else {
14091 3387452 : thisDXCoil.CrankcaseHeaterPower =
14092 3387452 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
14093 : }
14094 :
14095 : } // end of on/off if - else
14096 :
14097 6858982 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
14098 6858982 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
14099 6858982 : thisDXCoil.PartLoadRatio = PLRHeating;
14100 6858982 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
14101 6858982 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
14102 6858982 : thisDXCoil.MSSpeedNumLS = SpeedNumLS;
14103 6858982 : thisDXCoil.MSSpeedNumHS = SpeedNumHS;
14104 6858982 : thisDXCoil.MSSpeedRatio = SpeedRatio;
14105 6858982 : thisDXCoil.MSCycRatio = CycRatio;
14106 :
14107 : // set outlet node conditions
14108 6858982 : int airOutletNode = thisDXCoil.AirOutNode;
14109 6858982 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
14110 6858982 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
14111 :
14112 : // calc secondary coil if specified
14113 6858982 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
14114 0 : CalcSecondaryDXCoils(state, DXCoilNum);
14115 : }
14116 6858982 : }
14117 :
14118 63535486 : void UpdateDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current fan coil unit being simulated
14119 : {
14120 :
14121 : // SUBROUTINE INFORMATION:
14122 : // AUTHOR Fred Buhl
14123 : // DATE WRITTEN May 2000
14124 :
14125 : // PURPOSE OF THIS SUBROUTINE:
14126 : // This subroutine is for passing results to the outlet air node.
14127 :
14128 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14129 : int AirOutletNode; // air outlet node number
14130 : int AirInletNode; // air inlet node number
14131 :
14132 63535486 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
14133 :
14134 63535486 : AirOutletNode = thisDXCoil.AirOutNode;
14135 63535486 : AirInletNode = thisDXCoil.AirInNode;
14136 : // changed outputs
14137 63535486 : state.dataLoopNodes->Node(AirOutletNode).Enthalpy = thisDXCoil.OutletAirEnthalpy;
14138 63535486 : state.dataLoopNodes->Node(AirOutletNode).Temp = thisDXCoil.OutletAirTemp;
14139 63535486 : state.dataLoopNodes->Node(AirOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
14140 63535486 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRate = thisDXCoil.InletAirMassFlowRate;
14141 : // pass through outputs
14142 63535486 : state.dataLoopNodes->Node(AirOutletNode).Quality = state.dataLoopNodes->Node(AirInletNode).Quality;
14143 63535486 : state.dataLoopNodes->Node(AirOutletNode).Press = state.dataLoopNodes->Node(AirInletNode).Press;
14144 63535486 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMin = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMin;
14145 63535486 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMax = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax;
14146 63535486 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMinAvail;
14147 63535486 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMaxAvail;
14148 :
14149 63535486 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
14150 1314605 : state.dataLoopNodes->Node(AirOutletNode).CO2 = state.dataLoopNodes->Node(AirInletNode).CO2;
14151 : }
14152 63535486 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
14153 173539 : state.dataLoopNodes->Node(AirOutletNode).GenContam = state.dataLoopNodes->Node(AirInletNode).GenContam;
14154 : }
14155 63535486 : }
14156 :
14157 63535486 : void ReportDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current fan coil unit being simulated
14158 : {
14159 :
14160 : // SUBROUTINE INFORMATION:
14161 : // AUTHOR Fred Buhl
14162 : // DATE WRITTEN May 2000
14163 : // MODIFIED Richard Raustad/Don Shirey Oct 2001, Feb 2004
14164 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
14165 : // Always update evap value to support new coil type COIL:DX:MultiMode:CoolingEmpirical:
14166 : // Lixing Gu. Jan. 5, 2007, pass information to the AirflowNetwork model
14167 :
14168 : // PURPOSE OF THIS SUBROUTINE:
14169 : // Fills some of the report variables for the DX coils
14170 :
14171 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14172 :
14173 63535486 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
14174 :
14175 63535486 : if (thisDXCoil.reportCoilFinalSizes) {
14176 16840723 : if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->DoingSizing) {
14177 971 : Real64 ratedSensCap(0.0);
14178 971 : ratedSensCap = thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1);
14179 971 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
14180 971 : state, thisDXCoil.Name, thisDXCoil.DXCoilType, thisDXCoil.RatedTotCap(1), ratedSensCap, thisDXCoil.RatedAirVolFlowRate(1), -999.0);
14181 971 : thisDXCoil.reportCoilFinalSizes = false;
14182 : }
14183 : }
14184 :
14185 63535486 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
14186 :
14187 63535486 : switch (thisDXCoil.DXCoilType_Num) {
14188 8275125 : case HVAC::CoilDX_HeatingEmpirical:
14189 : case HVAC::CoilVRF_Heating:
14190 : case HVAC::CoilVRF_FluidTCtrl_Heating: {
14191 8275125 : thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
14192 8275125 : thisDXCoil.ElecHeatingConsumption = thisDXCoil.ElecHeatingPower * ReportingConstant;
14193 8275125 : thisDXCoil.DefrostConsumption = thisDXCoil.DefrostPower * ReportingConstant;
14194 8275125 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14195 8275125 : state.dataHVACGlobal->DXElecHeatingPower = thisDXCoil.ElecHeatingPower + thisDXCoil.CrankcaseHeaterPower;
14196 8275125 : state.dataHVACGlobal->DefrostElecPower = thisDXCoil.DefrostPower;
14197 8275125 : } break;
14198 6858976 : case HVAC::CoilDX_MultiSpeedHeating: {
14199 6858976 : thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
14200 6858976 : if (thisDXCoil.FuelType == Constant::eFuel::Electricity) {
14201 6219724 : thisDXCoil.ElecHeatingConsumption = thisDXCoil.ElecHeatingPower * ReportingConstant;
14202 : } else {
14203 639252 : thisDXCoil.FuelConsumed = thisDXCoil.FuelUsed * ReportingConstant;
14204 : }
14205 6858976 : thisDXCoil.DefrostConsumption = thisDXCoil.DefrostPower * ReportingConstant;
14206 6858976 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14207 6858976 : state.dataHVACGlobal->DXElecHeatingPower = thisDXCoil.ElecHeatingPower + thisDXCoil.CrankcaseHeaterPower;
14208 6858976 : state.dataHVACGlobal->DefrostElecPower = thisDXCoil.DefrostPower;
14209 6858976 : } break;
14210 6868303 : case HVAC::CoilDX_MultiSpeedCooling: {
14211 6868303 : thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
14212 6868303 : thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
14213 6868303 : thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
14214 6868303 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14215 6868303 : state.dataHVACGlobal->DXElecCoolingPower = thisDXCoil.ElecCoolingPower;
14216 6868303 : thisDXCoil.EvapCondPumpElecConsumption = thisDXCoil.EvapCondPumpElecPower * ReportingConstant;
14217 6868303 : thisDXCoil.EvapWaterConsump = thisDXCoil.EvapWaterConsumpRate * ReportingConstant;
14218 6868303 : if (thisDXCoil.FuelType == Constant::eFuel::Electricity) {
14219 5611681 : thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
14220 : } else {
14221 1256622 : thisDXCoil.FuelConsumed = thisDXCoil.FuelUsed * ReportingConstant;
14222 : }
14223 6868303 : if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
14224 0 : thisDXCoil.BasinHeaterConsumption = thisDXCoil.BasinHeaterPower * ReportingConstant;
14225 : }
14226 6868303 : } break;
14227 631844 : case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
14228 : case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
14229 : // water heating energy for HP water heater DX Coil condenser
14230 631844 : thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
14231 : // water heating power for HP water heater
14232 631844 : thisDXCoil.ElecWaterHeatingConsumption = thisDXCoil.ElecWaterHeatingPower * ReportingConstant;
14233 : // other usual DX cooling coil outputs
14234 631844 : thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
14235 631844 : thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
14236 631844 : thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
14237 631844 : thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
14238 631844 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14239 : // DXElecCoolingPower global is only used for air-to-air cooling and heating coils
14240 631844 : state.dataHVACGlobal->DXElecCoolingPower = 0.0;
14241 631844 : } break;
14242 40901238 : default: {
14243 40901238 : thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
14244 40901238 : thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
14245 40901238 : thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
14246 40901238 : thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
14247 40901238 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14248 40901238 : state.dataHVACGlobal->DXElecCoolingPower = thisDXCoil.ElecCoolingPower;
14249 40901238 : thisDXCoil.EvapCondPumpElecConsumption = thisDXCoil.EvapCondPumpElecPower * ReportingConstant;
14250 40901238 : thisDXCoil.EvapWaterConsump = thisDXCoil.EvapWaterConsumpRate * ReportingConstant;
14251 40901238 : if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
14252 122565 : thisDXCoil.BasinHeaterConsumption = thisDXCoil.BasinHeaterPower * ReportingConstant;
14253 : }
14254 40901238 : } break;
14255 : }
14256 :
14257 63535486 : if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
14258 : // calculate and report condensation rates (how much water extracted from the air stream)
14259 : // water flow of water in m3/s for water system interactions
14260 : // put here to catch all types of DX coils
14261 0 : Real64 Tavg = (thisDXCoil.InletAirTemp + thisDXCoil.OutletAirTemp) / 2.0;
14262 : // CR9155 Remove specific humidity calculations
14263 : // mdot * del HumRat / rho water
14264 0 : thisDXCoil.CondensateVdot =
14265 0 : max(0.0, (thisDXCoil.InletAirMassFlowRate * (thisDXCoil.InletAirHumRat - thisDXCoil.OutletAirHumRat) / Psychrometrics::RhoH2O(Tavg)));
14266 0 : thisDXCoil.CondensateVol = thisDXCoil.CondensateVdot * ReportingConstant;
14267 :
14268 0 : state.dataWaterData->WaterStorage(thisDXCoil.CondensateTankID).VdotAvailSupply(thisDXCoil.CondensateTankSupplyARRID) =
14269 0 : thisDXCoil.CondensateVdot;
14270 0 : state.dataWaterData->WaterStorage(thisDXCoil.CondensateTankID).TwaterSupply(thisDXCoil.CondensateTankSupplyARRID) = thisDXCoil.OutletAirTemp;
14271 : }
14272 :
14273 63535486 : state.dataAirLoop->LoopDXCoilRTF = max(thisDXCoil.CoolingCoilRuntimeFraction, thisDXCoil.HeatingCoilRuntimeFraction);
14274 63535486 : if (thisDXCoil.AirLoopNum > 0) {
14275 4710328 : state.dataAirLoop->AirLoopAFNInfo(thisDXCoil.AirLoopNum).AFNLoopDXCoilRTF =
14276 4710328 : max(thisDXCoil.CoolingCoilRuntimeFraction, thisDXCoil.HeatingCoilRuntimeFraction);
14277 : }
14278 63535486 : }
14279 :
14280 66 : void CalcTwoSpeedDXCoilStandardRating(EnergyPlusData &state, int const DXCoilNum)
14281 : {
14282 : // SUBROUTINE INFORMATION:
14283 : // AUTHOR B. Griffith, (Derived from CalcDXCoilStandardRating by Bereket Nigusse & Chandan Sharma)
14284 : // DATE WRITTEN July 2012
14285 :
14286 : // PURPOSE OF THIS SUBROUTINE:
14287 : // Calculate the following
14288 : // (1) Standard Rated (net) Cooling Capacity
14289 : // (2) Energy Efficiency Ratio (EER),
14290 : // (3) Integrated Energy Efficiency Ratio (IEER)
14291 :
14292 : // REFERENCES:
14293 : // ANSI/AHRI Standard 340/360-2007, Performance Rating of Commercial and Industrial Unitary Air-Conditioning and
14294 : // Heat Pump Equipment, Air-Conditioning, Heating, and Refrigeration Institute, Arlington VA.
14295 :
14296 : // Using/Aliasing
14297 : using Curve::CurveValue;
14298 : using namespace OutputReportPredefined;
14299 :
14300 : // SUBROUTINE PARAMETER DEFINITIONS:
14301 : // AHRI Standard 340/360-2007 Performance Rating of Commercial and Industrial Unitary Air-Conditioning and Heat Pump Equipment
14302 66 : Real64 constexpr CoolingCoilInletAirWetBulbTempRated(19.4); // 19.44C (67F)
14303 66 : Real64 constexpr CoolingCoilInletAirDryBulbTempRated(26.7);
14304 66 : Real64 constexpr OutdoorUnitInletAirDryBulbTempRated(35.0); // 35.00C (95F)
14305 66 : static Array1D<Real64> const OutdoorUnitInletAirDryBulbTempPLTestPoint(3, {27.5, 20.0, 18.3});
14306 66 : static Array1D<Real64> const NetCapacityFactorPLTestPoint(3, {0.75, 0.50, 0.25});
14307 66 : Real64 constexpr ConvFromSIToIP(3.412141633); // Conversion from SI to IP [3.412 Btu/hr-W]
14308 :
14309 66 : Real64 constexpr AirMassFlowRatioRated(1.0); // AHRI test is at the design flow rate
14310 : // and hence AirMassFlowRatio is 1.0
14311 :
14312 66 : Real64 constexpr DefaultFanPowerPerEvapAirFlowRate(773.3); // 365 W/1000 scfm or 773.3 W/(m3/s). The AHRI standard
14313 66 : Real64 constexpr DefaultFanPowerPerEvapAirFlowRateSEER2(934.4); // 441 W/1000 scfm or 934.4 W/(m3/s). The AHRI standard
14314 : // specifies a nominal/default fan electric power consumption per rated air
14315 : // volume flow rate to account for indoor fan electric power consumption
14316 : // when the standard tests are conducted on units that do not have an
14317 : // indoor air circulating fan. Used if user doesn't enter a specific value.
14318 :
14319 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14320 : static constexpr std::string_view RoutineName("CalcTwoSpeedDXCoilStandardRating");
14321 :
14322 66 : auto &NetCoolingCapRated = state.dataDXCoils->NetCoolingCapRated;
14323 66 : auto &EER = state.dataDXCoils->EER;
14324 66 : auto &IEER = state.dataDXCoils->IEER;
14325 66 : auto &TotCapTempModFac = state.dataDXCoils->TotCapTempModFac;
14326 66 : auto &TotCapFlowModFac = state.dataDXCoils->TotCapFlowModFac;
14327 66 : auto &EIRTempModFac = state.dataDXCoils->EIRTempModFac;
14328 66 : auto &EIRFlowModFac = state.dataDXCoils->EIRFlowModFac;
14329 66 : auto &TempDryBulb_Leaving_Apoint = state.dataDXCoils->TempDryBulb_Leaving_Apoint;
14330 :
14331 66 : constexpr Real64 AccuracyTolerance(0.2); // tolerance in AHRI 340/360 Table 6 note 1
14332 66 : constexpr int MaximumIterations(1000);
14333 : Real64 EIR;
14334 : Real64 TotalElecPowerRated;
14335 66 : Array1D<Real64> EER_TestPoint_SI(4); // 1 = A, 2 = B, 3= C, 4= D
14336 66 : Array1D<Real64> EER_TestPoint_IP(4); // 1 = A, 2 = B, 3= C, 4= D
14337 66 : Array1D<Real64> NetCapacity_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
14338 66 : Array1D<Real64> NetPower_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
14339 66 : Array1D<Real64> SupAirMdot_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
14340 :
14341 : Real64 HighSpeedNetCoolingCap;
14342 : Real64 LowSpeedNetCoolingCap;
14343 :
14344 : Real64 PartLoadAirMassFlowRate;
14345 : Real64 AirMassFlowRatio;
14346 : int SolverFlag;
14347 : Real64 EIR_HighSpeed;
14348 : Real64 EIR_LowSpeed;
14349 : int FanInletNode;
14350 : int FanOutletNode;
14351 : int Iter;
14352 : Real64 ExternalStatic;
14353 : Real64 FanStaticPressureRise;
14354 : Real64 FanHeatCorrection;
14355 : Real64 FanPowerCorrection;
14356 66 : Real64 FanPowerPerEvapAirFlowRate = 0.0;
14357 : Real64 FanPowerPerEvapAirFlowRateSEER2;
14358 : Real64 SpeedRatio;
14359 : Real64 CycRatio;
14360 : Real64 TargetNetCapacity;
14361 : Real64 SupplyAirHumRat;
14362 : Real64 SupplyAirRho;
14363 : Real64 SupplyAirVolFlowRate;
14364 : Real64 HighSpeedTotCoolingCap;
14365 : Real64 LowSpeedTotCoolingCap;
14366 : Real64 TotCoolingCap;
14367 : Real64 NetCoolingCap;
14368 : Real64 PLF;
14369 : Real64 RunTimeFraction;
14370 : Real64 LowerBoundMassFlowRate;
14371 : int PartLoadTestPoint;
14372 : int countStaticInputs;
14373 : int index;
14374 :
14375 : // Formats
14376 : static constexpr std::string_view Header(
14377 : "! <VAV DX Cooling Coil Standard Rating Information>, DX Coil Type, DX Coil Name, Fan Type, Fan Name, Standard Net Cooling Capacity "
14378 : "{{W}}, Standard Net Cooling Capacity {{Btu/h}}, IEER {{Btu/W-h}}, COP 100% Capacity {{W/W}}, COP 75% Capacity {{W/W}}, COP 50% Capacity "
14379 : "{{W/W}}, COP 25% Capacity {{W/W}}, EER 100% Capacity {{Btu/W-h}}, EER 75% Capacity {{Btu/W-h}}, EER 50% Capacity {{Btu/W-h}}, EER 25% "
14380 : "Capacity {{Btu/W-h}}, Supply Air Flow 100% {{kg/s}}, Supply Air Flow 75% {{kg/s}},Supply Air Flow 50% {{kg/s}},Supply Air Flow 25% "
14381 : "{{kg/s}}\n");
14382 :
14383 : static constexpr std::string_view Format_891{
14384 : " VAV DX Cooling Coil Standard Rating Information, "
14385 : "{},{},{},{},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.4R},{:.4R},{:.4R},{:.4R},\n"};
14386 :
14387 66 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
14388 :
14389 : // Get fan index and name if not already available
14390 66 : if (thisDXCoil.SupplyFanIndex == 0)
14391 66 : GetFanIndexForTwoSpeedCoil(state, DXCoilNum, thisDXCoil.SupplyFanIndex, thisDXCoil.SupplyFanName, thisDXCoil.supplyFanType);
14392 66 : if (thisDXCoil.SupplyFanIndex == 0) { // didn't find VAV fan, do not rate this coil
14393 14 : thisDXCoil.RateWithInternalStaticAndFanObject = false;
14394 28 : ShowWarningError(state,
14395 28 : format("CalcTwoSpeedDXCoilStandardRating: Did not find an appropriate fan associated with DX coil named = \"{}\". Standard "
14396 : "Ratings will not be calculated.",
14397 14 : thisDXCoil.Name));
14398 14 : return;
14399 : }
14400 52 : bool saveTurnFansOn = state.dataHVACGlobal->TurnFansOn;
14401 52 : bool saveTurnFansOff = state.dataHVACGlobal->TurnFansOff;
14402 52 : state.dataHVACGlobal->TurnFansOn = true; // enable fans, will override fan availability schedule if needed
14403 52 : state.dataHVACGlobal->TurnFansOff = false;
14404 :
14405 : // Calculate the Indoor fan electric power consumption. The electric power consumption is estimated
14406 : // using either user supplied or AHRI default value for fan power per air volume flow rate
14407 52 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14408 :
14409 29 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatioRated);
14410 29 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
14411 145 : for (Iter = 1; Iter <= 4; ++Iter) { // iterative solution in the event that net capacity is near a threshold for external static
14412 : // Obtain external static pressure from Table 5 in ANSI/AHRI Std. 340/360-2007
14413 116 : if (NetCoolingCapRated <= 21000.0) {
14414 14 : ExternalStatic = 50.0;
14415 102 : } else if (21000.0 < NetCoolingCapRated && NetCoolingCapRated <= 30800.0) {
14416 0 : ExternalStatic = 60.0;
14417 102 : } else if (30800.0 < NetCoolingCapRated && NetCoolingCapRated <= 39300.0) {
14418 0 : ExternalStatic = 70.0;
14419 102 : } else if (39300.0 < NetCoolingCapRated && NetCoolingCapRated <= 61500.0) {
14420 11 : ExternalStatic = 90.0;
14421 91 : } else if (61500.0 < NetCoolingCapRated && NetCoolingCapRated <= 82100.0) {
14422 3 : ExternalStatic = 100.0;
14423 88 : } else if (82100.0 < NetCoolingCapRated && NetCoolingCapRated <= 103000.0) {
14424 0 : ExternalStatic = 110.0;
14425 88 : } else if (103000.0 < NetCoolingCapRated && NetCoolingCapRated <= 117000.0) {
14426 0 : ExternalStatic = 140.0;
14427 88 : } else if (117000.0 < NetCoolingCapRated && NetCoolingCapRated <= 147000.0) {
14428 16 : ExternalStatic = 160.0;
14429 72 : } else if (147000.0 < NetCoolingCapRated) {
14430 72 : ExternalStatic = 190.0;
14431 : }
14432 116 : FanStaticPressureRise = ExternalStatic + thisDXCoil.InternalStaticPressureDrop;
14433 116 : FanInletNode = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->inletNodeNum;
14434 116 : FanOutletNode = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->outletNodeNum;
14435 :
14436 : // set node state variables in preparation for fan model.
14437 116 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
14438 116 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
14439 116 : state.dataLoopNodes->Node(FanInletNode).Temp = CoolingCoilInletAirDryBulbTempRated;
14440 116 : state.dataLoopNodes->Node(FanInletNode).HumRat = PsyWFnTdbTwbPb(
14441 116 : state, CoolingCoilInletAirDryBulbTempRated, CoolingCoilInletAirWetBulbTempRated, state.dataEnvrn->OutBaroPress, RoutineName);
14442 116 : state.dataLoopNodes->Node(FanInletNode).Enthalpy =
14443 116 : PsyHFnTdbW(CoolingCoilInletAirDryBulbTempRated, state.dataLoopNodes->Node(FanInletNode).HumRat);
14444 116 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
14445 116 : FanPowerCorrection = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->totalPower;
14446 :
14447 116 : FanHeatCorrection = state.dataLoopNodes->Node(FanInletNode).MassFlowRate *
14448 116 : (state.dataLoopNodes->Node(FanOutletNode).Enthalpy - state.dataLoopNodes->Node(FanInletNode).Enthalpy);
14449 :
14450 116 : NetCoolingCapRated = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14451 : }
14452 :
14453 : } else {
14454 23 : FanPowerPerEvapAirFlowRate = DefaultFanPowerPerEvapAirFlowRate;
14455 23 : FanPowerPerEvapAirFlowRateSEER2 = DefaultFanPowerPerEvapAirFlowRateSEER2;
14456 23 : FanPowerCorrection = DefaultFanPowerPerEvapAirFlowRate * thisDXCoil.RatedAirVolFlowRate(1);
14457 23 : FanHeatCorrection = DefaultFanPowerPerEvapAirFlowRate * thisDXCoil.RatedAirVolFlowRate(1);
14458 23 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatioRated);
14459 23 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
14460 23 : NetCoolingCapRated = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14461 : }
14462 :
14463 52 : SupAirMdot_TestPoint(1) = thisDXCoil.RatedAirMassFlowRate(1);
14464 :
14465 : // Calculate Energy Efficiency Ratio (EER) at (19.44C WB and 35.0C DB ), ANSI/AHRI Std. 340/360
14466 52 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
14467 52 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatioRated);
14468 52 : if (thisDXCoil.RatedCOP(1) > 0.0) {
14469 : // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
14470 52 : EIR = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP(1);
14471 : } else {
14472 0 : EIR = 0.0;
14473 : }
14474 52 : TotalElecPowerRated = EIR * (thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac) + FanPowerCorrection;
14475 :
14476 52 : if (TotalElecPowerRated > 0.0) {
14477 52 : EER = NetCoolingCapRated / TotalElecPowerRated;
14478 : } else {
14479 0 : EER = 0.0;
14480 : }
14481 :
14482 : // IEER - A point 100 % net capacity
14483 52 : EER_TestPoint_SI(1) = EER;
14484 52 : EER_TestPoint_IP(1) = EER * ConvFromSIToIP;
14485 :
14486 : // find coil leaving drybulb at point A, with full rated air flow rate.
14487 : // init coil
14488 52 : thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
14489 52 : thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(1);
14490 52 : thisDXCoil.InletAirTemp = 26.7;
14491 52 : thisDXCoil.InletAirHumRat = PsyWFnTdbTwbPb(state, 26.7, 19.4, state.dataEnvrn->OutBaroPress, RoutineName);
14492 52 : thisDXCoil.InletAirEnthalpy = PsyHFnTdbW(26.7, thisDXCoil.InletAirHumRat);
14493 :
14494 52 : Real64 const heldOutDryBulb = state.dataEnvrn->OutDryBulbTemp;
14495 52 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
14496 8 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = OutdoorUnitInletAirDryBulbTempRated;
14497 : } else {
14498 44 : state.dataEnvrn->OutDryBulbTemp = OutdoorUnitInletAirDryBulbTempRated;
14499 : }
14500 52 : SpeedRatio = 1.0;
14501 52 : CycRatio = 1.0;
14502 52 : CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio, true);
14503 52 : TempDryBulb_Leaving_Apoint = state.dataDXCoils->DXCoilOutletTemp(DXCoilNum); // store result
14504 :
14505 : // IEER - part load test points ***************************************************
14506 208 : for (PartLoadTestPoint = 1; PartLoadTestPoint <= 3; ++PartLoadTestPoint) {
14507 : // determine minimum unloading capacity fraction at point B conditions.
14508 156 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
14509 24 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
14510 : } else {
14511 132 : state.dataEnvrn->OutDryBulbTemp = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
14512 : }
14513 :
14514 156 : TargetNetCapacity = NetCapacityFactorPLTestPoint(PartLoadTestPoint) * NetCoolingCapRated;
14515 :
14516 : // set up parameters for the solver here
14517 156 : Real64 const par3 = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
14518 156 : Real64 par7 = FanPowerPerEvapAirFlowRate;
14519 156 : int fanInNode = 0;
14520 156 : int fanOutNode = 0;
14521 156 : Real64 externalStatic = 0.0;
14522 156 : int fanIndex = 0;
14523 156 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14524 87 : par7 = 0.0;
14525 87 : fanInNode = FanInletNode;
14526 87 : fanOutNode = FanOutletNode;
14527 87 : externalStatic = ExternalStatic;
14528 87 : fanIndex = thisDXCoil.SupplyFanIndex;
14529 : }
14530 :
14531 156 : LowerBoundMassFlowRate = 0.01 * thisDXCoil.RatedAirMassFlowRate(1);
14532 :
14533 : // OK, so there are two variables here which are const at compile time. The question is whether compile time data needs to be
14534 : // explicitly captured in the lambda capture block.
14535 : // For GCC it currently doesn't mind whether they are captured or not, no warnings.
14536 : // On Clang, if you list them, there is a compiler warning.
14537 : // On our version of MSVC, if you take them out, the compiler will fail. On newer versions, I think it's OK. Should be soon anyway.
14538 : // To avoid this, you could pragma away the Clang warning in this section, or tell Clang to hush via compiler flags. However, to keep things
14539 : // really simple, I'm just going to use two local variables and capture them instead of the original data.
14540 : // I'm not sure if there are any more of these instances in the codebase. If so I am going to tag all of them with CONST_LAMBDA_CAPTURE.
14541 156 : Real64 dbRated = CoolingCoilInletAirDryBulbTempRated;
14542 156 : Real64 wbRated = CoolingCoilInletAirWetBulbTempRated;
14543 : auto f = // (AUTO_OK_LAMBDA)
14544 55472 : [&state, DXCoilNum, TempDryBulb_Leaving_Apoint, TargetNetCapacity, par3, par7, fanInNode, fanOutNode, externalStatic, dbRated, wbRated](
14545 1204644 : Real64 SupplyAirMassFlowRate) {
14546 : static constexpr std::string_view RoutineName("CalcTwoSpeedDXCoilIEERResidual");
14547 55316 : auto &coil = state.dataDXCoils->DXCoil(DXCoilNum);
14548 55316 : Real64 AirMassFlowRatio = 0.0;
14549 55316 : if (coil.RatedAirMassFlowRate(1) > 0.0) {
14550 55316 : AirMassFlowRatio = SupplyAirMassFlowRate / coil.RatedAirMassFlowRate(1);
14551 : }
14552 55316 : Real64 SupplyAirHumRat = PsyWFnTdbTwbPb(state, dbRated, wbRated, state.dataEnvrn->OutBaroPress, RoutineName);
14553 55316 : Real64 SupplyAirRho = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, dbRated, SupplyAirHumRat, RoutineName);
14554 55316 : Real64 SupplyAirVolFlowRate = SupplyAirMassFlowRate / SupplyAirRho;
14555 :
14556 : Real64 FanHeatCorrection;
14557 55316 : if (coil.RateWithInternalStaticAndFanObject) {
14558 : // modify external static per AHRI 340/360, Table 6, note 1.
14559 33034 : Real64 FanStaticPressureRise = coil.InternalStaticPressureDrop + (externalStatic * pow_2(AirMassFlowRatio));
14560 33034 : auto &inletNode = state.dataLoopNodes->Node(fanInNode);
14561 33034 : auto &outletNode = state.dataLoopNodes->Node(fanOutNode);
14562 33034 : inletNode.MassFlowRate = SupplyAirMassFlowRate;
14563 33034 : outletNode.MassFlowRate = SupplyAirMassFlowRate;
14564 33034 : inletNode.Temp = dbRated;
14565 33034 : inletNode.HumRat = PsyWFnTdbTwbPb(state, dbRated, wbRated, state.dataEnvrn->OutBaroPress, RoutineName);
14566 33034 : inletNode.Enthalpy = PsyHFnTdbW(dbRated, inletNode.HumRat);
14567 33034 : state.dataFans->fans(coil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
14568 33034 : FanHeatCorrection = SupplyAirMassFlowRate * (outletNode.Enthalpy - inletNode.Enthalpy);
14569 : } else {
14570 22282 : FanHeatCorrection = par7 * SupplyAirVolFlowRate;
14571 : }
14572 :
14573 55316 : Real64 TotCapFlowModFac = Curve::CurveValue(state, coil.CCapFFlow(1), AirMassFlowRatio);
14574 55316 : Real64 TotCapTempModFac = Curve::CurveValue(state, coil.CCapFTemp(1), wbRated, par3);
14575 55316 : Real64 HighSpeedNetCoolingCap = coil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14576 :
14577 : // TotCapFlowModFac = CurveManager::CurveValue(state, coil.CCapFFlow(1), AirMassFlowRatio);
14578 55316 : TotCapTempModFac = Curve::CurveValue(state, coil.CCapFTemp2, wbRated, par3);
14579 55316 : Real64 LowSpeedNetCoolingCap = coil.RatedTotCap2 * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14580 :
14581 : Real64 SpeedRatio;
14582 : Real64 CycRatio;
14583 55316 : if (LowSpeedNetCoolingCap <= TargetNetCapacity) {
14584 42199 : CycRatio = 1.0;
14585 42199 : SpeedRatio = (TargetNetCapacity - LowSpeedNetCoolingCap) / (HighSpeedNetCoolingCap - LowSpeedNetCoolingCap);
14586 : } else { // minimum unloading limit exceeded for no cycling
14587 13117 : SpeedRatio = 0.0;
14588 13117 : CycRatio = TargetNetCapacity / LowSpeedNetCoolingCap;
14589 : }
14590 :
14591 55316 : coil.InletAirMassFlowRate = SupplyAirMassFlowRate;
14592 55316 : CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio, true);
14593 55316 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(DXCoilNum);
14594 55316 : return TempDryBulb_Leaving_Apoint - OutletAirTemp;
14595 156 : };
14596 156 : General::SolveRoot(state,
14597 : AccuracyTolerance,
14598 : MaximumIterations,
14599 : SolverFlag,
14600 : PartLoadAirMassFlowRate,
14601 : f,
14602 : LowerBoundMassFlowRate,
14603 156 : thisDXCoil.RatedAirMassFlowRate(1));
14604 :
14605 156 : if (SolverFlag == -1) {
14606 :
14607 0 : ShowWarningError(state, "CalcTwoSpeedDXCoilStandardRating: air flow rate solver failed. Iteration limit exceeded ");
14608 :
14609 0 : SupAirMdot_TestPoint(1 + PartLoadTestPoint) = -999.0;
14610 0 : EER_TestPoint_SI(1 + PartLoadTestPoint) = -999.0;
14611 0 : EER_TestPoint_IP(1 + PartLoadTestPoint) = -999.0;
14612 0 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = -999.0;
14613 0 : NetPower_TestPoint(1 + PartLoadTestPoint) = -999.0;
14614 :
14615 156 : } else if (SolverFlag == -2) {
14616 0 : ShowWarningError(state, "CalcTwoSpeedDXCoilStandardRating: air flow rate solver failed. root not bounded ");
14617 :
14618 0 : SupAirMdot_TestPoint(1 + PartLoadTestPoint) = -999.0;
14619 0 : EER_TestPoint_SI(1 + PartLoadTestPoint) = -999.0;
14620 0 : EER_TestPoint_IP(1 + PartLoadTestPoint) = -999.0;
14621 0 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = -999.0;
14622 0 : NetPower_TestPoint(1 + PartLoadTestPoint) = -999.0;
14623 : } else {
14624 : // now we have the supply air flow rate
14625 156 : SupAirMdot_TestPoint(1 + PartLoadTestPoint) = PartLoadAirMassFlowRate;
14626 156 : AirMassFlowRatio = PartLoadAirMassFlowRate / thisDXCoil.RatedAirMassFlowRate(1);
14627 156 : SupplyAirHumRat = PsyWFnTdbTwbPb(
14628 156 : state, CoolingCoilInletAirDryBulbTempRated, CoolingCoilInletAirWetBulbTempRated, state.dataEnvrn->OutBaroPress, RoutineName);
14629 156 : SupplyAirRho = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, CoolingCoilInletAirDryBulbTempRated, SupplyAirHumRat, RoutineName);
14630 156 : SupplyAirVolFlowRate = PartLoadAirMassFlowRate / SupplyAirRho;
14631 :
14632 156 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14633 87 : FanStaticPressureRise = thisDXCoil.InternalStaticPressureDrop + (ExternalStatic * pow_2(AirMassFlowRatio));
14634 87 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = PartLoadAirMassFlowRate;
14635 87 : state.dataLoopNodes->Node(FanInletNode).Temp = CoolingCoilInletAirDryBulbTempRated;
14636 87 : state.dataLoopNodes->Node(FanInletNode).HumRat = SupplyAirHumRat;
14637 87 : state.dataLoopNodes->Node(FanInletNode).Enthalpy = PsyHFnTdbW(CoolingCoilInletAirDryBulbTempRated, SupplyAirHumRat);
14638 :
14639 87 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
14640 87 : FanPowerCorrection = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->totalPower;
14641 :
14642 87 : FanHeatCorrection =
14643 87 : PartLoadAirMassFlowRate * (state.dataLoopNodes->Node(FanOutletNode).Enthalpy - state.dataLoopNodes->Node(FanInletNode).Enthalpy);
14644 :
14645 : } else {
14646 69 : FanPowerCorrection = FanPowerPerEvapAirFlowRate * PartLoadAirMassFlowRate;
14647 69 : FanHeatCorrection = FanPowerPerEvapAirFlowRate * PartLoadAirMassFlowRate;
14648 : }
14649 :
14650 156 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatio);
14651 : // Warn user if curve output goes negative
14652 156 : if (TotCapFlowModFac < 0.0) {
14653 0 : if (thisDXCoil.CCapFFlowErrorIndex == 0) {
14654 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
14655 0 : ShowContinueError(
14656 : state,
14657 0 : format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).", TotCapFlowModFac));
14658 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
14659 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
14660 : }
14661 0 : ShowRecurringWarningErrorAtEnd(
14662 : state,
14663 0 : format("{}{}\"{}\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
14664 : RoutineName,
14665 0 : thisDXCoil.DXCoilType,
14666 0 : thisDXCoil.Name),
14667 0 : thisDXCoil.CCapFFlowErrorIndex,
14668 : TotCapFlowModFac,
14669 : TotCapFlowModFac);
14670 0 : TotCapFlowModFac = 0.0;
14671 : }
14672 :
14673 468 : TotCapTempModFac = CurveValue(
14674 156 : state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14675 : // Warn user if curve output goes negative
14676 156 : if (TotCapTempModFac < 0.0) {
14677 0 : if (thisDXCoil.CCapFTempErrorIndex == 0) {
14678 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
14679 0 : ShowContinueError(
14680 : state,
14681 0 : format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
14682 0 : ShowContinueError(state,
14683 0 : format(" Negative value occurs using a coil inlet wet-bulb temperature of {:.1T} and an outdoor unit inlet air "
14684 : "dry-bulb temperature of {:.1T}.",
14685 : CoolingCoilInletAirWetBulbTempRated,
14686 : OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint)));
14687 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
14688 : }
14689 0 : ShowRecurringWarningErrorAtEnd(
14690 : state,
14691 0 : format("{}{} \"{}\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
14692 : RoutineName,
14693 0 : thisDXCoil.DXCoilType,
14694 0 : thisDXCoil.Name),
14695 0 : thisDXCoil.CCapFTempErrorIndex,
14696 : TotCapTempModFac,
14697 : TotCapTempModFac);
14698 0 : TotCapTempModFac = 0.0;
14699 : }
14700 :
14701 156 : HighSpeedTotCoolingCap = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac;
14702 156 : HighSpeedNetCoolingCap = HighSpeedTotCoolingCap - FanHeatCorrection;
14703 :
14704 468 : EIRTempModFac = CurveValue(
14705 156 : state, thisDXCoil.EIRFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14706 156 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatio);
14707 156 : if (thisDXCoil.RatedCOP(1) > 0.0) {
14708 : // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
14709 156 : EIR_HighSpeed = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP(1);
14710 : } else {
14711 0 : EIR = 0.0;
14712 : }
14713 :
14714 : // TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatio);
14715 312 : TotCapTempModFac = CurveValue(
14716 156 : state, thisDXCoil.CCapFTemp2, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14717 : // Warn user if curve output goes negative
14718 156 : if (TotCapTempModFac < 0.0) {
14719 0 : if (thisDXCoil.CCapFTempErrorIndex == 0) {
14720 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
14721 0 : ShowContinueError(
14722 : state,
14723 0 : format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
14724 0 : ShowContinueError(state,
14725 0 : format(" Negative value occurs using a coil inlet wet-bulb temperature of {:.1T} and an outdoor unit inlet air "
14726 : "dry-bulb temperature of {:.1T}.",
14727 : CoolingCoilInletAirWetBulbTempRated,
14728 : OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint)));
14729 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
14730 : }
14731 0 : ShowRecurringWarningErrorAtEnd(
14732 : state,
14733 0 : format("{}{} \"{}\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
14734 : RoutineName,
14735 0 : thisDXCoil.DXCoilType,
14736 0 : thisDXCoil.Name),
14737 0 : thisDXCoil.CCapFTempErrorIndex,
14738 : TotCapTempModFac,
14739 : TotCapTempModFac);
14740 0 : TotCapTempModFac = 0.0;
14741 : }
14742 :
14743 156 : LowSpeedTotCoolingCap = thisDXCoil.RatedTotCap2 * TotCapTempModFac * TotCapFlowModFac;
14744 156 : LowSpeedNetCoolingCap = LowSpeedTotCoolingCap - FanHeatCorrection;
14745 :
14746 312 : EIRTempModFac = CurveValue(
14747 156 : state, thisDXCoil.EIRFTemp2, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14748 156 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatio);
14749 156 : if (thisDXCoil.RatedCOP2 > 0.0) {
14750 : // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
14751 156 : EIR_LowSpeed = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP2;
14752 : } else {
14753 0 : EIR_LowSpeed = 0.0;
14754 : }
14755 :
14756 156 : if (LowSpeedNetCoolingCap <= TargetNetCapacity) {
14757 104 : CycRatio = 1.0;
14758 104 : SpeedRatio = (TargetNetCapacity - LowSpeedNetCoolingCap) / (HighSpeedNetCoolingCap - LowSpeedNetCoolingCap);
14759 104 : TotCoolingCap = HighSpeedTotCoolingCap * SpeedRatio + LowSpeedTotCoolingCap * (1.0 - SpeedRatio);
14760 104 : NetCoolingCap = TotCoolingCap - FanHeatCorrection;
14761 104 : EIR = EIR_HighSpeed * SpeedRatio + EIR_LowSpeed * (1.0 - SpeedRatio);
14762 104 : TotalElecPowerRated = TotCoolingCap * EIR + FanPowerCorrection;
14763 104 : EER_TestPoint_SI(1 + PartLoadTestPoint) = NetCoolingCap / TotalElecPowerRated;
14764 104 : EER_TestPoint_IP(1 + PartLoadTestPoint) = EER_TestPoint_SI(1 + PartLoadTestPoint) * ConvFromSIToIP;
14765 104 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = NetCoolingCap;
14766 104 : NetPower_TestPoint(1 + PartLoadTestPoint) = TotalElecPowerRated;
14767 : } else { // minimum unloading limit exceeded without cycling, so cycle
14768 52 : SpeedRatio = 0.0;
14769 52 : CycRatio = TargetNetCapacity / LowSpeedNetCoolingCap;
14770 52 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(1), CycRatio);
14771 52 : if (PLF < 0.7) {
14772 0 : PLF = 0.7;
14773 : }
14774 52 : RunTimeFraction = CycRatio / PLF;
14775 52 : RunTimeFraction = min(RunTimeFraction, 1.0);
14776 52 : TotCoolingCap = LowSpeedTotCoolingCap * RunTimeFraction;
14777 52 : NetCoolingCap = TotCoolingCap - FanHeatCorrection;
14778 52 : TotalElecPowerRated = LowSpeedTotCoolingCap * EIR_LowSpeed * RunTimeFraction + FanPowerCorrection;
14779 52 : EER_TestPoint_SI(1 + PartLoadTestPoint) = NetCoolingCap / TotalElecPowerRated;
14780 52 : EER_TestPoint_IP(1 + PartLoadTestPoint) = EER_TestPoint_SI(1 + PartLoadTestPoint) * ConvFromSIToIP;
14781 52 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = NetCoolingCap;
14782 52 : NetPower_TestPoint(1 + PartLoadTestPoint) = TotalElecPowerRated;
14783 : }
14784 : }
14785 : } // loop over 3 part load test points
14786 52 : state.dataHVACGlobal->TurnFansOn = saveTurnFansOn;
14787 52 : state.dataHVACGlobal->TurnFansOff = saveTurnFansOff;
14788 :
14789 52 : IEER = (0.02 * EER_TestPoint_IP(1)) + (0.617 * EER_TestPoint_IP(2)) + (0.238 * EER_TestPoint_IP(3)) + (0.125 * EER_TestPoint_IP(4));
14790 : // CalcMultiSpeedDXCoilCooling() //??
14791 : // begin output
14792 52 : if (state.dataDXCoils->CalcTwoSpeedDXCoilStandardRatingOneTimeEIOHeaderWrite) {
14793 23 : print(state.files.eio, Header);
14794 23 : state.dataDXCoils->CalcTwoSpeedDXCoilStandardRatingOneTimeEIOHeaderWrite = false;
14795 46 : state.dataOutRptPredefined->pdstVAVDXCoolCoil =
14796 23 : newPreDefSubTable(state, state.dataOutRptPredefined->pdrEquip, "VAV DX Cooling Standard Rating Details");
14797 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilType =
14798 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "DX Cooling Coil Type");
14799 23 : state.dataOutRptPredefined->pdchVAVDXFanName = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Assocated Fan");
14800 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilNetCapSI =
14801 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Net Cooling Capacity [W]");
14802 23 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP [W/W]");
14803 23 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEERIP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER [Btu/W-h]");
14804 23 : state.dataOutRptPredefined->pdchVAVDXCoolCoilIEERIP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "IEER [Btu/W-h]");
14805 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotA =
14806 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 100% [kg/s]");
14807 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_B =
14808 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 75% Capacity [W/W]");
14809 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_B_IP =
14810 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 75% Capacity [Btu/W-h]");
14811 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotB =
14812 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 75% [kg/s]");
14813 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_C =
14814 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 50% Capacity [W/W]");
14815 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_C_IP =
14816 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 50% Capacity [Btu/W-h]");
14817 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotC =
14818 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 50% [kg/s]");
14819 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_D =
14820 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 25% Capacity [W/W]");
14821 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_D_IP =
14822 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 25% Capacity [Btu/W-h]");
14823 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotD =
14824 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 25% [kg/s]");
14825 :
14826 : // determine footnote content
14827 23 : countStaticInputs = 0;
14828 92 : for (index = 1; index <= state.dataDXCoils->NumDXCoils; ++index) {
14829 :
14830 98 : if (state.dataDXCoils->DXCoil(index).RateWithInternalStaticAndFanObject &&
14831 29 : state.dataDXCoils->DXCoil(index).DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
14832 29 : ++countStaticInputs;
14833 : }
14834 : }
14835 :
14836 23 : if (countStaticInputs == state.dataDXCoils->NumDXMulSpeedCoils) {
14837 22 : addFootNoteSubTable(state,
14838 11 : state.dataOutRptPredefined->pdstVAVDXCoolCoil,
14839 : "Packaged VAV unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2");
14840 12 : } else if (countStaticInputs == 0) {
14841 24 : addFootNoteSubTable(state,
14842 12 : state.dataOutRptPredefined->pdstVAVDXCoolCoil,
14843 : "Indoor-coil-only unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2, with "
14844 : "supply fan specific power at 365 {{W/1000cfm}} (773.3 {{W/(m3/s)}})");
14845 : } else { // both
14846 0 : addFootNoteSubTable(state,
14847 0 : state.dataOutRptPredefined->pdstVAVDXCoolCoil,
14848 : "Packaged VAV unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2, "
14849 : "indoor-coil-only units with supply fan specific power at 365 {{W/1000cfm}} (773.3 {{W/(m3/s)}})");
14850 : }
14851 : }
14852 :
14853 52 : const auto &fan_type_name = [&]() -> std::pair<const char *, std::string> {
14854 52 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14855 58 : return {"Fan:VariableVolume", thisDXCoil.SupplyFanName};
14856 : } else {
14857 46 : return {"N/A", "N/A"};
14858 : }
14859 52 : }();
14860 :
14861 52 : print(state.files.eio,
14862 : Format_891,
14863 : "Coil:Cooling:DX:TwoSpeed",
14864 52 : thisDXCoil.Name,
14865 52 : fan_type_name.first,
14866 52 : fan_type_name.second,
14867 : NetCoolingCapRated,
14868 52 : (NetCoolingCapRated * ConvFromSIToIP),
14869 : IEER,
14870 : EER_TestPoint_SI(1),
14871 : EER_TestPoint_SI(2),
14872 : EER_TestPoint_SI(3),
14873 : EER_TestPoint_SI(4),
14874 : EER_TestPoint_IP(1),
14875 : EER_TestPoint_IP(2),
14876 : EER_TestPoint_IP(3),
14877 : EER_TestPoint_IP(4),
14878 : SupAirMdot_TestPoint(1),
14879 : SupAirMdot_TestPoint(2),
14880 : SupAirMdot_TestPoint(3),
14881 : SupAirMdot_TestPoint(4));
14882 :
14883 52 : if (state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag) {
14884 : static constexpr std::string_view Format_994(
14885 : "! <DX Cooling Coil Standard Rating Information>, Component Type, Component Name, Standard Rating (Net) "
14886 : "Cooling Capacity {W}, Standard Rating Net COP {W/W}, EER {Btu/W-h}, SEER User {Btu/W-h}, SEER Standard {Btu/W-h}, "
14887 : "IEER "
14888 : "{Btu/W-h}");
14889 22 : print(state.files.eio, "{}\n", Format_994);
14890 22 : state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag = false;
14891 : }
14892 : static constexpr std::string_view Format_995(" DX Cooling Coil Standard Rating Information, {}, {}, {:.1R}, {}, {}, {}, {}, {}\n");
14893 52 : print(state.files.eio,
14894 : Format_995,
14895 : "Coil:Cooling:DX:TwoSpeed",
14896 52 : thisDXCoil.Name,
14897 : NetCoolingCapRated,
14898 : EER_TestPoint_SI(1),
14899 : EER_TestPoint_IP(1),
14900 : "N/A",
14901 : "N/A",
14902 : IEER);
14903 :
14904 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilType, thisDXCoil.Name, "Coil:Cooling:DX:TwoSpeed");
14905 : // W to tons
14906 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilNetCapSI, thisDXCoil.Name, NetCoolingCapRated, 1);
14907 :
14908 : // TODO: Commercial and industrial unitary air-conditioning condensing units with a capacity greater than 135,000 Btu/h (39564.59445 Watts)
14909 : // as defined in ANSI/AHRI Standard 365(I-P). | Scope 2.2.6 (ANSI/AHRI 340-360 2022)
14910 : //
14911 : // These will convert with a factor of 1 which is ok
14912 : // SEER | Capacity less than 65K Btu/h (19050 W) - calculated as per AHRI Standard 210/240-2023.
14913 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilCOP, thisDXCoil.Name, EER_TestPoint_SI(1), 2);
14914 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilEERIP, thisDXCoil.Name, EER_TestPoint_IP(1), 2);
14915 : // These will convert with a factor of 1 which is ok
14916 : // IEER | Capacity of 65K Btu/h (19050 W) to less than 135K Btu/h (39565 W) - calculated as per AHRI Standard 340/360-2022.
14917 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilIEERIP, thisDXCoil.Name, IEER, 1);
14918 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERUserIP, thisDXCoil.Name, "N/A");
14919 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERStandardIP, thisDXCoil.Name, "N/A");
14920 :
14921 104 : addFootNoteSubTable(
14922 : state,
14923 52 : state.dataOutRptPredefined->pdstDXCoolCoil,
14924 : "ANSI/AHRI ratings account for supply air fan heat and electric power. <br/>"
14925 : "1 - EnergyPlus object type. <br/>"
14926 : "2 - Capacity less than 65K Btu/h (19050 W) - calculated as per AHRI Standard 210/240-2017. <br/>"
14927 : "  Capacity of 65K Btu/h (19050 W) to less than 135K Btu/h (39565 W) - calculated as per AHRI Standard 340/360-2007. <br/>"
14928 : "  Capacity from 135K (39565 W) to 250K Btu/hr (73268 W) - calculated as per AHRI Standard 365-2009 - Ratings not yet supported in "
14929 : "EnergyPlus. <br/>"
14930 : "3 - SEER (User) is calculated using user-input PLF curve and cooling coefficient of degradation. <br/>"
14931 : "  SEER (Standard) is calculated using the default PLF curve and cooling coefficient of degradation"
14932 : "from the appropriate AHRI standard.");
14933 :
14934 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilType, thisDXCoil.Name, "Coil:Cooling:DX:TwoSpeed");
14935 52 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14936 29 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXFanName, thisDXCoil.Name, thisDXCoil.SupplyFanName);
14937 : } else {
14938 23 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXFanName, thisDXCoil.Name, "None");
14939 : }
14940 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilNetCapSI, thisDXCoil.Name, NetCoolingCapRated, 2);
14941 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP, thisDXCoil.Name, EER_TestPoint_SI(1), 2);
14942 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilIEERIP, thisDXCoil.Name, IEER, 2);
14943 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEERIP, thisDXCoil.Name, EER_TestPoint_IP(1), 2);
14944 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotA, thisDXCoil.Name, SupAirMdot_TestPoint(1), 4);
14945 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_B, thisDXCoil.Name, EER_TestPoint_SI(2), 2);
14946 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_B_IP, thisDXCoil.Name, EER_TestPoint_IP(2), 2);
14947 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotB, thisDXCoil.Name, SupAirMdot_TestPoint(2), 4);
14948 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_C, thisDXCoil.Name, EER_TestPoint_SI(3), 2);
14949 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_C_IP, thisDXCoil.Name, EER_TestPoint_IP(3), 2);
14950 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotC, thisDXCoil.Name, SupAirMdot_TestPoint(3), 4);
14951 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_D, thisDXCoil.Name, EER_TestPoint_SI(4), 2);
14952 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_D_IP, thisDXCoil.Name, EER_TestPoint_IP(4), 2);
14953 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotD, thisDXCoil.Name, SupAirMdot_TestPoint(4), 4);
14954 :
14955 52 : state.dataEnvrn->OutDryBulbTemp = heldOutDryBulb; // reset the outdoor dry bulb when done with it
14956 122 : }
14957 :
14958 66 : void GetFanIndexForTwoSpeedCoil(
14959 : EnergyPlusData &state, int const CoolingCoilIndex, int &SupplyFanIndex, std::string &SupplyFanName, HVAC::FanType &supplyFanType)
14960 : {
14961 :
14962 : // SUBROUTINE INFORMATION:
14963 : // AUTHOR <author>
14964 : // DATE WRITTEN <date_written>
14965 :
14966 : // PURPOSE OF THIS SUBROUTINE:
14967 : // This routine looks up the given TwoSpeed DX coil and returns the companion supply fan index
14968 :
14969 : // Using/Aliasing
14970 66 : int NumPrimaryAirSys = state.dataHVACGlobal->NumPrimaryAirSys;
14971 :
14972 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14973 : int FoundBranch;
14974 : int FoundAirSysNum;
14975 : int AirSysNum;
14976 : int BranchNum;
14977 : int CompNum;
14978 :
14979 66 : FoundBranch = 0;
14980 66 : FoundAirSysNum = 0;
14981 66 : SupplyFanIndex = 0;
14982 66 : SupplyFanName = "n/a";
14983 322 : for (AirSysNum = 1; AirSysNum <= NumPrimaryAirSys; ++AirSysNum) {
14984 :
14985 512 : for (BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).NumBranches; ++BranchNum) {
14986 :
14987 1066 : for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).TotalComponents; ++CompNum) {
14988 :
14989 876 : if (state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num ==
14990 : SimAirServingZones::CompType::DXSystem) {
14991 :
14992 224 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name,
14993 224 : state.dataDXCoils->DXCoil(CoolingCoilIndex).CoilSystemName)) {
14994 66 : FoundBranch = BranchNum;
14995 66 : FoundAirSysNum = AirSysNum;
14996 66 : break;
14997 : }
14998 : // these are specified in SimAirServingZones and need to be moved to a Data* file. UnitarySystem=19
14999 652 : } else if (state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num ==
15000 : SimAirServingZones::CompType::UnitarySystemModel) {
15001 :
15002 12 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name,
15003 12 : state.dataDXCoils->DXCoil(CoolingCoilIndex).CoilSystemName)) {
15004 0 : FoundBranch = BranchNum;
15005 0 : FoundAirSysNum = AirSysNum;
15006 0 : break;
15007 : }
15008 : }
15009 : }
15010 :
15011 256 : if (FoundBranch > 0 && FoundAirSysNum > 0) {
15012 657 : for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).TotalComponents;
15013 : ++CompNum) {
15014 604 : if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
15015 : SimAirServingZones::CompType::Fan_Simple_VAV) {
15016 99 : SupplyFanName = state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).Name;
15017 99 : SupplyFanIndex = Fans::GetFanIndex(state, SupplyFanName);
15018 99 : supplyFanType = HVAC::FanType::VAV;
15019 99 : break;
15020 : // these are specified in SimAirServingZones and need to be moved to a Data* file. UnitarySystem=19
15021 505 : } else if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
15022 : SimAirServingZones::CompType::Fan_System_Object) {
15023 12 : SupplyFanName = state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).Name;
15024 12 : SupplyFanIndex = Fans::GetFanIndex(state, SupplyFanName);
15025 12 : supplyFanType = HVAC::FanType::SystemModel;
15026 :
15027 493 : } else if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
15028 : SimAirServingZones::CompType::UnitarySystemModel) {
15029 : // fan may not be specified in a unitary system object, keep looking
15030 : // Unitary System will "set" the fan index to the DX coil if contained within the HVAC system
15031 0 : if (state.dataDXCoils->DXCoil(CoolingCoilIndex).SupplyFanIndex > 0) break;
15032 : }
15033 : }
15034 : }
15035 : }
15036 : }
15037 66 : }
15038 :
15039 981 : void GetDXCoilIndex(EnergyPlusData &state,
15040 : std::string const &DXCoilName,
15041 : int &DXCoilIndex,
15042 : bool &ErrorsFound,
15043 : std::string_view const ThisObjectType,
15044 : bool const SuppressWarning)
15045 : {
15046 :
15047 : // SUBROUTINE INFORMATION:
15048 : // AUTHOR Richard Raustad
15049 : // DATE WRITTEN March 2005
15050 :
15051 : // PURPOSE OF THIS SUBROUTINE:
15052 : // This subroutine sets an index for a given DX Coil -- issues error message if that
15053 : // DX Coil is not a legal DX Coil.
15054 :
15055 981 : if (state.dataDXCoils->GetCoilsInputFlag) {
15056 139 : GetDXCoils(state);
15057 139 : state.dataDXCoils->GetCoilsInputFlag = false;
15058 : }
15059 :
15060 981 : DXCoilIndex = Util::FindItemInList(DXCoilName, state.dataDXCoils->DXCoil);
15061 981 : if (DXCoilIndex == 0) {
15062 7 : if (!SuppressWarning) {
15063 : // No warning printed if only searching for the existence of a DX Coil
15064 0 : if (!ThisObjectType.empty()) {
15065 0 : ShowSevereError(state, fmt::format("{}, GetDXCoilIndex: DX Coil not found={}", ThisObjectType, DXCoilName));
15066 : } else {
15067 0 : ShowSevereError(state, format("GetDXCoilIndex: DX Coil not found={}", DXCoilName));
15068 : }
15069 : }
15070 7 : ErrorsFound = true;
15071 : }
15072 981 : }
15073 :
15074 : std::string
15075 15 : GetDXCoilName(EnergyPlusData &state, int &DXCoilIndex, bool &ErrorsFound, std::string_view const ThisObjectType, bool const SuppressWarning)
15076 : {
15077 :
15078 : // SUBROUTINE INFORMATION:
15079 : // AUTHOR Richard Raustad
15080 : // DATE WRITTEN May 2017
15081 :
15082 : // PURPOSE OF THIS SUBROUTINE:
15083 : // This subroutine gets a name for a given DX Coil -- issues error message if that
15084 : // DX Coil is not a legal DX Coil.
15085 :
15086 15 : if (state.dataDXCoils->GetCoilsInputFlag) {
15087 0 : GetDXCoils(state);
15088 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15089 : }
15090 :
15091 15 : if (DXCoilIndex == 0) {
15092 0 : if (!SuppressWarning) {
15093 : // No warning printed if only searching for the existence of a DX Coil
15094 0 : if (!ThisObjectType.empty()) {
15095 0 : ShowSevereError(state, fmt::format("{}, GetDXCoilIndex: DX Coil not found ", ThisObjectType));
15096 : } else {
15097 0 : ShowSevereError(state, "GetDXCoilIndex: DX Coil not found ");
15098 : }
15099 : }
15100 0 : ErrorsFound = true;
15101 0 : return " "; // This does not seem great
15102 :
15103 : } else {
15104 15 : return state.dataDXCoils->DXCoil(DXCoilIndex).Name;
15105 : }
15106 : }
15107 :
15108 242 : Real64 GetCoilCapacity(EnergyPlusData &state,
15109 : std::string const &CoilType, // must match coil types in this module
15110 : std::string const &CoilName, // must match coil names for the coil type
15111 : bool &ErrorsFound // set to true if problem
15112 : )
15113 : {
15114 :
15115 : // FUNCTION INFORMATION:
15116 : // AUTHOR Linda Lawrie
15117 : // DATE WRITTEN February 2006
15118 :
15119 : // PURPOSE OF THIS FUNCTION:
15120 : // This function looks up the coil capacity for the given coil and returns it. If
15121 : // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
15122 : // as negative.
15123 :
15124 : // Return value
15125 : Real64 CoilCapacity; // returned capacity of matched coil
15126 :
15127 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15128 : int WhichCoil;
15129 :
15130 : // Obtains and Allocates DXCoils
15131 242 : if (state.dataDXCoils->GetCoilsInputFlag) {
15132 0 : GetDXCoils(state);
15133 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15134 : }
15135 :
15136 242 : if (Util::SameString(CoilType, "Coil:Heating:DX:SingleSpeed") || Util::SameString(CoilType, "Coil:Cooling:DX:SingleSpeed")) {
15137 242 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15138 242 : if (WhichCoil != 0) {
15139 242 : CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(1);
15140 : }
15141 0 : } else if (Util::SameString(CoilType, "Coil:Cooling:DX:TwoStageWithHumidityControlMode")) {
15142 0 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15143 0 : if (WhichCoil != 0) {
15144 0 : CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(state.dataDXCoils->DXCoil(WhichCoil).NumCapacityStages);
15145 : }
15146 0 : } else if (Util::SameString(CoilType, "Coil:Cooling:DX:TwoSpeed")) {
15147 0 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15148 0 : if (WhichCoil != 0) {
15149 0 : CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(1);
15150 : }
15151 0 : } else if (Util::SameString(CoilType, "Coil:Cooling:DX:MultiSpeed") || Util::SameString(CoilType, "Coil:Heating:DX:MultiSpeed")) {
15152 0 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15153 0 : if (WhichCoil != 0) {
15154 0 : CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).MSRatedTotCap(state.dataDXCoils->DXCoil(WhichCoil).NumOfSpeeds);
15155 : }
15156 : } else {
15157 0 : WhichCoil = 0;
15158 : }
15159 :
15160 242 : if (WhichCoil == 0) {
15161 0 : ShowSevereError(state, format("GetCoilCapacity: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15162 0 : ShowContinueError(state, "... returning capacity as -1000.");
15163 0 : ErrorsFound = true;
15164 0 : CoilCapacity = -1000.0;
15165 : }
15166 :
15167 242 : return CoilCapacity;
15168 : }
15169 :
15170 432 : Real64 GetCoilCapacityByIndexType(EnergyPlusData &state,
15171 : int const CoilIndex, // must match coil index for the coil type
15172 : int const CoilType_Num, // must match coil types in this module
15173 : bool &ErrorsFound // set to true if problem
15174 : )
15175 : {
15176 :
15177 : // FUNCTION INFORMATION:
15178 : // AUTHOR Richard Raustad
15179 : // DATE WRITTEN October 2010
15180 :
15181 : // PURPOSE OF THIS FUNCTION:
15182 : // This function looks up the coil capacity for the given coil and returns it. If
15183 : // incorrect coil index or type is given, ErrorsFound is returned as true and capacity is returned
15184 : // as negative.
15185 :
15186 : // Return value
15187 : Real64 CoilCapacity; // returned capacity of matched coil
15188 :
15189 : // Obtains and Allocates DXCoils
15190 432 : if (state.dataDXCoils->GetCoilsInputFlag) {
15191 0 : GetDXCoils(state);
15192 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15193 : }
15194 :
15195 432 : if (CoilIndex == 0) {
15196 0 : ShowSevereError(state, "GetCoilCapacityByIndexType: Invalid index passed = 0");
15197 0 : ShowContinueError(state, "... returning capacity as -1000.");
15198 0 : ErrorsFound = true;
15199 0 : CoilCapacity = -1000.0;
15200 0 : return CoilCapacity;
15201 : }
15202 :
15203 432 : if (CoilType_Num != state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
15204 0 : ShowSevereError(state, "GetCoilCapacityByIndexType: Index passed does not match DX Coil type passed.");
15205 0 : ShowContinueError(state, "... returning capacity as -1000.");
15206 0 : ErrorsFound = true;
15207 0 : CoilCapacity = -1000.0;
15208 : } else {
15209 432 : switch (state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
15210 33 : case HVAC::CoilDX_MultiSpeedCooling:
15211 : case HVAC::CoilDX_MultiSpeedHeating: {
15212 33 : CoilCapacity = state.dataDXCoils->DXCoil(CoilIndex).MSRatedTotCap(state.dataDXCoils->DXCoil(CoilIndex).NumOfSpeeds);
15213 33 : } break;
15214 399 : default: {
15215 399 : CoilCapacity = state.dataDXCoils->DXCoil(CoilIndex).RatedTotCap(state.dataDXCoils->DXCoil(CoilIndex).NumCapacityStages);
15216 399 : } break;
15217 : }
15218 : }
15219 :
15220 432 : return CoilCapacity;
15221 : }
15222 :
15223 406 : int GetCoilTypeNum(EnergyPlusData &state,
15224 : std::string const &CoilType, // must match coil types in this module
15225 : std::string const &CoilName, // must match coil names for the coil type
15226 : bool &ErrorsFound, // set to true if problem
15227 : ObjexxFCL::Optional_bool_const PrintWarning // prints warning when true
15228 : )
15229 : {
15230 :
15231 : // FUNCTION INFORMATION:
15232 : // AUTHOR R. Raustad - FSEC
15233 : // DATE WRITTEN August 2008
15234 :
15235 : // PURPOSE OF THIS FUNCTION:
15236 : // This function looks up the integerized coil type for the given coil and returns it. If
15237 : // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
15238 : // as negative.
15239 :
15240 : // Return value
15241 : int TypeNum; // returned integerized type of matched coil
15242 :
15243 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15244 : int WhichCoil;
15245 : bool PrintMessage;
15246 :
15247 : // Obtains and Allocates DXCoils
15248 406 : if (state.dataDXCoils->GetCoilsInputFlag) {
15249 101 : GetDXCoils(state);
15250 101 : state.dataDXCoils->GetCoilsInputFlag = false;
15251 : }
15252 :
15253 406 : if (present(PrintWarning)) {
15254 374 : PrintMessage = PrintWarning;
15255 : } else {
15256 32 : PrintMessage = true;
15257 : }
15258 :
15259 406 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15260 406 : if (WhichCoil != 0) {
15261 403 : TypeNum = state.dataDXCoils->DXCoil(WhichCoil).DXCoilType_Num;
15262 : } else {
15263 3 : if (PrintMessage) {
15264 0 : ShowSevereError(state, format("GetCoilTypeNum: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15265 : }
15266 3 : ErrorsFound = true;
15267 3 : TypeNum = 0;
15268 : }
15269 :
15270 406 : return TypeNum;
15271 : }
15272 :
15273 811 : Real64 GetMinOATCompressor(EnergyPlusData &state,
15274 : int const CoilIndex, // index to cooling coil
15275 : bool &ErrorsFound // set to true if problem
15276 : )
15277 : {
15278 :
15279 : // Obtains and Allocates DXCoils
15280 811 : if (state.dataDXCoils->GetCoilsInputFlag) {
15281 0 : GetDXCoils(state);
15282 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15283 : }
15284 :
15285 811 : if (CoilIndex == 0) {
15286 0 : ShowSevereError(state, "GetMinOATCompressor: Index passed = 0");
15287 0 : ShowContinueError(state, "... returning Min OAT for compressor operation as -1000.");
15288 0 : ErrorsFound = true;
15289 0 : return -1000.0;
15290 : } else {
15291 811 : return state.dataDXCoils->DXCoil(CoilIndex).MinOATCompressor;
15292 : }
15293 : }
15294 :
15295 387 : int GetCoilInletNode(EnergyPlusData &state,
15296 : std::string const &CoilType, // must match coil types in this module
15297 : std::string const &CoilName, // must match coil names for the coil type
15298 : bool &ErrorsFound // set to true if problem
15299 : )
15300 : {
15301 :
15302 : // FUNCTION INFORMATION:
15303 : // AUTHOR Linda Lawrie
15304 : // DATE WRITTEN February 2006
15305 :
15306 : // PURPOSE OF THIS FUNCTION:
15307 : // This function looks up the given coil and returns the inlet node number. If
15308 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
15309 : // as zero.
15310 :
15311 : // Return value
15312 : int NodeNumber; // returned node number of matched coil
15313 :
15314 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15315 : int WhichCoil;
15316 :
15317 : // Obtains and Allocates DXCoils
15318 387 : if (state.dataDXCoils->GetCoilsInputFlag) {
15319 1 : GetDXCoils(state);
15320 1 : state.dataDXCoils->GetCoilsInputFlag = false;
15321 : }
15322 :
15323 387 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15324 387 : if (WhichCoil != 0) {
15325 387 : NodeNumber = state.dataDXCoils->DXCoil(WhichCoil).AirInNode;
15326 : } else {
15327 0 : ShowSevereError(state, format("GetCoilInletNode: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15328 0 : ErrorsFound = true;
15329 0 : NodeNumber = 0;
15330 : }
15331 :
15332 387 : return NodeNumber;
15333 : }
15334 :
15335 0 : int getCoilInNodeIndex(EnergyPlusData &state,
15336 : int const CoilIndex, // coil index
15337 : bool &ErrorsFound // set to true if problem
15338 : )
15339 : {
15340 :
15341 : int NodeNumber; // returned node number of matched coil
15342 :
15343 : // Obtains and Allocates DXCoils
15344 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
15345 0 : GetDXCoils(state);
15346 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15347 : }
15348 :
15349 0 : if (CoilIndex != 0) {
15350 0 : NodeNumber = state.dataDXCoils->DXCoil(CoilIndex).AirInNode;
15351 : } else {
15352 0 : ShowSevereError(state, "GetCoilInletNode: Could not find Coil Type");
15353 0 : ErrorsFound = true;
15354 0 : NodeNumber = 0;
15355 : }
15356 :
15357 0 : return NodeNumber;
15358 : }
15359 :
15360 408 : int GetCoilOutletNode(EnergyPlusData &state,
15361 : std::string const &CoilType, // must match coil types in this module
15362 : std::string const &CoilName, // must match coil names for the coil type
15363 : bool &ErrorsFound // set to true if problem
15364 : )
15365 : {
15366 :
15367 : // FUNCTION INFORMATION:
15368 : // AUTHOR Linda Lawrie
15369 : // DATE WRITTEN February 2006
15370 :
15371 : // PURPOSE OF THIS FUNCTION:
15372 : // This function looks up the given coil and returns the inlet node number. If
15373 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
15374 : // as zero.
15375 :
15376 : // Return value
15377 : int NodeNumber; // returned node number of matched coil
15378 :
15379 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15380 : int WhichCoil;
15381 :
15382 : // Obtains and Allocates DXCoils
15383 408 : if (state.dataDXCoils->GetCoilsInputFlag) {
15384 6 : GetDXCoils(state);
15385 6 : state.dataDXCoils->GetCoilsInputFlag = false;
15386 : }
15387 :
15388 408 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15389 408 : if (WhichCoil != 0) {
15390 408 : NodeNumber = state.dataDXCoils->DXCoil(WhichCoil).AirOutNode;
15391 : } else {
15392 0 : ShowSevereError(
15393 : state,
15394 0 : format("GetCoilOutletNode: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil outlet node number.", CoilType, CoilName));
15395 0 : ErrorsFound = true;
15396 0 : NodeNumber = 0;
15397 : }
15398 :
15399 408 : return NodeNumber;
15400 : }
15401 :
15402 0 : int getCoilOutNodeIndex(EnergyPlusData &state,
15403 : int const CoilIndex, // must match coil types in this module
15404 : bool &ErrorsFound // set to true if problem
15405 : )
15406 : {
15407 :
15408 : int NodeNumber; // returned node number of matched coil
15409 :
15410 : // Obtains and Allocates DXCoils
15411 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
15412 0 : GetDXCoils(state);
15413 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15414 : }
15415 :
15416 0 : if (CoilIndex != 0) {
15417 0 : NodeNumber = state.dataDXCoils->DXCoil(CoilIndex).AirOutNode;
15418 : } else {
15419 0 : ShowSevereError(state, "GetCoilOutletNode: Could not find Coil Type");
15420 0 : ErrorsFound = true;
15421 0 : NodeNumber = 0;
15422 : }
15423 :
15424 0 : return NodeNumber;
15425 : }
15426 :
15427 593 : int GetCoilCondenserInletNode(EnergyPlusData &state,
15428 : std::string const &CoilType, // must match coil types in this module
15429 : std::string const &CoilName, // must match coil names for the coil type
15430 : bool &ErrorsFound // set to true if problem
15431 : )
15432 : {
15433 :
15434 : // FUNCTION INFORMATION:
15435 : // AUTHOR R. Raustad
15436 : // DATE WRITTEN January 2007
15437 :
15438 : // PURPOSE OF THIS FUNCTION:
15439 : // This function looks up the given coil and returns the condenser inlet node. If
15440 : // incorrect coil type or name is given, ErrorsFound is returned as true.
15441 :
15442 : // Return value
15443 : int CondNode; // returned condenser node number of matched coil
15444 :
15445 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15446 : int WhichCoil;
15447 :
15448 : // Obtains and Allocates DXCoils
15449 593 : if (state.dataDXCoils->GetCoilsInputFlag) {
15450 0 : GetDXCoils(state);
15451 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15452 : }
15453 :
15454 593 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15455 593 : if (WhichCoil != 0) {
15456 593 : CondNode = state.dataDXCoils->DXCoil(WhichCoil).CondenserInletNodeNum(1);
15457 : } else {
15458 0 : ShowSevereError(state, format("GetCoilCondenserInletNode: Invalid DX Coil, Type= \"{}\" Name=\"{}\"", CoilType, CoilName));
15459 0 : ErrorsFound = true;
15460 0 : CondNode = 0;
15461 : }
15462 :
15463 593 : return CondNode;
15464 : }
15465 :
15466 1 : Real64 GetDXCoilBypassedFlowFrac(EnergyPlusData &state,
15467 : std::string const &CoilType, // must match coil types in this module
15468 : std::string const &CoilName, // must match coil names for the coil type
15469 : bool &ErrorsFound // set to true if problem
15470 : )
15471 : {
15472 :
15473 : // FUNCTION INFORMATION:
15474 : // AUTHOR R. Raustad
15475 : // DATE WRITTEN June 2007
15476 :
15477 : // PURPOSE OF THIS FUNCTION:
15478 : // This function looks up the given coil and returns the bypassed air flow fraction.
15479 : // Bypassed air flow fraction can only be greater than 0 for multimode DX cooling coils and is typical for 1st stage
15480 : // If incorrect coil type or name is given, ErrorsFound is returned as true.
15481 :
15482 : // Return value
15483 : Real64 BypassFraction; // returned bypass air fraction of matched coil
15484 :
15485 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15486 : int WhichCoil;
15487 :
15488 : // Obtains and Allocates DXCoils
15489 1 : if (state.dataDXCoils->GetCoilsInputFlag) {
15490 0 : GetDXCoils(state);
15491 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15492 : }
15493 :
15494 1 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15495 1 : if (WhichCoil != 0) {
15496 1 : BypassFraction = state.dataDXCoils->DXCoil(WhichCoil).BypassedFlowFrac(1);
15497 : } else {
15498 0 : ShowSevereError(state, format("GetDXCoilBypassedFlowFrac: Invalid DX Coil Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15499 0 : ErrorsFound = true;
15500 0 : BypassFraction = 0.0;
15501 : }
15502 :
15503 1 : return BypassFraction;
15504 : }
15505 :
15506 3923968 : int GetHPCoolingCoilIndex(EnergyPlusData &state,
15507 : std::string const &HeatingCoilType, // Type of DX heating coil used in HP
15508 : std::string const &HeatingCoilName, // Name of DX heating coil used in HP
15509 : int const HeatingCoilIndex // Index of DX heating coil used in HP
15510 : )
15511 : {
15512 :
15513 : // FUNCTION INFORMATION:
15514 : // AUTHOR R. Raustad
15515 : // DATE WRITTEN February 2007
15516 :
15517 : // PURPOSE OF THIS FUNCTION:
15518 : // This function looks up the given DX heating coil and returns the companion DX cooling coil.
15519 :
15520 : // Return value
15521 : int DXCoolingCoilIndex; // Index of HP DX cooling coil returned from this function
15522 :
15523 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15524 : int WhichComp; // DO loop counter to find correct comp set
15525 : int WhichCompanionComp; // DO loop counter to find companion coil comp set
15526 : int WhichHXAssistedComp; // DO loop counter when DX coil is used in a HX assisted cooling coil
15527 :
15528 3923968 : DXCoolingCoilIndex = 0;
15529 :
15530 : DataLoopNode::ConnectionObjectType HeatingCoilTypeNum = static_cast<DataLoopNode::ConnectionObjectType>(
15531 3923968 : getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC, Util::makeUPPER(HeatingCoilType)));
15532 :
15533 : DataLoopNode::ConnectionObjectType CompSetsParentType; // Parent object type which uses DX heating coil pass into this function
15534 3923968 : std::string CompSetsParentName;
15535 133255165 : for (WhichComp = 1; WhichComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichComp) {
15536 :
15537 139677864 : if (HeatingCoilTypeNum != state.dataBranchNodeConnections->CompSets(WhichComp).ComponentObjectType ||
15538 6422699 : !Util::SameString(HeatingCoilName, state.dataBranchNodeConnections->CompSets(WhichComp).CName))
15539 129331197 : continue;
15540 3923968 : CompSetsParentType = state.dataBranchNodeConnections->CompSets(WhichComp).ParentObjectType;
15541 3923968 : CompSetsParentName = state.dataBranchNodeConnections->CompSets(WhichComp).ParentCName;
15542 3923968 : if ((CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAir) ||
15543 3923911 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::ZoneHVACPackagedTerminalHeatPump) ||
15544 3923902 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed) ||
15545 3923902 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass) ||
15546 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitarySystem)) {
15547 : // Search for DX cooling coils
15548 145253174 : for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
15549 157006622 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, CompSetsParentName) ||
15550 15677356 : (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
15551 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed))
15552 141329206 : continue;
15553 : DXCoolingCoilIndex =
15554 60 : Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
15555 60 : break;
15556 : }
15557 145253803 : for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
15558 157007345 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, CompSetsParentName) ||
15559 15677496 : (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
15560 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed))
15561 141329835 : continue;
15562 : DXCoolingCoilIndex =
15563 14 : Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
15564 14 : break;
15565 : }
15566 : // Search for Heat Exchanger Assisted DX cooling coils
15567 3923968 : if (DXCoolingCoilIndex == 0) {
15568 145252366 : for (WhichHXAssistedComp = 1; WhichHXAssistedComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichHXAssistedComp) {
15569 157005679 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ParentCName, CompSetsParentName) ||
15570 15677207 : (state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ComponentObjectType !=
15571 : DataLoopNode::ConnectionObjectType::CoilSystemCoolingDXHeatExchangerAssisted))
15572 141328472 : continue;
15573 : DataLoopNode::ConnectionObjectType HXCompSetsParentType; // Used when DX cooling coil is a child of a HX assisted cooling coil
15574 0 : HXCompSetsParentType = state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ComponentObjectType;
15575 0 : std::string const &HXCompSetsParentName = state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).CName;
15576 0 : for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
15577 0 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, HXCompSetsParentName) ||
15578 0 : (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
15579 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed))
15580 0 : continue;
15581 : DXCoolingCoilIndex =
15582 0 : Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
15583 0 : break;
15584 : }
15585 0 : break;
15586 : }
15587 : }
15588 3923968 : } else {
15589 : // ErrorFound, Coil:Heating:DX:SingleSpeed is used in wrong type of parent object (should never get here)
15590 0 : ShowSevereError(state,
15591 0 : format("Configuration error in {}\"{}\"",
15592 0 : BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(CompSetsParentType)],
15593 : CompSetsParentName));
15594 0 : ShowContinueError(state, "DX heating coil not allowed in this configuration.");
15595 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
15596 : }
15597 3923968 : break;
15598 : }
15599 :
15600 : // Check and warn user is crankcase heater power or max OAT for crankcase heater differs in DX cooling and heating coils
15601 3923968 : if (DXCoolingCoilIndex > 0) {
15602 74 : if (state.dataDXCoils->DXCoil(DXCoolingCoilIndex).CrankcaseHeaterCapacity != 0.0) {
15603 14 : if (state.dataDXCoils->DXCoil(DXCoolingCoilIndex).CrankcaseHeaterCapacity !=
15604 28 : state.dataDXCoils->DXCoil(HeatingCoilIndex).CrankcaseHeaterCapacity ||
15605 14 : state.dataDXCoils->DXCoil(DXCoolingCoilIndex).MaxOATCrankcaseHeater !=
15606 14 : state.dataDXCoils->DXCoil(HeatingCoilIndex).MaxOATCrankcaseHeater) {
15607 0 : ShowWarningError(state, "Crankcase heater capacity or max outdoor temp for crankcase heater operation specified in");
15608 0 : ShowContinueError(state, format("Coil:Cooling:DX:SingleSpeed = {}", state.dataDXCoils->DXCoil(DXCoolingCoilIndex).Name));
15609 0 : ShowContinueError(state, format("is different than that specified in Coil:Heating:DX:SingleSpeed = {}.", HeatingCoilName));
15610 0 : ShowContinueError(state,
15611 0 : format("Both of these DX coils are part of {}={}.",
15612 0 : BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(CompSetsParentType)],
15613 : CompSetsParentName));
15614 0 : ShowContinueError(state, "The value specified in the DX heating coil will be used and the simulation continues...");
15615 : }
15616 : }
15617 : }
15618 :
15619 3923968 : return DXCoolingCoilIndex;
15620 3923968 : }
15621 :
15622 20 : int GetDXCoilNumberOfSpeeds(EnergyPlusData &state,
15623 : std::string const &CoilType, // must match coil types in this module
15624 : std::string const &CoilName, // must match coil names for the coil type
15625 : bool &ErrorsFound // set to true if problem
15626 : )
15627 : {
15628 :
15629 : // FUNCTION INFORMATION:
15630 : // AUTHOR L. Gu
15631 : // DATE WRITTEN July 2007
15632 :
15633 : // PURPOSE OF THIS FUNCTION:
15634 : // This function looks up the given coil and returns the number of speeds for multispeed coils.
15635 : // If incorrect coil type or name is given, ErrorsFound is returned as true.
15636 :
15637 : // Return value
15638 : int NumberOfSpeeds; // returned the number of speed of matched coil
15639 :
15640 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15641 : int WhichCoil;
15642 :
15643 : // Obtains and Allocates DXCoils
15644 20 : if (state.dataDXCoils->GetCoilsInputFlag) {
15645 0 : GetDXCoils(state);
15646 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15647 : }
15648 :
15649 20 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15650 20 : if (WhichCoil != 0) {
15651 20 : NumberOfSpeeds = state.dataDXCoils->DXCoil(WhichCoil).NumOfSpeeds;
15652 : } else {
15653 0 : ShowSevereError(state, format("GetDXCoilNumberOfSpeeds: Invalid DX Coil Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15654 0 : ErrorsFound = true;
15655 0 : NumberOfSpeeds = 0;
15656 : }
15657 :
15658 20 : return NumberOfSpeeds;
15659 : }
15660 :
15661 148005 : int GetDXCoilAvailSchPtr(EnergyPlusData &state,
15662 : std::string const &CoilType, // must match coil types in this module
15663 : std::string const &CoilName, // must match coil names for the coil type
15664 : bool &ErrorsFound, // set to true if problem
15665 : ObjexxFCL::Optional_int_const CoilIndex // Coil index number
15666 : )
15667 : {
15668 :
15669 : // FUNCTION INFORMATION:
15670 : // AUTHOR Richard Raustad
15671 : // DATE WRITTEN January 2013
15672 :
15673 : // PURPOSE OF THIS FUNCTION:
15674 : // This function looks up the given coil and returns the availability schedule index. If
15675 : // incorrect coil type or name is given, ErrorsFound is returned as true and schedule index is returned
15676 : // as -1.
15677 :
15678 : // Return value
15679 : int SchPtr; // returned availabiltiy schedule of matched coil
15680 :
15681 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15682 : int WhichCoil;
15683 :
15684 : // Obtains and Allocates DXCoils
15685 148005 : if (state.dataDXCoils->GetCoilsInputFlag) {
15686 0 : GetDXCoils(state);
15687 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15688 : }
15689 :
15690 148005 : if (present(CoilIndex)) {
15691 147880 : if (CoilIndex == 0) {
15692 0 : ShowSevereError(state, "GetDXCoilAvailSchPtr: Invalid index passed = 0");
15693 0 : ShowContinueError(state, "... returning DXCoilAvailSchPtr as -1.");
15694 0 : ErrorsFound = true;
15695 0 : SchPtr = -1;
15696 0 : return SchPtr;
15697 : } else {
15698 147880 : WhichCoil = CoilIndex;
15699 : }
15700 : } else {
15701 125 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15702 : }
15703 148005 : if (WhichCoil != 0) {
15704 148005 : SchPtr = state.dataDXCoils->DXCoil(WhichCoil).SchedPtr;
15705 : } else {
15706 0 : if (!present(CoilIndex)) {
15707 0 : ShowSevereError(state,
15708 0 : format("GetDXCoilAvailSch: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil availability schedule index.",
15709 : CoilType,
15710 : CoilName));
15711 : }
15712 0 : ErrorsFound = true;
15713 0 : SchPtr = -1;
15714 : }
15715 :
15716 148005 : return SchPtr;
15717 : }
15718 :
15719 1 : Real64 GetDXCoilAirFlow(EnergyPlusData &state,
15720 : std::string const &CoilType, // must match coil types in this module
15721 : std::string const &CoilName, // must match coil names for the coil type
15722 : bool &ErrorsFound // set to true if problem
15723 : )
15724 : {
15725 :
15726 : // FUNCTION INFORMATION:
15727 : // AUTHOR Richard Raustad
15728 : // DATE WRITTEN January 2013
15729 :
15730 : // PURPOSE OF THIS FUNCTION:
15731 : // This function looks up the given coil and returns the availability schedule index. If
15732 : // incorrect coil type or name is given, ErrorsFound is returned as true and schedule index is returned
15733 : // as -1.
15734 :
15735 : // Return value
15736 : Real64 AirFlow; // returned coil air flow rate
15737 :
15738 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15739 : int WhichCoil;
15740 :
15741 : // Obtains and Allocates DXCoils
15742 1 : if (state.dataDXCoils->GetCoilsInputFlag) {
15743 0 : GetDXCoils(state);
15744 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15745 : }
15746 :
15747 1 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15748 1 : if (WhichCoil != 0) {
15749 1 : switch (state.dataDXCoils->DXCoil(WhichCoil).DXCoilType_Num) {
15750 1 : case HVAC::CoilDX_CoolingSingleSpeed:
15751 : case HVAC::CoilDX_CoolingTwoSpeed:
15752 : case HVAC::CoilDX_HeatingEmpirical:
15753 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
15754 1 : AirFlow = state.dataDXCoils->DXCoil(WhichCoil).RatedAirVolFlowRate(1);
15755 1 : } break;
15756 0 : case HVAC::CoilDX_MultiSpeedCooling:
15757 : case HVAC::CoilDX_MultiSpeedHeating: {
15758 0 : AirFlow = state.dataDXCoils->DXCoil(WhichCoil).MSRatedAirVolFlowRate(1);
15759 0 : } break;
15760 0 : default: {
15761 0 : ShowSevereError(
15762 : state,
15763 0 : format("GetDXCoilAirFlow: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil air flow rate.", CoilType, CoilName));
15764 0 : ErrorsFound = true;
15765 0 : AirFlow = -1.0;
15766 0 : } break;
15767 : }
15768 : } else {
15769 0 : ShowSevereError(
15770 0 : state, format("GetDXCoilAirFlow: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil air flow rate.", CoilType, CoilName));
15771 0 : ErrorsFound = true;
15772 0 : AirFlow = -1.0;
15773 : }
15774 :
15775 1 : return AirFlow;
15776 : }
15777 :
15778 576 : int GetDXCoilCapFTCurveIndex(EnergyPlusData &state,
15779 : int const CoilIndex, // coil index pointer
15780 : bool &ErrorsFound // set to true if problem
15781 : )
15782 : {
15783 :
15784 : // FUNCTION INFORMATION:
15785 : // AUTHOR Richard Raustad
15786 : // DATE WRITTEN August 2013
15787 :
15788 : // PURPOSE OF THIS FUNCTION:
15789 : // This function looks up the given coil and returns the CapFT schedule index. If
15790 : // incorrect coil index is given, ErrorsFound is returned as true and schedule index is returned
15791 : // as -1.
15792 :
15793 : // Return value
15794 : int CapFTCurveIndex; // returned coil CapFT curve index
15795 :
15796 : // Obtains and Allocates DXCoils
15797 576 : if (state.dataDXCoils->GetCoilsInputFlag) {
15798 0 : GetDXCoils(state);
15799 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15800 : }
15801 :
15802 576 : if (CoilIndex != 0) {
15803 576 : switch (state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
15804 449 : case HVAC::CoilDX_CoolingSingleSpeed:
15805 : case HVAC::CoilDX_CoolingTwoSpeed:
15806 : case HVAC::CoilDX_HeatingEmpirical:
15807 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
15808 449 : CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).CCapFTemp(1);
15809 449 : } break;
15810 51 : case HVAC::CoilDX_MultiSpeedCooling:
15811 : case HVAC::CoilDX_MultiSpeedHeating: {
15812 51 : CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).MSCCapFTemp(state.dataDXCoils->DXCoil(CoilIndex).NumOfSpeeds);
15813 51 : } break;
15814 76 : case HVAC::CoilVRF_Heating: {
15815 76 : CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).CCapFTemp(1);
15816 76 : } break;
15817 0 : default: {
15818 : // CALL ShowSevereError(state, 'GetDXCoilCapFTCurveIndex: Could not find Coil, Type="'// &
15819 : // TRIM(cAllCoilTypes(DXCoil(CoilIndex)%DXCoilType_Num))//'" Name="'//TRIM(DXCoil(CoilIndex)%Name)// &
15820 : // '" when accessing coil capacity as a function of temperture curve.')
15821 0 : ErrorsFound = true;
15822 0 : CapFTCurveIndex = 0;
15823 0 : } break;
15824 : }
15825 : } else {
15826 : // CALL ShowSevereError(state, 'GetDXCoilCapFTCurveIndex: Could not find Coil, Index = 0'// &
15827 : // ' when accessing coil air flow rate.')
15828 0 : ErrorsFound = true;
15829 0 : CapFTCurveIndex = 0;
15830 : }
15831 :
15832 576 : return CapFTCurveIndex;
15833 : }
15834 :
15835 1228 : void SetDXCoolingCoilData(
15836 : EnergyPlusData &state,
15837 : int const DXCoilNum, // Number of DX Cooling Coil
15838 : bool &ErrorsFound, // Set to true if certain errors found
15839 : ObjexxFCL::Optional_int HeatingCoilPLFCurvePTR, // Parameter equivalent of heating coil PLR curve index
15840 : ObjexxFCL::Optional<DataHeatBalance::RefrigCondenserType> CondenserType, // Parameter equivalent of condenser type parameter
15841 : ObjexxFCL::Optional_int CondenserInletNodeNum, // Parameter equivalent of condenser inlet node number
15842 : ObjexxFCL::Optional<Real64> MaxOATCrankcaseHeater, // Parameter equivalent of condenser Max OAT for Crank Case Heater temp
15843 : ObjexxFCL::Optional<Real64> MinOATCooling, // Parameter equivalent of condenser Min OAT for compressor cooling operation
15844 : ObjexxFCL::Optional<Real64> MaxOATCooling, // Parameter equivalent of condenser Max OAT for compressor cooling operation
15845 : ObjexxFCL::Optional<Real64> MinOATHeating, // Parameter equivalent of condenser Min OAT for compressor heating operation
15846 : ObjexxFCL::Optional<Real64> MaxOATHeating, // Parameter equivalent of condenser Max OAT for compressor heating operation
15847 : ObjexxFCL::Optional<HVAC::OATType> HeatingPerformanceOATType, // Parameter equivalent to condenser entering air temp type (1-db, 2=wb)
15848 : ObjexxFCL::Optional<StandardRatings::DefrostStrat> DefrostStrategy,
15849 : ObjexxFCL::Optional<StandardRatings::HPdefrostControl> DefrostControl,
15850 : ObjexxFCL::Optional_int DefrostEIRPtr,
15851 : ObjexxFCL::Optional<Real64> DefrostFraction,
15852 : ObjexxFCL::Optional<Real64> DefrostCapacity,
15853 : ObjexxFCL::Optional<Real64> MaxOATDefrost,
15854 : ObjexxFCL::Optional_bool CoolingCoilPresent,
15855 : ObjexxFCL::Optional_bool HeatingCoilPresent,
15856 : ObjexxFCL::Optional<Real64> HeatSizeRatio,
15857 : ObjexxFCL::Optional<Real64> TotCap,
15858 : ObjexxFCL::Optional_int SupplyFanIndex,
15859 : ObjexxFCL::Optional_string SupplyFanName,
15860 : ObjexxFCL::Optional<HVAC::FanType> supplyFanType)
15861 : {
15862 :
15863 : // SUBROUTINE INFORMATION:
15864 : // AUTHOR Richard Raustad, FSEC
15865 : // DATE WRITTEN December 2008
15866 :
15867 : // PURPOSE OF THIS SUBROUTINE:
15868 : // This routine was designed to allow the DX coil to access information from a gas or
15869 : // electric heating coil when these coils are each used in a parent object.
15870 : // Also, this is an illustration of setting Data from an outside source.
15871 :
15872 : // Using/Aliasing
15873 :
15874 : // Obtains and Allocates DXCoils
15875 1228 : if (state.dataDXCoils->GetCoilsInputFlag) {
15876 0 : GetDXCoils(state);
15877 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15878 : }
15879 :
15880 1228 : if (DXCoilNum <= 0 || DXCoilNum > state.dataDXCoils->NumDXCoils) {
15881 0 : ShowSevereError(state,
15882 0 : format("SetDXCoolingCoilData: called with DX Cooling Coil Number out of range={} should be >0 and <{}",
15883 : DXCoilNum,
15884 0 : state.dataDXCoils->NumDXCoils));
15885 0 : ErrorsFound = true;
15886 0 : return;
15887 : }
15888 :
15889 1228 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
15890 1228 : if (present(HeatingCoilPLFCurvePTR)) {
15891 48 : thisDXCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurvePTR;
15892 : }
15893 :
15894 1228 : if (present(CondenserType)) {
15895 124 : thisDXCoil.CondenserType = CondenserType;
15896 : }
15897 :
15898 1228 : if (present(CondenserInletNodeNum)) {
15899 124 : thisDXCoil.CondenserInletNodeNum(1) = CondenserInletNodeNum;
15900 : }
15901 :
15902 1228 : if (present(MaxOATCrankcaseHeater)) {
15903 124 : thisDXCoil.MaxOATCrankcaseHeater = MaxOATCrankcaseHeater;
15904 : }
15905 :
15906 1228 : if (present(MaxOATCooling)) {
15907 62 : thisDXCoil.MaxOATCompressor = MaxOATCooling;
15908 : }
15909 :
15910 1228 : if (present(MaxOATHeating)) {
15911 16 : thisDXCoil.MaxOATCompressor = MaxOATHeating;
15912 : }
15913 :
15914 1228 : if (present(MinOATCooling)) {
15915 62 : thisDXCoil.MinOATCompressor = MinOATCooling;
15916 : }
15917 :
15918 1228 : if (present(MinOATHeating)) {
15919 62 : thisDXCoil.MinOATCompressor = MinOATHeating;
15920 : }
15921 :
15922 1228 : if (present(HeatingPerformanceOATType)) {
15923 62 : thisDXCoil.HeatingPerformanceOATType = HeatingPerformanceOATType;
15924 : }
15925 :
15926 1228 : if (present(DefrostStrategy)) {
15927 62 : thisDXCoil.DefrostStrategy = DefrostStrategy;
15928 : }
15929 :
15930 1228 : if (present(DefrostControl)) {
15931 62 : thisDXCoil.DefrostControl = DefrostControl;
15932 : }
15933 :
15934 1228 : if (present(DefrostEIRPtr)) {
15935 62 : thisDXCoil.DefrostEIRFT = DefrostEIRPtr;
15936 : }
15937 :
15938 1228 : if (present(DefrostFraction)) {
15939 62 : thisDXCoil.DefrostTime = DefrostFraction;
15940 : }
15941 :
15942 1228 : if (present(DefrostCapacity)) {
15943 62 : thisDXCoil.DefrostCapacity = DefrostCapacity;
15944 : }
15945 :
15946 1228 : if (present(MaxOATDefrost)) {
15947 62 : thisDXCoil.MaxOATDefrost = MaxOATDefrost;
15948 : }
15949 :
15950 1228 : if (present(CoolingCoilPresent)) {
15951 62 : thisDXCoil.CoolingCoilPresent = CoolingCoilPresent;
15952 : }
15953 :
15954 1228 : if (present(HeatingCoilPresent)) {
15955 62 : thisDXCoil.HeatingCoilPresent = HeatingCoilPresent;
15956 : }
15957 :
15958 1228 : if (present(HeatSizeRatio)) {
15959 0 : thisDXCoil.HeatSizeRatio = HeatSizeRatio;
15960 : }
15961 :
15962 1228 : if (present(TotCap)) {
15963 0 : thisDXCoil.RatedTotCap(1) = TotCap;
15964 : }
15965 :
15966 1228 : if (present(SupplyFanIndex)) {
15967 16 : thisDXCoil.SupplyFanIndex = SupplyFanIndex;
15968 : }
15969 :
15970 1228 : if (present(SupplyFanName)) {
15971 16 : thisDXCoil.SupplyFanName = SupplyFanName;
15972 : }
15973 :
15974 1228 : if (present(supplyFanType)) {
15975 16 : thisDXCoil.supplyFanType = supplyFanType;
15976 16 : if (thisDXCoil.SupplyFanIndex > 0) {
15977 16 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
15978 16 : thisDXCoil.Name,
15979 16 : thisDXCoil.DXCoilType,
15980 16 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->Name,
15981 16 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->type,
15982 : thisDXCoil.SupplyFanIndex);
15983 : }
15984 : }
15985 : }
15986 :
15987 2 : void SetCoilSystemHeatingDXFlag(EnergyPlusData &state,
15988 : std::string const &CoilType, // must match coil types in this module
15989 : std::string const &CoilName // must match coil names for the coil type
15990 : )
15991 : {
15992 :
15993 : // SUBROUTINE INFORMATION:
15994 : // AUTHOR B. Griffith
15995 : // DATE WRITTEN Jan. 2012
15996 :
15997 : // PURPOSE OF THIS SUBROUTINE:
15998 : // inform DX heating coil that is is part of a CoilSystem:Heating:DX
15999 : // and therefore it need not find its companion cooling coil
16000 :
16001 : // METHODOLOGY EMPLOYED:
16002 : // set value of logical flag FindCompanionUpStreamCoil to true
16003 :
16004 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16005 : int WhichCoil;
16006 :
16007 : // Obtains and Allocates DXCoils
16008 2 : if (state.dataDXCoils->GetCoilsInputFlag) {
16009 0 : GetDXCoils(state);
16010 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16011 : }
16012 :
16013 2 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
16014 2 : if (WhichCoil != 0) {
16015 2 : state.dataDXCoils->DXCoil(WhichCoil).FindCompanionUpStreamCoil = false;
16016 : } else {
16017 0 : ShowSevereError(state, format("SetCoilSystemHeatingDXFlag: Could not find Coil, Type=\"{}\"Name=\"{}\"", CoilType, CoilName));
16018 : }
16019 2 : }
16020 :
16021 67 : void SetCoilSystemCoolingData(EnergyPlusData &state,
16022 : std::string const &CoilName, // must match coil names for the coil type
16023 : std::string const &CoilSystemName)
16024 : {
16025 :
16026 : // SUBROUTINE INFORMATION:
16027 : // AUTHOR B. Griffith
16028 : // DATE WRITTEN July 2012
16029 :
16030 : // PURPOSE OF THIS SUBROUTINE:
16031 : // inform the child DX coil what the name of its parent is.
16032 :
16033 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16034 : int WhichCoil;
16035 :
16036 67 : if (state.dataDXCoils->GetCoilsInputFlag) {
16037 0 : GetDXCoils(state);
16038 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16039 : }
16040 :
16041 67 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
16042 67 : if (WhichCoil != 0) {
16043 67 : state.dataDXCoils->DXCoil(WhichCoil).CoilSystemName = CoilSystemName;
16044 : } else {
16045 0 : ShowSevereError(state, format("SetCoilSystemCoolingData: Could not find Coil \"Name=\"{}\"", CoilName));
16046 : }
16047 67 : }
16048 :
16049 39471 : Real64 CalcSHRUserDefinedCurves(EnergyPlusData &state,
16050 : Real64 const InletDryBulb, // inlet air dry bulb temperature [C]
16051 : Real64 const InletWetBulb, // inlet air wet bulb temperature [C]
16052 : Real64 const AirMassFlowRatio, // ratio of actual air mass flow to rated air mass flow
16053 : int const SHRFTempCurveIndex, // SHR modifier curve index
16054 : int const SHRFFlowCurveIndex, // SHR modifier curve index
16055 : Real64 const SHRRated // rated sensible heat ratio, user input
16056 : )
16057 : {
16058 :
16059 : // SUBROUTINE INFORMATION:
16060 : // AUTHOR Bereket Nigusse, FSEC
16061 : // DATE WRITTEN December 2012
16062 :
16063 : // PURPOSE OF THIS FUNCTION:
16064 : // Returns the oprating sensible heat ratio for a given Rated SHR abd coil entering
16065 : // air DBT and WBT, and supply air mass flow fraction.
16066 :
16067 : // METHODOLOGY EMPLOYED:
16068 : // Model uses user specified rated SHR, and SHR modifying curves for temperature and flow
16069 : // fraction. The curves adjust the rated SHR based on biquadratic curve for temperatures
16070 : // and quadratic function for supply air mass flow ratio (actual vs rated).
16071 : // The biquadratic and quadratic curves are normalized caurves generated from manufacturer's
16072 : // performance data
16073 :
16074 : // Using/Aliasing
16075 : using Curve::CurveValue;
16076 :
16077 : // Return value
16078 : Real64 SHRopr; // operating SHR, corrected for Temp and Flow Fraction
16079 :
16080 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16081 : Real64 SHRTempModFac; // Sensible Heat Ratio modifier (function of entering wetbulb, entering drybulb)
16082 : Real64 SHRFlowModFac; // Sensible Heat Ratio modifier (function of actual vs rated flow)
16083 :
16084 : // Get SHR modifying factor (function of inlet wetbulb & drybulb) for off-rated conditions
16085 39471 : if (SHRFTempCurveIndex == 0) {
16086 0 : SHRTempModFac = 1.0;
16087 : } else {
16088 39471 : SHRTempModFac = CurveValue(state, SHRFTempCurveIndex, InletWetBulb, InletDryBulb);
16089 39471 : if (SHRTempModFac < 0.0) {
16090 0 : SHRTempModFac = 0.0;
16091 : }
16092 : }
16093 : // Get SHR modifying factor (function of mass flow ratio) for off-rated conditions
16094 39471 : if (SHRFFlowCurveIndex == 0) {
16095 0 : SHRFlowModFac = 1.0;
16096 : } else {
16097 39471 : SHRFlowModFac = CurveValue(state, SHRFFlowCurveIndex, AirMassFlowRatio);
16098 39471 : if (SHRFlowModFac < 0.0) {
16099 0 : SHRFlowModFac = 0.0;
16100 : }
16101 : }
16102 : // Calculate "operating" sensible heat ratio
16103 39471 : SHRopr = SHRRated * SHRTempModFac * SHRFlowModFac;
16104 :
16105 39471 : if (SHRopr < 0.0) SHRopr = 0.0; // SHR cannot be less than zero
16106 39471 : if (SHRopr > 1.0) SHRopr = 1.0; // SHR cannot be greater than 1.0
16107 :
16108 39471 : return SHRopr;
16109 : }
16110 :
16111 5 : void SetDXCoilTypeData(EnergyPlusData &state, std::string const &CoilName) // must match coil names for the coil type
16112 : {
16113 :
16114 : // SUBROUTINE INFORMATION:
16115 : // AUTHOR B. Nigusse
16116 : // DATE WRITTEN January 2013
16117 :
16118 : // PURPOSE OF THIS SUBROUTINE:
16119 : // inform the child DX coil if the DX cooling coil is for 100% DOAS application.
16120 :
16121 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16122 : int WhichCoil;
16123 :
16124 5 : if (state.dataDXCoils->GetCoilsInputFlag) {
16125 0 : GetDXCoils(state);
16126 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16127 : }
16128 :
16129 5 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
16130 5 : if (WhichCoil != 0) {
16131 5 : state.dataDXCoils->DXCoil(WhichCoil).ISHundredPercentDOASDXCoil = true;
16132 : } else {
16133 : // DXCoil(WhichCoil)%ISHundredPercentDOASDXCoil = .FALSE. //Autodesk:BoundsViolation DXCoil(0): DXCoil is not allocated with a 0
16134 : // element: Commented out
16135 0 : ShowSevereError(state, format("SetDXCoilTypeData: Could not find Coil \"Name=\"{}\"", CoilName));
16136 : }
16137 5 : }
16138 :
16139 163851 : void CalcSecondaryDXCoils(EnergyPlusData &state, int const DXCoilNum)
16140 : {
16141 :
16142 : // SUBROUTINE INFORMATION:
16143 : // AUTHOR B. Nigusse
16144 : // DATE WRITTEN February 2015
16145 :
16146 : // PURPOSE OF THIS SUBROUTINE:
16147 : // Calculates secondary zone heat gain from secondary DX coils placed in a zone.
16148 :
16149 : // METHODOLOGY EMPLOYED:
16150 : // Energy balance:
16151 : // (1) Condenser placed in a zone, the zone total (sensible) heat
16152 : // gain rate is given Qcond = QEvap + WcompPluscondFanPower
16153 : // (2) Evaporator placed in a zone, the zone total heat removal
16154 : // rate is given Qevap = Qcond - WcompPluscondFanPower
16155 : // Furthermore, the evaporator total heat removal is split into
16156 : // latent and sensible components using user specified SHR
16157 :
16158 : // Using/Aliasing
16159 : using Curve::CurveValue;
16160 :
16161 : // SUBROUTINE PARAMETER DEFINITIONS:
16162 : static constexpr std::string_view RoutineName("CalcSecondaryDXCoils");
16163 :
16164 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16165 : Real64 CondInletDryBulb; // condenser entering air dry-bulb temperature (C)
16166 : Real64 EvapAirMassFlow; // Condenser air mass flow rate [kg/s]
16167 : Real64 EvapInletDryBulb; // evaporator inlet air drybulb [C]
16168 : Real64 EvapInletHumRat; // evaporator inlet air humidity ratio [kg/kg]
16169 : Real64 EvapInletWetBulb; // evaporator inlet air wetbulb [C]
16170 : Real64 EvapInletEnthalpy; // evaporator inlet air enthalpy [J/kg]
16171 : Real64 FullLoadOutAirEnth; // evaporator outlet full load enthalpy [J/kg]
16172 : Real64 FullLoadOutAirHumRat; // evaporator outlet humidity ratio at full load
16173 : Real64 FullLoadOutAirTemp; // evaporator outlet air temperature at full load [C]
16174 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
16175 163851 : Real64 SHR(0); // sensible heat ratio
16176 : Real64 RhoAir; // secondary coil entering air density [kg/m3]
16177 163851 : Real64 PartLoadRatio(0); // primary coil part-load ratio [-]
16178 : Real64 SecCoilRatedSHR; // secondary DX coil nominal or rated sensible heat ratio
16179 : Real64 SecCoilFlowFraction; // secondary coil flow fraction, is 1.0 for single speed machine
16180 : Real64 TotalHeatRemovalRate; // secondary coil total heat removal rate
16181 : Real64 TotalHeatRejectionRate; // secondary coil total heat rejection rate
16182 : int SecCoilSHRFT; // index of the SHR modifier curve for temperature of a secondary DX coil
16183 : int SecCoilSHRFF; // index of the sHR modifier curve for flow fraction of a secondary DX coil
16184 : int MSSpeedNumLS; // current low speed number of multspeed HP
16185 : int MSSpeedNumHS; // current high speed number of multspeed HP
16186 : Real64 MSSpeedRatio; // current speed ratio of multspeed HP
16187 : Real64 MSCycRatio; // current cycling ratio of multspeed HP
16188 : Real64 SHRHighSpeed; // sensible heat ratio at high speed
16189 : Real64 SHRLowSpeed; // sensible heat ratio at low speed
16190 :
16191 163851 : EvapAirMassFlow = 0.0;
16192 :
16193 163851 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
16194 :
16195 163851 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
16196 163851 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
16197 : // Select the correct unit type
16198 163851 : switch (thisDXCoil.DXCoilType_Num) {
16199 81926 : case HVAC::CoilDX_CoolingSingleSpeed:
16200 : case HVAC::CoilDX_CoolingTwoSpeed:
16201 : case HVAC::CoilDX_MultiSpeedCooling: {
16202 : // total sensible heat gain of the secondary zone from the secondary coil (condenser)
16203 81926 : if (thisDXCoil.ElecCoolingPower > 0.0) {
16204 18553 : TotalHeatRejectionRate = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
16205 : } else {
16206 63373 : TotalHeatRejectionRate = 0.0;
16207 63373 : return;
16208 : }
16209 18553 : thisDXCoil.SecCoilSensibleHeatGainRate = TotalHeatRejectionRate;
16210 18553 : } break;
16211 81925 : case HVAC::CoilDX_HeatingEmpirical: {
16212 : // evaporator coil in the secondary zone
16213 81925 : if (thisDXCoil.ElecHeatingPower > 0.0) {
16214 30261 : TotalHeatRemovalRate = max(0.0, thisDXCoil.TotalHeatingEnergyRate - thisDXCoil.ElecHeatingPower);
16215 : } else {
16216 51664 : TotalHeatRemovalRate = 0.0;
16217 51664 : thisDXCoil.SecCoilSHR = 0.0;
16218 51664 : return;
16219 : }
16220 30261 : thisDXCoil.SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower;
16221 30261 : EvapInletDryBulb = secZoneHB.ZT;
16222 30261 : EvapInletHumRat = secZoneHB.airHumRat;
16223 30261 : RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat);
16224 30261 : EvapAirMassFlow = RhoAir * thisDXCoil.SecCoilAirFlow;
16225 : ;
16226 30261 : PartLoadRatio = thisDXCoil.CompressorPartLoadRatio;
16227 30261 : SecCoilRatedSHR = thisDXCoil.SecCoilRatedSHR;
16228 30261 : if ((EvapAirMassFlow > HVAC::SmallMassFlow) && (PartLoadRatio > 0.0) &&
16229 30261 : (EvapInletDryBulb > thisDXCoil.MinOATCompressor)) { // coil is running
16230 30261 : SecCoilFlowFraction = 1.0; // for single speed DX coil the secondary coil (condenser) flow fraction is 1.0
16231 30261 : CondInletDryBulb = state.dataLoopNodes->Node(thisDXCoil.AirInNode).Temp;
16232 30261 : EvapInletWetBulb = PsyTwbFnTdbWPb(state, EvapInletDryBulb, EvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
16233 30261 : EvapInletEnthalpy = PsyHFnTdbW(EvapInletDryBulb, EvapInletHumRat);
16234 30261 : SecCoilSHRFT = thisDXCoil.SecCoilSHRFT;
16235 30261 : SecCoilSHRFF = thisDXCoil.SecCoilSHRFF;
16236 : // determine the current SHR
16237 30261 : SHR = CalcSecondaryDXCoilsSHR(state,
16238 : DXCoilNum,
16239 : EvapAirMassFlow,
16240 : TotalHeatRemovalRate,
16241 : PartLoadRatio,
16242 : SecCoilRatedSHR,
16243 : EvapInletDryBulb,
16244 : EvapInletHumRat,
16245 : EvapInletWetBulb,
16246 : EvapInletEnthalpy,
16247 : CondInletDryBulb,
16248 : SecCoilFlowFraction,
16249 : SecCoilSHRFT,
16250 : SecCoilSHRFF);
16251 : // Calculate full load output conditions
16252 30261 : FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16253 30261 : hTinwout = EvapInletEnthalpy - (1.0 - SHR) * ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
16254 30261 : FullLoadOutAirHumRat = PsyWFnTdbH(state, EvapInletDryBulb, hTinwout, RoutineName, true);
16255 30261 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
16256 : // when the air outlet temperature falls below the saturation temperature, it is reset to saturation temperature
16257 30261 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
16258 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName);
16259 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
16260 : // Adjust SHR for the new outlet condition that balances energy
16261 0 : hTinwout = PsyHFnTdbW(EvapInletDryBulb, FullLoadOutAirHumRat);
16262 0 : SHR = 1.0 - (EvapInletEnthalpy - hTinwout) / ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
16263 0 : SHR = min(SHR, 1.0);
16264 : }
16265 : // calculate the sensible and latent zone heat removal (extraction) rate by the secondary coil
16266 30261 : thisDXCoil.SecCoilSensibleHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate * SHR;
16267 30261 : thisDXCoil.SecCoilLatentHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate - thisDXCoil.SecCoilSensibleHeatRemovalRate;
16268 : } else {
16269 : // DX coil is off;
16270 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
16271 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
16272 0 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
16273 0 : SHR = 0.0; // SHR is set to zero if the coil is off
16274 : }
16275 30261 : thisDXCoil.SecCoilSHR = SHR;
16276 30261 : } break;
16277 0 : case HVAC::CoilDX_MultiSpeedHeating: {
16278 0 : EvapInletDryBulb = secZoneHB.ZT;
16279 0 : EvapInletHumRat = secZoneHB.airHumRat;
16280 0 : RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat);
16281 0 : MSSpeedRatio = thisDXCoil.MSSpeedRatio;
16282 0 : MSCycRatio = thisDXCoil.MSCycRatio;
16283 0 : MSSpeedNumHS = thisDXCoil.MSSpeedNumHS;
16284 0 : MSSpeedNumLS = thisDXCoil.MSSpeedNumLS;
16285 0 : if (MSSpeedRatio > 0.0) {
16286 0 : EvapAirMassFlow = RhoAir * (thisDXCoil.MSSecCoilAirFlow(MSSpeedNumHS) * MSSpeedRatio +
16287 0 : thisDXCoil.MSSecCoilAirFlow(MSSpeedNumLS) * (1.0 - MSSpeedRatio));
16288 0 : } else if (MSCycRatio > 0.0) {
16289 0 : EvapAirMassFlow = RhoAir * thisDXCoil.MSSecCoilAirFlow(MSSpeedNumLS);
16290 : }
16291 0 : if (thisDXCoil.ElecHeatingPower > 0.0) {
16292 0 : TotalHeatRemovalRate = max(0.0, thisDXCoil.TotalHeatingEnergyRate - thisDXCoil.ElecHeatingPower);
16293 : } else {
16294 0 : TotalHeatRemovalRate = 0.0;
16295 0 : return;
16296 : }
16297 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower;
16298 0 : if ((EvapAirMassFlow > HVAC::SmallMassFlow) && (MSSpeedRatio > 0.0 || MSCycRatio > 0.0) &&
16299 0 : (EvapInletDryBulb > thisDXCoil.MinOATCompressor)) { // coil is running
16300 0 : SecCoilFlowFraction = 1.0; // for single speed DX coil the secondary coil (condenser) flow fraction is 1.0
16301 0 : CondInletDryBulb = state.dataLoopNodes->Node(thisDXCoil.AirInNode).Temp;
16302 0 : EvapInletWetBulb = PsyTwbFnTdbWPb(state, EvapInletDryBulb, EvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
16303 0 : EvapInletEnthalpy = PsyHFnTdbW(EvapInletDryBulb, EvapInletHumRat);
16304 : // determine the current SHR
16305 0 : if (MSSpeedRatio > 0.0) {
16306 : // calculate SHR for the higher speed
16307 0 : PartLoadRatio = 1.0;
16308 0 : SecCoilFlowFraction = 1.0;
16309 0 : SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumHS);
16310 0 : SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumHS);
16311 0 : SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumHS);
16312 0 : SHRHighSpeed = CalcSecondaryDXCoilsSHR(state,
16313 : DXCoilNum,
16314 : EvapAirMassFlow,
16315 : TotalHeatRemovalRate,
16316 : PartLoadRatio,
16317 : SecCoilRatedSHR,
16318 : EvapInletDryBulb,
16319 : EvapInletHumRat,
16320 : EvapInletWetBulb,
16321 : EvapInletEnthalpy,
16322 : CondInletDryBulb,
16323 : SecCoilFlowFraction,
16324 : SecCoilSHRFT,
16325 : SecCoilSHRFF);
16326 : // calculate SHR for the lower speed
16327 0 : SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumLS);
16328 0 : SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumLS);
16329 0 : SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumLS);
16330 0 : SHRLowSpeed = CalcSecondaryDXCoilsSHR(state,
16331 : DXCoilNum,
16332 : EvapAirMassFlow,
16333 : TotalHeatRemovalRate,
16334 : PartLoadRatio,
16335 : SecCoilRatedSHR,
16336 : EvapInletDryBulb,
16337 : EvapInletHumRat,
16338 : EvapInletWetBulb,
16339 : EvapInletEnthalpy,
16340 : CondInletDryBulb,
16341 : SecCoilFlowFraction,
16342 : SecCoilSHRFT,
16343 : SecCoilSHRFF);
16344 0 : SHR = SHRHighSpeed * MSSpeedRatio + SHRLowSpeed * (1.0 - MSSpeedRatio);
16345 :
16346 0 : } else if (MSCycRatio > 0.0) {
16347 : // calculate SHR for the lower speed
16348 0 : PartLoadRatio = MSCycRatio;
16349 0 : SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumLS);
16350 0 : SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumLS);
16351 0 : SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumLS);
16352 0 : SecCoilFlowFraction = 1.0;
16353 0 : SHRLowSpeed = CalcSecondaryDXCoilsSHR(state,
16354 : DXCoilNum,
16355 : EvapAirMassFlow,
16356 : TotalHeatRemovalRate,
16357 : MSCycRatio,
16358 : SecCoilRatedSHR,
16359 : EvapInletDryBulb,
16360 : EvapInletHumRat,
16361 : EvapInletWetBulb,
16362 : EvapInletEnthalpy,
16363 : CondInletDryBulb,
16364 : SecCoilFlowFraction,
16365 : SecCoilSHRFT,
16366 : SecCoilSHRFF);
16367 0 : SHR = SHRLowSpeed;
16368 : }
16369 : // Calculate full load output conditions
16370 0 : FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16371 0 : hTinwout = EvapInletEnthalpy - (1.0 - SHR) * ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
16372 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, EvapInletDryBulb, hTinwout, RoutineName, true);
16373 0 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
16374 : // when the air outlet temperature falls below the saturation temperature, it is reset to saturation temperature
16375 0 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
16376 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName);
16377 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
16378 : // Adjust SHR for the new outlet condition that balances energy
16379 0 : hTinwout = PsyHFnTdbW(EvapInletDryBulb, FullLoadOutAirHumRat);
16380 0 : SHR = 1.0 - (EvapInletEnthalpy - hTinwout) / (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16381 0 : SHR = min(SHR, 1.0);
16382 : }
16383 : // calculate the sensible and latent zone heat removal (extraction) rate by the secondary coil
16384 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate * SHR;
16385 0 : thisDXCoil.SecCoilLatentHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate - thisDXCoil.SecCoilSensibleHeatRemovalRate;
16386 : } else {
16387 : // DX coil is off;
16388 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
16389 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
16390 0 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
16391 0 : SHR = 0.0; // SHR is set to rated value if the coil is off
16392 : }
16393 0 : thisDXCoil.SecCoilSHR = SHR;
16394 0 : } break;
16395 0 : default:
16396 0 : break;
16397 : }
16398 :
16399 : } else {
16400 0 : thisDXCoil.SecCoilSensibleHeatGainRate = 0.0;
16401 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
16402 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
16403 0 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
16404 : }
16405 : }
16406 :
16407 30261 : Real64 CalcSecondaryDXCoilsSHR(EnergyPlusData &state,
16408 : [[maybe_unused]] int const DXCoilNum,
16409 : Real64 const EvapAirMassFlow,
16410 : Real64 const TotalHeatRemovalRate,
16411 : Real64 const PartLoadRatio,
16412 : Real64 const SecCoilRatedSHR,
16413 : Real64 const EvapInletDryBulb,
16414 : Real64 const EvapInletHumRat,
16415 : Real64 const EvapInletWetBulb,
16416 : Real64 const EvapInletEnthalpy,
16417 : Real64 const CondInletDryBulb,
16418 : Real64 const SecCoilFlowFraction,
16419 : int const SecCoilSHRFT,
16420 : int const SecCoilSHRFF)
16421 : {
16422 :
16423 : // SUBROUTINE INFORMATION:
16424 : // AUTHOR B. Nigusse
16425 : // DATE WRITTEN February 2015
16426 :
16427 : // PURPOSE OF THIS SUBROUTINE:
16428 : // Calculates secondary coil (evaporator) sensible heat ratio.
16429 :
16430 : // METHODOLOGY EMPLOYED:
16431 : // Energy balance:
16432 : // (1) checks if the seconday coil operation is dry and calculates appliavle SHR.
16433 : // (2) determines SHR from user specified rated SHR values and SHR modifier curves for
16434 : // temperature and flor fraction.
16435 : // (3) if secondary coil operates dry then the larger of the user SHR value and dry
16436 : // coil operation SHR is selected.
16437 :
16438 : // Using/Aliasing
16439 : using Curve::CurveValue;
16440 :
16441 : // SUBROUTINE PARAMETER DEFINITIONS:
16442 30261 : int constexpr MaxIter(30);
16443 30261 : Real64 constexpr RelaxationFactor(0.4);
16444 30261 : Real64 constexpr Tolerance(0.1);
16445 30261 : Real64 constexpr DryCoilTestEvapInletHumRatReset(0.00001);
16446 : static constexpr std::string_view RoutineName("CalcSecondaryDXCoilsSHR");
16447 :
16448 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16449 : Real64 DryCoilTestEvapInletHumRat; // evaporator coil inlet humidity ratio test for dry coil
16450 : Real64 DryCoilTestEvapInletWetBulb; // evaporator coil inlet dry bulb temperature test for dry coil
16451 : Real64 FullLoadOutAirEnth; // evaporator outlet full load enthalpy [J/kg]
16452 : Real64 FullLoadOutAirTemp; // evaporator outlet air temperature at full load [C]
16453 : Real64 hTinwADP; // enthaly of air at secondary coil entering temperature and Humidity ratio at ADP
16454 : Real64 SHRadp; // Sensible heat ratio
16455 : Real64 hADP; // enthaly of air at secondary coil at ADP
16456 : Real64 tADP; // dry bulb temperature of air at secondary coil at ADP
16457 : Real64 wADP; // humidity ratio of air at secondary coil at ADP
16458 : Real64 HumRatError; // humidity ratio error
16459 : bool CoilMightBeDry; // TRUE means the secondary DX coi runs dry
16460 : int Counter; // iteration counter
16461 : bool Converged; // convergence flag
16462 : Real64 SHR; // current time step sensible heat ratio of secondary coil
16463 :
16464 30261 : CoilMightBeDry = false;
16465 30261 : FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16466 30261 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, EvapInletHumRat);
16467 30261 : if (FullLoadOutAirTemp > PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
16468 30261 : CoilMightBeDry = true;
16469 : // find wADP, humidity ratio at apparatus dewpoint and inlet hum rat that would have dry coil
16470 30261 : DryCoilTestEvapInletHumRat = EvapInletHumRat;
16471 30261 : DryCoilTestEvapInletWetBulb = EvapInletWetBulb;
16472 30261 : Counter = 0;
16473 30261 : Converged = false;
16474 60522 : while (!Converged) {
16475 : // assumes coil bypass factor (CBF) = 0.0
16476 30261 : hADP = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16477 30261 : tADP = PsyTsatFnHPb(state, hADP, state.dataEnvrn->OutBaroPress, RoutineName);
16478 30261 : wADP = min(EvapInletHumRat, PsyWFnTdbH(state, tADP, hADP, RoutineName));
16479 30261 : hTinwADP = PsyHFnTdbW(EvapInletDryBulb, wADP);
16480 30261 : if ((EvapInletEnthalpy - hADP) > 1.e-10) {
16481 30261 : SHRadp = min((hTinwADP - hADP) / (EvapInletEnthalpy - hADP), 1.0);
16482 : } else {
16483 0 : SHRadp = 1.0;
16484 : }
16485 30261 : if ((wADP > DryCoilTestEvapInletHumRat) || (Counter >= 1 && Counter < MaxIter)) {
16486 0 : if (DryCoilTestEvapInletHumRat <= 0.0) DryCoilTestEvapInletHumRat = DryCoilTestEvapInletHumRatReset;
16487 0 : HumRatError = (DryCoilTestEvapInletHumRat - wADP) / DryCoilTestEvapInletHumRat;
16488 0 : DryCoilTestEvapInletHumRat = RelaxationFactor * wADP + (1.0 - RelaxationFactor) * DryCoilTestEvapInletHumRat;
16489 : DryCoilTestEvapInletWetBulb =
16490 0 : PsyTwbFnTdbWPb(state, EvapInletDryBulb, DryCoilTestEvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
16491 0 : ++Counter;
16492 0 : if (std::abs(HumRatError) <= Tolerance) {
16493 0 : Converged = true;
16494 : } else {
16495 0 : Converged = false;
16496 : }
16497 : } else {
16498 30261 : Converged = true;
16499 : }
16500 : }
16501 : }
16502 : // determine SHR from user specified nominal value and SHR modifier curves
16503 30261 : SHR = CalcSHRUserDefinedCurves(state, CondInletDryBulb, EvapInletWetBulb, SecCoilFlowFraction, SecCoilSHRFT, SecCoilSHRFF, SecCoilRatedSHR);
16504 30261 : if (CoilMightBeDry) {
16505 30261 : if ((EvapInletHumRat < DryCoilTestEvapInletHumRat) && (SHRadp > SHR)) { // coil is dry for sure
16506 0 : SHR = 1.0;
16507 30261 : } else if (SHRadp > SHR) {
16508 0 : SHR = SHRadp;
16509 : }
16510 : }
16511 30261 : return SHR;
16512 : }
16513 :
16514 683992 : void CalcVRFCoolingCoil_FluidTCtrl(EnergyPlusData &state,
16515 : int const DXCoilNum, // the number of the DX coil to be simulated
16516 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
16517 : bool const FirstHVACIteration, // true if this is the first iteration of HVAC
16518 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
16519 : HVAC::FanOp const fanOp, // Allows parent object to control fan operation
16520 : Real64 const CompCycRatio, // cycling ratio of VRF condenser
16521 : ObjexxFCL::Optional_int_const PerfMode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
16522 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio // ratio of compressor on airflow to compressor off airflow
16523 : )
16524 : {
16525 : // SUBROUTINE INFORMATION:
16526 : // AUTHOR Xiufeng Pang, LBNL
16527 : // DATE WRITTEN Jan 2013
16528 : // MODIFIED Nov 2015, RP Zhang, LBNL
16529 :
16530 : // PURPOSE OF THIS SUBROUTINE:
16531 : // Calculates the air-side performance of a direct-expansion, air-cooled
16532 : // VRF terminal unit cooling coil, for the VRF_FluidTCtrl model.
16533 :
16534 : // METHODOLOGY EMPLOYED:
16535 : // This subroutine is derived from CalcVRFCoolingCoil, and implements the new VRF model for FluidTCtrl.
16536 :
16537 : // Using/Aliasing
16538 : using Curve::CurveValue;
16539 683992 : Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
16540 683992 : Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
16541 : using General::CreateSysTimeIntervalString;
16542 :
16543 : using namespace HVACVariableRefrigerantFlow;
16544 :
16545 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16546 :
16547 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
16548 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
16549 : // (average flow if cycling fan, full flow if constant fan)
16550 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
16551 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
16552 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
16553 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
16554 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
16555 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
16556 : Real64 RatedCBF; // coil bypass factor at rated conditions
16557 : Real64 CBF; // coil bypass factor at off rated conditions
16558 : Real64 A0; // NTU * air mass flow rate, used in CBF calculation
16559 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
16560 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
16561 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
16562 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
16563 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
16564 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
16565 : Real64 RhoAir; // Density of air [kg/m3]
16566 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
16567 683992 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
16568 : Real64 AirFlowRatio; // ratio of compressor on airflow to average timestep airflow
16569 : // used when constant fan mode yields different air flow rates when compressor is ON and OFF
16570 : // (e.g. Packaged Terminal Heat Pump)
16571 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
16572 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
16573 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
16574 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
16575 :
16576 : int Mode; // Performance mode for Multimode DX coil; Always 1 for other coil types
16577 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
16578 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
16579 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
16580 : Real64 ADiff; // Used for exponential
16581 :
16582 : // Followings for VRF FluidTCtrl Only
16583 : Real64 QCoilReq; // Coil load (W)
16584 : Real64 FanSpdRatio; // Fan speed ratio
16585 : Real64 AirMassFlowMin; // Min air mass flow rate due to OA requirement [kg/s]
16586 : Real64 ActualSH; // Super heating degrees (C)
16587 : Real64 ActualSC; // Sub cooling degrees (C)
16588 :
16589 : // If Performance mode not present, then set to 1. Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
16590 683992 : if (present(PerfMode)) {
16591 0 : Mode = PerfMode;
16592 : } else {
16593 683992 : Mode = 1;
16594 : }
16595 :
16596 : // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
16597 : // during cooling and when no cooling is required (constant fan, fan speed changes)
16598 683992 : if (present(OnOffAirFlowRatio)) {
16599 0 : AirFlowRatio = OnOffAirFlowRatio;
16600 : } else {
16601 683992 : AirFlowRatio = 1.0;
16602 : }
16603 :
16604 683992 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
16605 :
16606 : // Initialize coil air side parameters
16607 683992 : CondInletTemp = 0.0;
16608 683992 : CondInletHumRat = 0.0;
16609 683992 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
16610 683992 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
16611 683992 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
16612 683992 : InletAirHumRat = thisDXCoil.InletAirHumRat;
16613 683992 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
16614 683992 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
16615 683992 : thisDXCoil.PartLoadRatio = 0.0;
16616 683992 : thisDXCoil.BasinHeaterPower = 0.0;
16617 683992 : thisDXCoil.EvaporatingTemp = state.dataHVACVarRefFlow->VRF(thisDXCoil.VRFOUPtr).IUEvaporatingTemp;
16618 :
16619 683992 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
16620 0 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
16621 0 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
16622 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
16623 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
16624 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
16625 : } else {
16626 0 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
16627 : // If node is not connected to anything, pressure = default, use weather data
16628 0 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
16629 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
16630 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
16631 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
16632 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
16633 : } else {
16634 0 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
16635 0 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
16636 : }
16637 : }
16638 : } else {
16639 683992 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
16640 683992 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
16641 683992 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
16642 683992 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
16643 : }
16644 :
16645 683992 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
16646 0 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
16647 0 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
16648 : // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
16649 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
16650 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
16651 0 : CompAmbTemp = OutdoorDryBulb;
16652 : } else { // for air or water-cooled, inlet temp is stored in OutdoorDryBulb temp
16653 683992 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp or water inlet temp
16654 683992 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
16655 0 : CompAmbTemp = state.dataEnvrn->OutDryBulbTemp; // for crankcase heater use actual outdoor temp for water-cooled
16656 : } else {
16657 683992 : CompAmbTemp = OutdoorDryBulb;
16658 : }
16659 : }
16660 :
16661 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
16662 : // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
16663 683992 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
16664 60444 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
16665 60444 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
16666 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
16667 : }
16668 : } else {
16669 623548 : CrankcaseHeatingPower = 0.0;
16670 : }
16671 :
16672 : // calculate end time of current time step to determine if error messages should be printed
16673 683992 : state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
16674 :
16675 : // The following checks are not necessary for VRF-FluidTCtrl model. (1) OAT check is already performed in the VRF OU routines (2)
16676 : // VRF-FluidTCtrl model is physics based, not system curve based, and thus doesn't require special performance curves for operations at
16677 : // low inlet temperatures
16678 : // Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
16679 : // Wait for next time step to print warnings. If simulation iterates, print out
16680 : // the warning for the last iteration only. Must wait for next time step to accomplish this.
16681 : // If a warning occurs and the simulation down shifts, the warning is not valid.
16682 : // if ( DXCoil( DXCoilNum ).PrintLowAmbMessage ) { // .AND. &
16683 : // if ( CurrentEndTime > DXCoil( DXCoilNum ).CurrentEndTimeLast && TimeStepSys >= DXCoil( DXCoilNum ).TimeStepSysLast ) {
16684 : // if ( DXCoil( DXCoilNum ).LowAmbErrIndex == 0 ) {
16685 : // ShowWarningMessage(state, DXCoil( DXCoilNum ).LowAmbBuffer1 );
16686 : // ShowContinueError(state, DXCoil( DXCoilNum ).LowAmbBuffer2 );
16687 : // ShowContinueError(state, "... Operation at low inlet temperatures may require special performance curves." );
16688 : // }
16689 : // ShowRecurringWarningErrorAtEnd(state, DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Low condenser inlet
16690 : // temperature error continues...", DXCoil( DXCoilNum ).LowAmbErrIndex, DXCoil( DXCoilNum ).LowTempLast, DXCoil( DXCoilNum ).LowTempLast,
16691 : // _,
16692 : // "[C]", "[C]" );
16693 : // }
16694 : // }
16695 : //
16696 : // if ( DXCoil( DXCoilNum ).PrintHighAmbMessage ) { // .AND. &
16697 : // if ( CurrentEndTime > DXCoil( DXCoilNum ).CurrentEndTimeLast && TimeStepSys >= DXCoil( DXCoilNum ).TimeStepSysLast ) {
16698 : // if ( DXCoil( DXCoilNum ).HighAmbErrIndex == 0 ) {
16699 : // ShowWarningMessage(state, DXCoil( DXCoilNum ).HighAmbBuffer1 );
16700 : // ShowContinueError(state, DXCoil( DXCoilNum ).HighAmbBuffer2 );
16701 : // ShowContinueError(state, "... Operation at high inlet temperatures may require special performance curves." );
16702 : // }
16703 : // ShowRecurringWarningErrorAtEnd(state, DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - High condenser inlet
16704 : // temperature error continues...", DXCoil( DXCoilNum ).HighAmbErrIndex, DXCoil( DXCoilNum ).HighTempLast, DXCoil( DXCoilNum
16705 : // ).HighTempLast,
16706 : // _, "[C]", "[C]" );
16707 : // }
16708 : // }
16709 :
16710 683992 : if (thisDXCoil.PrintLowOutTempMessage) {
16711 0 : if ((state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime > thisDXCoil.CurrentEndTimeLast) &&
16712 0 : (TimeStepSys >= thisDXCoil.TimeStepSysLast)) {
16713 0 : if (thisDXCoil.LowOutletTempIndex == 0) {
16714 0 : ShowWarningMessage(state, thisDXCoil.LowOutTempBuffer1);
16715 0 : ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
16716 0 : ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
16717 0 : ShowContinueError(state,
16718 0 : format(" 1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
16719 0 : thisDXCoil.FullLoadInletAirTempLast));
16720 0 : ShowContinueError(state, " 2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
16721 0 : ShowContinueError(state,
16722 : " 3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
16723 : }
16724 0 : ShowRecurringWarningErrorAtEnd(state,
16725 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
16726 : "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
16727 : "Outlet air temperature statistics follow:",
16728 0 : thisDXCoil.LowOutletTempIndex,
16729 0 : thisDXCoil.FullLoadOutAirTempLast,
16730 0 : thisDXCoil.FullLoadOutAirTempLast);
16731 : }
16732 : }
16733 :
16734 : // save last system time step and last end time of current time step (used to determine if warning is valid)
16735 683992 : thisDXCoil.TimeStepSysLast = TimeStepSys;
16736 683992 : thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime;
16737 683992 : thisDXCoil.PrintLowAmbMessage = false;
16738 683992 : thisDXCoil.PrintLowOutTempMessage = false;
16739 :
16740 683992 : if ((AirMassFlow > 0.0) && (GetCurrentScheduleValue(state, thisDXCoil.SchedPtr) > 0.0) && (PartLoadRatio > 0.0) &&
16741 : (compressorOp == HVAC::CompressorOp::On)) { // for cycling fan, reset mass flow to full on rate
16742 :
16743 304587 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
16744 0 : ShowFatalError(state, format("{} \"{}\" - Rated total cooling capacity is zero or less.", thisDXCoil.DXCoilType, thisDXCoil.Name));
16745 : }
16746 :
16747 304587 : TotCap = thisDXCoil.RatedTotCap(Mode);
16748 304587 : QCoilReq = -PartLoadRatio * TotCap;
16749 304587 : if (PartLoadRatio == 0.0) {
16750 0 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
16751 : } else {
16752 304587 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
16753 : }
16754 :
16755 : // Call ControlVRFIUCoil to calculate: (1) FanSpdRatio, (2) coil inlet/outlet conditions, and (3) SH/SC
16756 304587 : ControlVRFIUCoil(state,
16757 : DXCoilNum,
16758 : QCoilReq,
16759 : thisDXCoil.InletAirTemp,
16760 : thisDXCoil.InletAirHumRat,
16761 : thisDXCoil.EvaporatingTemp,
16762 : AirMassFlowMin,
16763 : FanSpdRatio,
16764 : OutletAirHumRat,
16765 : OutletAirTemp,
16766 : OutletAirEnthalpy,
16767 : ActualSH,
16768 : ActualSC);
16769 304587 : AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
16770 :
16771 304587 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
16772 304587 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
16773 : // VolFlowperRatedTotCap was checked at the initialization step
16774 : // No need to check VolFlowperRatedTotCap at the simulation
16775 : // New VRF_FluidTCtrl model implements VAV fan which can vary air flow rate during simulation
16776 :
16777 304587 : RatedCBF = thisDXCoil.RatedCBF(Mode);
16778 304587 : if (RatedCBF > 0.0) {
16779 304587 : A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
16780 : } else {
16781 0 : A0 = 0.0;
16782 : }
16783 304587 : ADiff = -A0 / AirMassFlow;
16784 304587 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
16785 304587 : CBF = std::exp(ADiff);
16786 : } else {
16787 0 : CBF = 0.0;
16788 : }
16789 :
16790 : // The following checks are not necessary for VRF-FluidTCtrl model. (1) OAT check is already performed in the VRF OU routines (2)
16791 : // VRF-FluidTCtrl model is physics based, not system curve based, and thus doesn't require special performance curves for operations
16792 : // at low inlet temperatures
16793 : // // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
16794 : // if ( OutdoorDryBulb < DXCoil( DXCoilNum ).MinOATCompressor && ! WarmupFlag ) {
16795 : // DXCoil( DXCoilNum ).PrintLowAmbMessage = true;
16796 : // DXCoil( DXCoilNum ).LowTempLast = OutdoorDryBulb;
16797 : // if ( DXCoil( DXCoilNum ).LowAmbErrIndex == 0 ) {
16798 : // DXCoil( DXCoilNum ).LowAmbBuffer1 = DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Condenser
16799 : // inlet temperature below " + RoundSigDigits( DXCoil( DXCoilNum ).MinOATCompressor, 2 ) + " C. Condenser inlet temperature = " +
16800 : // RoundSigDigits( OutdoorDryBulb, 2 );
16801 : // DXCoil( DXCoilNum ).LowAmbBuffer2 = " ... Occurrence info = " + EnvironmentName + ", " + CurMnDy + " " +
16802 : // CreateSysTimeIntervalString();
16803 : // }
16804 : // }
16805 : //
16806 : // // check boundary for high ambient temperature and post warnings to individual DX coil buffers to print at end of time step
16807 : // if ( OutdoorDryBulb > DXCoil( DXCoilNum ).MaxOATCompressor && ! WarmupFlag ) {
16808 : // DXCoil( DXCoilNum ).PrintHighAmbMessage = true;
16809 : // DXCoil( DXCoilNum ).HighTempLast = OutdoorDryBulb;
16810 : // if ( DXCoil( DXCoilNum ).HighAmbErrIndex == 0 ) {
16811 : // DXCoil( DXCoilNum ).HighAmbBuffer1 = DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Condenser
16812 : // inlet temperature above " + RoundSigDigits( DXCoil( DXCoilNum ).MaxOATCompressor, 2 ) + " C. Condenser temperature = " +
16813 : // RoundSigDigits( OutdoorDryBulb, 2 ); DXCoil( DXCoilNum ).HighAmbBuffer2 = " ... Occurrence info = " + EnvironmentName + ",
16814 : // "
16815 : // + CurMnDy + " " + CreateSysTimeIntervalString();
16816 : // }
16817 : // }
16818 :
16819 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
16820 : // InletAirHumRat may be modified in this ADP/BF loop, use temporary varible for calculations
16821 :
16822 : // commented, not used issue #6950
16823 : // InletAirHumRatTemp = InletAirHumRat;
16824 :
16825 : //// Calculate apparatus dew point conditions using TotCap and CBF
16826 : // hDelta = TotCap / AirMassFlow;
16827 : //// there is an issue here with using CBF to calculate the ADP enthalpy.
16828 : //// at low loads the bypass factor increases significantly.
16829 : // hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
16830 : // tADP = PsyTsatFnHPb(hADP, OutdoorPressure, RoutineName);
16831 : //// Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
16832 : //// tADP = PsyTsatFnHPb(hADP,InletAirPressure)
16833 : // wADP = min(InletAirHumRat, PsyWFnTdbH(tADP, hADP, RoutineName));
16834 : // hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
16835 : // if ((InletAirEnthalpy - hADP) > 1.e-10) {
16836 : // SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
16837 : //} else {
16838 : // SHR = 1.0;
16839 : //}
16840 : // commented, not used issue #6950 ends here
16841 :
16842 304587 : if (thisDXCoil.PLFFPLR(Mode) > 0 && CompCycRatio < 1.0) {
16843 0 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CompCycRatio); // Calculate part-load factor
16844 : } else {
16845 304587 : PLF = 1.0;
16846 : }
16847 :
16848 304587 : if (PLF < 0.7) {
16849 0 : if (thisDXCoil.ErrIndex2 == 0) {
16850 0 : ShowWarningMessage(
16851 : state,
16852 0 : format(
16853 0 : "The PLF curve value for the DX cooling coil {} ={:.3R} for part-load ratio ={:.3R}", thisDXCoil.Name, PLF, PartLoadRatio));
16854 0 : ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
16855 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
16856 : }
16857 0 : ShowRecurringWarningErrorAtEnd(
16858 0 : state, thisDXCoil.Name + ", DX cooling coil PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
16859 0 : PLF = 0.7;
16860 : }
16861 :
16862 304587 : thisDXCoil.PartLoadRatio = PartLoadRatio;
16863 304587 : thisDXCoil.CoolingCoilRuntimeFraction = CompCycRatio / PLF;
16864 304587 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
16865 0 : if (thisDXCoil.ErrIndex3 == 0) {
16866 0 : ShowWarningMessage(state,
16867 0 : format("The runtime fraction for DX cooling coil {} exceeded 1.0. [{:.4R}].",
16868 0 : thisDXCoil.Name,
16869 0 : thisDXCoil.CoolingCoilRuntimeFraction));
16870 0 : ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
16871 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
16872 0 : ShowContinueErrorTimeStamp(state, "");
16873 : }
16874 0 : ShowRecurringWarningErrorAtEnd(state,
16875 0 : thisDXCoil.Name + ", DX cooling coil runtime fraction > 1.0 warning continues...",
16876 0 : thisDXCoil.ErrIndex3,
16877 0 : thisDXCoil.CoolingCoilRuntimeFraction,
16878 0 : thisDXCoil.CoolingCoilRuntimeFraction);
16879 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
16880 304587 : } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
16881 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
16882 : }
16883 :
16884 : // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
16885 304587 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
16886 :
16887 : // Check for saturation error and modify temperature at constant enthalpy
16888 304587 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) {
16889 150 : OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
16890 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
16891 : // IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
16892 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
16893 150 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
16894 : }
16895 :
16896 : // Store actual outlet conditions when DX coil is ON for use in heat recovery module
16897 304587 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = OutletAirTemp;
16898 304587 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = OutletAirHumRat;
16899 :
16900 : // Add warning message for cold cooling coil (OutletAirTemp < 2 C)
16901 304587 : if (OutletAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
16902 0 : thisDXCoil.PrintLowOutTempMessage = true;
16903 0 : thisDXCoil.FullLoadOutAirTempLast = OutletAirTemp;
16904 0 : if (thisDXCoil.LowOutletTempIndex == 0) {
16905 0 : thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
16906 0 : thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
16907 : "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
16908 0 : thisDXCoil.DXCoilType,
16909 0 : thisDXCoil.Name,
16910 0 : OutletAirTemp);
16911 0 : thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + " " +
16912 0 : CreateSysTimeIntervalString(state);
16913 : }
16914 : }
16915 :
16916 : // Coil total cooling
16917 304587 : Real64 AirMassFlowRate = thisDXCoil.InletAirMassFlowRate;
16918 : // Coil total/sensible/latent cooling rates
16919 304587 : CalcComponentSensibleLatentOutput(AirMassFlowRate,
16920 : InletAirDryBulbTemp,
16921 : InletAirHumRat,
16922 : OutletAirTemp,
16923 : OutletAirHumRat,
16924 304587 : thisDXCoil.SensCoolingEnergyRate,
16925 304587 : thisDXCoil.LatCoolingEnergyRate,
16926 304587 : thisDXCoil.TotalCoolingEnergyRate);
16927 :
16928 : // Coil outlet conditions
16929 304587 : thisDXCoil.OutletAirTemp = OutletAirTemp;
16930 304587 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
16931 304587 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
16932 :
16933 : // Coil SH/SC
16934 304587 : thisDXCoil.ActualSH = ActualSH;
16935 304587 : thisDXCoil.ActualSC = ActualSC;
16936 :
16937 : } else {
16938 : // DX coil is off; just pass through conditions
16939 :
16940 379405 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
16941 379405 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
16942 379405 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
16943 :
16944 379405 : thisDXCoil.ElecCoolingPower = 0.0;
16945 379405 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
16946 379405 : thisDXCoil.SensCoolingEnergyRate = 0.0;
16947 379405 : thisDXCoil.LatCoolingEnergyRate = 0.0;
16948 379405 : thisDXCoil.EvapCondPumpElecPower = 0.0;
16949 379405 : thisDXCoil.EvapWaterConsumpRate = 0.0;
16950 :
16951 379405 : thisDXCoil.ActualSH = 999.0;
16952 379405 : thisDXCoil.ActualSC = 999.0;
16953 :
16954 : // Reset globals when DX coil is OFF for use in heat recovery module
16955 379405 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
16956 379405 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
16957 :
16958 : } // end of on/off
16959 :
16960 : // set water system demand request (if needed)
16961 683992 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
16962 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
16963 0 : thisDXCoil.EvapWaterConsumpRate;
16964 : }
16965 :
16966 683992 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
16967 683992 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
16968 683992 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
16969 683992 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
16970 683992 : thisDXCoil.CondInletTemp = CondInletTemp;
16971 683992 : state.dataDXCoils->DXCoilTotalCooling(DXCoilNum) = thisDXCoil.TotalCoolingEnergyRate;
16972 683992 : state.dataDXCoils->DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
16973 683992 : }
16974 :
16975 683992 : void CalcVRFHeatingCoil_FluidTCtrl(EnergyPlusData &state,
16976 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
16977 : int const DXCoilNum, // the number of the DX heating coil to be simulated
16978 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
16979 : HVAC::FanOp const fanOp, // Allows parent object to control fan mode
16980 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
16981 : ObjexxFCL::Optional<Real64 const> MaxHeatCap // maximum allowed heating capacity
16982 : )
16983 : {
16984 : // SUBROUTINE INFORMATION:
16985 : // AUTHOR Xiufeng Pang (XP), LBNL
16986 : // DATE WRITTEN Mar 2013
16987 : // MODIFIED Nov 2015, RP Zhang, LBNL
16988 :
16989 : // PURPOSE OF THIS SUBROUTINE:
16990 : // Calculates the air-side performance of a direct-expansion, air-cooled
16991 : // VRF terminal unit heating coil, for the new VRF model.
16992 :
16993 : // METHODOLOGY EMPLOYED:
16994 : // This subroutine is derived from CalcVRFCoolingCoil, and implements the new VRF model for FluidTCtrl.
16995 :
16996 : // Using/Aliasing
16997 : using Curve::CurveValue;
16998 :
16999 : using namespace HVACVariableRefrigerantFlow;
17000 :
17001 : // INTERFACE BLOCK SPECIFICATIONS
17002 : static constexpr std::string_view RoutineNameFullLoad("CalcVRFHeatingCoil_FluidTCtrl:fullload");
17003 :
17004 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
17005 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
17006 : Real64 AirMassFlowRatio; // Ratio of actual air mass flow to rated air mass flow
17007 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s]
17008 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W]
17009 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
17010 : Real64 TotCapAdj; // adjusted total cooling capacity at off-rated conditions [W]
17011 : // on the type of curve
17012 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
17013 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
17014 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
17015 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
17016 : Real64 FullLoadOutAirEnth; // outlet full load enthalpy [J/kg]
17017 : Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
17018 : Real64 FullLoadOutAirTemp; // outlet air temperature at full load [C]
17019 : Real64 FullLoadOutAirRH; // outlet air relative humidity at full load
17020 683992 : Real64 EIRTempModFac(0.0); // EIR modifier (function of entering drybulb, outside drybulb) depending on the
17021 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17022 : // type of curve
17023 : // Real64 DefrostEIRTempModFac; // EIR modifier for defrost (function of entering wetbulb, outside drybulb)
17024 : Real64 EIRFlowModFac; // EIR modifier (function of actual supply air flow vs rated flow)
17025 : Real64 EIR; // EIR at part load and off rated conditions
17026 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup
17027 : Real64 PLRHeating; // PartLoadRatio in heating
17028 : Real64 OutdoorCoilT; // Outdoor coil temperature (C)
17029 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
17030 : Real64 FractionalDefrostTime; // Fraction of time step system is in defrost
17031 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
17032 : Real64 InputPowerMultiplier; // Multiplier for power when system is in defrost
17033 : Real64 LoadDueToDefrost; // Additional load due to defrost
17034 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
17035 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
17036 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
17037 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
17038 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
17039 683992 : constexpr int Mode(1); // Performance mode for MultiMode DX coil. Always 1 for other coil types
17040 : Real64 AirFlowRatio; // Ratio of compressor on airflow to average timestep airflow
17041 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
17042 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
17043 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
17044 :
17045 : // Followings for VRF FluidTCtrl Only
17046 : Real64 QCoilReq; // Coil load (W)
17047 : Real64 FanSpdRatio; // Fan Speed Ratio
17048 : Real64 AirMassFlowMin; // Min air mass flow rate due to OA requirement [kg/s]
17049 : Real64 ActualSH; // Actual Super Heating
17050 : Real64 ActualSC; // Actual Sub Cooling
17051 :
17052 683992 : if (present(OnOffAirFlowRatio)) {
17053 0 : AirFlowRatio = OnOffAirFlowRatio;
17054 : } else {
17055 683992 : AirFlowRatio = 1.0;
17056 : }
17057 :
17058 : // Air cooled condenser
17059 683992 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
17060 683992 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
17061 683992 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
17062 683992 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
17063 :
17064 683992 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
17065 :
17066 683992 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
17067 683992 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
17068 683992 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
17069 683992 : InletAirHumRat = thisDXCoil.InletAirHumRat;
17070 683992 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
17071 683992 : PLRHeating = 0.0;
17072 683992 : thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
17073 683992 : thisDXCoil.CondensingTemp = state.dataHVACVarRefFlow->VRF(thisDXCoil.VRFOUPtr).IUCondensingTemp;
17074 :
17075 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
17076 683992 : if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
17077 60444 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
17078 60444 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
17079 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
17080 : }
17081 : } else {
17082 623548 : CrankcaseHeatingPower = 0.0;
17083 : }
17084 :
17085 676634 : if ((AirMassFlow > 0.0) && (compressorOp == HVAC::CompressorOp::On) && (GetCurrentScheduleValue(state, thisDXCoil.SchedPtr) > 0.0) &&
17086 1360626 : (PartLoadRatio > 0.0) && (OutdoorDryBulb > thisDXCoil.MinOATCompressor)) {
17087 :
17088 133476 : TotCap = thisDXCoil.RatedTotCap(Mode);
17089 133476 : HeatingCapacityMultiplier = 1.0;
17090 : // Modify total heating capacity based on defrost heating capacity multiplier
17091 : // MaxHeatCap passed from parent object VRF Condenser and is used to limit capacity of TU's to that available from condenser
17092 133476 : if (present(MaxHeatCap)) {
17093 133460 : TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
17094 133460 : TotCap = min(MaxHeatCap, TotCap);
17095 : } else {
17096 16 : TotCapAdj = TotCap * HeatingCapacityMultiplier;
17097 : }
17098 :
17099 133476 : QCoilReq = PartLoadRatio * TotCap;
17100 133476 : if (PartLoadRatio == 0.0) {
17101 0 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
17102 : } else {
17103 133476 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
17104 : }
17105 :
17106 : // Call ControlVRFIUCoil to calculate: (1) FanSpdRatio, (2) coil inlet/outlet conditions, and (3) SH/SC
17107 133476 : ControlVRFIUCoil(state,
17108 : DXCoilNum,
17109 : QCoilReq,
17110 : thisDXCoil.InletAirTemp,
17111 : thisDXCoil.InletAirHumRat,
17112 : thisDXCoil.CondensingTemp,
17113 : AirMassFlowMin,
17114 : FanSpdRatio,
17115 : OutletAirHumRat,
17116 : OutletAirTemp,
17117 : OutletAirEnthalpy,
17118 : ActualSH,
17119 : ActualSC);
17120 133476 : AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
17121 :
17122 133476 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
17123 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17124 133476 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
17125 : // VolFlowperRatedTotCap was checked at the initialization step
17126 : // No need to check VolFlowperRatedTotCap at the simulation
17127 : // New VRF_FluidTCtrl model implements VAV fan which can vary air flow rate during simulation
17128 :
17129 133476 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
17130 :
17131 : // Calculating adjustment factors for defrost
17132 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
17133 133476 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
17134 133476 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
17135 :
17136 : // Initializing defrost adjustment factors
17137 133476 : LoadDueToDefrost = 0.0;
17138 133476 : FractionalDefrostTime = 0.0;
17139 133476 : InputPowerMultiplier = 1.0;
17140 :
17141 : // Calculate full load outlet conditions
17142 133476 : FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
17143 133476 : FullLoadOutAirHumRat = InletAirHumRat;
17144 133476 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
17145 133476 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
17146 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17147 : // FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
17148 133476 : if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
17149 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
17150 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17151 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
17152 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
17153 : }
17154 :
17155 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
17156 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
17157 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
17158 : // advised to use the bi-quaratic curve if sufficient manufacturer data is available.
17159 133476 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
17160 0 : if (state.dataCurveManager->PerfCurve(thisDXCoil.EIRFTemp(Mode))->numDims == 1) {
17161 0 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), OutdoorDryBulb);
17162 : } else {
17163 0 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
17164 : }
17165 0 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
17166 : } else {
17167 133476 : EIRTempModFac = 1.0;
17168 133476 : EIRFlowModFac = 1.0;
17169 : }
17170 133476 : EIR = thisDXCoil.RatedEIR(Mode) * EIRTempModFac * EIRFlowModFac;
17171 :
17172 : // Calculate PLRHeating: modified PartLoadRatio due to defrost ( reverse-cycle defrost only )
17173 133476 : if (TotCap > 0.0) {
17174 133476 : PLRHeating = min(1.0, (PartLoadRatio + LoadDueToDefrost / TotCap));
17175 : } else {
17176 0 : PLRHeating = min(1.0, PartLoadRatio);
17177 : }
17178 :
17179 133476 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
17180 0 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PLRHeating); // Calculate part-load factor
17181 : } else {
17182 133476 : PLF = 1.0;
17183 : }
17184 :
17185 133476 : if (PLF < 0.7) {
17186 0 : if (thisDXCoil.PLRErrIndex == 0) {
17187 0 : ShowWarningMessage(
17188 : state,
17189 0 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
17190 0 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
17191 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
17192 0 : ShowContinueErrorTimeStamp(state, "");
17193 : }
17194 0 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
17195 0 : PLF = 0.7;
17196 : }
17197 :
17198 133476 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
17199 133476 : if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
17200 0 : if (thisDXCoil.ErrIndex4 == 0) {
17201 0 : ShowWarningMessage(state,
17202 0 : format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
17203 0 : thisDXCoil.Name,
17204 0 : thisDXCoil.HeatingCoilRuntimeFraction));
17205 0 : ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
17206 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
17207 0 : ShowContinueErrorTimeStamp(state, "");
17208 : }
17209 0 : ShowRecurringWarningErrorAtEnd(state,
17210 0 : thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
17211 0 : thisDXCoil.ErrIndex4,
17212 0 : thisDXCoil.HeatingCoilRuntimeFraction,
17213 0 : thisDXCoil.HeatingCoilRuntimeFraction);
17214 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
17215 133476 : } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
17216 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
17217 : }
17218 :
17219 : // if cycling fan, send coil part-load fraction to on / off fan via HVACDataGlobals
17220 133476 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
17221 133476 : thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
17222 :
17223 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
17224 : // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
17225 133476 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
17226 133476 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
17227 : } else {
17228 0 : thisDXCoil.CrankcaseHeaterPower =
17229 0 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
17230 0 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
17231 : }
17232 :
17233 133476 : thisDXCoil.OutletAirTemp = OutletAirTemp;
17234 133476 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
17235 133476 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
17236 133476 : thisDXCoil.CompressorPartLoadRatio = PartLoadRatio;
17237 133476 : thisDXCoil.ActualSH = ActualSH;
17238 133476 : thisDXCoil.ActualSC = ActualSC;
17239 133476 : thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy) * PartLoadRatio;
17240 133476 : thisDXCoil.DefrostPower = thisDXCoil.DefrostPower * thisDXCoil.HeatingCoilRuntimeFraction;
17241 :
17242 : } else {
17243 : // DX coil is off; just pass through conditions
17244 :
17245 550516 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
17246 550516 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
17247 550516 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
17248 :
17249 550516 : thisDXCoil.ElecHeatingPower = 0.0;
17250 550516 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
17251 550516 : thisDXCoil.DefrostPower = 0.0;
17252 :
17253 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
17254 : // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
17255 550516 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
17256 550516 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
17257 : } else {
17258 0 : thisDXCoil.CrankcaseHeaterPower =
17259 0 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
17260 : }
17261 550516 : thisDXCoil.CompressorPartLoadRatio = 0.0;
17262 :
17263 550516 : thisDXCoil.ActualSH = 999.0;
17264 550516 : thisDXCoil.ActualSC = 999.0;
17265 : } // end of on/off if - else
17266 :
17267 683992 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
17268 683992 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
17269 683992 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
17270 683992 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
17271 683992 : state.dataDXCoils->DXCoilTotalHeating(DXCoilNum) = thisDXCoil.TotalHeatingEnergyRate;
17272 683992 : state.dataDXCoils->DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
17273 683992 : state.dataDXCoils->DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;
17274 :
17275 : // calc secondary coil if specified
17276 683992 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
17277 0 : CalcSecondaryDXCoils(state, DXCoilNum);
17278 : }
17279 683992 : }
17280 :
17281 1846744 : void ControlVRFIUCoil(EnergyPlusData &state,
17282 : int const CoilIndex, // index to VRFTU coil
17283 : Real64 const QCoil, // coil load
17284 : Real64 const Tin, // inlet air temperature
17285 : Real64 const Win, // inlet air humidity ratio
17286 : Real64 const TeTc, // evaporating or condensing temperature
17287 : Real64 const OAMassFlow, // mass flow rate of outdoor air
17288 : Real64 &FanSpdRatio, // fan speed ratio: actual flow rate / rated flow rate
17289 : Real64 &Wout, // outlet air humidity ratio
17290 : Real64 &Tout, // outlet air temperature
17291 : Real64 &Hout, // outlet air enthalpy
17292 : Real64 &SHact, // actual SH
17293 : Real64 &SCact // actual SC
17294 : )
17295 : {
17296 : // SUBROUTINE INFORMATION:
17297 : // AUTHOR Xiufeng Pang, LBNL
17298 : // DATE WRITTEN Feb 2013
17299 : // MODIFIED Nov 2015, RP Zhang, LBNL
17300 : //
17301 : // PURPOSE OF THIS SUBROUTINE:
17302 : // Analyze the VRF Indoor Unit operations given coil loads.
17303 : // Calculated parameters include: (1) Fan Speed Ratio (2) SH/SC, (3) Coil Outlet conditions
17304 : //
17305 : // METHODOLOGY EMPLOYED:
17306 : // A new physics based VRF model applicable for Fluid Temperature Control.
17307 : //
17308 : // USE STATEMENTS:
17309 : using Psychrometrics::PsyHFnTdbW;
17310 :
17311 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
17312 1846744 : int MaxIter(500); // Max iteration numbers (-)
17313 : int SolFla; // Solving flag for SolveRoot (-)
17314 1846744 : int constexpr FlagCoolMode(0); // Flag for cooling mode
17315 1846744 : int constexpr FlagHeatMode(1); // Flag for heating mode
17316 : Real64 BF; // Bypass factor (-)
17317 : Real64 C1Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17318 : Real64 C2Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17319 : Real64 C3Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17320 : Real64 C1Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17321 : Real64 C2Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17322 : Real64 C3Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17323 : Real64 CoilOnOffRatio; // coil on/off ratio: time coil is on divided by total time
17324 : Real64 deltaT; // Difference between evaporating/condensing temperature and coil surface temperature (C)
17325 : Real64 FanSpdRatioMin; // Min fan speed ratio, below which the cycling will be activated (-)
17326 : Real64 FanSpdRatioMax; // Max fan speed ratio (-)
17327 : Real64 Garate; // Nominal air mass flow rate (m3/s)
17328 : Real64 MaxSH; // Max super heating degrees (C)
17329 : Real64 MaxSC; // Max subcooling degrees (C)
17330 : Real64 QinSenMin1; // Coil capacity at minimum fan speed, corresponding to real SH (W)
17331 : Real64 QinSenMin2; // Coil capacity at minimum fan speed, corresponding to corresponds maximum SH (W)
17332 : Real64 QinSenPerFlowRate; // Coil capacity per air mass flow rate(W-s/kg)
17333 : Real64 QCoilSenCoolingLoad; // Coil sensible cooling load (W)
17334 : Real64 QCoilSenHeatingLoad; // Coil sensible heating load (W)
17335 : Real64 Ratio1; // Fan speed ratio (-)
17336 : Real64 RHsat; // Relative humidity of the air at saturated condition(-)
17337 : Real64 SH; // Super heating degrees (C)
17338 : Real64 SC; // Subcooling degrees (C)
17339 : Real64 Ts_1; // Air temperature at the coil surface, corresponding to SH (C)
17340 : Real64 Ts_2; // Air temperature at the coil surface, corresponding to MaxSH (C)
17341 : Real64 To_1; // Air temperature at the coil outlet, corresponding to SH (C)
17342 : Real64 To_2; // Air temperature at the coil outlet, corresponding to MaxSH (C)
17343 : Real64 Ts; // Air temperature at the coil surface (C)
17344 : Real64 Ws; // Air humidity ratio at the coil surface (kg/kg)
17345 :
17346 1846744 : RHsat = 0.98; // Saturated RH
17347 1846744 : MaxSH = 15;
17348 1846744 : MaxSC = 20;
17349 1846744 : Garate = state.dataDXCoils->DXCoil(CoilIndex).RatedAirMassFlowRate(1);
17350 : // why always limit the minimum fan speed ratio to 0.65?
17351 1846744 : FanSpdRatioMin = min(max(OAMassFlow / Garate, 0.65), 1.0); // ensure that coil flow rate is higher than OA flow rate
17352 :
17353 1846744 : if (QCoil == 0) {
17354 : // No Heating or Cooling
17355 0 : FanSpdRatio = OAMassFlow / Garate;
17356 0 : CoilOnOffRatio = 0.0;
17357 :
17358 0 : SHact = 999.0;
17359 0 : SCact = 999.0;
17360 0 : Tout = Tin;
17361 0 : Hout = PsyHFnTdbW(Tin, Win);
17362 0 : Wout = Win;
17363 :
17364 1846744 : } else if (QCoil < 0) {
17365 : // Cooling Mode
17366 :
17367 : // Obtain coil cooling loads
17368 1293837 : QCoilSenCoolingLoad = -QCoil;
17369 :
17370 : // Coefficients describing coil performance
17371 1293837 : SH = state.dataDXCoils->DXCoil(CoilIndex).SH;
17372 1293837 : C1Tevap = state.dataDXCoils->DXCoil(CoilIndex).C1Te;
17373 1293837 : C2Tevap = state.dataDXCoils->DXCoil(CoilIndex).C2Te;
17374 1293837 : C3Tevap = state.dataDXCoils->DXCoil(CoilIndex).C3Te;
17375 1293837 : BF = state.dataDXCoils->DXCoil(CoilIndex).RateBFVRFIUEvap;
17376 :
17377 : // Coil sensible heat transfer_minimum value
17378 1293837 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilIndex, Tin, TeTc, SH, BF, QinSenPerFlowRate, Ts_1);
17379 1293837 : To_1 = Tin - QinSenPerFlowRate / 1005;
17380 1293837 : QinSenMin1 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds real SH
17381 :
17382 1293837 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilIndex, Tin, TeTc, MaxSH, BF, QinSenPerFlowRate, Ts_2);
17383 1293837 : To_2 = Tin - QinSenPerFlowRate / 1005;
17384 1293837 : QinSenMin2 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds maximum SH
17385 :
17386 1293837 : if (QCoilSenCoolingLoad > QinSenMin1) {
17387 : // Increase fan speed to meet room sensible load; SH is not updated
17388 784204 : FanSpdRatioMax = 1.0;
17389 2053140 : auto f = [QCoilSenCoolingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
17390 2053140 : return FanSpdResidualCool(FanSpdRto, QCoilSenCoolingLoad, Ts_1, Tin, Garate, BF);
17391 784204 : };
17392 784204 : General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, Ratio1, f, FanSpdRatioMin, FanSpdRatioMax);
17393 784204 : if (SolFla < 0) Ratio1 = FanSpdRatioMax; // over capacity
17394 784204 : FanSpdRatio = Ratio1;
17395 784204 : CoilOnOffRatio = 1.0;
17396 :
17397 784204 : Tout = To_1; // Since SH is not updated
17398 784204 : Ws = PsyWFnTdbRhPb(state, Ts_1, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
17399 784204 : if (Ws < Win) {
17400 779645 : Wout = Win - (Win - Ws) * (1 - BF);
17401 : } else {
17402 4559 : Wout = Win;
17403 : }
17404 784204 : Hout = PsyHFnTdbW(Tout, Wout);
17405 784204 : SCact = 999.0;
17406 784204 : SHact = SH;
17407 :
17408 : } else {
17409 : // Low load modification algorithm
17410 : // Need to increase SH to further reduce coil capacity
17411 : // May further implement coil cycling control if SC modification is not enough
17412 :
17413 509633 : FanSpdRatio = FanSpdRatioMin;
17414 :
17415 509633 : CoilOnOffRatio = 1.0;
17416 :
17417 509633 : Tout = Tin - QCoilSenCoolingLoad / 1005.0 / FanSpdRatioMin / Garate;
17418 509633 : Ts = Tin - (Tin - Tout) / (1 - BF);
17419 509633 : deltaT = Ts - TeTc;
17420 :
17421 : // Update SH
17422 509633 : if (C3Tevap <= 0.0) {
17423 507605 : if (C2Tevap > 0.0) {
17424 507605 : SHact = (deltaT - C1Tevap) / C2Tevap;
17425 : } else {
17426 0 : SHact = 998.0;
17427 : }
17428 : } else {
17429 2028 : SHact = (-C2Tevap + sqrt(pow_2(C2Tevap) - 4 * C3Tevap * (C1Tevap - deltaT))) / 2 / C3Tevap;
17430 : }
17431 :
17432 509633 : Ws = PsyWFnTdbRhPb(state, Ts, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
17433 509633 : if (Ws < Win) {
17434 340869 : Wout = Win - (Win - Ws) * (1 - BF);
17435 : } else {
17436 168764 : Wout = Win;
17437 : }
17438 :
17439 509633 : if (SHact > MaxSH) {
17440 : // Further implement On/Off Control
17441 141368 : SHact = MaxSH;
17442 141368 : CoilOnOffRatio = QCoilSenCoolingLoad / QinSenMin2;
17443 :
17444 141368 : Ts = Ts_2;
17445 141368 : Ws = PsyWFnTdbRhPb(state, Ts, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
17446 141368 : if (Ws < Win) {
17447 128867 : Wout = Win - (Win - Ws) * (1 - BF);
17448 : } else {
17449 12501 : Wout = Win;
17450 : }
17451 :
17452 : // outlet air temperature and humidity ratio is time-weighted
17453 141368 : Tout = CoilOnOffRatio * To_2 + (1 - CoilOnOffRatio) * Tin;
17454 141368 : Wout = CoilOnOffRatio * Wout + (1 - CoilOnOffRatio) * Win;
17455 : }
17456 :
17457 509633 : Hout = PsyHFnTdbW(Tout, Wout);
17458 509633 : SCact = 999.0;
17459 : }
17460 :
17461 552907 : } else if (QCoil > 0) {
17462 : // Heating Mode
17463 :
17464 : // Obtain zonal heating loads
17465 552907 : QCoilSenHeatingLoad = QCoil;
17466 :
17467 : // Coefficients describing coil performance
17468 552907 : SC = state.dataDXCoils->DXCoil(CoilIndex).SC;
17469 552907 : C1Tcond = state.dataDXCoils->DXCoil(CoilIndex).C1Tc;
17470 552907 : C2Tcond = state.dataDXCoils->DXCoil(CoilIndex).C2Tc;
17471 552907 : C3Tcond = state.dataDXCoils->DXCoil(CoilIndex).C3Tc;
17472 552907 : BF = state.dataDXCoils->DXCoil(CoilIndex).RateBFVRFIUCond;
17473 :
17474 : // Coil sensible heat transfer_minimum value
17475 552907 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilIndex, Tin, TeTc, SC, BF, QinSenPerFlowRate, Ts_1);
17476 552907 : To_1 = QinSenPerFlowRate / 1005 + Tin;
17477 552907 : QinSenMin1 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds real SH
17478 :
17479 552907 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilIndex, Tin, TeTc, MaxSC, BF, QinSenPerFlowRate, Ts_2);
17480 552907 : To_2 = QinSenPerFlowRate / 1005 + Tin;
17481 552907 : QinSenMin2 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds maximum SH
17482 :
17483 552907 : if (QCoilSenHeatingLoad > QinSenMin1) {
17484 : // Modulate fan speed to meet room sensible load; SC is not updated
17485 134083 : FanSpdRatioMax = 1.0;
17486 363165 : auto f = [QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
17487 363165 : return FanSpdResidualHeat(FanSpdRto, QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF);
17488 134083 : };
17489 134083 : General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, Ratio1, f, FanSpdRatioMin, FanSpdRatioMax);
17490 : // this will likely cause problems eventually, -1 and -2 mean different things
17491 134083 : if (SolFla < 0) Ratio1 = FanSpdRatioMax; // over capacity
17492 134083 : FanSpdRatio = Ratio1;
17493 134083 : CoilOnOffRatio = 1.0;
17494 :
17495 134083 : Tout = Tin + (Ts_1 - Tin) * (1 - BF);
17496 134083 : Wout = Win;
17497 134083 : Hout = PsyHFnTdbW(Tout, Wout);
17498 134083 : SHact = 999.0;
17499 134083 : SCact = SC;
17500 :
17501 : } else {
17502 : // Low load modification algorithm
17503 : // Need to increase SC to further reduce coil heating capacity
17504 : // May further implement coil cycling control if SC modification is not enough
17505 :
17506 418824 : FanSpdRatio = FanSpdRatioMin;
17507 418824 : CoilOnOffRatio = 1.0;
17508 :
17509 418824 : Tout = Tin + QCoilSenHeatingLoad / 1005.0 / FanSpdRatio / Garate;
17510 418824 : Ts = Tin + (Tout - Tin) / (1 - BF);
17511 418824 : deltaT = TeTc - Ts;
17512 :
17513 : // Update SC
17514 418824 : if (C3Tcond <= 0.0) {
17515 0 : if (C2Tcond > 0.0) {
17516 0 : SCact = (deltaT - C1Tcond) / C2Tcond;
17517 : } else {
17518 0 : SCact = 998.0;
17519 : }
17520 : } else {
17521 418824 : SCact = (-C2Tcond + sqrt(pow_2(C2Tcond) - 4 * C3Tcond * (C1Tcond - deltaT))) / 2 / C3Tcond;
17522 : }
17523 :
17524 418824 : if (SCact > MaxSC) {
17525 : // Implement On/Off Control
17526 271995 : SCact = MaxSC;
17527 271995 : CoilOnOffRatio = QCoilSenHeatingLoad / QinSenMin2;
17528 : // outlet air temperature is time-weighted
17529 271995 : Tout = CoilOnOffRatio * To_2 + (1 - CoilOnOffRatio) * Tin;
17530 : }
17531 418824 : Wout = Win;
17532 418824 : Hout = PsyHFnTdbW(Tout, Wout);
17533 418824 : SHact = 999.0;
17534 : }
17535 : }
17536 1846744 : }
17537 :
17538 3693520 : void CalcVRFCoilSenCap(EnergyPlusData &state,
17539 : int const OperationMode, // mode 0 for cooling, 1 for heating
17540 : int const CoilNum, // index to VRFTU cooling or heating coil
17541 : Real64 const Tinlet, // dry bulb temperature of air entering the coil
17542 : Real64 const TeTc, // evaporating or condensing temperature
17543 : Real64 const SHSC, // SH at cooling /SC at heating
17544 : Real64 const BF, // Bypass factor
17545 : Real64 &Q_sen, // VRF coil sensible capacity per air mass flow rate
17546 : Real64 &T_coil_surf // Air temperature at coil surface
17547 : )
17548 : {
17549 : // SUBROUTINE INFORMATION:
17550 : // AUTHOR Rongpeng Zhang, LBNL
17551 : // DATE WRITTEN Jul 2015
17552 : //
17553 : // PURPOSE OF THIS SUBROUTINE:
17554 : // Calculate the VRF coil sensible capacity per air mass flow rate, given:
17555 : // (1) refrigerant temperature (Te or Tc), (2) SH or SC, and (3) inlet air temperature.
17556 : //
17557 : // METHODOLOGY EMPLOYED:
17558 : // A new physics based VRF model appliable for Fluid Temperature Control.
17559 : //
17560 :
17561 3693520 : int constexpr FlagCoolMode(0); // Flag for cooling mode
17562 3693520 : int constexpr FlagHeatMode(1); // Flag for heating mode
17563 : Real64 C1Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17564 : Real64 C2Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17565 : Real64 C3Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17566 : Real64 C1Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17567 : Real64 C2Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17568 : Real64 C3Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17569 : Real64 deltaT; // Difference between Te/Tc and coil surface temperature (C)
17570 : Real64 SH; // Super heating at cooling mode(C)
17571 : Real64 SC; // Subcooling at heating mode (C)
17572 : Real64 T_coil_in; // Air temperature at coil inlet (C)
17573 : Real64 T_coil_out; // Air temperature at coil outlet (C)
17574 :
17575 3693520 : if (OperationMode == FlagCoolMode) {
17576 : // Cooling: OperationMode 0
17577 :
17578 2587706 : C1Tevap = state.dataDXCoils->DXCoil(CoilNum).C1Te;
17579 2587706 : C2Tevap = state.dataDXCoils->DXCoil(CoilNum).C2Te;
17580 2587706 : C3Tevap = state.dataDXCoils->DXCoil(CoilNum).C3Te;
17581 2587706 : SH = SHSC;
17582 2587706 : T_coil_in = Tinlet;
17583 :
17584 : // Coil surface temperature
17585 2587706 : deltaT = C3Tevap * SH * SH + C2Tevap * SH + C1Tevap;
17586 2587706 : T_coil_surf = TeTc + deltaT;
17587 :
17588 : // Outlet air temperature
17589 2587706 : T_coil_out = T_coil_in - (T_coil_in - T_coil_surf) * (1 - BF);
17590 :
17591 : // Coil sensilbe heat transfer per mass flow rate
17592 2587706 : Q_sen = max(1005 * (T_coil_in - T_coil_out), 0.0);
17593 :
17594 1105814 : } else if (OperationMode == FlagHeatMode) {
17595 : // Heating: OperationMode 1
17596 :
17597 1105814 : C1Tcond = state.dataDXCoils->DXCoil(CoilNum).C1Tc;
17598 1105814 : C2Tcond = state.dataDXCoils->DXCoil(CoilNum).C2Tc;
17599 1105814 : C3Tcond = state.dataDXCoils->DXCoil(CoilNum).C3Tc;
17600 1105814 : SC = SHSC;
17601 1105814 : T_coil_in = Tinlet;
17602 :
17603 : // Coil surface temperature
17604 1105814 : deltaT = C3Tcond * SC * SC + C2Tcond * SC + C1Tcond;
17605 1105814 : T_coil_surf = TeTc - deltaT;
17606 :
17607 : // Coil outlet air temperature
17608 1105814 : T_coil_out = T_coil_in + (T_coil_surf - T_coil_in) * (1 - BF);
17609 :
17610 : // Coil sensilbe heat transfer_minimum value
17611 1105814 : Q_sen = max(1005 * (T_coil_out - T_coil_in), 0.0);
17612 : }
17613 3693520 : }
17614 :
17615 16 : void CalcVRFCoilCapModFac(EnergyPlusData &state,
17616 : int const OperationMode, // mode 0 for cooling, 1 for heating
17617 : ObjexxFCL::Optional<int const> CoilIndex, // index to VRFTU cooling or heating coil
17618 : ObjexxFCL::Optional<std::string> CoilName, // name of VRFTU cooling or heating coil
17619 : Real64 const Tinlet, // dry bulb temperature of air entering the coil
17620 : ObjexxFCL::Optional<Real64 const> TeTc, // evaporating or condensing temperature
17621 : ObjexxFCL::Optional<Real64 const> SHSC, // SH at cooling /SC at heating
17622 : ObjexxFCL::Optional<Real64 const> BF, // Bypass factor
17623 : Real64 &CapModFac // Coil capacity modification factor
17624 : )
17625 : {
17626 : // SUBROUTINE INFORMATION:
17627 : // AUTHOR Rongpeng Zhang, LBNL
17628 : // DATE WRITTEN Jul 2015
17629 : //
17630 : // PURPOSE OF THIS SUBROUTINE:
17631 : // Calculate the VRF coil capacity modification factor, which is the ratio of
17632 : // the capacity at real conditions and that at rated conditions.
17633 : // This is used for the coil sizing subroutine.
17634 : //
17635 : // METHODOLOGY EMPLOYED:
17636 : // A new physics based VRF model applicable for Fluid Temperature Control.
17637 : //
17638 :
17639 16 : bool ErrorsFound(false); // Flag for errors
17640 16 : int constexpr FlagCoolMode(0); // Flag for cooling mode
17641 16 : int constexpr FlagHeatMode(1); // Flag for heating mode
17642 16 : Real64 constexpr SH_rate(3); // Super heating at cooling mode, default 3(C)
17643 16 : Real64 constexpr SC_rate(5); // Subcooling at heating mode, default 5 (C)
17644 16 : Real64 constexpr Te_rate(6); // Evaporating temperature at cooling mode, default 6 (C)
17645 16 : Real64 constexpr Tc_rate(44); // Condensing temperature at heating mode, default 44 (C)
17646 : int CoilNum; // index to VRFTU cooling or heating coil
17647 : Real64 BF_real; // Bypass factor (-)
17648 : Real64 BFC_rate; // Bypass factor at cooling mode (-)
17649 : Real64 BFH_rate; // Bypass factor at heating mode (-)
17650 : Real64 SHSC_real; // Super heating or Subcooling (C)
17651 : Real64 TeTc_real; // Evaporating temperature or condensing temperature (C)
17652 : Real64 Ts; // Air temperature at coil surface (C)
17653 : Real64 Q_real; // Coil capacity at given condition (W)
17654 : Real64 Q_rate; // Coil capacity at rated condition (W)
17655 :
17656 16 : if (present(CoilIndex)) {
17657 0 : CoilNum = CoilIndex;
17658 : } else {
17659 16 : GetDXCoilIndex(state, CoilName, CoilNum, ErrorsFound, "", true);
17660 : }
17661 :
17662 16 : BFC_rate = state.dataDXCoils->DXCoil(CoilNum).RateBFVRFIUEvap;
17663 16 : BFH_rate = state.dataDXCoils->DXCoil(CoilNum).RateBFVRFIUCond;
17664 :
17665 16 : if (OperationMode == FlagCoolMode) {
17666 : // Cooling: OperationMode 0
17667 :
17668 16 : if (present(BF)) {
17669 0 : BF_real = BF;
17670 : } else {
17671 16 : BF_real = BFC_rate;
17672 : }
17673 16 : if (present(TeTc)) {
17674 0 : TeTc_real = TeTc;
17675 : } else {
17676 16 : TeTc_real = Te_rate;
17677 : }
17678 16 : if (present(SHSC)) {
17679 0 : SHSC_real = SHSC;
17680 : } else {
17681 16 : SHSC_real = SH_rate;
17682 : }
17683 :
17684 : // Coil capacity at rated conditions
17685 16 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilNum, 26, Te_rate, SH_rate, BFC_rate, Q_rate, Ts);
17686 :
17687 : // Coil capacity at given conditions
17688 16 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilNum, Tinlet, TeTc_real, SHSC_real, BF_real, Q_real, Ts);
17689 :
17690 16 : if (Q_rate > 0) {
17691 16 : CapModFac = Q_real / Q_rate;
17692 : } else {
17693 0 : CapModFac = 1.0;
17694 : }
17695 :
17696 0 : } else if (OperationMode == FlagHeatMode) {
17697 : // Heating: OperationMode 1
17698 :
17699 0 : if (present(BF)) {
17700 0 : BF_real = BF;
17701 : } else {
17702 0 : BF_real = BFH_rate;
17703 : }
17704 0 : if (present(TeTc)) {
17705 0 : TeTc_real = TeTc;
17706 : } else {
17707 0 : TeTc_real = Tc_rate;
17708 : }
17709 0 : if (present(SHSC)) {
17710 0 : SHSC_real = SHSC;
17711 : } else {
17712 0 : SHSC_real = SC_rate;
17713 : }
17714 :
17715 : // Coil capacity at rated conditions
17716 0 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilNum, 20, Tc_rate, SC_rate, BFH_rate, Q_rate, Ts);
17717 :
17718 : // Coil capacity at given conditions
17719 0 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilNum, Tinlet, TeTc_real, SHSC_real, BF_real, Q_real, Ts);
17720 :
17721 0 : if (Q_rate > 0) {
17722 0 : CapModFac = Q_real / Q_rate;
17723 : } else {
17724 0 : CapModFac = 1.0;
17725 : }
17726 : }
17727 16 : }
17728 :
17729 2053140 : Real64 FanSpdResidualCool(
17730 : Real64 const FanSpdRto, Real64 const QCoilSenCoolingLoad, Real64 const Ts_1, Real64 const Tin, Real64 const Garate, Real64 const BF)
17731 : {
17732 : // FUNCTION INFORMATION:
17733 : // AUTHOR Xiufeng Pang (XP)
17734 : // DATE WRITTEN Mar 2013
17735 : // MODIFIED Nov 2015, RP Zhang, LBNL
17736 : //
17737 : // PURPOSE OF THIS FUNCTION:
17738 : // Calculates residual function (desired zone cooling load - actual coil cooling capacity)
17739 : // This is used to modify the fan speed to adjust the coil cooling capacity to match
17740 : // the zone cooling load.
17741 : //
17742 2053140 : Real64 ZnSenLoad = QCoilSenCoolingLoad;
17743 : // +-100 W minimum zone load?
17744 2053140 : if (std::abs(ZnSenLoad) < 100.0) ZnSenLoad = sign(100.0, ZnSenLoad);
17745 2053140 : Real64 Tout = Tin - (Tin - Ts_1) * (1 - BF);
17746 2053140 : Real64 TotCap = FanSpdRto * Garate * 1005.0 * (Tin - Tout);
17747 2053140 : return (TotCap - ZnSenLoad) / ZnSenLoad;
17748 : }
17749 :
17750 363165 : Real64 FanSpdResidualHeat(Real64 FanSpdRto, Real64 QCoilSenHeatingLoad, Real64 Ts_1, Real64 Tin, Real64 Garate, Real64 BF)
17751 : {
17752 :
17753 : // FUNCTION INFORMATION:
17754 : // AUTHOR Xiufeng Pang (XP)
17755 : // DATE WRITTEN Mar 2013
17756 : // MODIFIED Nov 2015, RP Zhang, LBNL
17757 : //
17758 : // PURPOSE OF THIS FUNCTION:
17759 : // Calculates residual function (desired zone heating load - actual heating coil capacity)
17760 : // This is used to modify the fan speed to adjust the coil heating capacity to match
17761 : // the zone heating load.
17762 : //
17763 :
17764 363165 : Real64 ZnSenLoad = QCoilSenHeatingLoad;
17765 : // +-100 W minimum zone load?
17766 363165 : if (std::abs(ZnSenLoad) < 100.0) ZnSenLoad = sign(100.0, ZnSenLoad);
17767 363165 : Real64 Tout = Tin + (Ts_1 - Tin) * (1 - BF);
17768 363165 : Real64 TotCap = FanSpdRto * Garate * 1005.0 * (Tout - Tin);
17769 363165 : return (TotCap - ZnSenLoad) / ZnSenLoad;
17770 : }
17771 :
17772 0 : void SetMSHPDXCoilHeatRecoveryFlag(EnergyPlusData &state, int const DXCoilNum)
17773 : {
17774 :
17775 : // SUBROUTINE INFORMATION:
17776 : // AUTHOR L. Gu
17777 : // DATE WRITTEN Sep. 2015
17778 :
17779 : // PURPOSE OF THIS SUBROUTINE:
17780 : // Set the heat recovery flag true when the parent object requests heat recovery.
17781 :
17782 0 : if (state.dataDXCoils->DXCoil(DXCoilNum).FuelType != Constant::eFuel::Electricity) {
17783 0 : state.dataDXCoils->DXCoil(DXCoilNum).MSHPHeatRecActive = true;
17784 : }
17785 0 : }
17786 :
17787 32 : void SetDXCoilAirLoopNumber(EnergyPlusData &state, std::string const &CoilName, int const AirLoopNum)
17788 : {
17789 : // SUBROUTINE INFORMATION:
17790 : // AUTHOR L. Gu
17791 : // DATE WRITTEN March, 2018
17792 :
17793 : // PURPOSE OF THIS SUBROUTINE:
17794 : // Set AirLoopNum for AFN model with multiple AirLoops
17795 :
17796 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
17797 : int WhichCoil;
17798 :
17799 32 : if (state.dataDXCoils->GetCoilsInputFlag) {
17800 0 : GetDXCoils(state);
17801 0 : state.dataDXCoils->GetCoilsInputFlag = false;
17802 : }
17803 :
17804 32 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
17805 32 : if (WhichCoil != 0) {
17806 32 : state.dataDXCoils->DXCoil(WhichCoil).AirLoopNum = AirLoopNum;
17807 : } else {
17808 0 : ShowSevereError(state, format("SetDXCoilAirLoopNumber: Could not find Coil \"Name=\"{}\"", CoilName));
17809 : }
17810 32 : } // must match coil names for the coil type
17811 :
17812 1 : void DisableLatentDegradation(EnergyPlusData &state, int const DXCoilNum)
17813 : {
17814 : // SUBROUTINE INFORMATION:
17815 : // AUTHOR L. Gu
17816 : // DATE WRITTEN JUne, 2019
17817 :
17818 : // PURPOSE OF THIS SUBROUTINE:
17819 : // Disable latent degradation when direct solution is used.
17820 :
17821 1 : state.dataDXCoils->DXCoil(DXCoilNum).Twet_Rated(1) = 0.0;
17822 1 : }
17823 :
17824 : } // namespace EnergyPlus::DXCoils
|