Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <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 : // Functions
127 :
128 521504 : void SimDXCoil(EnergyPlusData &state,
129 : std::string_view CompName, // name of the fan coil unit
130 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
131 : bool const FirstHVACIteration, // True when first HVAC iteration
132 : int &CompIndex,
133 : HVAC::FanOp const fanOp, // allows parent object to control fan mode
134 : ObjexxFCL::Optional<Real64 const> PartLoadRatio, // part load ratio (for single speed cycling unit)
135 : ObjexxFCL::Optional<Real64 const> OnOffAFR, // ratio of compressor on airflow to compressor off airflow
136 : ObjexxFCL::Optional<Real64 const> CoilCoolingHeatingPLRRatio, // used for cycling fan RH control
137 : ObjexxFCL::Optional<Real64 const> MaxCap, // maximum cooling capacity of VRF terminal units
138 : ObjexxFCL::Optional<Real64 const> CompCyclingRatio // cycling ratio of VRF condenser connected to this TU
139 : )
140 : {
141 :
142 : // SUBROUTINE INFORMATION:
143 : // AUTHOR Fred Buhl
144 : // DATE WRITTEN May 2000
145 : // MODIFIED Don Shirey, Sept 2000, October 2001, June 2005
146 :
147 : // PURPOSE OF THIS SUBROUTINE:
148 : // Manages the simulation of a single speed on/off DX coil.
149 :
150 : // Using/Aliasing
151 :
152 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
153 : int DXCoilNum; // index of fan coil unit being simulated
154 : Real64 AirFlowRatio; // ratio of compressor on airflow to compressor off airflow
155 : Real64 CompCycRatio; // compressor cycling ratio of VRF condenser
156 :
157 : // First time SimDXCoil is called, get the input for all the DX coils (condensing units)
158 521504 : if (state.dataDXCoils->GetCoilsInputFlag) {
159 0 : GetDXCoils(state);
160 0 : state.dataDXCoils->GetCoilsInputFlag = false; // Set GetInputFlag false so you don't get coil inputs again
161 : }
162 :
163 521504 : if (CompIndex == 0) {
164 7 : DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
165 7 : if (DXCoilNum == 0) {
166 0 : ShowFatalError(state, format("DX Coil not found={}", CompName));
167 : }
168 7 : CompIndex = DXCoilNum;
169 : } else {
170 521497 : DXCoilNum = CompIndex;
171 521497 : if (DXCoilNum > state.dataDXCoils->NumDXCoils || DXCoilNum < 1) {
172 0 : ShowFatalError(state,
173 0 : format("SimDXCoil: Invalid CompIndex passed={}, Number of DX Coils={}, Coil name={}",
174 : DXCoilNum,
175 0 : state.dataDXCoils->NumDXCoils,
176 : CompName));
177 : }
178 521497 : if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
179 86 : if (!CompName.empty() && CompName != state.dataDXCoils->DXCoil(DXCoilNum).Name) {
180 0 : ShowFatalError(state,
181 0 : format("SimDXCoil: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
182 : DXCoilNum,
183 : CompName,
184 0 : state.dataDXCoils->DXCoil(DXCoilNum).Name));
185 : }
186 86 : state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
187 : }
188 : }
189 :
190 521504 : if (present(OnOffAFR)) {
191 414840 : AirFlowRatio = OnOffAFR;
192 : } else {
193 106664 : AirFlowRatio = 1.0;
194 : }
195 :
196 521504 : if (present(CompCyclingRatio)) {
197 38582 : CompCycRatio = CompCyclingRatio;
198 : } else {
199 482922 : CompCycRatio = 1.0;
200 : }
201 :
202 : // Initialize the DX coil unit
203 521504 : InitDXCoil(state, DXCoilNum);
204 :
205 : // Select the correct unit type
206 521504 : switch (state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType_Num) { // Autodesk:OPTIONAL PartLoadRatio, MaxCap used in this block without PRESENT check
207 247087 : case HVAC::CoilDX_CoolingSingleSpeed: {
208 247087 : if (present(CoilCoolingHeatingPLRRatio)) {
209 59945 : CalcDoe2DXCoil(state, DXCoilNum, compressorOp, FirstHVACIteration, PartLoadRatio, fanOp, _, AirFlowRatio, CoilCoolingHeatingPLRRatio);
210 : } else {
211 187142 : CalcDoe2DXCoil(state, DXCoilNum, compressorOp, FirstHVACIteration, PartLoadRatio, fanOp, _, AirFlowRatio);
212 : }
213 247087 : } break;
214 127966 : case HVAC::CoilDX_HeatingEmpirical: {
215 127966 : CalcDXHeatingCoil(state, DXCoilNum, PartLoadRatio, fanOp, AirFlowRatio);
216 127966 : } break;
217 161 : case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
218 : case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
219 : // call the HPWHDXCoil routine to calculate water side performance set up the DX coil info for air-side calcs
220 161 : CalcHPWHDXCoil(state, DXCoilNum, PartLoadRatio);
221 : // CALL CalcDoe2DXCoil(state, DXCoilNum, compressorOp, FirstHVACIteration,PartLoadRatio), perform air-side calculations
222 161 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp);
223 161 : } break;
224 49492 : case HVAC::CoilVRF_Cooling: {
225 49492 : CalcVRFCoolingCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, CompCycRatio, _, AirFlowRatio, MaxCap);
226 49492 : } break;
227 49492 : case HVAC::CoilVRF_Heating: {
228 49492 : CalcDXHeatingCoil(state, DXCoilNum, PartLoadRatio, fanOp, AirFlowRatio, MaxCap);
229 49492 : } break;
230 23653 : case HVAC::CoilVRF_FluidTCtrl_Cooling: {
231 23653 : CalcVRFCoolingCoil_FluidTCtrl(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, CompCycRatio, _, _, MaxCap);
232 23653 : } break;
233 23653 : case HVAC::CoilVRF_FluidTCtrl_Heating: {
234 23653 : CalcVRFHeatingCoil_FluidTCtrl(state, compressorOp, DXCoilNum, PartLoadRatio, fanOp, _, MaxCap);
235 23653 : } break;
236 0 : default: {
237 0 : ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
238 0 : ShowContinueError(state, format("Invalid DX Coil Type={}", state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType));
239 0 : ShowFatalError(state, "Preceding condition causes termination.");
240 0 : } break;
241 : }
242 :
243 : // Update the unit outlet nodes
244 521504 : UpdateDXCoil(state, DXCoilNum);
245 :
246 : // Report the result of the simulation
247 521504 : ReportDXCoil(state, DXCoilNum);
248 521504 : }
249 :
250 17558 : void SimDXCoilMultiSpeed(EnergyPlusData &state,
251 : std::string_view CompName, // name of the fan coil unit
252 : Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) /
253 : Real64 const CycRatio, // cycling part load ratio for variable speed
254 : int &CompIndex,
255 : ObjexxFCL::Optional_int_const SpeedNum, // Speed number for multispeed cooling coil only
256 : ObjexxFCL::Optional<HVAC::FanOp const> fanOp, // Fan operation mode
257 : HVAC::CompressorOp compressorOp, // Compressor on/off; 1=on, 0=off
258 : ObjexxFCL::Optional_int_const SingleMode // Single mode operation Yes/No; 1=Yes, 0=No
259 : )
260 : {
261 :
262 : // SUBROUTINE INFORMATION:
263 : // AUTHOR Fred Buhl
264 : // DATE WRITTEN September 2002
265 : // MODIFIED Lixing Gu, Sep. 2007
266 :
267 : // PURPOSE OF THIS SUBROUTINE:
268 : // Manages the simulation of a multi speed DX coil.
269 :
270 : // Using/Aliasing
271 :
272 : // Locals
273 : // SUBROUTINE ARGUMENT DEFINITIONS:
274 : // (CompressorSpeedMax - CompressorSpeedMin)
275 : // for variable speed or 2 speed compressors
276 : // or 2 speed compressors
277 :
278 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
279 : int DXCoilNum; // index of fan coil unit being simulated
280 : int SingleModeOper; // SingleMode Operation
281 :
282 : // First time SimDXCoil is called, get the input for all the DX coils (condensing units)
283 17558 : if (state.dataDXCoils->GetCoilsInputFlag) {
284 0 : GetDXCoils(state);
285 0 : state.dataDXCoils->GetCoilsInputFlag = false; // Set GetInputFlag false so you don't get coil inputs again
286 : }
287 :
288 : // find correct DX Coil
289 :
290 17558 : if (CompIndex == 0) {
291 0 : DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
292 0 : if (DXCoilNum == 0) {
293 0 : ShowFatalError(state, format("DX Coil not found={}", CompName));
294 : }
295 0 : CompIndex = DXCoilNum;
296 : } else {
297 17558 : DXCoilNum = CompIndex;
298 17558 : if (DXCoilNum > state.dataDXCoils->NumDXCoils || DXCoilNum < 1) {
299 0 : ShowFatalError(state,
300 0 : format("SimDXCoilMultiSpeed: Invalid CompIndex passed={}, Number of DX Coils={}, Coil name={}",
301 : DXCoilNum,
302 0 : state.dataDXCoils->NumDXCoils,
303 : CompName));
304 : }
305 17558 : if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
306 17 : if (!CompName.empty() && CompName != state.dataDXCoils->DXCoil(DXCoilNum).Name) {
307 0 : ShowFatalError(state,
308 0 : format("SimDXCoilMultiSpeed: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
309 : DXCoilNum,
310 : CompName,
311 0 : state.dataDXCoils->DXCoil(DXCoilNum).Name));
312 : }
313 17 : state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
314 : }
315 : }
316 :
317 17558 : if (present(SingleMode)) {
318 212 : SingleModeOper = SingleMode;
319 : } else {
320 17346 : SingleModeOper = 0;
321 : }
322 :
323 : // Initialize the DX coil unit
324 17558 : InitDXCoil(state, DXCoilNum);
325 :
326 : // Select the correct unit type
327 17558 : switch (state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType_Num) {
328 17109 : case HVAC::CoilDX_CoolingTwoSpeed: {
329 17109 : CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio);
330 17109 : } break;
331 250 : case HVAC::CoilDX_MultiSpeedCooling: {
332 250 : if (present(SpeedNum))
333 250 : CalcMultiSpeedDXCoilCooling(state,
334 : DXCoilNum,
335 : SpeedRatio,
336 : CycRatio,
337 : SpeedNum,
338 : fanOp,
339 : compressorOp,
340 : SingleModeOper); // Autodesk:OPTIONAL fanOp, CompressorOp used without PRESENT check
341 :
342 250 : } break;
343 199 : case HVAC::CoilDX_MultiSpeedHeating: {
344 199 : if (present(SpeedNum))
345 199 : CalcMultiSpeedDXCoilHeating(state,
346 : DXCoilNum,
347 : SpeedRatio,
348 : CycRatio,
349 : SpeedNum,
350 : fanOp,
351 : SingleModeOper); // Autodesk:OPTIONAL fanOp used without PRESENT check
352 :
353 199 : } break;
354 0 : default: {
355 0 : ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
356 0 : ShowContinueError(state, format("Invalid DX Coil Type={}", state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType));
357 0 : ShowFatalError(state, "Preceding condition causes termination.");
358 0 : } break;
359 : }
360 :
361 : // Update the unit outlet nodes
362 17558 : UpdateDXCoil(state, DXCoilNum);
363 :
364 : // Report the result of the simulation
365 17558 : ReportDXCoil(state, DXCoilNum);
366 17558 : }
367 :
368 0 : void SimDXCoilMultiMode(EnergyPlusData &state,
369 : std::string_view CompName, // name of the fan coil unit
370 : [[maybe_unused]] HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off !unused1208
371 : bool const FirstHVACIteration, // true if first hvac iteration
372 : Real64 const PartLoadRatio, // part load ratio
373 : HVAC::CoilMode const DehumidMode, // dehumidification mode (0=normal, 1=enhanced)
374 : int &CompIndex,
375 : HVAC::FanOp const fanOp // allows parent object to control fan mode
376 : )
377 : {
378 :
379 : // SUBROUTINE INFORMATION:
380 : // AUTHOR M. J. Witte (based on SimDXCoilMultiSpeed by Fred Buhl)
381 : // DATE WRITTEN February 2005
382 : // MODIFIED April 2010, Chandan sharma, added basin heater
383 :
384 : // PURPOSE OF THIS SUBROUTINE:
385 : // Manages the simulation of a DX coil with multiple performance modes, such as
386 : // multiple stages, or sub-cool reheat for humidity control.
387 :
388 : // Using/Aliasing
389 :
390 : // SUBROUTINE PARAMETER DEFINITIONS:
391 : static constexpr std::string_view RoutineName("SimDXCoilMultiMode");
392 :
393 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
394 : int DXCoilNum; // index of coil being simulated
395 : int PerfMode; // Performance mode for MultiMode DX coil; Always 1 for other coil types
396 : // 1-2=normal mode: 1=stage 1 only, 2=stage 1&2
397 : // 3-4=enhanced dehumidification mode: 3=stage 1 only, 4=stage 1&2
398 : Real64 AirMassFlow; // Dry air mass flow rate through coil [kg/s]
399 :
400 : Real64 S1OutletAirTemp; // Stage 1 Outlet air dry bulb temp [C]
401 : Real64 S1OutletAirHumRat; // Stage 1 Outlet air humidity ratio [kgWater/kgDryAir]
402 : Real64 S1OutletAirEnthalpy; // Stage 1 Outlet air enthalpy
403 : Real64 S1PLR; // Stage 1 Ratio of actual sensible cooling load to
404 : // steady-state sensible cooling capacity
405 : Real64 S1TotalCoolingEnergyRate; // Stage 1 Total cooling rate [W]
406 : Real64 S1SensCoolingEnergyRate; // Stage 1 Sensible cooling rate [W]
407 : Real64 S1LatCoolingEnergyRate; // Stage 1 Latent cooling rate [W]
408 : Real64 S1ElecCoolingPower; // Stage 1 Electric power input [W]
409 0 : Real64 S1RuntimeFraction(0.0); // Stage 1 Run time fraction (overlaps with stage1&2 run time)
410 : Real64 S1EvapCondPumpElecPower; // Stage 1 Evaporative condenser pump electric power input [W]
411 : Real64 S1EvapWaterConsumpRate; // Stage 1 Evap condenser water consumption rate [m3/s]
412 : Real64 S1CrankcaseHeaterPower; // Stage 1 Report variable for average crankcase heater power [W]
413 : Real64 S1FFullLoadOutAirTemp; // Stage 1 Full load outlet temperature [C]
414 : Real64 S1FullLoadOutAirHumRat; // Stage 1 Full load outlet humidity ratio [kgWater/kgDryAir]
415 :
416 : Real64 S12OutletAirTemp; // Stage 1&2 Outlet air dry bulb temp [C]
417 : Real64 S12OutletAirHumRat; // Stage 1&2 Outlet air humidity ratio [kgWater/kgDryAir]
418 : Real64 S12OutletAirEnthalpy; // Stage 1&2 Outlet air enthalpy
419 : // ! steady-state sensible cooling capacity
420 : Real64 S12TotalCoolingEnergyRate; // Stage 1&2 Total cooling rate [W]
421 : Real64 S12SensCoolingEnergyRate; // Stage 1&2 Sensible cooling rate [W]
422 : Real64 S12LatCoolingEnergyRate; // Stage 1&2 Latent cooling rate [W]
423 : Real64 S12ElecCoolingPower; // Stage 1&2 Electric power input [W]
424 : Real64 S12ElecCoolFullLoadPower; // Stage 1&2 Electric power input at full load (PLR=1) [W]
425 0 : Real64 S12RuntimeFraction(0.0); // Stage 1&2 Run time fraction (overlaps with stage1 run time)
426 : Real64 S12EvapCondPumpElecPower; // Stage 1&2 Evaporative condenser pump electric power input [W]
427 : Real64 S12EvapWaterConsumpRate; // Stage 1&2 Evap condenser water consumption rate [m3/s]
428 : Real64 S12CrankcaseHeaterPower; // Stage 1&2 Report variable for average crankcase heater power [W]
429 : Real64 S2PLR; // Stage 2 Ratio of actual sensible cooling load to
430 : // steady-state sensible cooling capacity
431 : Real64 TSat; // calculation to avoid calling psych routines twice
432 : Real64 NodePress; // Pressure at condenser inlet node (Pa)
433 :
434 : // First time SimDXCoil is called, get the input for all the DX coils (condensing units)
435 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
436 0 : GetDXCoils(state);
437 0 : state.dataDXCoils->GetCoilsInputFlag = false; // Set GetInputFlag false so you don't get coil inputs again
438 : }
439 :
440 : // find correct DX Coil
441 0 : if (CompIndex == 0) {
442 0 : DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
443 0 : if (DXCoilNum == 0) {
444 0 : ShowFatalError(state, format("DX Coil not found={}", CompName));
445 : }
446 0 : CompIndex = DXCoilNum;
447 : } else {
448 0 : DXCoilNum = CompIndex;
449 0 : if (DXCoilNum > state.dataDXCoils->NumDXCoils || DXCoilNum < 1) {
450 0 : ShowFatalError(state,
451 0 : format("SimDXCoilMultiMode: Invalid CompIndex passed={}, Number of DX Coils={}, Coil name={}",
452 : DXCoilNum,
453 0 : state.dataDXCoils->NumDXCoils,
454 : CompName));
455 : }
456 0 : if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
457 0 : if ((CompName != "") && (CompName != state.dataDXCoils->DXCoil(DXCoilNum).Name)) {
458 0 : ShowFatalError(state,
459 0 : format("SimDXCoilMultiMode: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
460 : DXCoilNum,
461 : CompName,
462 0 : state.dataDXCoils->DXCoil(DXCoilNum).Name));
463 : }
464 0 : state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
465 : }
466 : }
467 :
468 : // Initialize the DX coil unit
469 0 : InitDXCoil(state, DXCoilNum);
470 :
471 0 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
472 : // Select the correct unit type
473 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
474 : // Initialize local variables
475 0 : S1RuntimeFraction = 0.0;
476 0 : S1OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
477 0 : S1OutletAirHumRat = thisDXCoil.InletAirHumRat;
478 0 : S1OutletAirTemp = thisDXCoil.InletAirTemp;
479 0 : S1ElecCoolingPower = 0.0;
480 0 : S1TotalCoolingEnergyRate = 0.0;
481 0 : S1SensCoolingEnergyRate = 0.0;
482 0 : S1LatCoolingEnergyRate = 0.0;
483 0 : S1CrankcaseHeaterPower = 0.0;
484 0 : S1EvapWaterConsumpRate = 0.0;
485 0 : S1EvapCondPumpElecPower = 0.0;
486 :
487 0 : S12RuntimeFraction = 0.0;
488 0 : S12OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
489 0 : S12OutletAirHumRat = thisDXCoil.InletAirHumRat;
490 0 : S12OutletAirTemp = thisDXCoil.InletAirTemp;
491 0 : S12ElecCoolingPower = 0.0;
492 0 : S12TotalCoolingEnergyRate = 0.0;
493 0 : S12SensCoolingEnergyRate = 0.0;
494 0 : S12LatCoolingEnergyRate = 0.0;
495 0 : S12CrankcaseHeaterPower = 0.0;
496 0 : S12EvapWaterConsumpRate = 0.0;
497 0 : S12EvapCondPumpElecPower = 0.0;
498 :
499 0 : thisDXCoil.DehumidificationMode = DehumidMode;
500 0 : if ((int)DehumidMode > thisDXCoil.NumDehumidModes) {
501 0 : ShowFatalError(state,
502 0 : format("{} \"{}\" - Requested enhanced dehumidification mode not available.", thisDXCoil.DXCoilType, thisDXCoil.Name));
503 : }
504 :
505 : // If a single-stage coil OR If part load is zero,
506 : // run stage 1 at zero part load to set leaving conditions
507 0 : if ((thisDXCoil.NumCapacityStages == 1) || (PartLoadRatio <= 0.0)) {
508 : // Run stage 1 at its part load
509 0 : PerfMode = (int)DehumidMode * 2 + 1; // This. This is not good. Don't do math on enums.
510 0 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, PerfMode);
511 0 : S1PLR = PartLoadRatio;
512 0 : S2PLR = 0.0;
513 : } else {
514 : // If a two-stage coil
515 : // Run stage 1 at full load
516 0 : PerfMode = (int)DehumidMode * 2 + 1;
517 0 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, 1.0, fanOp, PerfMode);
518 0 : S1SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
519 0 : if (S1SensCoolingEnergyRate > 0.0) {
520 0 : S1PLR = PartLoadRatio;
521 : } else {
522 0 : S1PLR = 0.0;
523 : }
524 : // Run stage 1+2 at full load
525 0 : if (thisDXCoil.NumCapacityStages >= 2) {
526 0 : PerfMode = (int)DehumidMode * 2 + 2;
527 0 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, 1.0, fanOp, PerfMode);
528 0 : S12SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
529 0 : S12ElecCoolFullLoadPower = thisDXCoil.ElecCoolingPower;
530 : }
531 :
532 : // Determine run-time fractions for each stage based on sensible capacities
533 : // Relationships:
534 : // Stage 1 PLR1= Load/Cap1
535 : // Stage1+2 PLR12= Load/Cap12
536 : // Stage 2 PLR2= (Load-Cap1)/(Cap2)
537 : // PLR = Load/(Cap1+Cap2)
538 : // Load= PLR*(Cap1+Cap2)
539 : // PLR1= MIN(1,(PLR*(Cap1+Cap2)/Cap1))
540 : // PLR2= MIN(1,((PLR*(Cap1+Cap2)-Cap1)/Cap2))
541 :
542 0 : if (S1SensCoolingEnergyRate > 0.0) {
543 0 : S1PLR = PartLoadRatio * S12SensCoolingEnergyRate / S1SensCoolingEnergyRate;
544 : } else {
545 0 : S1PLR = 0.0;
546 : }
547 0 : S1PLR = min(1.0, S1PLR);
548 0 : S1PLR = max(0.0, S1PLR);
549 0 : if ((S12SensCoolingEnergyRate - S1SensCoolingEnergyRate) > 0.0) {
550 0 : S2PLR = (PartLoadRatio * S12SensCoolingEnergyRate - S1SensCoolingEnergyRate) / (S12SensCoolingEnergyRate - S1SensCoolingEnergyRate);
551 : } else {
552 0 : S2PLR = 0.0;
553 : }
554 0 : S2PLR = min(1.0, S2PLR);
555 0 : S2PLR = max(0.0, S2PLR);
556 :
557 : // Run stage 1 at its part load
558 0 : PerfMode = (int)DehumidMode * 2 + 1;
559 0 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, S1PLR, fanOp, PerfMode);
560 : }
561 : // For stage-1 only operation, all outputs are set by CalcDoe2DXCoil.
562 : // No further adjustments are necessary.
563 :
564 : // Run stage 2 if needed and available
565 0 : if ((S2PLR > 0.0) && (thisDXCoil.NumCapacityStages >= 2)) {
566 : // Store stage 1 outputs
567 0 : S1RuntimeFraction = thisDXCoil.CoolingCoilRuntimeFraction;
568 0 : S1OutletAirEnthalpy = thisDXCoil.OutletAirEnthalpy;
569 0 : S1OutletAirHumRat = thisDXCoil.OutletAirHumRat;
570 0 : S1OutletAirTemp = thisDXCoil.OutletAirTemp;
571 0 : S1ElecCoolingPower = thisDXCoil.ElecCoolingPower;
572 0 : S1TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate;
573 0 : S1SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
574 0 : S1LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate;
575 0 : S1CrankcaseHeaterPower = thisDXCoil.CrankcaseHeaterPower;
576 0 : S1EvapWaterConsumpRate = thisDXCoil.EvapWaterConsumpRate;
577 0 : S1EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecPower;
578 :
579 : // Save first stage full load outlet conditions to pass to heat recovery
580 0 : S1FFullLoadOutAirTemp = state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum);
581 0 : S1FullLoadOutAirHumRat = state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum);
582 :
583 : // Run stage 1+2 at its part load
584 0 : PerfMode = (int)DehumidMode * 2 + 2;
585 0 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, S2PLR, fanOp, PerfMode);
586 0 : S12RuntimeFraction = thisDXCoil.CoolingCoilRuntimeFraction;
587 0 : S12OutletAirEnthalpy = thisDXCoil.OutletAirEnthalpy;
588 0 : S12OutletAirHumRat = thisDXCoil.OutletAirHumRat;
589 0 : S12OutletAirTemp = thisDXCoil.OutletAirTemp;
590 0 : S12ElecCoolingPower = thisDXCoil.ElecCoolingPower;
591 0 : S12TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate;
592 0 : S12SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
593 0 : S12LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate;
594 0 : S12CrankcaseHeaterPower = thisDXCoil.CrankcaseHeaterPower;
595 0 : S12EvapWaterConsumpRate = thisDXCoil.EvapWaterConsumpRate;
596 0 : S12EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecPower;
597 :
598 : // Determine combined performance
599 0 : thisDXCoil.OutletAirEnthalpy = (1.0 - S2PLR) * S1OutletAirEnthalpy + S2PLR * S12OutletAirEnthalpy;
600 0 : thisDXCoil.OutletAirHumRat = (1.0 - S2PLR) * S1OutletAirHumRat + S2PLR * S12OutletAirHumRat;
601 0 : thisDXCoil.OutletAirTemp = PsyTdbFnHW(thisDXCoil.OutletAirEnthalpy, thisDXCoil.OutletAirHumRat);
602 : // Check for saturation error and modify temperature at constant enthalpy
603 0 : if (thisDXCoil.CondenserInletNodeNum(PerfMode) != 0) {
604 0 : NodePress = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(PerfMode)).Press;
605 : // If node is not connected to anything, pressure = default, use weather data
606 0 : if (NodePress == state.dataLoopNodes->DefaultNodeValues.Press) NodePress = state.dataEnvrn->OutBaroPress;
607 0 : TSat = PsyTsatFnHPb(state, thisDXCoil.OutletAirEnthalpy, NodePress, RoutineName);
608 0 : if (thisDXCoil.OutletAirTemp < TSat) {
609 0 : thisDXCoil.OutletAirTemp = TSat;
610 : }
611 0 : thisDXCoil.OutletAirHumRat = PsyWFnTdbH(state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirEnthalpy, RoutineName);
612 : } else {
613 0 : TSat = PsyTsatFnHPb(state, thisDXCoil.OutletAirEnthalpy, state.dataEnvrn->OutBaroPress, RoutineName);
614 0 : if (thisDXCoil.OutletAirTemp < TSat) {
615 0 : thisDXCoil.OutletAirTemp = TSat;
616 : }
617 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
618 : // IF(DXCoil(DXCoilNum)%OutletAirTemp .LT. PsyTsatFnHPb(DXCoil(DXCoilNum)%OutletAirEnthalpy, &
619 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)) THEN
620 : // DXCoil(DXCoilNum)%OutletAirTemp = PsyTsatFnHPb(DXCoil(DXCoilNum)%OutletAirEnthalpy, &
621 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)
622 0 : thisDXCoil.OutletAirHumRat = PsyWFnTdbH(state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirEnthalpy, RoutineName);
623 : }
624 :
625 : // DXCoil(DXCoilNum)%ElecCoolingPower = (1-S12RuntimeFraction)*S1ElecCoolingPower &
626 : // +S12RuntimeFraction*S12ElecCoolingPower
627 : // S12ElecCoolingPower overstates S1 portion of power, because it is also adjust by S12PLR
628 : // So, must make an adjustment for S12ElecCoolingPower/S12ElecCoolFullLoadPower
629 : // when subtracting off S1ElecCoolingPower
630 0 : if (S12ElecCoolFullLoadPower > 0.0) {
631 0 : thisDXCoil.ElecCoolingPower =
632 0 : S1RuntimeFraction * S1ElecCoolingPower +
633 0 : S12RuntimeFraction * (S12ElecCoolingPower - S1ElecCoolingPower * S12ElecCoolingPower / S12ElecCoolFullLoadPower);
634 : } else {
635 0 : thisDXCoil.ElecCoolingPower = 0.0;
636 : }
637 :
638 0 : thisDXCoil.CoolingCoilRuntimeFraction = S1RuntimeFraction;
639 :
640 0 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
641 0 : CalcComponentSensibleLatentOutput(AirMassFlow,
642 : thisDXCoil.InletAirTemp,
643 : thisDXCoil.InletAirHumRat,
644 : thisDXCoil.OutletAirTemp,
645 : thisDXCoil.OutletAirHumRat,
646 0 : thisDXCoil.SensCoolingEnergyRate,
647 0 : thisDXCoil.LatCoolingEnergyRate,
648 0 : thisDXCoil.TotalCoolingEnergyRate);
649 :
650 0 : thisDXCoil.EvapWaterConsumpRate = (1.0 - S12RuntimeFraction) * S1EvapWaterConsumpRate + S12RuntimeFraction * S12EvapWaterConsumpRate;
651 0 : thisDXCoil.EvapCondPumpElecPower = (1.0 - S12RuntimeFraction) * S1EvapCondPumpElecPower + S12RuntimeFraction * S12EvapCondPumpElecPower;
652 :
653 : // Stage 1 runtime sets the crankcase heater power
654 0 : thisDXCoil.CrankcaseHeaterPower = S1CrankcaseHeaterPower;
655 :
656 0 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
657 0 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
658 :
659 : // calculate average full load outlet conditions for second stage operation
660 0 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) =
661 0 : (1.0 - S2PLR) * S1FFullLoadOutAirTemp + S2PLR * state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum);
662 0 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) =
663 0 : (1.0 - S2PLR) * S1FullLoadOutAirHumRat + S2PLR * state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum);
664 :
665 : } // End if stage 2 is operating
666 :
667 : // set the part load ratio and heat reclaim capacity for use by desuperheater heating coils
668 0 : thisDXCoil.PartLoadRatio = S1PLR;
669 0 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = S1PLR;
670 :
671 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
672 0 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
673 :
674 0 : thisDXCoil.CoolingCoilStg2RuntimeFrac = S12RuntimeFraction;
675 :
676 : // Calculate basin heater power
677 0 : CalcBasinHeaterPowerForMultiModeDXCoil(state, DXCoilNum, DehumidMode);
678 : } else {
679 0 : ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
680 0 : ShowContinueError(state, format("Invalid DX Coil Type={}", thisDXCoil.DXCoilType));
681 0 : ShowFatalError(state, "Preceding condition causes termination.");
682 : }
683 :
684 : // Update the unit outlet nodes
685 0 : UpdateDXCoil(state, DXCoilNum);
686 :
687 : // Report the result of the simulation
688 0 : ReportDXCoil(state, DXCoilNum);
689 0 : }
690 :
691 135 : void GetDXCoils(EnergyPlusData &state)
692 : {
693 :
694 : // SUBROUTINE INFORMATION:
695 : // AUTHOR Fred Buhl
696 : // DATE WRITTEN May 2000
697 : // MODIFIED Aug 2000, Don Shirey, Sept 2000, Feb/Oct 2001, Sept 2003, Jan/July 2004
698 : // Feb 2005, M. J. Witte, GARD Analytics, Inc., Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
699 : // May 2005, Rich Raustad, FSEC, Added COIL:DX:HeatPumpWaterHeater
700 : // Jun 2007, L. Gu, FSEC, Added new coil type COIL:DX:MULTISPEED:COOLING and COIL:DX:MULTISPEED:HEATING
701 : // Apr 2010, Chandan Sharma, FSEC, added basin heater inputs
702 : // Jul 2015, RP Zhang, XF Pang, LBNL, Added new coil type for VRF-FluidTemperatureControl Model
703 :
704 : // PURPOSE OF THIS SUBROUTINE:
705 : // Obtains input data for DX coils and stores it in DX coil data structure
706 :
707 : // METHODOLOGY EMPLOYED:
708 : // Uses "Get" routines to read in data.
709 :
710 : // Using/Aliasing
711 : using BranchNodeConnections::TestCompSet;
712 : using Curve::checkCurveIsNormalizedToOne;
713 : using Curve::CurveValue;
714 : using Curve::GetCurveIndex;
715 : using DataSizing::AutoSize;
716 : using EMSManager::ManageEMS;
717 :
718 : using GlobalNames::VerifyUniqueCoilName;
719 : using NodeInputManager::GetOnlySingleNode;
720 : using OutAirNodeManager::CheckOutAirNodeNumber;
721 : using WaterManager::SetupTankDemandComponent;
722 : using WaterManager::SetupTankSupplyComponent;
723 :
724 : // SUBROUTINE PARAMETER DEFINITIONS:
725 : static constexpr std::string_view RoutineName("GetDXCoils: "); // include trailing blank space
726 : static constexpr std::string_view routineName = "GetDXCoils"; // include trailing blank space
727 :
728 135 : constexpr Real64 minOATCompDXCooling = -25.0; // min OAT for compressor operation for DX cooling coils
729 :
730 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
731 : int DXCoilIndex; // loop index
732 : int DXCoilNum; // current DX coil number
733 : int NumAlphas; // Number of alphas in input
734 : int NumNumbers; // Number of numeric items in input
735 135 : Array1D_string Alphas2; // Alpha input items for object
736 135 : Array1D<Real64> Numbers2; // Numeric input items for object
737 135 : Array1D_string cAlphaFields2; // Alpha field names
738 135 : Array1D_string cNumericFields2; // Numeric field names
739 135 : Array1D_bool lAlphaBlanks2; // Logical array, alpha field input BLANK = .TRUE.
740 135 : Array1D_bool lNumericBlanks2; // Logical array, numeric field input BLANK = .TRUE.
741 : int NumAlphas2; // Number of alphas in input for performance object
742 : int NumNumbers2; // Number of numeric items in input for performance object
743 : int IOStatus; // Input status returned from GetObjectItem
744 135 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
745 : int DXHPWaterHeaterCoilNum; // Loop index for 1,NumDXHeatPumpWaterHeaterCoils
746 : int CapacityStageNum; // Loop index for 1,Number of capacity stages
747 : int DehumidModeNum; // Loop index for 1,Number of enhanced dehumidification modes
748 : int PerfModeNum; // Performance mode index
749 : int PerfObjectNum; // Item number for performance object
750 : int AlphaIndex; // Index for current alpha field
751 135 : std::string CurrentModuleObject; // Object type for getting and error messages
752 135 : std::string PerfObjectType; // Performance object type for getting and error messages
753 135 : std::string PerfObjectName; // Performance object name for getting and error messages
754 : Real64 InletAirTemp; // Used to pass proper inlet air temp to HPWH DX coil performance curves
755 : Real64 InletWaterTemp; // Used to pass proper inlet water temp to HPWH DX coil performance curves
756 : int I; // Index of speeds
757 : Real64 CurveVal; // Used to verify modifier curves equal 1 at rated conditions
758 135 : Array1D_string Alphas; // Alpha input items for object
759 135 : Array1D_string cAlphaFields; // Alpha field names
760 135 : Array1D_string cNumericFields; // Numeric field names
761 135 : Array1D<Real64> Numbers; // Numeric input items for object
762 135 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
763 135 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
764 135 : int MaxNumbers(0); // Maximum number of numeric input fields
765 135 : int MaxAlphas(0); // Maximum number of alpha input fields
766 135 : int TotalArgs(0); // Total number of alpha and numeric arguments (max) for a
767 : // certain object in the input file
768 : Real64 MinCurveVal; // used for testing PLF curve output
769 : Real64 MinCurvePLR; // used for testing PLF curve output
770 : Real64 MaxCurveVal; // used for testing PLF curve output
771 : Real64 MaxCurvePLR; // used for testing PLF curve output
772 : Real64 CurveInput; // index used for testing PLF curve output
773 :
774 : // find number of each type of DX coil and calculate the total number
775 135 : state.dataDXCoils->NumDoe2DXCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:SingleSpeed");
776 135 : state.dataDXCoils->NumDXHeatingCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:DX:SingleSpeed");
777 135 : state.dataDXCoils->NumDXMulSpeedCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:TwoSpeed");
778 270 : state.dataDXCoils->NumDXMulModeCoils =
779 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:TwoStageWithHumidityControlMode");
780 270 : state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils =
781 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped));
782 270 : state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils =
783 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped));
784 135 : state.dataDXCoils->NumDXMulSpeedCoolCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:MultiSpeed");
785 135 : state.dataDXCoils->NumDXMulSpeedHeatCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:DX:MultiSpeed");
786 270 : state.dataDXCoils->NumVRFCoolingCoils =
787 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling));
788 270 : state.dataDXCoils->NumVRFHeatingCoils =
789 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating));
790 270 : state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils =
791 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling));
792 270 : state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils =
793 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating));
794 :
795 135 : state.dataDXCoils->NumDXCoils = state.dataDXCoils->NumDoe2DXCoils + state.dataDXCoils->NumDXHeatingCoils + state.dataDXCoils->NumDXMulSpeedCoils +
796 135 : state.dataDXCoils->NumDXMulModeCoils + state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils +
797 135 : state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils + state.dataDXCoils->NumDXMulSpeedCoolCoils +
798 135 : state.dataDXCoils->NumDXMulSpeedHeatCoils + state.dataDXCoils->NumVRFCoolingCoils +
799 135 : state.dataDXCoils->NumVRFHeatingCoils + state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils +
800 135 : state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils;
801 :
802 : // Determine max number of alpha and numeric arguments for all objects being read, in order to allocate local arrays
803 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:SingleSpeed", TotalArgs, NumAlphas, NumNumbers);
804 135 : MaxNumbers = NumNumbers;
805 135 : MaxAlphas = NumAlphas;
806 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:DX:SingleSpeed", TotalArgs, NumAlphas, NumNumbers);
807 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
808 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
809 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:TwoSpeed", TotalArgs, NumAlphas, NumNumbers);
810 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
811 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
812 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
813 : state, "Coil:Cooling:DX:TwoStageWithHumidityControlMode", TotalArgs, NumAlphas, NumNumbers);
814 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
815 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
816 270 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
817 135 : state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped), TotalArgs, NumAlphas, NumNumbers);
818 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
819 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
820 270 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
821 135 : state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped), TotalArgs, NumAlphas, NumNumbers);
822 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
823 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
824 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:MultiSpeed", TotalArgs, NumAlphas, NumNumbers);
825 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
826 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
827 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:DX:MultiSpeed", TotalArgs, NumAlphas, NumNumbers);
828 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
829 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
830 270 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
831 135 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling), TotalArgs, NumAlphas, NumNumbers);
832 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
833 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
834 270 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
835 135 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating), TotalArgs, NumAlphas, NumNumbers);
836 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
837 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
838 270 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
839 135 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling), TotalArgs, NumAlphas, NumNumbers);
840 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
841 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
842 270 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
843 135 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating), TotalArgs, NumAlphas, NumNumbers);
844 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
845 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
846 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "CoilPerformance:DX:Cooling", TotalArgs, NumAlphas, NumNumbers);
847 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
848 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
849 :
850 135 : Alphas.allocate(MaxAlphas);
851 135 : cAlphaFields.allocate(MaxAlphas);
852 135 : cNumericFields.allocate(MaxNumbers);
853 135 : Numbers.dimension(MaxNumbers, 0.0);
854 135 : lAlphaBlanks.dimension(MaxAlphas, true);
855 135 : lNumericBlanks.dimension(MaxNumbers, true);
856 :
857 135 : Alphas2.allocate(MaxAlphas);
858 135 : cAlphaFields2.allocate(MaxAlphas);
859 135 : cNumericFields2.allocate(MaxNumbers);
860 135 : Numbers2.dimension(MaxNumbers, 0.0);
861 135 : lAlphaBlanks2.dimension(MaxAlphas, true);
862 135 : lNumericBlanks2.dimension(MaxNumbers, true);
863 :
864 : // allocate the data structure
865 :
866 : // Derived types
867 135 : state.dataDXCoils->DXCoil.allocate(state.dataDXCoils->NumDXCoils);
868 135 : state.dataDXCoils->DXCoilNumericFields.allocate(state.dataDXCoils->NumDXCoils);
869 135 : state.dataHeatBal->HeatReclaimDXCoil.allocate(state.dataDXCoils->NumDXCoils);
870 135 : state.dataDXCoils->CheckEquipName.dimension(state.dataDXCoils->NumDXCoils, true);
871 :
872 : // Module level variable arrays
873 135 : state.dataDXCoils->DXCoilOutletTemp.allocate(state.dataDXCoils->NumDXCoils);
874 135 : state.dataDXCoils->DXCoilOutletHumRat.allocate(state.dataDXCoils->NumDXCoils);
875 135 : state.dataDXCoils->DXCoilPartLoadRatio.allocate(state.dataDXCoils->NumDXCoils);
876 135 : state.dataDXCoils->DXCoilFanOp.allocate(state.dataDXCoils->NumDXCoils);
877 135 : state.dataDXCoils->DXCoilFullLoadOutAirTemp.allocate(state.dataDXCoils->NumDXCoils);
878 135 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat.allocate(state.dataDXCoils->NumDXCoils);
879 135 : state.dataDXCoils->DXCoilTotalCooling.allocate(state.dataDXCoils->NumDXCoils);
880 135 : state.dataDXCoils->DXCoilTotalHeating.allocate(state.dataDXCoils->NumDXCoils);
881 135 : state.dataDXCoils->DXCoilCoolInletAirWBTemp.allocate(state.dataDXCoils->NumDXCoils);
882 135 : state.dataDXCoils->DXCoilHeatInletAirDBTemp.allocate(state.dataDXCoils->NumDXCoils);
883 135 : state.dataDXCoils->DXCoilHeatInletAirWBTemp.allocate(state.dataDXCoils->NumDXCoils);
884 :
885 : // initialize the module level arrays
886 135 : state.dataDXCoils->DXCoilOutletTemp = 0.0;
887 135 : state.dataDXCoils->DXCoilOutletHumRat = 0.0;
888 135 : state.dataDXCoils->DXCoilPartLoadRatio = 0.0;
889 135 : state.dataDXCoils->DXCoilFanOp = HVAC::FanOp::Invalid;
890 135 : state.dataDXCoils->DXCoilFullLoadOutAirTemp = 0.0;
891 135 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat = 0.0;
892 :
893 : // initialize the coil counter
894 135 : DXCoilNum = 0;
895 :
896 : // Loop over the Doe2 DX Coils and get & load the data
897 135 : CurrentModuleObject = "Coil:Cooling:DX:SingleSpeed";
898 197 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDoe2DXCoils; ++DXCoilIndex) {
899 :
900 62 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
901 : CurrentModuleObject,
902 : DXCoilIndex,
903 : Alphas,
904 : NumAlphas,
905 : Numbers,
906 : NumNumbers,
907 : IOStatus,
908 : lNumericBlanks,
909 : lAlphaBlanks,
910 : cAlphaFields,
911 : cNumericFields);
912 :
913 62 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
914 :
915 62 : ++DXCoilNum;
916 : // allocate single performance mode for numeric field strings used for sizing routine
917 62 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
918 62 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
919 62 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
920 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
921 62 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
922 :
923 62 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
924 62 : thisDXCoil.Name = Alphas(1);
925 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
926 62 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
927 62 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
928 62 : thisDXCoil.DXCoilType = CurrentModuleObject;
929 62 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingSingleSpeed;
930 62 : if (lAlphaBlanks(2)) {
931 10 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
932 52 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
933 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
934 0 : ErrorsFound = true;
935 : }
936 62 : thisDXCoil.RatedTotCap(1) = Numbers(1);
937 62 : thisDXCoil.RatedSHR(1) = Numbers(2);
938 62 : thisDXCoil.RatedCOP(1) = Numbers(3);
939 62 : if (thisDXCoil.RatedCOP(1) <= 0.0) {
940 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
941 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(3), Numbers(3)));
942 0 : ErrorsFound = true;
943 : }
944 :
945 62 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(4);
946 62 : thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(5);
947 62 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(6);
948 :
949 62 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
950 62 : Alphas(3),
951 : ErrorsFound,
952 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
953 62 : Alphas(1),
954 : DataLoopNode::NodeFluidType::Air,
955 : DataLoopNode::ConnectionType::Inlet,
956 : NodeInputManager::CompFluidStream::Primary,
957 : ObjectIsNotParent);
958 :
959 124 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
960 62 : Alphas(4),
961 : ErrorsFound,
962 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
963 62 : Alphas(1),
964 : DataLoopNode::NodeFluidType::Air,
965 : DataLoopNode::ConnectionType::Outlet,
966 : NodeInputManager::CompFluidStream::Primary,
967 : ObjectIsNotParent);
968 :
969 62 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
970 :
971 62 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
972 62 : if (thisDXCoil.CCapFTemp(1) == 0) {
973 0 : if (lAlphaBlanks(5)) {
974 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
975 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
976 : } else {
977 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
978 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
979 : }
980 0 : ErrorsFound = true;
981 : } else {
982 : // Verify Curve Object, only legal type is BiQuadratic
983 186 : ErrorsFound |= Curve::CheckCurveDims(state,
984 62 : thisDXCoil.CCapFTemp(1), // Curve index
985 : {2}, // Valid dimensions
986 : RoutineName, // Routine name
987 : CurrentModuleObject, // Object Type
988 : thisDXCoil.Name, // Object Name
989 62 : cAlphaFields(5)); // Field Name
990 :
991 62 : if (!ErrorsFound) {
992 62 : checkCurveIsNormalizedToOne(state,
993 186 : std::string{RoutineName} + CurrentModuleObject,
994 62 : thisDXCoil.Name,
995 62 : thisDXCoil.CCapFTemp(1),
996 62 : cAlphaFields(5),
997 62 : Alphas(5),
998 : RatedInletWetBulbTemp,
999 : RatedOutdoorAirTemp);
1000 : }
1001 : }
1002 :
1003 62 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
1004 62 : if (thisDXCoil.CCapFFlow(1) == 0) {
1005 0 : if (lAlphaBlanks(6)) {
1006 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1007 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
1008 : } else {
1009 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1010 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
1011 : }
1012 0 : ErrorsFound = true;
1013 : } else {
1014 : // Verify Curve Object, only legal type is Quadratic
1015 186 : ErrorsFound |= Curve::CheckCurveDims(state,
1016 62 : thisDXCoil.CCapFFlow(1), // Curve index
1017 : {1}, // Valid dimensions
1018 : RoutineName, // Routine name
1019 : CurrentModuleObject, // Object Type
1020 : thisDXCoil.Name, // Object Name
1021 62 : cAlphaFields(6)); // Field Name
1022 :
1023 62 : if (!ErrorsFound) {
1024 62 : checkCurveIsNormalizedToOne(
1025 248 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
1026 : }
1027 : }
1028 :
1029 62 : thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
1030 62 : if (thisDXCoil.EIRFTemp(1) == 0) {
1031 0 : if (lAlphaBlanks(7)) {
1032 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1033 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
1034 : } else {
1035 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1036 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
1037 : }
1038 0 : ErrorsFound = true;
1039 : } else {
1040 : // Verify Curve Object, only legal type is BiQuadratic
1041 186 : ErrorsFound |= Curve::CheckCurveDims(state,
1042 62 : thisDXCoil.EIRFTemp(1), // Curve index
1043 : {2}, // Valid dimensions
1044 : RoutineName, // Routine name
1045 : CurrentModuleObject, // Object Type
1046 : thisDXCoil.Name, // Object Name
1047 62 : cAlphaFields(7)); // Field Name
1048 :
1049 62 : if (!ErrorsFound) {
1050 62 : checkCurveIsNormalizedToOne(state,
1051 186 : std::string{RoutineName} + CurrentModuleObject,
1052 62 : thisDXCoil.Name,
1053 62 : thisDXCoil.EIRFTemp(1),
1054 62 : cAlphaFields(7),
1055 62 : Alphas(7),
1056 : RatedInletWetBulbTemp,
1057 : RatedOutdoorAirTemp);
1058 : }
1059 : }
1060 :
1061 62 : thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
1062 62 : if (thisDXCoil.EIRFFlow(1) == 0) {
1063 0 : if (lAlphaBlanks(8)) {
1064 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1065 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
1066 : } else {
1067 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1068 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
1069 : }
1070 0 : ErrorsFound = true;
1071 : } else {
1072 : // Verify Curve Object, only legal type is Quadratic
1073 186 : ErrorsFound |= Curve::CheckCurveDims(state,
1074 62 : thisDXCoil.EIRFFlow(1), // Curve index
1075 : {1}, // Valid dimensions
1076 : RoutineName, // Routine name
1077 : CurrentModuleObject, // Object Type
1078 : thisDXCoil.Name, // Object Name
1079 62 : cAlphaFields(8)); // Field Name
1080 :
1081 62 : if (!ErrorsFound) {
1082 62 : checkCurveIsNormalizedToOne(
1083 248 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
1084 : }
1085 : }
1086 :
1087 62 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
1088 62 : if (thisDXCoil.PLFFPLR(1) == 0) {
1089 0 : if (lAlphaBlanks(9)) {
1090 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1091 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
1092 : } else {
1093 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1094 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
1095 : }
1096 0 : ErrorsFound = true;
1097 : } else {
1098 : // Verify Curve Object, only legal types are Quadratic or Cubic
1099 186 : ErrorsFound |= Curve::CheckCurveDims(state,
1100 62 : thisDXCoil.PLFFPLR(1), // Curve index
1101 : {1}, // Valid dimensions
1102 : RoutineName, // Routine name
1103 : CurrentModuleObject, // Object Type
1104 : thisDXCoil.Name, // Object Name
1105 62 : cAlphaFields(9)); // Field Name
1106 :
1107 62 : if (!ErrorsFound) {
1108 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
1109 62 : MinCurveVal = 999.0;
1110 62 : MaxCurveVal = -999.0;
1111 62 : CurveInput = 0.0;
1112 6262 : while (CurveInput <= 1.0) {
1113 6200 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
1114 6200 : if (CurveVal < MinCurveVal) {
1115 62 : MinCurveVal = CurveVal;
1116 62 : MinCurvePLR = CurveInput;
1117 : }
1118 6200 : if (CurveVal > MaxCurveVal) {
1119 4568 : MaxCurveVal = CurveVal;
1120 4568 : MaxCurvePLR = CurveInput;
1121 : }
1122 6200 : CurveInput += 0.01;
1123 : }
1124 62 : if (MinCurveVal < 0.7) {
1125 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1126 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFields(9), Alphas(9)));
1127 0 : ShowContinueError(state,
1128 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
1129 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
1130 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
1131 : }
1132 :
1133 62 : if (MaxCurveVal > 1.0) {
1134 2 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1135 2 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
1136 4 : ShowContinueError(state,
1137 4 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
1138 4 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
1139 2 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
1140 : }
1141 : }
1142 : }
1143 :
1144 : // Set minimum OAT for compressor operation
1145 62 : thisDXCoil.MinOATCompressor = Numbers(7);
1146 62 : if (NumNumbers < 6)
1147 0 : thisDXCoil.MinOATCompressor = minOATCompDXCooling; // input field is after min fields and won't default if field not included
1148 :
1149 62 : thisDXCoil.Twet_Rated(1) = Numbers(8);
1150 62 : thisDXCoil.Gamma_Rated(1) = Numbers(9);
1151 62 : thisDXCoil.MaxONOFFCyclesperHour(1) = Numbers(10);
1152 62 : thisDXCoil.LatentCapacityTimeConstant(1) = Numbers(11);
1153 :
1154 : // Numbers (7) through (11) must all be greater than zero to use the latent capacity degradation model
1155 76 : if ((Numbers(8) > 0.0 || Numbers(9) > 0.0 || Numbers(10) > 0.0 || Numbers(11) > 0.0) &&
1156 14 : (Numbers(8) <= 0.0 || Numbers(9) <= 0.0 || Numbers(10) <= 0.0 || Numbers(11) <= 0.0)) {
1157 0 : ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1158 0 : ShowContinueError(state, "...At least one of the four input parameters for the latent capacity degradation model");
1159 0 : ShowContinueError(state, "...is set to zero. Therefore, the latent degradation model will not be used for this simulation.");
1160 : }
1161 :
1162 : // outdoor condenser node
1163 62 : if (lAlphaBlanks(10)) {
1164 48 : thisDXCoil.CondenserInletNodeNum(1) = 0;
1165 : } else {
1166 28 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
1167 14 : Alphas(10),
1168 : ErrorsFound,
1169 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
1170 14 : thisDXCoil.Name,
1171 : DataLoopNode::NodeFluidType::Air,
1172 : DataLoopNode::ConnectionType::OutsideAirReference,
1173 : NodeInputManager::CompFluidStream::Primary,
1174 : ObjectIsNotParent);
1175 :
1176 14 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
1177 4 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1178 8 : ShowContinueError(
1179 : state,
1180 8 : format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(10), Alphas(10)));
1181 12 : ShowContinueError(
1182 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
1183 : }
1184 : }
1185 :
1186 62 : if ((Util::SameString(Alphas(11), "AirCooled")) || lAlphaBlanks(11)) {
1187 48 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
1188 14 : } else if (Util::SameString(Alphas(11), "EvaporativelyCooled")) {
1189 14 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
1190 14 : thisDXCoil.ReportEvapCondVars = true;
1191 : } else {
1192 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1193 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(11), Alphas(11)));
1194 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
1195 0 : ErrorsFound = true;
1196 : }
1197 :
1198 62 : thisDXCoil.EvapCondEffect(1) = Numbers(12);
1199 62 : if (thisDXCoil.EvapCondEffect(1) < 0.0 || thisDXCoil.EvapCondEffect(1) > 1.0) {
1200 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1201 0 : ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields(11)));
1202 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(12)));
1203 0 : ErrorsFound = true;
1204 : }
1205 :
1206 62 : thisDXCoil.EvapCondAirFlow(1) = Numbers(13);
1207 62 : if (thisDXCoil.EvapCondAirFlow(1) < 0.0 && thisDXCoil.EvapCondAirFlow(1) != AutoSize) {
1208 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1209 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(12)));
1210 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(13)));
1211 0 : ErrorsFound = true;
1212 : }
1213 :
1214 62 : thisDXCoil.EvapCondPumpElecNomPower(1) = Numbers(14);
1215 62 : if (thisDXCoil.EvapCondPumpElecNomPower(1) < 0.0 && thisDXCoil.EvapCondPumpElecNomPower(1) != AutoSize) {
1216 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1217 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(13)));
1218 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(14)));
1219 0 : ErrorsFound = true;
1220 : }
1221 :
1222 : // Set crankcase heater capacity
1223 62 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(15);
1224 62 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
1225 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1226 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(14)));
1227 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(15)));
1228 0 : ErrorsFound = true;
1229 : }
1230 :
1231 : // Set crankcase heater cutout temperature
1232 62 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(16);
1233 :
1234 62 : if (thisDXCoil.RatedCOP(1) > 0.0) {
1235 62 : thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
1236 : }
1237 :
1238 : // A12, \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
1239 62 : if (!lAlphaBlanks(12)) {
1240 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(12));
1241 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
1242 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(12), Alphas(12)));
1243 0 : ErrorsFound = true;
1244 : } else {
1245 6 : ErrorsFound |= Curve::CheckCurveDims(state,
1246 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
1247 : {1}, // Valid dimensions
1248 : RoutineName, // Routine name
1249 : CurrentModuleObject, // Object Type
1250 : thisDXCoil.Name, // Object Name
1251 2 : cAlphaFields(12)); // Field Name
1252 : }
1253 : }
1254 :
1255 : // Get Water System tank connections
1256 : // A13, \field Name of Water Storage Tank for Supply
1257 62 : thisDXCoil.EvapWaterSupplyName = Alphas(13);
1258 62 : if (lAlphaBlanks(13)) {
1259 62 : 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 62 : thisDXCoil.CondensateCollectName = Alphas(14);
1273 62 : if (lAlphaBlanks(14)) {
1274 62 : 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 62 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(17);
1288 62 : 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 62 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(18);
1296 62 : 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 62 : if (!lAlphaBlanks(15)) {
1308 0 : if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(15))) == nullptr) {
1309 0 : ShowWarningItemNotFound(
1310 0 : state, eoh, cAlphaFields(15), Alphas(15), "Basin heater will be available to operate throughout the simulation.");
1311 : }
1312 : }
1313 :
1314 62 : if (!lAlphaBlanks(16) && NumAlphas > 15) {
1315 0 : thisDXCoil.SHRFTemp(1) = GetCurveIndex(state, Alphas(16)); // convert curve name to number
1316 0 : if (thisDXCoil.SHRFTemp(1) == 0) {
1317 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1318 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
1319 : } else {
1320 : // Verify Curve Object, only legal type is BiQuadratic
1321 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1322 0 : thisDXCoil.SHRFTemp(1), // Curve index
1323 : {2}, // Valid dimensions
1324 : RoutineName, // Routine name
1325 : CurrentModuleObject, // Object Type
1326 : thisDXCoil.Name, // Object Name
1327 0 : cAlphaFields(16)); // Field Name
1328 : }
1329 : }
1330 :
1331 62 : if (!lAlphaBlanks(17) && NumAlphas > 16) {
1332 2 : thisDXCoil.SHRFFlow(1) = GetCurveIndex(state, Alphas(17)); // convert curve name to number
1333 2 : if (thisDXCoil.SHRFTemp(1) == 0) {
1334 2 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1335 2 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
1336 : } else {
1337 : // Verify Curve Object, only legal type is Quadratic and Cubic
1338 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1339 0 : thisDXCoil.SHRFFlow(1), // Curve index
1340 : {1}, // Valid dimensions
1341 : RoutineName, // Routine name
1342 : CurrentModuleObject, // Object Type
1343 : thisDXCoil.Name, // Object Name
1344 0 : cAlphaFields(17)); // Field Name
1345 : }
1346 : }
1347 :
1348 62 : if (thisDXCoil.SHRFTemp(1) > 0 && thisDXCoil.SHRFFlow(1) > 0) {
1349 0 : thisDXCoil.UserSHRCurveExists = true;
1350 : }
1351 : // get User Input flag for ASHRAE Standard 127 Standard Ratings Reporting
1352 62 : if (lAlphaBlanks(18)) {
1353 62 : thisDXCoil.ASHRAE127StdRprt = false;
1354 : } else {
1355 0 : if (Alphas(18) == "YES" || Alphas(18) == "Yes") {
1356 0 : thisDXCoil.ASHRAE127StdRprt = true;
1357 : } else {
1358 0 : thisDXCoil.ASHRAE127StdRprt = false;
1359 : }
1360 : }
1361 : // A19; \field Zone Name for Condenser Placement
1362 62 : if (!lAlphaBlanks(19) && NumAlphas > 18) {
1363 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(19), state.dataHeatBal->Zone);
1364 :
1365 0 : if (thisDXCoil.SecZonePtr > 0) {
1366 0 : SetupZoneInternalGain(state,
1367 : thisDXCoil.SecZonePtr,
1368 : thisDXCoil.Name,
1369 : DataHeatBalance::IntGainType::SecCoolingDXCoilSingleSpeed,
1370 : &thisDXCoil.SecCoilSensibleHeatGainRate);
1371 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
1372 : } else {
1373 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1374 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(19), Alphas(19)));
1375 : }
1376 : }
1377 :
1378 : } // end of the Doe2 DX coil loop
1379 :
1380 135 : if (ErrorsFound) {
1381 0 : ShowFatalError(state,
1382 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
1383 : }
1384 :
1385 : // Loop over the Multimode DX Coils and get & load the data
1386 135 : CurrentModuleObject = "Coil:Cooling:DX:TwoStageWithHumidityControlMode";
1387 137 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulModeCoils; ++DXCoilIndex) {
1388 :
1389 2 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1390 : CurrentModuleObject,
1391 : DXCoilIndex,
1392 : Alphas,
1393 : NumAlphas,
1394 : Numbers,
1395 : NumNumbers,
1396 : IOStatus,
1397 : lNumericBlanks,
1398 : lAlphaBlanks,
1399 : cAlphaFields,
1400 : cNumericFields);
1401 :
1402 2 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
1403 2 : ++DXCoilNum;
1404 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
1405 2 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
1406 :
1407 2 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
1408 2 : thisDXCoil.Name = Alphas(1);
1409 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
1410 2 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
1411 2 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
1412 2 : thisDXCoil.DXCoilType = CurrentModuleObject;
1413 2 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingTwoStageWHumControl;
1414 2 : if (lAlphaBlanks(2)) {
1415 2 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
1416 0 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
1417 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
1418 0 : ErrorsFound = true;
1419 : }
1420 :
1421 2 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
1422 2 : Alphas(3),
1423 : ErrorsFound,
1424 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoStageWithHumidityControlMode,
1425 2 : Alphas(1),
1426 : DataLoopNode::NodeFluidType::Air,
1427 : DataLoopNode::ConnectionType::Inlet,
1428 : NodeInputManager::CompFluidStream::Primary,
1429 : ObjectIsNotParent);
1430 :
1431 4 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
1432 2 : Alphas(4),
1433 : ErrorsFound,
1434 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoStageWithHumidityControlMode,
1435 2 : Alphas(1),
1436 : DataLoopNode::NodeFluidType::Air,
1437 : DataLoopNode::ConnectionType::Outlet,
1438 : NodeInputManager::CompFluidStream::Primary,
1439 : ObjectIsNotParent);
1440 :
1441 2 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
1442 :
1443 : // A5; \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
1444 2 : if (!lAlphaBlanks(5)) {
1445 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
1446 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
1447 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(5), Alphas(5)));
1448 0 : ErrorsFound = true;
1449 : } else {
1450 6 : ErrorsFound |= Curve::CheckCurveDims(state,
1451 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
1452 : {1}, // Valid dimensions
1453 : RoutineName, // Routine name
1454 : CurrentModuleObject, // Object Type
1455 : thisDXCoil.Name, // Object Name
1456 2 : cAlphaFields(5)); // Field Name
1457 : }
1458 : }
1459 :
1460 : // Set crankcase heater capacity
1461 2 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(1);
1462 2 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
1463 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1464 0 : ShowContinueError(state, format("...{} must be >= 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
1465 0 : ErrorsFound = true;
1466 : }
1467 :
1468 : // Set crankcase heater cutout temperature
1469 2 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(2);
1470 :
1471 : // Number of capacity stages
1472 2 : thisDXCoil.NumCapacityStages = Numbers(3);
1473 : // Check if requested number of capacity stages exceeds limits
1474 2 : if ((thisDXCoil.NumCapacityStages > MaxCapacityStages) || (thisDXCoil.NumCapacityStages < 1)) {
1475 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1476 0 : ShowContinueError(state, format("...illegal {} = {}", cNumericFields(3), thisDXCoil.NumCapacityStages));
1477 0 : ShowContinueError(state, format("...Valid range is 1 to {}", MaxCapacityStages));
1478 0 : ErrorsFound = true;
1479 : }
1480 :
1481 : // Number of enhanced dehumidification modes
1482 2 : thisDXCoil.NumDehumidModes = Numbers(4);
1483 : // Check if requested number of enhanced dehumidification modes exceeds limits
1484 2 : if ((thisDXCoil.NumDehumidModes > MaxDehumidModes) || (thisDXCoil.NumDehumidModes < 0)) {
1485 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1486 0 : ShowContinueError(state, format("...illegal {} = {}", cNumericFields(4), thisDXCoil.NumDehumidModes));
1487 0 : ShowContinueError(state, format("...Valid range is 0 to {}", MaxDehumidModes));
1488 0 : ErrorsFound = true;
1489 : }
1490 :
1491 : // Set starting alpha index for coil performance inputs
1492 2 : AlphaIndex = 6;
1493 : // allocate performance modes for numeric field strings used for sizing routine
1494 4 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(
1495 2 : thisDXCoil.NumDehumidModes * 2 + thisDXCoil.NumCapacityStages * 2); // not sure this math is correct, ask MW
1496 :
1497 : // Loop through capacity stages and dehumidification modes
1498 6 : for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
1499 12 : for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
1500 : // Check if sufficient number of fields entered
1501 8 : if ((AlphaIndex + 1) > NumAlphas) {
1502 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1503 0 : ShowContinueError(state, "...not enough remaining fields for specified Number of Operating Modes.");
1504 0 : ShowContinueError(state, "...Need additional Coil Performance Object Type and Coil Performance Object Name fields.");
1505 0 : ErrorsFound = true;
1506 : } else {
1507 8 : PerfObjectType = Alphas(AlphaIndex);
1508 8 : PerfObjectName = Alphas(AlphaIndex + 1);
1509 8 : PerfModeNum = DehumidModeNum * 2 + CapacityStageNum;
1510 8 : thisDXCoil.CoilPerformanceType(PerfModeNum) = PerfObjectType;
1511 8 : if (Util::SameString(PerfObjectType, "CoilPerformance:DX:Cooling")) {
1512 8 : thisDXCoil.CoilPerformanceType_Num(PerfModeNum) = HVAC::CoilPerfDX_CoolBypassEmpirical;
1513 : } else {
1514 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1515 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(AlphaIndex), PerfObjectType));
1516 0 : ShowContinueError(state, "Must be \"CoilPerformance:DX:Cooling\".");
1517 0 : ErrorsFound = true;
1518 : }
1519 8 : thisDXCoil.CoilPerformanceName(PerfModeNum) = PerfObjectName;
1520 : // Get for CoilPerformance object
1521 8 : PerfObjectNum = state.dataInputProcessing->inputProcessor->getObjectItemNum(state, PerfObjectType, PerfObjectName);
1522 8 : if (PerfObjectNum > 0) {
1523 :
1524 8 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1525 : PerfObjectType,
1526 : PerfObjectNum,
1527 : Alphas2,
1528 : NumAlphas2,
1529 : Numbers2,
1530 : NumNumbers2,
1531 : IOStatus,
1532 : lNumericBlanks2,
1533 : lAlphaBlanks2,
1534 : cAlphaFields2,
1535 : cNumericFields2);
1536 :
1537 : // allocate performance mode numeric field strings used for sizing routine
1538 8 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum)
1539 8 : .PerfMode(PerfModeNum)
1540 8 : .FieldNames.allocate(NumNumbers2); // use MaxNumbers here??
1541 8 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(PerfModeNum).FieldNames = cNumericFields2;
1542 :
1543 8 : thisDXCoil.RatedTotCap(PerfModeNum) = Numbers2(1);
1544 8 : thisDXCoil.RatedSHR(PerfModeNum) = Numbers2(2);
1545 8 : thisDXCoil.RatedCOP(PerfModeNum) = Numbers2(3);
1546 : // Rated flow is immediately adjusted for bypass fraction if not autosized
1547 8 : thisDXCoil.BypassedFlowFrac(PerfModeNum) = Numbers2(5);
1548 8 : thisDXCoil.RatedAirVolFlowRate(PerfModeNum) = Numbers2(4);
1549 8 : if (thisDXCoil.RatedAirVolFlowRate(PerfModeNum) != AutoSize) {
1550 0 : thisDXCoil.RatedAirVolFlowRate(PerfModeNum) *= (1.0 - thisDXCoil.BypassedFlowFrac(PerfModeNum));
1551 : }
1552 :
1553 8 : thisDXCoil.CCapFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(2)); // convert curve name to number
1554 8 : if (thisDXCoil.CCapFTemp(PerfModeNum) == 0) {
1555 0 : if (lAlphaBlanks2(2)) {
1556 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1557 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(2)));
1558 : } else {
1559 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1560 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(2), Alphas2(2)));
1561 : }
1562 0 : ErrorsFound = true;
1563 : } else {
1564 : // Verify Curve Object, only legal type is BiQuadratic
1565 24 : ErrorsFound |= Curve::CheckCurveDims(state,
1566 8 : thisDXCoil.CCapFTemp(PerfModeNum), // Curve index
1567 : {2}, // Valid dimensions
1568 : RoutineName, // Routine name
1569 : CurrentModuleObject, // Object Type
1570 : thisDXCoil.Name, // Object Name
1571 8 : cAlphaFields2(2)); // Field Name
1572 :
1573 8 : if (!ErrorsFound) {
1574 8 : checkCurveIsNormalizedToOne(state,
1575 24 : std::string{RoutineName} + CurrentModuleObject,
1576 8 : thisDXCoil.Name,
1577 8 : thisDXCoil.CCapFTemp(PerfModeNum),
1578 8 : cAlphaFields2(2),
1579 8 : Alphas2(2),
1580 : RatedInletWetBulbTemp,
1581 : RatedOutdoorAirTemp);
1582 : }
1583 : }
1584 :
1585 8 : thisDXCoil.CCapFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(3)); // convert curve name to number
1586 8 : if (thisDXCoil.CCapFFlow(PerfModeNum) == 0) {
1587 0 : if (lAlphaBlanks2(3)) {
1588 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1589 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(3)));
1590 : } else {
1591 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1592 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(3), Alphas2(3)));
1593 : }
1594 0 : ErrorsFound = true;
1595 : } else {
1596 : // Verify Curve Object, only legal type is Quadratic
1597 24 : ErrorsFound |= Curve::CheckCurveDims(state,
1598 8 : thisDXCoil.CCapFFlow(PerfModeNum), // Curve index
1599 : {1}, // Valid dimensions
1600 : RoutineName, // Routine name
1601 : CurrentModuleObject, // Object Type
1602 : thisDXCoil.Name, // Object Name
1603 8 : cAlphaFields2(3)); // Field Name
1604 :
1605 8 : if (!ErrorsFound) {
1606 8 : checkCurveIsNormalizedToOne(state,
1607 24 : std::string{RoutineName} + CurrentModuleObject,
1608 8 : thisDXCoil.Name,
1609 8 : thisDXCoil.CCapFFlow(PerfModeNum),
1610 8 : cAlphaFields2(3),
1611 8 : Alphas2(3),
1612 : 1.0);
1613 : }
1614 : }
1615 :
1616 8 : thisDXCoil.EIRFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(4)); // convert curve name to number
1617 8 : if (thisDXCoil.EIRFTemp(PerfModeNum) == 0) {
1618 0 : if (lAlphaBlanks2(4)) {
1619 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1620 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(4)));
1621 : } else {
1622 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1623 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(4), Alphas2(4)));
1624 : }
1625 0 : ErrorsFound = true;
1626 : } else {
1627 : // Verify Curve Object, only legal type is BiQuadratic
1628 24 : ErrorsFound |= Curve::CheckCurveDims(state,
1629 8 : thisDXCoil.EIRFTemp(PerfModeNum), // Curve index
1630 : {2}, // Valid dimensions
1631 : RoutineName, // Routine name
1632 : CurrentModuleObject, // Object Type
1633 : thisDXCoil.Name, // Object Name
1634 8 : cAlphaFields2(4)); // Field Name
1635 :
1636 8 : if (!ErrorsFound) {
1637 8 : checkCurveIsNormalizedToOne(state,
1638 24 : std::string{RoutineName} + CurrentModuleObject,
1639 8 : thisDXCoil.Name,
1640 8 : thisDXCoil.EIRFTemp(PerfModeNum),
1641 8 : cAlphaFields2(4),
1642 8 : Alphas2(4),
1643 : RatedInletWetBulbTemp,
1644 : RatedOutdoorAirTemp);
1645 : }
1646 : }
1647 :
1648 8 : thisDXCoil.EIRFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(5)); // convert curve name to number
1649 8 : if (thisDXCoil.EIRFFlow(PerfModeNum) == 0) {
1650 0 : if (lAlphaBlanks2(5)) {
1651 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1652 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(5)));
1653 : } else {
1654 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1655 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(5), Alphas2(5)));
1656 : }
1657 0 : ErrorsFound = true;
1658 : } else {
1659 : // Verify Curve Object, only legal type is Quadratic
1660 24 : ErrorsFound |= Curve::CheckCurveDims(state,
1661 8 : thisDXCoil.EIRFFlow(PerfModeNum), // Curve index
1662 : {1}, // Valid dimensions
1663 : RoutineName, // Routine name
1664 : CurrentModuleObject, // Object Type
1665 : thisDXCoil.Name, // Object Name
1666 8 : cAlphaFields2(5)); // Field Name
1667 :
1668 8 : if (!ErrorsFound) {
1669 8 : checkCurveIsNormalizedToOne(state,
1670 24 : std::string{RoutineName} + CurrentModuleObject,
1671 8 : thisDXCoil.Name,
1672 8 : thisDXCoil.EIRFFlow(PerfModeNum),
1673 8 : cAlphaFields2(5),
1674 8 : Alphas2(5),
1675 : 1.0);
1676 : }
1677 : }
1678 :
1679 8 : thisDXCoil.PLFFPLR(PerfModeNum) = GetCurveIndex(state, Alphas2(6)); // convert curve name to number
1680 8 : if (thisDXCoil.PLFFPLR(PerfModeNum) == 0) {
1681 0 : if (lAlphaBlanks2(6)) {
1682 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1683 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(6)));
1684 : } else {
1685 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1686 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(6), Alphas2(6)));
1687 : }
1688 0 : ErrorsFound = true;
1689 : } else {
1690 : // Verify Curve Object, only legal types are Quadratic or Cubic
1691 24 : ErrorsFound |= Curve::CheckCurveDims(state,
1692 8 : thisDXCoil.PLFFPLR(PerfModeNum), // Curve index
1693 : {1}, // Valid dimensions
1694 : RoutineName, // Routine name
1695 : CurrentModuleObject, // Object Type
1696 : thisDXCoil.Name, // Object Name
1697 8 : cAlphaFields2(6)); // Field Name
1698 :
1699 8 : if (!ErrorsFound) {
1700 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
1701 8 : MinCurveVal = 999.0;
1702 8 : MaxCurveVal = -999.0;
1703 8 : CurveInput = 0.0;
1704 808 : while (CurveInput <= 1.0) {
1705 800 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(PerfModeNum), CurveInput);
1706 800 : if (CurveVal < MinCurveVal) {
1707 8 : MinCurveVal = CurveVal;
1708 8 : MinCurvePLR = CurveInput;
1709 : }
1710 800 : if (CurveVal > MaxCurveVal) {
1711 8 : MaxCurveVal = CurveVal;
1712 8 : MaxCurvePLR = CurveInput;
1713 : }
1714 800 : CurveInput += 0.01;
1715 : }
1716 8 : if (MinCurveVal < 0.7) {
1717 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1718 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields2(6), Alphas2(6)));
1719 0 : ShowContinueError(
1720 : state,
1721 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
1722 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
1723 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 0.7);
1724 : }
1725 :
1726 8 : if (MaxCurveVal > 1.0) {
1727 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1728 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields2(6), Alphas2(6)));
1729 0 : ShowContinueError(
1730 : state,
1731 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
1732 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
1733 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 1.0);
1734 : }
1735 : }
1736 : }
1737 :
1738 8 : thisDXCoil.Twet_Rated(PerfModeNum) = Numbers2(6);
1739 8 : thisDXCoil.Gamma_Rated(PerfModeNum) = Numbers2(7);
1740 8 : thisDXCoil.MaxONOFFCyclesperHour(PerfModeNum) = Numbers2(8);
1741 8 : thisDXCoil.LatentCapacityTimeConstant(PerfModeNum) = Numbers2(9);
1742 : // Numbers2 (6) through (9) must all be greater than zero to use the latent capacity degradation model
1743 8 : if ((Numbers2(6) > 0.0 || Numbers2(7) > 0.0 || Numbers2(8) > 0.0 || Numbers2(9) > 0.0) &&
1744 0 : (Numbers2(6) <= 0.0 || Numbers2(7) <= 0.0 || Numbers2(8) <= 0.0 || Numbers2(9) <= 0.0)) {
1745 0 : ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, PerfObjectType, PerfObjectName));
1746 0 : ShowContinueError(state, "...At least one of the four input parameters for the latent capacity degradation model");
1747 0 : ShowContinueError(state,
1748 : "...is set to zero. Therefore, the latent degradation model will not be used for this simulation.");
1749 : }
1750 :
1751 : // outdoor condenser node
1752 8 : if (lAlphaBlanks2(7)) {
1753 8 : thisDXCoil.CondenserInletNodeNum(PerfModeNum) = 0;
1754 : } else {
1755 0 : thisDXCoil.CondenserInletNodeNum(PerfModeNum) =
1756 0 : GetOnlySingleNode(state,
1757 0 : Alphas2(7),
1758 : ErrorsFound,
1759 0 : (DataLoopNode::ConnectionObjectType)getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC,
1760 0 : Util::makeUPPER(PerfObjectType)),
1761 : PerfObjectName,
1762 : DataLoopNode::NodeFluidType::Air,
1763 : DataLoopNode::ConnectionType::OutsideAirReference,
1764 : NodeInputManager::CompFluidStream::Primary,
1765 : ObjectIsNotParent);
1766 0 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(PerfModeNum))) {
1767 0 : ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, PerfObjectType, PerfObjectName));
1768 0 : ShowContinueError(state, format("may not be valid {}=\"{}\".", cAlphaFields2(7), Alphas2(7)));
1769 0 : ShowContinueError(state, "node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
1770 0 : ShowContinueError(state,
1771 : "This node needs to be included in an air system or the coil model will not be valid, and the "
1772 : "simulation continues");
1773 : }
1774 : }
1775 8 : if ((Util::SameString(Alphas2(8), "AirCooled")) || lAlphaBlanks2(8)) {
1776 8 : thisDXCoil.CondenserType(PerfModeNum) = DataHeatBalance::RefrigCondenserType::Air;
1777 0 : } else if (Util::SameString(Alphas2(8), "EvaporativelyCooled")) {
1778 0 : thisDXCoil.CondenserType(PerfModeNum) = DataHeatBalance::RefrigCondenserType::Evap;
1779 0 : thisDXCoil.ReportEvapCondVars = true;
1780 : } else {
1781 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1782 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields2(8), Alphas2(8)));
1783 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
1784 0 : ErrorsFound = true;
1785 : }
1786 :
1787 8 : thisDXCoil.EvapCondEffect(PerfModeNum) = Numbers2(10);
1788 8 : if (thisDXCoil.EvapCondEffect(PerfModeNum) < 0.0 || thisDXCoil.EvapCondEffect(PerfModeNum) > 1.0) {
1789 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1790 0 : ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields2(10)));
1791 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(10)));
1792 0 : ErrorsFound = true;
1793 : }
1794 :
1795 8 : thisDXCoil.EvapCondAirFlow(PerfModeNum) = Numbers2(11);
1796 8 : if (thisDXCoil.EvapCondAirFlow(PerfModeNum) < 0.0 && thisDXCoil.EvapCondAirFlow(PerfModeNum) != AutoSize) {
1797 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1798 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields2(11)));
1799 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(11)));
1800 0 : ErrorsFound = true;
1801 : }
1802 :
1803 8 : thisDXCoil.EvapCondPumpElecNomPower(PerfModeNum) = Numbers2(12);
1804 8 : if (thisDXCoil.EvapCondPumpElecNomPower(PerfModeNum) < 0.0 && thisDXCoil.EvapCondAirFlow(PerfModeNum) != AutoSize) {
1805 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1806 0 : ShowContinueError(state, format("...{} cannot be less than zero.", cNumericFields2(12)));
1807 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(12)));
1808 0 : ErrorsFound = true;
1809 : }
1810 :
1811 8 : thisDXCoil.RatedEIR(PerfModeNum) = 1.0 / thisDXCoil.RatedCOP(PerfModeNum);
1812 :
1813 : // read in user specified SHR modifier curves
1814 8 : if (!lAlphaBlanks2(9) && NumAlphas2 > 8) {
1815 0 : thisDXCoil.SHRFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(9)); // convert curve name to number
1816 0 : if (thisDXCoil.SHRFTemp(PerfModeNum) == 0) {
1817 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1818 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(9), Alphas2(9)));
1819 : } else {
1820 : // Verify Curve Object, only legal type is BiQuadratic
1821 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1822 0 : thisDXCoil.SHRFTemp(PerfModeNum), // Curve index
1823 : {2}, // Valid dimensions
1824 : RoutineName, // Routine name
1825 : CurrentModuleObject, // Object Type
1826 : thisDXCoil.Name, // Object Name
1827 0 : cAlphaFields2(9)); // Field Name
1828 : }
1829 : }
1830 :
1831 8 : if (!lAlphaBlanks2(10) && NumAlphas2 > 9) {
1832 0 : thisDXCoil.SHRFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(10)); // convert curve name to number
1833 0 : if (thisDXCoil.SHRFTemp(PerfModeNum) == 0) {
1834 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1835 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(10), Alphas2(10)));
1836 : } else {
1837 : // Verify Curve Object, only legal type is BiQuadratic
1838 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1839 0 : thisDXCoil.SHRFFlow(PerfModeNum), // Curve index
1840 : {1}, // Valid dimensions
1841 : RoutineName, // Routine name
1842 : CurrentModuleObject, // Object Type
1843 : thisDXCoil.Name, // Object Name
1844 0 : cAlphaFields2(10)); // Field Name
1845 : }
1846 : }
1847 8 : if (thisDXCoil.SHRFTemp(PerfModeNum) > 0 && thisDXCoil.SHRFFlow(PerfModeNum) > 0) {
1848 0 : thisDXCoil.UserSHRCurveExists = true;
1849 : } else {
1850 8 : thisDXCoil.UserSHRCurveExists = false;
1851 : }
1852 :
1853 : } else { // invalid performance object
1854 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1855 0 : ShowContinueError(state, format("... not found {}=\"{}\".", PerfObjectType, PerfObjectName));
1856 0 : ErrorsFound = true;
1857 : } // end of valid performance object check
1858 8 : AlphaIndex += 2;
1859 : } // end of sufficient number of fields entered check
1860 : } // End of multimode DX capacity stages loop
1861 : // Warn if inputs entered for unused capacity stages
1862 4 : for (CapacityStageNum = (thisDXCoil.NumCapacityStages + 1); CapacityStageNum <= MaxCapacityStages; ++CapacityStageNum) {
1863 0 : if ((AlphaIndex <= NumAlphas) && ((!Alphas(AlphaIndex).empty()) || (!Alphas(AlphaIndex + 1).empty()))) {
1864 0 : ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1865 0 : ShowContinueError(state, format("...Capacity Stage {} not active. Therefore,{}", CapacityStageNum, cAlphaFields(AlphaIndex)));
1866 0 : ShowContinueError(state, format("... and {} fields will be ignored.", cAlphaFields(AlphaIndex + 1)));
1867 : }
1868 0 : AlphaIndex += 2;
1869 : } // End of unused capacity stages loop
1870 : } // End of multimode DX dehumidification modes loo
1871 :
1872 : // Get Water System tank connections
1873 : // A14, \field Name of Water Storage Tank for Supply
1874 2 : thisDXCoil.EvapWaterSupplyName = Alphas(14);
1875 2 : if (lAlphaBlanks(14)) {
1876 2 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
1877 : } else {
1878 0 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
1879 0 : SetupTankDemandComponent(state,
1880 : thisDXCoil.Name,
1881 : CurrentModuleObject,
1882 : thisDXCoil.EvapWaterSupplyName,
1883 : ErrorsFound,
1884 0 : thisDXCoil.EvapWaterSupTankID,
1885 0 : thisDXCoil.EvapWaterTankDemandARRID);
1886 : }
1887 :
1888 : // A15; \field Name of Water Storage Tank for Condensate Collection
1889 2 : thisDXCoil.CondensateCollectName = Alphas(15);
1890 2 : if (lAlphaBlanks(15)) {
1891 2 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
1892 : } else {
1893 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
1894 0 : SetupTankSupplyComponent(state,
1895 : thisDXCoil.Name,
1896 : CurrentModuleObject,
1897 : thisDXCoil.CondensateCollectName,
1898 : ErrorsFound,
1899 0 : thisDXCoil.CondensateTankID,
1900 0 : thisDXCoil.CondensateTankSupplyARRID);
1901 : }
1902 :
1903 : // Set minimum OAT for compressor operation
1904 2 : thisDXCoil.MinOATCompressor = Numbers(5);
1905 2 : if (NumNumbers < 5)
1906 0 : thisDXCoil.MinOATCompressor = minOATCompDXCooling; // input field is after min fields and won't default if field not included
1907 :
1908 : // Basin heater power as a function of temperature must be greater than or equal to 0
1909 2 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(6);
1910 2 : if (Numbers(6) < 0.0) {
1911 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1912 0 : ShowContinueError(state, format("...{} must be >= 0.", cNumericFields(6)));
1913 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(6)));
1914 0 : ErrorsFound = true;
1915 : }
1916 :
1917 2 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(7);
1918 2 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
1919 0 : if (NumNumbers < 7) {
1920 0 : thisDXCoil.BasinHeaterSetPointTemp = 2.0;
1921 : }
1922 0 : if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
1923 0 : ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1924 0 : ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(7)));
1925 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(7)));
1926 : }
1927 : }
1928 :
1929 2 : if (!lAlphaBlanks(16)) {
1930 0 : if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(16))) == nullptr) {
1931 0 : ShowWarningItemNotFound(
1932 0 : state, eoh, cAlphaFields(16), Alphas(16), "Basin heater will be available to operate throughout the simulation.");
1933 : }
1934 : }
1935 :
1936 : } // end of the Multimode DX coil loop
1937 :
1938 135 : if (ErrorsFound) {
1939 0 : ShowFatalError(state,
1940 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
1941 : }
1942 :
1943 : //************* Read Heat Pump (DX Heating Coil) Input **********
1944 135 : CurrentModuleObject = "Coil:Heating:DX:SingleSpeed";
1945 147 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXHeatingCoils; ++DXCoilIndex) {
1946 :
1947 12 : ++DXCoilNum;
1948 :
1949 12 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1950 : CurrentModuleObject,
1951 : DXCoilIndex,
1952 : Alphas,
1953 : NumAlphas,
1954 : Numbers,
1955 : NumNumbers,
1956 : IOStatus,
1957 : lNumericBlanks,
1958 : lAlphaBlanks,
1959 : cAlphaFields,
1960 : cNumericFields);
1961 :
1962 12 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
1963 : // allocate single performance mode for numeric field strings used for sizing routine
1964 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
1965 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
1966 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
1967 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
1968 12 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
1969 :
1970 12 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
1971 12 : thisDXCoil.Name = Alphas(1);
1972 12 : thisDXCoil.DXCoilType = CurrentModuleObject;
1973 12 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatingEmpirical;
1974 12 : if (lAlphaBlanks(2)) {
1975 3 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
1976 9 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
1977 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
1978 0 : ErrorsFound = true;
1979 : }
1980 :
1981 12 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
1982 12 : Alphas(3),
1983 : ErrorsFound,
1984 : DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
1985 12 : Alphas(1),
1986 : DataLoopNode::NodeFluidType::Air,
1987 : DataLoopNode::ConnectionType::Inlet,
1988 : NodeInputManager::CompFluidStream::Primary,
1989 : ObjectIsNotParent);
1990 :
1991 24 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
1992 12 : Alphas(4),
1993 : ErrorsFound,
1994 : DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
1995 12 : Alphas(1),
1996 : DataLoopNode::NodeFluidType::Air,
1997 : DataLoopNode::ConnectionType::Outlet,
1998 : NodeInputManager::CompFluidStream::Primary,
1999 : ObjectIsNotParent);
2000 :
2001 12 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
2002 :
2003 12 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
2004 12 : if (thisDXCoil.CCapFTemp(1) == 0) {
2005 0 : if (lAlphaBlanks(5)) {
2006 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2007 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
2008 : } else {
2009 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2010 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
2011 : }
2012 0 : ErrorsFound = true;
2013 : } else {
2014 : // only legal types are Quadratic, BiQuadratic and Cubic
2015 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2016 12 : thisDXCoil.CCapFTemp(1), // Curve index
2017 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2018 : RoutineName, // Routine name
2019 : CurrentModuleObject, // Object Type
2020 : thisDXCoil.Name, // Object Name
2021 12 : cAlphaFields(5)); // Field Name
2022 :
2023 12 : if (!ErrorsFound) {
2024 12 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
2025 7 : checkCurveIsNormalizedToOne(state,
2026 21 : std::string{RoutineName} + CurrentModuleObject,
2027 7 : thisDXCoil.Name,
2028 7 : thisDXCoil.CCapFTemp(1),
2029 7 : cAlphaFields(5),
2030 7 : Alphas(5),
2031 : RatedOutdoorAirTempHeat);
2032 : } else {
2033 5 : checkCurveIsNormalizedToOne(state,
2034 15 : std::string{RoutineName} + CurrentModuleObject,
2035 5 : thisDXCoil.Name,
2036 5 : thisDXCoil.CCapFTemp(1),
2037 5 : cAlphaFields(5),
2038 5 : Alphas(5),
2039 : RatedInletAirTempHeat,
2040 : RatedOutdoorAirTempHeat);
2041 : }
2042 : }
2043 : }
2044 :
2045 12 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
2046 12 : if (thisDXCoil.CCapFFlow(1) == 0) {
2047 0 : if (lAlphaBlanks(6)) {
2048 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2049 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
2050 : } else {
2051 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2052 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
2053 : }
2054 0 : ErrorsFound = true;
2055 : } else {
2056 : // Verify Curve Object, only legal type is Quadratic
2057 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2058 12 : thisDXCoil.CCapFFlow(1), // Curve index
2059 : {1}, // Valid dimensions
2060 : RoutineName, // Routine name
2061 : CurrentModuleObject, // Object Type
2062 : thisDXCoil.Name, // Object Name
2063 12 : cAlphaFields(6)); // Field Name
2064 :
2065 12 : if (!ErrorsFound) {
2066 12 : checkCurveIsNormalizedToOne(
2067 48 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
2068 : }
2069 : }
2070 :
2071 12 : thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
2072 12 : if (thisDXCoil.EIRFTemp(1) == 0) {
2073 0 : if (lAlphaBlanks(7)) {
2074 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2075 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
2076 : } else {
2077 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2078 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
2079 : }
2080 0 : ErrorsFound = true;
2081 : } else {
2082 : // only legal types are Quadratic, BiQuadratic and Cubic
2083 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2084 12 : thisDXCoil.EIRFTemp(1), // Curve index
2085 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2086 : RoutineName, // Routine name
2087 : CurrentModuleObject, // Object Type
2088 : thisDXCoil.Name, // Object Name
2089 12 : cAlphaFields(7)); // Field Name
2090 :
2091 12 : if (!ErrorsFound) {
2092 12 : if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(1))->numDims == 1) {
2093 7 : checkCurveIsNormalizedToOne(state,
2094 21 : std::string{RoutineName} + CurrentModuleObject,
2095 7 : thisDXCoil.Name,
2096 7 : thisDXCoil.EIRFTemp(1),
2097 7 : cAlphaFields(7),
2098 7 : Alphas(7),
2099 : RatedOutdoorAirTempHeat);
2100 : } else {
2101 5 : checkCurveIsNormalizedToOne(state,
2102 15 : std::string{RoutineName} + CurrentModuleObject,
2103 5 : thisDXCoil.Name,
2104 5 : thisDXCoil.EIRFTemp(1),
2105 5 : cAlphaFields(7),
2106 5 : Alphas(7),
2107 : RatedInletAirTempHeat,
2108 : RatedOutdoorAirTempHeat);
2109 : }
2110 : }
2111 : }
2112 :
2113 12 : thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
2114 12 : if (thisDXCoil.EIRFFlow(1) == 0) {
2115 0 : if (lAlphaBlanks(8)) {
2116 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2117 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
2118 : } else {
2119 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2120 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
2121 : }
2122 0 : ErrorsFound = true;
2123 : } else {
2124 : // Verify Curve Object, only legal type is Quadratic or Cubic
2125 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2126 12 : thisDXCoil.EIRFFlow(1), // Curve index
2127 : {1}, // Valid dimensions
2128 : RoutineName, // Routine name
2129 : CurrentModuleObject, // Object Type
2130 : thisDXCoil.Name, // Object Name
2131 12 : cAlphaFields(8)); // Field Name
2132 :
2133 12 : if (!ErrorsFound) {
2134 12 : checkCurveIsNormalizedToOne(
2135 48 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
2136 : }
2137 : }
2138 :
2139 12 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
2140 12 : if (thisDXCoil.PLFFPLR(1) == 0) {
2141 0 : if (lAlphaBlanks(9)) {
2142 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2143 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
2144 : } else {
2145 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2146 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
2147 : }
2148 0 : ErrorsFound = true;
2149 : } else {
2150 : // Verify Curve Object, only legal types are Quadratic or Cubic
2151 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2152 12 : thisDXCoil.PLFFPLR(1), // Curve index
2153 : {1}, // Valid dimensions
2154 : RoutineName, // Routine name
2155 : CurrentModuleObject, // Object Type
2156 : thisDXCoil.Name, // Object Name
2157 12 : cAlphaFields(9)); // Field Name
2158 :
2159 12 : if (!ErrorsFound) {
2160 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
2161 12 : MinCurveVal = 999.0;
2162 12 : MaxCurveVal = -999.0;
2163 12 : CurveInput = 0.0;
2164 1212 : while (CurveInput <= 1.0) {
2165 1200 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
2166 1200 : if (CurveVal < MinCurveVal) {
2167 12 : MinCurveVal = CurveVal;
2168 12 : MinCurvePLR = CurveInput;
2169 : }
2170 1200 : if (CurveVal > MaxCurveVal) {
2171 854 : MaxCurveVal = CurveVal;
2172 854 : MaxCurvePLR = CurveInput;
2173 : }
2174 1200 : CurveInput += 0.01;
2175 : }
2176 12 : if (MinCurveVal < 0.7) {
2177 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2178 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
2179 0 : ShowContinueError(state,
2180 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
2181 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
2182 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
2183 : }
2184 :
2185 12 : if (MaxCurveVal > 1.0) {
2186 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2187 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
2188 0 : ShowContinueError(state,
2189 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
2190 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
2191 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
2192 : }
2193 : }
2194 : }
2195 :
2196 : // Only required for reverse cycle heat pumps
2197 12 : thisDXCoil.DefrostEIRFT = GetCurveIndex(state, Alphas(10)); // convert curve name to number
2198 : // A11; \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
2199 12 : if (!lAlphaBlanks(11)) {
2200 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(11));
2201 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
2202 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(11), Alphas(11)));
2203 0 : ErrorsFound = true;
2204 : } else {
2205 6 : ErrorsFound |= Curve::CheckCurveDims(state,
2206 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
2207 : {1}, // Valid dimensions
2208 : RoutineName, // Routine name
2209 : CurrentModuleObject, // Object Type
2210 : thisDXCoil.Name, // Object Name
2211 2 : cAlphaFields(11)); // Field Name
2212 : }
2213 : }
2214 :
2215 12 : if (Util::SameString(Alphas(12), "ReverseCycle")) {
2216 :
2217 3 : if (thisDXCoil.DefrostEIRFT == 0) {
2218 0 : if (lAlphaBlanks(10)) {
2219 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2220 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(10)));
2221 0 : ShowContinueError(state, format("...field is required because {} is \"ReverseCycle\".", cAlphaFields(12)));
2222 : } else {
2223 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2224 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
2225 : }
2226 0 : ErrorsFound = true;
2227 : } else {
2228 : // Verify Curve Object, only legal type is BiQuadratic
2229 6 : ErrorsFound |= Curve::CheckCurveDims(state,
2230 : thisDXCoil.DefrostEIRFT, // Curve index
2231 : {2}, // Valid dimensions
2232 : RoutineName, // Routine name
2233 : CurrentModuleObject, // Object Type
2234 : thisDXCoil.Name, // Object Name
2235 3 : cAlphaFields(10)); // Field Name
2236 :
2237 3 : if (!ErrorsFound) {
2238 3 : checkCurveIsNormalizedToOne(state,
2239 9 : std::string{RoutineName} + CurrentModuleObject,
2240 3 : thisDXCoil.Name,
2241 : thisDXCoil.DefrostEIRFT,
2242 3 : cAlphaFields(10),
2243 3 : Alphas(10),
2244 : RatedInletAirTempHeat,
2245 : RatedOutdoorAirTempHeat);
2246 : }
2247 : }
2248 : }
2249 :
2250 12 : if (Util::SameString(Alphas(12), "ReverseCycle")) thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
2251 12 : if (Util::SameString(Alphas(12), "Resistive")) thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
2252 :
2253 12 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
2254 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2255 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(12), Alphas(12)));
2256 0 : ShowContinueError(state, "...valid values for this field are ReverseCycle or Resistive.");
2257 0 : ErrorsFound = true;
2258 : }
2259 :
2260 12 : if (Util::SameString(Alphas(13), "Timed")) thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::Timed;
2261 12 : if (Util::SameString(Alphas(13), "OnDemand")) thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
2262 12 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
2263 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2264 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(13), Alphas(13)));
2265 0 : ShowContinueError(state, "...valid values for this field are Timed or OnDemand.");
2266 0 : ErrorsFound = true;
2267 : }
2268 :
2269 12 : thisDXCoil.RatedSHR(1) = 1.0;
2270 12 : thisDXCoil.RatedTotCap(1) = Numbers(1);
2271 12 : thisDXCoil.RatedCOP(1) = Numbers(2);
2272 12 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(3);
2273 12 : thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(4);
2274 12 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(5);
2275 :
2276 : // Set minimum OAT for heat pump compressor operation
2277 12 : thisDXCoil.MinOATCompressor = Numbers(6);
2278 :
2279 12 : thisDXCoil.OATempCompressorOn = Numbers(7);
2280 :
2281 12 : if (lNumericBlanks(7) || lNumericBlanks(6)) { //??TBD:BPS 6 or 5 | 7 or 6
2282 12 : thisDXCoil.OATempCompressorOnOffBlank = true;
2283 : } else {
2284 0 : thisDXCoil.OATempCompressorOnOffBlank = false;
2285 : }
2286 :
2287 12 : if (thisDXCoil.OATempCompressorOn < thisDXCoil.MinOATCompressor) thisDXCoil.OATempCompressorOn = thisDXCoil.MinOATCompressor;
2288 :
2289 : // Set maximum outdoor temp for defrost to occur
2290 12 : thisDXCoil.MaxOATDefrost = Numbers(8);
2291 :
2292 : // Set crankcase heater capacity
2293 12 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(9);
2294 12 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
2295 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2296 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(8)));
2297 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(9)));
2298 0 : ErrorsFound = true;
2299 : }
2300 :
2301 : // Set crankcase heater cutout temperature
2302 12 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(10);
2303 :
2304 : // Set defrost time period
2305 12 : thisDXCoil.DefrostTime = Numbers(11);
2306 12 : if (thisDXCoil.DefrostTime == 0.0 && thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
2307 0 : ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2308 0 : ShowContinueError(state, format("...{} = 0.0 for defrost control = TIMED.", cNumericFields(11)));
2309 : }
2310 :
2311 : // Set defrost capacity (for resistive defrost)
2312 12 : thisDXCoil.DefrostCapacity = Numbers(12);
2313 12 : if (thisDXCoil.DefrostCapacity == 0.0 && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
2314 0 : ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2315 0 : ShowContinueError(state, format("...{} = 0.0 for defrost strategy = RESISTIVE.", cNumericFields(12)));
2316 : }
2317 :
2318 : // Set Region number for calculating HSPF
2319 12 : thisDXCoil.RegionNum = Numbers(13);
2320 :
2321 12 : if (lNumericBlanks(13)) {
2322 11 : thisDXCoil.RegionNum = 4;
2323 : }
2324 :
2325 12 : thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
2326 :
2327 : // A14 is optional evaporator node name
2328 12 : if (lAlphaBlanks(14)) {
2329 12 : thisDXCoil.CondenserInletNodeNum(1) = 0;
2330 : } else {
2331 0 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
2332 0 : Alphas(14),
2333 : ErrorsFound,
2334 : DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
2335 0 : thisDXCoil.Name,
2336 : DataLoopNode::NodeFluidType::Air,
2337 : DataLoopNode::ConnectionType::OutsideAirReference,
2338 : NodeInputManager::CompFluidStream::Primary,
2339 : ObjectIsNotParent);
2340 : // warn if not an outdoor node, but allow
2341 0 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
2342 0 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2343 0 : ShowContinueError(
2344 : state,
2345 0 : format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(14), Alphas(14)));
2346 0 : ShowContinueError(
2347 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
2348 : }
2349 : }
2350 :
2351 : // A14, \field Zone Name for Evaporator Placement
2352 12 : if (!lAlphaBlanks(15) && NumAlphas > 14) {
2353 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(15), state.dataHeatBal->Zone);
2354 0 : if (thisDXCoil.SecZonePtr > 0) {
2355 0 : SetupZoneInternalGain(state,
2356 : thisDXCoil.SecZonePtr,
2357 : thisDXCoil.Name,
2358 : DataHeatBalance::IntGainType::SecHeatingDXCoilSingleSpeed,
2359 : &thisDXCoil.SecCoilSensibleHeatRemovalRate,
2360 : nullptr,
2361 : nullptr,
2362 : &thisDXCoil.SecCoilLatentHeatRemovalRate);
2363 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
2364 : } else {
2365 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2366 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15), Alphas(15)));
2367 : }
2368 : }
2369 12 : if (thisDXCoil.SecZonePtr > 0) {
2370 : // N14, \field Secondary Coil Air Flow Rate
2371 0 : if (!lNumericBlanks(13)) {
2372 0 : thisDXCoil.SecCoilAirFlow = Numbers(14);
2373 : }
2374 : // N15, \field Secondary Coil Fan Flow Scaling Factor
2375 0 : if (!lNumericBlanks(15)) {
2376 0 : thisDXCoil.SecCoilAirFlowScalingFactor = Numbers(15);
2377 : }
2378 : // N16, \field Nominal Sensible Heat Ratio of Secondary Coil
2379 0 : if (!lNumericBlanks(16)) {
2380 0 : thisDXCoil.SecCoilRatedSHR = Numbers(16);
2381 : } else {
2382 0 : thisDXCoil.SecCoilRatedSHR = 1.0;
2383 : }
2384 : // A16, \field Sensible Heat Ratio Modifier Function of Temperature Curve Name
2385 0 : if (!lAlphaBlanks(16)) {
2386 0 : thisDXCoil.SecCoilSHRFT = GetCurveIndex(state, Alphas(16));
2387 0 : if (thisDXCoil.SecCoilSHRFT == 0) {
2388 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2389 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
2390 : }
2391 : }
2392 : // A17; \field Sensible Heat Ratio Function of Flow Fraction Curve Name
2393 0 : if (!lAlphaBlanks(17)) {
2394 0 : thisDXCoil.SecCoilSHRFF = GetCurveIndex(state, Alphas(17));
2395 0 : if (thisDXCoil.SecCoilSHRFF == 0) {
2396 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2397 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
2398 : }
2399 : }
2400 : }
2401 :
2402 : } // end of the DX heating coil loop
2403 :
2404 135 : if (ErrorsFound) {
2405 0 : ShowFatalError(state,
2406 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
2407 : }
2408 :
2409 135 : CurrentModuleObject = "Coil:Cooling:DX:TwoSpeed";
2410 147 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedCoils; ++DXCoilIndex) {
2411 :
2412 12 : ++DXCoilNum;
2413 :
2414 12 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2415 : CurrentModuleObject,
2416 : DXCoilIndex,
2417 : Alphas,
2418 : NumAlphas,
2419 : Numbers,
2420 : NumNumbers,
2421 : IOStatus,
2422 : lNumericBlanks,
2423 : lAlphaBlanks,
2424 : cAlphaFields,
2425 : cNumericFields);
2426 :
2427 12 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
2428 :
2429 : // allocate single performance mode for numeric field strings used for sizing routine
2430 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
2431 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
2432 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
2433 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
2434 12 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
2435 :
2436 12 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
2437 12 : thisDXCoil.Name = Alphas(1);
2438 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
2439 12 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
2440 12 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
2441 12 : thisDXCoil.DXCoilType = CurrentModuleObject;
2442 12 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingTwoSpeed;
2443 12 : if (lAlphaBlanks(2)) {
2444 2 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
2445 10 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
2446 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
2447 0 : ErrorsFound = true;
2448 : }
2449 12 : thisDXCoil.RatedTotCap(1) = Numbers(1);
2450 12 : thisDXCoil.RatedSHR(1) = Numbers(2);
2451 12 : thisDXCoil.RatedCOP(1) = Numbers(3);
2452 12 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(4);
2453 :
2454 12 : thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(5);
2455 12 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(6);
2456 :
2457 12 : if (!lNumericBlanks(7)) {
2458 5 : thisDXCoil.InternalStaticPressureDrop = Numbers(7);
2459 5 : thisDXCoil.RateWithInternalStaticAndFanObject = true;
2460 : } else {
2461 7 : thisDXCoil.InternalStaticPressureDrop = -999.0;
2462 7 : thisDXCoil.RateWithInternalStaticAndFanObject = false;
2463 : }
2464 :
2465 12 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
2466 12 : Alphas(3),
2467 : ErrorsFound,
2468 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
2469 12 : Alphas(1),
2470 : DataLoopNode::NodeFluidType::Air,
2471 : DataLoopNode::ConnectionType::Inlet,
2472 : NodeInputManager::CompFluidStream::Primary,
2473 : ObjectIsNotParent);
2474 :
2475 24 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
2476 12 : Alphas(4),
2477 : ErrorsFound,
2478 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
2479 12 : Alphas(1),
2480 : DataLoopNode::NodeFluidType::Air,
2481 : DataLoopNode::ConnectionType::Outlet,
2482 : NodeInputManager::CompFluidStream::Primary,
2483 : ObjectIsNotParent);
2484 :
2485 12 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
2486 :
2487 12 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
2488 12 : if (thisDXCoil.CCapFTemp(1) == 0) {
2489 0 : if (lAlphaBlanks(5)) {
2490 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2491 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
2492 : } else {
2493 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2494 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
2495 : }
2496 0 : ErrorsFound = true;
2497 : } else {
2498 : // Verify Curve Object, only legal type is BiQuadratic
2499 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2500 12 : thisDXCoil.CCapFTemp(1), // Curve index
2501 : {2}, // Valid dimensions
2502 : RoutineName, // Routine name
2503 : CurrentModuleObject, // Object Type
2504 : thisDXCoil.Name, // Object Name
2505 12 : cAlphaFields(5)); // Field Name
2506 :
2507 12 : if (!ErrorsFound) {
2508 12 : checkCurveIsNormalizedToOne(state,
2509 36 : std::string{RoutineName} + CurrentModuleObject,
2510 12 : thisDXCoil.Name,
2511 12 : thisDXCoil.CCapFTemp(1),
2512 12 : cAlphaFields(5),
2513 12 : Alphas(5),
2514 : RatedInletWetBulbTemp,
2515 : RatedOutdoorAirTemp);
2516 : }
2517 : }
2518 :
2519 12 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
2520 12 : if (thisDXCoil.CCapFFlow(1) == 0) {
2521 0 : if (lAlphaBlanks(6)) {
2522 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2523 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
2524 : } else {
2525 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2526 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
2527 : }
2528 0 : ErrorsFound = true;
2529 : } else {
2530 : // Verify Curve Object, only legal type is Quadratic
2531 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2532 12 : thisDXCoil.CCapFFlow(1), // Curve index
2533 : {1}, // Valid dimensions
2534 : RoutineName, // Routine name
2535 : CurrentModuleObject, // Object Type
2536 : thisDXCoil.Name, // Object Name
2537 12 : cAlphaFields(6)); // Field Name
2538 :
2539 12 : if (!ErrorsFound) {
2540 12 : checkCurveIsNormalizedToOne(
2541 48 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
2542 : }
2543 : }
2544 :
2545 12 : thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
2546 12 : if (thisDXCoil.EIRFTemp(1) == 0) {
2547 0 : if (lAlphaBlanks(7)) {
2548 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2549 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
2550 : } else {
2551 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2552 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
2553 : }
2554 0 : ErrorsFound = true;
2555 : } else {
2556 : // Verify Curve Object, only legal type is BiQuadratic
2557 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2558 12 : thisDXCoil.EIRFTemp(1), // Curve index
2559 : {2}, // Valid dimensions
2560 : RoutineName, // Routine name
2561 : CurrentModuleObject, // Object Type
2562 : thisDXCoil.Name, // Object Name
2563 12 : cAlphaFields(7)); // Field Name
2564 :
2565 12 : if (!ErrorsFound) {
2566 12 : checkCurveIsNormalizedToOne(state,
2567 36 : std::string{RoutineName} + CurrentModuleObject,
2568 12 : thisDXCoil.Name,
2569 12 : thisDXCoil.EIRFTemp(1),
2570 12 : cAlphaFields(7),
2571 12 : Alphas(7),
2572 : RatedInletWetBulbTemp,
2573 : RatedOutdoorAirTemp);
2574 : }
2575 : }
2576 :
2577 12 : thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
2578 12 : if (thisDXCoil.EIRFFlow(1) == 0) {
2579 0 : if (lAlphaBlanks(8)) {
2580 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2581 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
2582 : } else {
2583 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2584 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
2585 : }
2586 0 : ErrorsFound = true;
2587 : } else {
2588 : // Verify Curve Object, only legal type is Quadratic
2589 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2590 12 : thisDXCoil.EIRFFlow(1), // Curve index
2591 : {1}, // Valid dimensions
2592 : RoutineName, // Routine name
2593 : CurrentModuleObject, // Object Type
2594 : thisDXCoil.Name, // Object Name
2595 12 : cAlphaFields(8)); // Field Name
2596 :
2597 12 : if (!ErrorsFound) {
2598 12 : checkCurveIsNormalizedToOne(
2599 48 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
2600 : }
2601 : }
2602 :
2603 12 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
2604 12 : if (thisDXCoil.PLFFPLR(1) == 0) {
2605 0 : if (lAlphaBlanks(9)) {
2606 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2607 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
2608 : } else {
2609 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2610 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
2611 : }
2612 0 : ErrorsFound = true;
2613 : } else {
2614 : // Verify Curve Object, only legal types are Quadratic or Cubic
2615 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2616 12 : thisDXCoil.PLFFPLR(1), // Curve index
2617 : {1}, // Valid dimensions
2618 : RoutineName, // Routine name
2619 : CurrentModuleObject, // Object Type
2620 : thisDXCoil.Name, // Object Name
2621 12 : cAlphaFields(9)); // Field Name
2622 :
2623 12 : if (!ErrorsFound) {
2624 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
2625 12 : MinCurveVal = 999.0;
2626 12 : MaxCurveVal = -999.0;
2627 12 : CurveInput = 0.0;
2628 1212 : while (CurveInput <= 1.0) {
2629 1200 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
2630 1200 : if (CurveVal < MinCurveVal) {
2631 12 : MinCurveVal = CurveVal;
2632 12 : MinCurvePLR = CurveInput;
2633 : }
2634 1200 : if (CurveVal > MaxCurveVal) {
2635 1052 : MaxCurveVal = CurveVal;
2636 1052 : MaxCurvePLR = CurveInput;
2637 : }
2638 1200 : CurveInput += 0.01;
2639 : }
2640 12 : if (MinCurveVal < 0.7) {
2641 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2642 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
2643 0 : ShowContinueError(state,
2644 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
2645 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
2646 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
2647 : }
2648 :
2649 12 : if (MaxCurveVal > 1.0) {
2650 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2651 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
2652 0 : ShowContinueError(state,
2653 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
2654 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
2655 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
2656 : }
2657 : }
2658 : }
2659 :
2660 12 : thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
2661 :
2662 12 : thisDXCoil.RatedTotCap2 = Numbers(8);
2663 12 : thisDXCoil.RatedSHR2 = Numbers(9);
2664 12 : thisDXCoil.RatedCOP2 = Numbers(10);
2665 12 : thisDXCoil.RatedAirVolFlowRate2 = Numbers(11);
2666 :
2667 12 : thisDXCoil.FanPowerPerEvapAirFlowRate_LowSpeed(1) = Numbers(12);
2668 12 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023_LowSpeed(1) = Numbers(13);
2669 :
2670 12 : if (lNumericBlanks(14)) {
2671 11 : thisDXCoil.MinOATCompressor = -25.0;
2672 : } else {
2673 1 : thisDXCoil.MinOATCompressor = Numbers(14);
2674 : }
2675 :
2676 12 : thisDXCoil.CCapFTemp2 = GetCurveIndex(state, Alphas(10)); // convert curve name to number
2677 12 : if (thisDXCoil.CCapFTemp2 == 0) {
2678 0 : if (lAlphaBlanks(10)) {
2679 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2680 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(10)));
2681 : } else {
2682 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2683 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
2684 : }
2685 0 : ErrorsFound = true;
2686 : } else {
2687 : // Verify Curve Object, only legal type is BiQuadratic
2688 24 : ErrorsFound |= Curve::CheckCurveDims(state,
2689 : thisDXCoil.CCapFTemp2, // Curve index
2690 : {2}, // Valid dimensions
2691 : RoutineName, // Routine name
2692 : CurrentModuleObject, // Object Type
2693 : thisDXCoil.Name, // Object Name
2694 12 : cAlphaFields(10)); // Field Name
2695 :
2696 12 : if (!ErrorsFound) {
2697 12 : checkCurveIsNormalizedToOne(state,
2698 36 : std::string{RoutineName} + CurrentModuleObject,
2699 12 : thisDXCoil.Name,
2700 : thisDXCoil.CCapFTemp2,
2701 12 : cAlphaFields(10),
2702 12 : Alphas(10),
2703 : RatedInletWetBulbTemp,
2704 : RatedOutdoorAirTemp);
2705 : }
2706 : }
2707 :
2708 12 : thisDXCoil.EIRFTemp2 = GetCurveIndex(state, Alphas(11)); // convert curve name to number
2709 12 : if (thisDXCoil.EIRFTemp2 == 0) {
2710 0 : if (lAlphaBlanks(11)) {
2711 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2712 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(11)));
2713 : } else {
2714 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2715 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
2716 : }
2717 0 : ErrorsFound = true;
2718 : } else {
2719 : // Verify Curve Object, only legal type is BiQuadratic
2720 24 : ErrorsFound |= Curve::CheckCurveDims(state,
2721 : thisDXCoil.EIRFTemp2, // Curve index
2722 : {2}, // Valid dimensions
2723 : RoutineName, // Routine name
2724 : CurrentModuleObject, // Object Type
2725 : thisDXCoil.Name, // Object Name
2726 12 : cAlphaFields(11)); // Field Name
2727 :
2728 12 : if (!ErrorsFound) {
2729 12 : checkCurveIsNormalizedToOne(state,
2730 36 : std::string{RoutineName} + CurrentModuleObject,
2731 12 : thisDXCoil.Name,
2732 : thisDXCoil.EIRFTemp2,
2733 12 : cAlphaFields(11),
2734 12 : Alphas(11),
2735 : RatedInletWetBulbTemp,
2736 : RatedOutdoorAirTemp);
2737 : }
2738 : }
2739 :
2740 : // outdoor condenser node
2741 12 : if (lAlphaBlanks(12)) {
2742 6 : thisDXCoil.CondenserInletNodeNum(1) = 0;
2743 : } else {
2744 12 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
2745 6 : Alphas(12),
2746 : ErrorsFound,
2747 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
2748 6 : thisDXCoil.Name,
2749 : DataLoopNode::NodeFluidType::Air,
2750 : DataLoopNode::ConnectionType::OutsideAirReference,
2751 : NodeInputManager::CompFluidStream::Primary,
2752 : ObjectIsNotParent);
2753 6 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
2754 4 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2755 8 : ShowContinueError(
2756 : state,
2757 8 : format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(12), Alphas(12)));
2758 12 : ShowContinueError(
2759 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
2760 : }
2761 : }
2762 :
2763 12 : if ((Util::SameString(Alphas(13), "AirCooled")) || lAlphaBlanks(13)) {
2764 10 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
2765 2 : } else if (Util::SameString(Alphas(13), "EvaporativelyCooled")) {
2766 2 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
2767 2 : thisDXCoil.ReportEvapCondVars = true;
2768 : } else {
2769 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2770 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(13), Alphas(13)));
2771 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
2772 0 : ErrorsFound = true;
2773 : }
2774 :
2775 12 : thisDXCoil.EvapCondEffect(1) = Numbers(15);
2776 12 : if (thisDXCoil.EvapCondEffect(1) < 0.0 || thisDXCoil.EvapCondEffect(1) > 1.0) {
2777 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2778 0 : ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields(15)));
2779 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(15)));
2780 0 : ErrorsFound = true;
2781 : }
2782 :
2783 12 : thisDXCoil.EvapCondAirFlow(1) = Numbers(16);
2784 12 : if (thisDXCoil.EvapCondAirFlow(1) < 0.0 && thisDXCoil.EvapCondAirFlow(1) != AutoSize) {
2785 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2786 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(16)));
2787 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(16)));
2788 0 : ErrorsFound = true;
2789 : }
2790 :
2791 12 : thisDXCoil.EvapCondPumpElecNomPower(1) = Numbers(17);
2792 12 : if (thisDXCoil.EvapCondPumpElecNomPower(1) < 0.0 && thisDXCoil.EvapCondPumpElecNomPower(1) != AutoSize) {
2793 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2794 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(17)));
2795 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(17)));
2796 0 : ErrorsFound = true;
2797 : }
2798 :
2799 12 : thisDXCoil.EvapCondEffect2 = Numbers(18);
2800 12 : if (thisDXCoil.EvapCondEffect2 < 0.0 || thisDXCoil.EvapCondEffect2 > 1.0) {
2801 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2802 0 : ShowContinueError(state, format("...{} cannot be cannot be < 0.0 or > 1.0.", cNumericFields(18)));
2803 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(18)));
2804 0 : ErrorsFound = true;
2805 : }
2806 :
2807 12 : thisDXCoil.EvapCondAirFlow2 = Numbers(19);
2808 12 : if (thisDXCoil.EvapCondAirFlow2 < 0.0 && thisDXCoil.EvapCondAirFlow2 != AutoSize) {
2809 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2810 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(19)));
2811 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(19)));
2812 0 : ErrorsFound = true;
2813 : }
2814 :
2815 12 : thisDXCoil.EvapCondPumpElecNomPower2 = Numbers(20);
2816 12 : if (thisDXCoil.EvapCondPumpElecNomPower2 < 0.0 && thisDXCoil.EvapCondPumpElecNomPower2 != AutoSize) {
2817 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2818 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(20)));
2819 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(20)));
2820 0 : ErrorsFound = true;
2821 : }
2822 :
2823 12 : thisDXCoil.RatedEIR2 = 1.0 / thisDXCoil.RatedCOP2;
2824 :
2825 : // Get Water System tank connections
2826 : // A14, \field Name of Water Storage Tank for Supply
2827 12 : thisDXCoil.EvapWaterSupplyName = Alphas(14);
2828 12 : if (lAlphaBlanks(14)) {
2829 12 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
2830 : } else {
2831 0 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
2832 0 : SetupTankDemandComponent(state,
2833 : thisDXCoil.Name,
2834 : CurrentModuleObject,
2835 : thisDXCoil.EvapWaterSupplyName,
2836 : ErrorsFound,
2837 0 : thisDXCoil.EvapWaterSupTankID,
2838 0 : thisDXCoil.EvapWaterTankDemandARRID);
2839 : }
2840 :
2841 : // A15; \field Name of Water Storage Tank for Condensate Collection
2842 12 : thisDXCoil.CondensateCollectName = Alphas(15);
2843 12 : if (lAlphaBlanks(15)) {
2844 12 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
2845 : } else {
2846 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
2847 0 : SetupTankSupplyComponent(state,
2848 : thisDXCoil.Name,
2849 : CurrentModuleObject,
2850 : thisDXCoil.CondensateCollectName,
2851 : ErrorsFound,
2852 0 : thisDXCoil.CondensateTankID,
2853 0 : thisDXCoil.CondensateTankSupplyARRID);
2854 : }
2855 :
2856 : // Basin heater power as a function of temperature must be greater than or equal to 0
2857 12 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(21);
2858 12 : if (Numbers(21) < 0.0) {
2859 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2860 0 : ShowContinueError(state, format("...{} must be >= 0.0.", cNumericFields(21)));
2861 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(21)));
2862 0 : ErrorsFound = true;
2863 : }
2864 :
2865 12 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(22);
2866 12 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
2867 4 : if (NumNumbers < 22) {
2868 0 : thisDXCoil.BasinHeaterSetPointTemp = 2.0;
2869 : }
2870 4 : if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
2871 0 : ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2872 0 : ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(22)));
2873 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(22)));
2874 : }
2875 : }
2876 :
2877 12 : if (!lAlphaBlanks(16)) {
2878 1 : if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(16))) == nullptr) {
2879 2 : ShowWarningItemNotFound(
2880 1 : state, eoh, cAlphaFields(16), Alphas(16), "Basin heater will be available to operate throughout the simulation.");
2881 : }
2882 : }
2883 :
2884 12 : if (!lAlphaBlanks(17) && NumAlphas > 16) {
2885 0 : thisDXCoil.SHRFTemp(1) = GetCurveIndex(state, Alphas(17)); // convert curve name to number
2886 : // DXCoil(DXCoilNum)%SHRFTemp2 = DXCoil(DXCoilNum)%SHRFTemp(1)
2887 0 : if (thisDXCoil.SHRFTemp(1) == 0) {
2888 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2889 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
2890 : } else {
2891 : // Verify Curve Object, only legal type is BiQuadratic
2892 0 : ErrorsFound |= Curve::CheckCurveDims(state,
2893 0 : thisDXCoil.SHRFTemp(1), // Curve index
2894 : {2}, // Valid dimensions
2895 : RoutineName, // Routine name
2896 : CurrentModuleObject, // Object Type
2897 : thisDXCoil.Name, // Object Name
2898 0 : cAlphaFields(17)); // Field Name
2899 : }
2900 : }
2901 :
2902 12 : if (!lAlphaBlanks(18) && NumAlphas > 17) {
2903 0 : thisDXCoil.SHRFFlow(1) = GetCurveIndex(state, Alphas(18)); // convert curve name to number
2904 : // DXCoil(DXCoilNum)%SHRFFlow2 = DXCoil(DXCoilNum)%SHRFFlow(1)
2905 0 : if (thisDXCoil.SHRFFlow(1) == 0) {
2906 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2907 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(18), Alphas(18)));
2908 : } else {
2909 : // Verify Curve Object, only legal type is BiQuadratic
2910 0 : ErrorsFound |= Curve::CheckCurveDims(state,
2911 0 : thisDXCoil.SHRFFlow(1), // Curve index
2912 : {1}, // Valid dimensions
2913 : RoutineName, // Routine name
2914 : CurrentModuleObject, // Object Type
2915 : thisDXCoil.Name, // Object Name
2916 0 : cAlphaFields(18)); // Field Name
2917 : }
2918 : }
2919 :
2920 12 : if (!lAlphaBlanks(19) && NumAlphas > 18) {
2921 0 : thisDXCoil.SHRFTemp2 = GetCurveIndex(state, Alphas(19)); // convert curve name to number
2922 0 : if (thisDXCoil.SHRFTemp2 == 0) {
2923 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2924 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(19), Alphas(19)));
2925 : } else {
2926 : // Verify Curve Object, only legal type is BiQuadratic
2927 0 : ErrorsFound |= Curve::CheckCurveDims(state,
2928 : thisDXCoil.SHRFTemp2, // Curve index
2929 : {2}, // Valid dimensions
2930 : RoutineName, // Routine name
2931 : CurrentModuleObject, // Object Type
2932 : thisDXCoil.Name, // Object Name
2933 0 : cAlphaFields(19)); // Field Name
2934 : }
2935 : }
2936 :
2937 12 : if (!lAlphaBlanks(20) && NumAlphas > 19) {
2938 0 : thisDXCoil.SHRFFlow2 = GetCurveIndex(state, Alphas(20)); // convert curve name to number
2939 0 : if (thisDXCoil.SHRFTemp2 == 0) {
2940 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2941 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(20), Alphas(20)));
2942 : } else {
2943 : // Verify Curve Object, only legal type is BiQuadratic
2944 0 : ErrorsFound |= Curve::CheckCurveDims(state,
2945 : thisDXCoil.SHRFFlow2, // Curve index
2946 : {1}, // Valid dimensions
2947 : RoutineName, // Routine name
2948 : CurrentModuleObject, // Object Type
2949 : thisDXCoil.Name, // Object Name
2950 0 : cAlphaFields(20)); // Field Name
2951 : }
2952 : }
2953 12 : if (thisDXCoil.SHRFTemp(1) > 0 && thisDXCoil.SHRFFlow(1) > 0 && thisDXCoil.SHRFTemp2 > 0 && thisDXCoil.SHRFFlow2 > 0) {
2954 0 : thisDXCoil.UserSHRCurveExists = true;
2955 : } else {
2956 12 : thisDXCoil.UserSHRCurveExists = false;
2957 : }
2958 : // A21; \field Zone Name for Condenser Placement
2959 12 : if (!lAlphaBlanks(21) && NumAlphas > 20) {
2960 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(21), state.dataHeatBal->Zone);
2961 0 : if (thisDXCoil.SecZonePtr > 0) {
2962 0 : SetupZoneInternalGain(state,
2963 : thisDXCoil.SecZonePtr,
2964 : thisDXCoil.Name,
2965 : DataHeatBalance::IntGainType::SecCoolingDXCoilTwoSpeed,
2966 : &thisDXCoil.SecCoilSensibleHeatGainRate);
2967 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
2968 : } else {
2969 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2970 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(21), Alphas(21)));
2971 : }
2972 : }
2973 : }
2974 :
2975 135 : if (ErrorsFound) {
2976 0 : ShowFatalError(state,
2977 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
2978 : }
2979 :
2980 : // Loop over the Pumped DX Water Heater Coils and get & load the data
2981 135 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped);
2982 144 : for (DXHPWaterHeaterCoilNum = 1; DXHPWaterHeaterCoilNum <= state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils; ++DXHPWaterHeaterCoilNum) {
2983 :
2984 9 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2985 : CurrentModuleObject,
2986 : DXHPWaterHeaterCoilNum,
2987 : Alphas,
2988 : NumAlphas,
2989 : Numbers,
2990 : NumNumbers,
2991 : IOStatus,
2992 : lNumericBlanks,
2993 : lAlphaBlanks,
2994 : cAlphaFields,
2995 : cNumericFields);
2996 :
2997 9 : ++DXCoilNum;
2998 :
2999 : // allocate single performance mode for numeric field strings used for sizing routine
3000 9 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
3001 9 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
3002 9 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
3003 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
3004 9 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
3005 :
3006 9 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
3007 9 : thisDXCoil.Name = Alphas(1);
3008 9 : thisDXCoil.DXCoilType = CurrentModuleObject;
3009 9 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatPumpWaterHeaterPumped;
3010 9 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOff(state); // heat pump water heater DX coil has no schedule
3011 :
3012 : // Store the HPWH DX coil heating capacity in RatedTotCap2. After backing off pump and fan heat,
3013 : // move to RatedTotCap() for use by DX coil
3014 9 : thisDXCoil.RatedTotCap2 = Numbers(1);
3015 9 : if (thisDXCoil.RatedTotCap2 <= 0.0) {
3016 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3017 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
3018 0 : ErrorsFound = true;
3019 : }
3020 :
3021 9 : thisDXCoil.RatedCOP(1) = Numbers(2);
3022 9 : if (thisDXCoil.RatedCOP(1) <= 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(2), Numbers(2)));
3025 0 : ErrorsFound = true;
3026 : }
3027 :
3028 9 : thisDXCoil.RatedSHR(1) = Numbers(3);
3029 9 : if (thisDXCoil.RatedSHR(1) <= 0.0 || thisDXCoil.RatedSHR(1) > 1.0) {
3030 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3031 0 : ShowContinueError(state, format("...{} must be > 0 and <= 1. entered value=[{:.3T}].", cNumericFields(3), Numbers(3)));
3032 :
3033 0 : ErrorsFound = true;
3034 : }
3035 :
3036 9 : thisDXCoil.RatedInletDBTemp = Numbers(4);
3037 9 : if (thisDXCoil.RatedInletDBTemp <= 5.0) {
3038 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3039 0 : ShowContinueError(state, format("...{} must be > 5 {{C}}. entered value=[{:.1T}].", cNumericFields(4), Numbers(4)));
3040 0 : ErrorsFound = true;
3041 : }
3042 :
3043 9 : thisDXCoil.RatedInletWBTemp = Numbers(5);
3044 9 : if (thisDXCoil.RatedInletWBTemp <= 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(5), Numbers(5)));
3047 0 : ErrorsFound = true;
3048 : }
3049 :
3050 9 : thisDXCoil.RatedInletWaterTemp = Numbers(6);
3051 9 : if (thisDXCoil.RatedInletWaterTemp <= 25.0) {
3052 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3053 0 : ShowContinueError(state, format("...{} must be > 25 {{C}}. entered value=[{:.1T}].", cNumericFields(6), Numbers(6)));
3054 0 : ErrorsFound = true;
3055 : }
3056 :
3057 9 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(7);
3058 9 : if (thisDXCoil.RatedAirVolFlowRate(1) != Constant::AutoCalculate) {
3059 0 : if (thisDXCoil.RatedAirVolFlowRate(1) <= 0.0) {
3060 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3061 0 : ShowContinueError(state, format("...{} must be > 0.0. entered value=[{:.3T}].", cNumericFields(7), Numbers(7)));
3062 0 : ErrorsFound = true;
3063 : }
3064 : }
3065 :
3066 9 : thisDXCoil.RatedHPWHCondWaterFlow = Numbers(8);
3067 : // move to init
3068 9 : if (thisDXCoil.RatedHPWHCondWaterFlow != Constant::AutoCalculate) {
3069 0 : if (thisDXCoil.RatedHPWHCondWaterFlow <= 0.0) {
3070 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3071 0 : ShowContinueError(state, format("...{} must be > 0.0 entered value=[{:.3T}].", cNumericFields(8), Numbers(8)));
3072 0 : ErrorsFound = true;
3073 : }
3074 : // check the range of flow rate to be >= 1 gpm/ton and <= 5 gpm/ton
3075 0 : if (thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2 < 1.79405e-8 ||
3076 0 : thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2 > 8.97024e-8) {
3077 0 : ShowWarningError(state, format("{}{}=\"{}\", outside range", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3078 0 : ShowContinueError(state,
3079 0 : format("...{} per watt of {} is outside the recommended range of >= 1.79405E-8 m3/s/W (0.083 gpm/MBH) and <= "
3080 : "8.97024E-8 m3/s/W (0.417 gpm/MBH).",
3081 : cNumericFields(8),
3082 : cNumericFields(1)));
3083 0 : ShowContinueError(
3084 0 : state, format("...Entered Flow rate per watt = [{:.10T}].", (thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2)));
3085 : }
3086 : }
3087 :
3088 9 : if (Util::SameString(Alphas(2), "Yes") || Util::SameString(Alphas(2), "No")) {
3089 : // initialized to TRUE on allocate
3090 9 : if (Util::SameString(Alphas(2), "No")) thisDXCoil.FanPowerIncludedInCOP = false;
3091 : } else {
3092 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3093 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(2), Alphas(2)));
3094 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3095 0 : ErrorsFound = true;
3096 : }
3097 :
3098 9 : if (Util::SameString(Alphas(3), "Yes") || Util::SameString(Alphas(3), "No")) {
3099 : // initialized to FALSE on allocate
3100 9 : if (Util::SameString(Alphas(3), "Yes")) thisDXCoil.CondPumpPowerInCOP = true;
3101 : } else {
3102 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3103 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(3), Alphas(3)));
3104 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3105 0 : ErrorsFound = true;
3106 : }
3107 :
3108 9 : if (Util::SameString(Alphas(4), "Yes") || Util::SameString(Alphas(4), "No")) {
3109 : // initialized to FALSE on allocate
3110 9 : if (Util::SameString(Alphas(4), "Yes")) thisDXCoil.CondPumpHeatInCapacity = true;
3111 : } else {
3112 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3113 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(4), Alphas(4)));
3114 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3115 0 : ErrorsFound = true;
3116 : }
3117 :
3118 9 : thisDXCoil.HPWHCondPumpElecNomPower = Numbers(9);
3119 9 : if (thisDXCoil.HPWHCondPumpElecNomPower < 0.0) {
3120 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3121 0 : ShowContinueError(state, format("...{} must be >= 0.0 entered value=[{:.3T}].", cNumericFields(9), Numbers(9)));
3122 0 : ErrorsFound = true;
3123 : }
3124 :
3125 9 : thisDXCoil.HPWHCondPumpFracToWater = Numbers(10);
3126 9 : if (thisDXCoil.HPWHCondPumpFracToWater <= 0.0 || thisDXCoil.HPWHCondPumpFracToWater > 1.0) {
3127 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3128 0 : ShowContinueError(state, format("...{} must be >= 0 and <= 1. entered value=[{:.3T}].", cNumericFields(10), Numbers(10)));
3129 0 : ErrorsFound = true;
3130 : }
3131 :
3132 : // Air nodes
3133 9 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
3134 9 : Alphas(5),
3135 : ErrorsFound,
3136 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3137 9 : Alphas(1),
3138 : DataLoopNode::NodeFluidType::Air,
3139 : DataLoopNode::ConnectionType::Inlet,
3140 : NodeInputManager::CompFluidStream::Primary,
3141 : ObjectIsNotParent);
3142 :
3143 18 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
3144 9 : Alphas(6),
3145 : ErrorsFound,
3146 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3147 9 : Alphas(1),
3148 : DataLoopNode::NodeFluidType::Air,
3149 : DataLoopNode::ConnectionType::Outlet,
3150 : NodeInputManager::CompFluidStream::Primary,
3151 : ObjectIsNotParent);
3152 :
3153 9 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(5), Alphas(6), "Air Nodes");
3154 :
3155 : // Check if the air inlet node is OA node, to justify whether the coil is placed in zone or not
3156 9 : thisDXCoil.IsDXCoilInZone = !CheckOutAirNodeNumber(state, thisDXCoil.AirInNode);
3157 :
3158 : // Water nodes
3159 9 : thisDXCoil.WaterInNode = GetOnlySingleNode(state,
3160 9 : Alphas(7),
3161 : ErrorsFound,
3162 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3163 9 : Alphas(1),
3164 : DataLoopNode::NodeFluidType::Water,
3165 : DataLoopNode::ConnectionType::Inlet,
3166 : NodeInputManager::CompFluidStream::Secondary,
3167 : ObjectIsNotParent);
3168 :
3169 18 : thisDXCoil.WaterOutNode = GetOnlySingleNode(state,
3170 9 : Alphas(8),
3171 : ErrorsFound,
3172 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3173 9 : Alphas(1),
3174 : DataLoopNode::NodeFluidType::Water,
3175 : DataLoopNode::ConnectionType::Outlet,
3176 : NodeInputManager::CompFluidStream::Secondary,
3177 : ObjectIsNotParent);
3178 :
3179 9 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(7), Alphas(8), "Water Nodes");
3180 :
3181 9 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(11);
3182 9 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
3183 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3184 0 : ShowContinueError(state, format("...{} must be >= 0.0 entered value=[{:.1T}].", cNumericFields(11), Numbers(11)));
3185 0 : ErrorsFound = true;
3186 : }
3187 :
3188 9 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(12);
3189 9 : if (thisDXCoil.MaxOATCrankcaseHeater < 0.0) {
3190 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3191 0 : ShowContinueError(state, format("...{} must be >= 0 {{C}}. entered value=[{:.1T}].", cNumericFields(12), Numbers(12)));
3192 0 : ErrorsFound = true;
3193 : }
3194 :
3195 9 : if (!lAlphaBlanks(9)) {
3196 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(9));
3197 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
3198 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(9), Alphas(9)));
3199 0 : ErrorsFound = true;
3200 : } else {
3201 6 : ErrorsFound |= Curve::CheckCurveDims(state,
3202 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
3203 : {1}, // Valid dimensions
3204 : RoutineName, // Routine name
3205 : CurrentModuleObject, // Object Type
3206 : thisDXCoil.Name, // Object Name
3207 2 : cAlphaFields(9)); // Field Name
3208 : }
3209 : }
3210 :
3211 9 : thisDXCoil.InletAirTemperatureType = static_cast<HVAC::OATType>(getEnumValue(HVAC::oatTypeNamesUC, Alphas(10)));
3212 :
3213 : // set rated inlet air temperature for curve object verification
3214 9 : if (thisDXCoil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
3215 9 : InletAirTemp = thisDXCoil.RatedInletWBTemp;
3216 : } else {
3217 0 : InletAirTemp = thisDXCoil.RatedInletDBTemp;
3218 : }
3219 : // set rated water temperature for curve object verification
3220 9 : InletWaterTemp = thisDXCoil.RatedInletWaterTemp;
3221 :
3222 9 : if (!lAlphaBlanks(11)) {
3223 9 : thisDXCoil.HCapFTemp = GetCurveIndex(state, Alphas(11));
3224 9 : if (thisDXCoil.HCapFTemp == 0) {
3225 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3226 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
3227 0 : ErrorsFound = true;
3228 : } else {
3229 : // Verify Curve Object, only legal types are BiQuadratic or Cubic
3230 18 : ErrorsFound |= Curve::CheckCurveDims(state,
3231 : thisDXCoil.HCapFTemp, // Curve index
3232 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
3233 : RoutineName, // Routine name
3234 : CurrentModuleObject, // Object Type
3235 : thisDXCoil.Name, // Object Name
3236 9 : cAlphaFields(11)); // Field Name
3237 :
3238 9 : if (!ErrorsFound) {
3239 9 : if (state.dataCurveManager->curves(thisDXCoil.HCapFTemp)->numDims == 1) {
3240 2 : checkCurveIsNormalizedToOne(state,
3241 6 : std::string{RoutineName} + CurrentModuleObject,
3242 2 : thisDXCoil.Name,
3243 : thisDXCoil.HCapFTemp,
3244 2 : cAlphaFields(11),
3245 2 : Alphas(11),
3246 : InletAirTemp);
3247 : } else {
3248 7 : checkCurveIsNormalizedToOne(state,
3249 21 : std::string{RoutineName} + CurrentModuleObject,
3250 7 : thisDXCoil.Name,
3251 : thisDXCoil.HCapFTemp,
3252 7 : cAlphaFields(11),
3253 7 : Alphas(11),
3254 : InletAirTemp,
3255 : InletWaterTemp);
3256 : }
3257 : }
3258 : }
3259 : }
3260 :
3261 9 : if (!lAlphaBlanks(12)) {
3262 2 : thisDXCoil.HCapFAirFlow = GetCurveIndex(state, Alphas(12));
3263 2 : if (thisDXCoil.HCapFAirFlow == 0) {
3264 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3265 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(12), Alphas(12)));
3266 0 : ErrorsFound = true;
3267 : } else {
3268 : // Verify Curve Object, only legal types are Cubic or Quadratic
3269 4 : ErrorsFound |= Curve::CheckCurveDims(state,
3270 : thisDXCoil.HCapFAirFlow, // Curve index
3271 : {1}, // Valid dimensions
3272 : RoutineName, // Routine name
3273 : CurrentModuleObject, // Object Type
3274 : thisDXCoil.Name, // Object Name
3275 2 : cAlphaFields(12)); // Field Name
3276 :
3277 2 : if (!ErrorsFound) {
3278 2 : checkCurveIsNormalizedToOne(state,
3279 6 : std::string{RoutineName} + CurrentModuleObject,
3280 2 : thisDXCoil.Name,
3281 : thisDXCoil.HCapFAirFlow,
3282 2 : cAlphaFields(12),
3283 2 : Alphas(12),
3284 : 1.0);
3285 : }
3286 : }
3287 : }
3288 :
3289 9 : if (!lAlphaBlanks(13)) {
3290 2 : thisDXCoil.HCapFWaterFlow = GetCurveIndex(state, Alphas(13));
3291 2 : if (thisDXCoil.HCapFWaterFlow == 0) {
3292 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3293 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(13), Alphas(13)));
3294 0 : ErrorsFound = true;
3295 : } else {
3296 : // Verify Curve Object, only legal types are Cubic or Quadratic
3297 4 : ErrorsFound |= Curve::CheckCurveDims(state,
3298 : thisDXCoil.HCapFWaterFlow, // Curve index
3299 : {1}, // Valid dimensions
3300 : RoutineName, // Routine name
3301 : CurrentModuleObject, // Object Type
3302 : thisDXCoil.Name, // Object Name
3303 2 : cAlphaFields(13)); // Field Name
3304 :
3305 2 : if (!ErrorsFound) {
3306 2 : checkCurveIsNormalizedToOne(state,
3307 6 : std::string{RoutineName} + CurrentModuleObject,
3308 2 : thisDXCoil.Name,
3309 : thisDXCoil.HCapFWaterFlow,
3310 2 : cAlphaFields(13),
3311 2 : Alphas(13),
3312 : 1.0);
3313 : }
3314 : }
3315 : }
3316 :
3317 9 : if (!lAlphaBlanks(14)) {
3318 9 : thisDXCoil.HCOPFTemp = GetCurveIndex(state, Alphas(14));
3319 9 : if (thisDXCoil.HCOPFTemp == 0) {
3320 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3321 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14), Alphas(14)));
3322 0 : ErrorsFound = true;
3323 : } else {
3324 : // Verify Curve Object, only legal types are BiQuadratic or Cubic
3325 18 : ErrorsFound |= Curve::CheckCurveDims(state,
3326 : thisDXCoil.HCOPFTemp, // Curve index
3327 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
3328 : RoutineName, // Routine name
3329 : CurrentModuleObject, // Object Type
3330 : thisDXCoil.Name, // Object Name
3331 9 : cAlphaFields(14)); // Field Name
3332 :
3333 9 : if (!ErrorsFound) {
3334 9 : if (state.dataCurveManager->curves(thisDXCoil.HCOPFTemp)->numDims == 1) {
3335 0 : checkCurveIsNormalizedToOne(state,
3336 0 : std::string{RoutineName} + CurrentModuleObject,
3337 0 : thisDXCoil.Name,
3338 : thisDXCoil.HCOPFTemp,
3339 0 : cAlphaFields(14),
3340 0 : Alphas(14),
3341 : InletAirTemp);
3342 : } else {
3343 9 : checkCurveIsNormalizedToOne(state,
3344 27 : std::string{RoutineName} + CurrentModuleObject,
3345 9 : thisDXCoil.Name,
3346 : thisDXCoil.HCOPFTemp,
3347 9 : cAlphaFields(14),
3348 9 : Alphas(14),
3349 : InletAirTemp,
3350 : InletWaterTemp);
3351 : }
3352 : }
3353 : }
3354 : }
3355 :
3356 9 : if (!lAlphaBlanks(15)) {
3357 2 : thisDXCoil.HCOPFAirFlow = GetCurveIndex(state, Alphas(15));
3358 2 : if (thisDXCoil.HCOPFAirFlow == 0) {
3359 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3360 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15), Alphas(15)));
3361 0 : ErrorsFound = true;
3362 : } else {
3363 : // Verify Curve Object, only legal types are Cubic or Quadratic
3364 4 : ErrorsFound |= Curve::CheckCurveDims(state,
3365 : thisDXCoil.HCOPFAirFlow, // Curve index
3366 : {1}, // Valid dimensions
3367 : RoutineName, // Routine name
3368 : CurrentModuleObject, // Object Type
3369 : thisDXCoil.Name, // Object Name
3370 2 : cAlphaFields(15)); // Field Name
3371 :
3372 2 : if (!ErrorsFound) {
3373 2 : checkCurveIsNormalizedToOne(state,
3374 6 : std::string{RoutineName} + CurrentModuleObject,
3375 2 : thisDXCoil.Name,
3376 : thisDXCoil.HCOPFAirFlow,
3377 2 : cAlphaFields(15),
3378 2 : Alphas(15),
3379 : 1.0);
3380 : }
3381 : }
3382 : }
3383 :
3384 9 : if (!lAlphaBlanks(16)) {
3385 2 : thisDXCoil.HCOPFWaterFlow = GetCurveIndex(state, Alphas(16));
3386 2 : if (thisDXCoil.HCOPFWaterFlow == 0) {
3387 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3388 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
3389 0 : ErrorsFound = true;
3390 : } else {
3391 : // Verify Curve Object, only legal types are Cubic or Quadratic
3392 4 : ErrorsFound |= Curve::CheckCurveDims(state,
3393 : thisDXCoil.HCOPFWaterFlow, // Curve index
3394 : {1}, // Valid dimensions
3395 : RoutineName, // Routine name
3396 : CurrentModuleObject, // Object Type
3397 : thisDXCoil.Name, // Object Name
3398 2 : cAlphaFields(16)); // Field Name
3399 :
3400 2 : if (!ErrorsFound) {
3401 2 : checkCurveIsNormalizedToOne(state,
3402 6 : std::string{RoutineName} + CurrentModuleObject,
3403 2 : thisDXCoil.Name,
3404 : thisDXCoil.HCOPFWaterFlow,
3405 2 : cAlphaFields(16),
3406 2 : Alphas(16),
3407 : 1.0);
3408 : }
3409 : }
3410 : }
3411 :
3412 9 : if (!lAlphaBlanks(17)) {
3413 9 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(17));
3414 9 : if (thisDXCoil.PLFFPLR(1) == 0) {
3415 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3416 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
3417 0 : ErrorsFound = true;
3418 : } else {
3419 : // Verify Curve Object, only legal types are Cubic or Quadratic
3420 27 : ErrorsFound |= Curve::CheckCurveDims(state,
3421 9 : thisDXCoil.PLFFPLR(1), // Curve index
3422 : {1}, // Valid dimensions
3423 : RoutineName, // Routine name
3424 : CurrentModuleObject, // Object Type
3425 : thisDXCoil.Name, // Object Name
3426 9 : cAlphaFields(17)); // Field Name
3427 :
3428 9 : if (!ErrorsFound) {
3429 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
3430 9 : MinCurveVal = 999.0;
3431 9 : MaxCurveVal = -999.0;
3432 9 : CurveInput = 0.0;
3433 909 : while (CurveInput <= 1.0) {
3434 900 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
3435 900 : if (CurveVal < MinCurveVal) {
3436 9 : MinCurveVal = CurveVal;
3437 9 : MinCurvePLR = CurveInput;
3438 : }
3439 900 : if (CurveVal > MaxCurveVal) {
3440 702 : MaxCurveVal = CurveVal;
3441 702 : MaxCurvePLR = CurveInput;
3442 : }
3443 900 : CurveInput += 0.01;
3444 : }
3445 9 : if (MinCurveVal < 0.7) {
3446 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3447 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(17), Alphas(17)));
3448 0 : ShowContinueError(state,
3449 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
3450 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
3451 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
3452 : }
3453 :
3454 9 : if (MaxCurveVal > 1.0) {
3455 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3456 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(17), Alphas(17)));
3457 0 : ShowContinueError(state,
3458 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
3459 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
3460 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
3461 : }
3462 : }
3463 : }
3464 : }
3465 :
3466 : // assume compressor resides at the inlet to the DX Coil
3467 9 : thisDXCoil.CondenserInletNodeNum(1) = thisDXCoil.AirInNode;
3468 :
3469 : // set condenser type as HPWH
3470 9 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::WaterHeater;
3471 :
3472 : } // end of the DX water heater coil loop
3473 :
3474 135 : if (ErrorsFound) {
3475 0 : ShowFatalError(state,
3476 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
3477 : }
3478 : // Loop over the Wrapped DX Water Heater Coils and get & load the data
3479 135 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped);
3480 142 : for (DXHPWaterHeaterCoilNum = 1; DXHPWaterHeaterCoilNum <= state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils; ++DXHPWaterHeaterCoilNum) {
3481 :
3482 7 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3483 : CurrentModuleObject,
3484 : DXHPWaterHeaterCoilNum,
3485 : Alphas,
3486 : NumAlphas,
3487 : Numbers,
3488 : NumNumbers,
3489 : IOStatus,
3490 : lNumericBlanks,
3491 : lAlphaBlanks,
3492 : cAlphaFields,
3493 : cNumericFields);
3494 :
3495 7 : ++DXCoilNum;
3496 :
3497 : // allocate single performance mode for numeric field strings used for sizing routine
3498 7 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
3499 7 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
3500 7 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
3501 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
3502 7 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
3503 :
3504 7 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
3505 7 : thisDXCoil.Name = Alphas(1);
3506 7 : thisDXCoil.DXCoilType = CurrentModuleObject;
3507 7 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatPumpWaterHeaterWrapped;
3508 7 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOff(state); // heat pump water heater DX coil has no schedule
3509 :
3510 : // Store the HPWH DX coil heating capacity in RatedTotCap2. After backing off pump and fan heat,
3511 : // move to RatedTotCap() for use by DX coil
3512 7 : thisDXCoil.RatedTotCap2 = Numbers(1);
3513 7 : if (thisDXCoil.RatedTotCap2 <= 0.0) {
3514 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3515 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
3516 0 : ErrorsFound = true;
3517 : }
3518 :
3519 7 : thisDXCoil.RatedCOP(1) = Numbers(2);
3520 7 : if (thisDXCoil.RatedCOP(1) <= 0.0) {
3521 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3522 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(2), Numbers(2)));
3523 0 : ErrorsFound = true;
3524 : }
3525 :
3526 7 : thisDXCoil.RatedSHR(1) = Numbers(3);
3527 7 : if (thisDXCoil.RatedSHR(1) <= 0.0 || thisDXCoil.RatedSHR(1) > 1.0) {
3528 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3529 0 : ShowContinueError(state, format("...{} must be > 0 and <= 1. entered value=[{:.3T}].", cNumericFields(3), Numbers(3)));
3530 :
3531 0 : ErrorsFound = true;
3532 : }
3533 :
3534 7 : thisDXCoil.RatedInletDBTemp = Numbers(4);
3535 7 : if (thisDXCoil.RatedInletDBTemp <= 5.0) {
3536 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3537 0 : ShowContinueError(state, format("...{} must be > 5 {{C}}. entered value=[{:.1T}].", cNumericFields(4), Numbers(4)));
3538 0 : ErrorsFound = true;
3539 : }
3540 :
3541 7 : thisDXCoil.RatedInletWBTemp = Numbers(5);
3542 7 : if (thisDXCoil.RatedInletWBTemp <= 5.0) {
3543 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3544 0 : ShowContinueError(state, format("...{} must be > 5 {{C}}. entered value=[{:.1T}].", cNumericFields(5), Numbers(5)));
3545 0 : ErrorsFound = true;
3546 : }
3547 :
3548 7 : thisDXCoil.RatedInletWaterTemp = Numbers(6);
3549 7 : if (thisDXCoil.RatedInletWaterTemp <= 25.0) {
3550 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3551 0 : ShowContinueError(state, format("...{} must be > 25 {{C}}. entered value=[{:.1T}].", cNumericFields(6), Numbers(6)));
3552 0 : ErrorsFound = true;
3553 : }
3554 :
3555 7 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(7);
3556 7 : if (thisDXCoil.RatedAirVolFlowRate(1) != Constant::AutoCalculate) {
3557 7 : if (thisDXCoil.RatedAirVolFlowRate(1) <= 0.0) {
3558 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3559 0 : ShowContinueError(state, format("...{} must be > 0.0. entered value=[{:.3T}].", cNumericFields(7), Numbers(7)));
3560 0 : ErrorsFound = true;
3561 : }
3562 : }
3563 :
3564 7 : if (Util::SameString(Alphas(2), "Yes") || Util::SameString(Alphas(2), "No")) {
3565 : // initialized to TRUE on allocate
3566 7 : if (Util::SameString(Alphas(2), "No")) thisDXCoil.FanPowerIncludedInCOP = false;
3567 : } else {
3568 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3569 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(2), Alphas(2)));
3570 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3571 0 : ErrorsFound = true;
3572 : }
3573 :
3574 : // Air nodes
3575 7 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
3576 7 : Alphas(3),
3577 : ErrorsFound,
3578 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3579 7 : Alphas(1),
3580 : DataLoopNode::NodeFluidType::Air,
3581 : DataLoopNode::ConnectionType::Inlet,
3582 : NodeInputManager::CompFluidStream::Primary,
3583 : ObjectIsNotParent);
3584 :
3585 14 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
3586 7 : Alphas(4),
3587 : ErrorsFound,
3588 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3589 7 : Alphas(1),
3590 : DataLoopNode::NodeFluidType::Air,
3591 : DataLoopNode::ConnectionType::Outlet,
3592 : NodeInputManager::CompFluidStream::Primary,
3593 : ObjectIsNotParent);
3594 :
3595 7 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
3596 :
3597 : // Check if the air inlet node is OA node, to justify whether the coil is placed in zone or not
3598 7 : thisDXCoil.IsDXCoilInZone = !CheckOutAirNodeNumber(state, thisDXCoil.AirInNode);
3599 :
3600 7 : std::string const DummyCondenserInletName("DUMMY CONDENSER INLET " + thisDXCoil.Name);
3601 7 : std::string const DummyCondenserOutletName("DUMMY CONDENSER OUTLET " + thisDXCoil.Name);
3602 7 : thisDXCoil.WaterInNode = GetOnlySingleNode(state,
3603 : DummyCondenserInletName,
3604 : ErrorsFound,
3605 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3606 7 : Alphas(1),
3607 : DataLoopNode::NodeFluidType::Water,
3608 : DataLoopNode::ConnectionType::Inlet,
3609 : NodeInputManager::CompFluidStream::Secondary,
3610 : ObjectIsNotParent);
3611 :
3612 14 : thisDXCoil.WaterOutNode = GetOnlySingleNode(state,
3613 : DummyCondenserOutletName,
3614 : ErrorsFound,
3615 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3616 7 : Alphas(1),
3617 : DataLoopNode::NodeFluidType::Water,
3618 : DataLoopNode::ConnectionType::Outlet,
3619 : NodeInputManager::CompFluidStream::Secondary,
3620 : ObjectIsNotParent);
3621 :
3622 7 : TestCompSet(state, CurrentModuleObject, Alphas(1), DummyCondenserInletName, DummyCondenserOutletName, "Water Nodes");
3623 :
3624 7 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(8);
3625 7 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
3626 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3627 0 : ShowContinueError(state, format("...{} must be >= 0.0 entered value=[{:.1T}].", cNumericFields(8), Numbers(8)));
3628 0 : ErrorsFound = true;
3629 : }
3630 :
3631 7 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(9);
3632 7 : if (thisDXCoil.MaxOATCrankcaseHeater < 0.0) {
3633 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3634 0 : ShowContinueError(state, format("...{} must be >= 0 {{C}}. entered value=[{:.1T}].", cNumericFields(9), Numbers(9)));
3635 0 : ErrorsFound = true;
3636 : }
3637 :
3638 : // Coil:WaterHeating:AirToWaterHeatPump:Wrapped
3639 7 : if (!lAlphaBlanks(5)) {
3640 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
3641 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
3642 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(5), Alphas(5)));
3643 0 : ErrorsFound = true;
3644 : } else {
3645 6 : ErrorsFound |= Curve::CheckCurveDims(state,
3646 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
3647 : {1}, // Valid dimensions
3648 : RoutineName, // Routine name
3649 : CurrentModuleObject, // Object Type
3650 : thisDXCoil.Name, // Object Name
3651 2 : cAlphaFields(5)); // Field Name
3652 : }
3653 : }
3654 :
3655 7 : if (Util::SameString(Alphas(6), "DryBulbTemperature")) {
3656 0 : thisDXCoil.InletAirTemperatureType = HVAC::OATType::DryBulb;
3657 7 : } else if (Util::SameString(Alphas(6), "WetBulbTemperature")) {
3658 7 : thisDXCoil.InletAirTemperatureType = HVAC::OATType::WetBulb;
3659 : } else {
3660 : // wrong temperature type selection
3661 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3662 0 : ShowContinueError(state, format("...{} must be DryBulbTemperature or WetBulbTemperature.", cAlphaFields(6)));
3663 0 : ShowContinueError(state, format("...entered value=\"{}\".", Alphas(6)));
3664 0 : ErrorsFound = true;
3665 : }
3666 :
3667 : // set rated inlet air temperature for curve object verification
3668 7 : if (thisDXCoil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
3669 7 : InletAirTemp = thisDXCoil.RatedInletWBTemp;
3670 : } else {
3671 0 : InletAirTemp = thisDXCoil.RatedInletDBTemp;
3672 : }
3673 : // set rated water temperature for curve object verification
3674 7 : InletWaterTemp = thisDXCoil.RatedInletWaterTemp;
3675 :
3676 7 : if (!lAlphaBlanks(7)) {
3677 7 : thisDXCoil.HCapFTemp = GetCurveIndex(state, Alphas(7));
3678 7 : if (thisDXCoil.HCapFTemp == 0) {
3679 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3680 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
3681 0 : ErrorsFound = true;
3682 : } else {
3683 : // Verify Curve Object, only legal types are BiQuadratic or Cubic
3684 14 : ErrorsFound |= Curve::CheckCurveDims(state,
3685 : thisDXCoil.HCapFTemp, // Curve index
3686 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
3687 : RoutineName, // Routine name
3688 : CurrentModuleObject, // Object Type
3689 : thisDXCoil.Name, // Object Name
3690 7 : cAlphaFields(7)); // Field Name
3691 :
3692 7 : if (!ErrorsFound) {
3693 7 : if (state.dataCurveManager->curves(thisDXCoil.HCapFTemp)->numDims == 1) {
3694 0 : checkCurveIsNormalizedToOne(state,
3695 0 : std::string{RoutineName} + CurrentModuleObject,
3696 0 : thisDXCoil.Name,
3697 : thisDXCoil.HCapFTemp,
3698 0 : cAlphaFields(7),
3699 0 : Alphas(7),
3700 : InletAirTemp);
3701 : } else {
3702 7 : checkCurveIsNormalizedToOne(state,
3703 21 : std::string{RoutineName} + CurrentModuleObject,
3704 7 : thisDXCoil.Name,
3705 : thisDXCoil.HCapFTemp,
3706 7 : cAlphaFields(7),
3707 7 : Alphas(7),
3708 : InletAirTemp,
3709 : InletWaterTemp);
3710 : }
3711 : }
3712 : }
3713 : }
3714 :
3715 7 : if (!lAlphaBlanks(8)) {
3716 2 : thisDXCoil.HCapFAirFlow = GetCurveIndex(state, Alphas(8));
3717 2 : if (thisDXCoil.HCapFAirFlow == 0) {
3718 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3719 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
3720 0 : ErrorsFound = true;
3721 : } else {
3722 : // Verify Curve Object, only legal types are Cubic or Quadratic
3723 4 : ErrorsFound |= Curve::CheckCurveDims(state,
3724 : thisDXCoil.HCapFAirFlow, // Curve index
3725 : {1}, // Valid dimensions
3726 : RoutineName, // Routine name
3727 : CurrentModuleObject, // Object Type
3728 : thisDXCoil.Name, // Object Name
3729 2 : cAlphaFields(8)); // Field Name
3730 :
3731 2 : if (!ErrorsFound) {
3732 2 : checkCurveIsNormalizedToOne(state,
3733 6 : std::string{RoutineName} + CurrentModuleObject,
3734 2 : thisDXCoil.Name,
3735 : thisDXCoil.HCapFAirFlow,
3736 2 : cAlphaFields(8),
3737 2 : Alphas(8),
3738 : 1.0);
3739 : }
3740 : }
3741 : }
3742 :
3743 7 : if (!lAlphaBlanks(9)) {
3744 7 : thisDXCoil.HCOPFTemp = GetCurveIndex(state, Alphas(9));
3745 7 : if (thisDXCoil.HCOPFTemp == 0) {
3746 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3747 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
3748 0 : ErrorsFound = true;
3749 : } else {
3750 : // Verify Curve Object, only legal types are BiQuadratic or Cubic
3751 14 : ErrorsFound |= Curve::CheckCurveDims(state,
3752 : thisDXCoil.HCOPFTemp, // Curve index
3753 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
3754 : RoutineName, // Routine name
3755 : CurrentModuleObject, // Object Type
3756 : thisDXCoil.Name, // Object Name
3757 7 : cAlphaFields(9)); // Field Name
3758 :
3759 7 : if (!ErrorsFound) {
3760 7 : if (state.dataCurveManager->curves(thisDXCoil.HCOPFTemp)->numDims == 1) {
3761 0 : checkCurveIsNormalizedToOne(state,
3762 0 : std::string{RoutineName} + CurrentModuleObject,
3763 0 : thisDXCoil.Name,
3764 : thisDXCoil.HCOPFTemp,
3765 0 : cAlphaFields(9),
3766 0 : Alphas(9),
3767 : InletAirTemp);
3768 : } else {
3769 7 : checkCurveIsNormalizedToOne(state,
3770 21 : std::string{RoutineName} + CurrentModuleObject,
3771 7 : thisDXCoil.Name,
3772 : thisDXCoil.HCOPFTemp,
3773 7 : cAlphaFields(9),
3774 7 : Alphas(9),
3775 : InletAirTemp,
3776 : InletWaterTemp);
3777 : }
3778 : }
3779 : }
3780 : }
3781 :
3782 7 : if (!lAlphaBlanks(10)) {
3783 2 : thisDXCoil.HCOPFAirFlow = GetCurveIndex(state, Alphas(10));
3784 2 : if (thisDXCoil.HCOPFAirFlow == 0) {
3785 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3786 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
3787 0 : ErrorsFound = true;
3788 : } else {
3789 : // Verify Curve Object, only legal types are Cubic or Quadratic
3790 4 : ErrorsFound |= Curve::CheckCurveDims(state,
3791 : thisDXCoil.HCOPFAirFlow, // Curve index
3792 : {1}, // Valid dimensions
3793 : RoutineName, // Routine name
3794 : CurrentModuleObject, // Object Type
3795 : thisDXCoil.Name, // Object Name
3796 2 : cAlphaFields(10)); // Field Name
3797 :
3798 2 : if (!ErrorsFound) {
3799 2 : checkCurveIsNormalizedToOne(state,
3800 6 : std::string{RoutineName} + CurrentModuleObject,
3801 2 : thisDXCoil.Name,
3802 : thisDXCoil.HCOPFAirFlow,
3803 2 : cAlphaFields(10),
3804 2 : Alphas(10),
3805 : 1.0);
3806 : }
3807 : }
3808 : }
3809 :
3810 7 : if (!lAlphaBlanks(11)) {
3811 4 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(11));
3812 4 : if (thisDXCoil.PLFFPLR(1) == 0) {
3813 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3814 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
3815 0 : ErrorsFound = true;
3816 : } else {
3817 : // Verify Curve Object, only legal types are Cubic or Quadratic
3818 12 : ErrorsFound |= Curve::CheckCurveDims(state,
3819 4 : thisDXCoil.PLFFPLR(1), // Curve index
3820 : {1}, // Valid dimensions
3821 : RoutineName, // Routine name
3822 : CurrentModuleObject, // Object Type
3823 : thisDXCoil.Name, // Object Name
3824 4 : cAlphaFields(11)); // Field Name
3825 :
3826 4 : if (!ErrorsFound) {
3827 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
3828 4 : MinCurveVal = 999.0;
3829 4 : MaxCurveVal = -999.0;
3830 4 : CurveInput = 0.0;
3831 404 : while (CurveInput <= 1.0) {
3832 400 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
3833 400 : if (CurveVal < MinCurveVal) {
3834 4 : MinCurveVal = CurveVal;
3835 4 : MinCurvePLR = CurveInput;
3836 : }
3837 400 : if (CurveVal > MaxCurveVal) {
3838 4 : MaxCurveVal = CurveVal;
3839 4 : MaxCurvePLR = CurveInput;
3840 : }
3841 400 : CurveInput += 0.01;
3842 : }
3843 4 : if (MinCurveVal < 0.7) {
3844 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3845 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(11), Alphas(11)));
3846 0 : ShowContinueError(state,
3847 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
3848 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
3849 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
3850 : }
3851 :
3852 4 : if (MaxCurveVal > 1.0) {
3853 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3854 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(11), Alphas(11)));
3855 0 : ShowContinueError(state,
3856 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
3857 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
3858 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
3859 : }
3860 : }
3861 : }
3862 : }
3863 :
3864 : // assume compressor resides at the inlet to the DX Coil
3865 7 : thisDXCoil.CondenserInletNodeNum(1) = thisDXCoil.AirInNode;
3866 :
3867 : // set condenser type as HPWH
3868 7 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::WaterHeater;
3869 :
3870 7 : } // end of the DX water heater wrapped coil loop
3871 :
3872 135 : if (ErrorsFound) {
3873 0 : ShowFatalError(state,
3874 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
3875 : }
3876 :
3877 : // DX Multispeed cooling coil
3878 135 : CurrentModuleObject = "Coil:Cooling:DX:MultiSpeed";
3879 163 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedCoolCoils; ++DXCoilIndex) {
3880 :
3881 28 : ++DXCoilNum;
3882 :
3883 28 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3884 : CurrentModuleObject,
3885 : DXCoilIndex,
3886 : Alphas,
3887 : NumAlphas,
3888 : Numbers,
3889 : NumNumbers,
3890 : IOStatus,
3891 : lNumericBlanks,
3892 : lAlphaBlanks,
3893 : cAlphaFields,
3894 : cNumericFields);
3895 :
3896 28 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
3897 : // allocate single performance mode for numeric field strings used for sizing routine (all fields are in this object)
3898 28 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
3899 28 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
3900 28 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
3901 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
3902 28 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
3903 :
3904 28 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
3905 28 : thisDXCoil.Name = Alphas(1);
3906 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
3907 28 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
3908 28 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
3909 28 : thisDXCoil.DXCoilType = CurrentModuleObject;
3910 28 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_MultiSpeedCooling;
3911 28 : if (lAlphaBlanks(2)) {
3912 18 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
3913 10 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
3914 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
3915 0 : ErrorsFound = true;
3916 : }
3917 :
3918 28 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
3919 28 : Alphas(3),
3920 : ErrorsFound,
3921 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
3922 28 : Alphas(1),
3923 : DataLoopNode::NodeFluidType::Air,
3924 : DataLoopNode::ConnectionType::Inlet,
3925 : NodeInputManager::CompFluidStream::Primary,
3926 : ObjectIsNotParent);
3927 :
3928 56 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
3929 28 : Alphas(4),
3930 : ErrorsFound,
3931 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
3932 28 : Alphas(1),
3933 : DataLoopNode::NodeFluidType::Air,
3934 : DataLoopNode::ConnectionType::Outlet,
3935 : NodeInputManager::CompFluidStream::Primary,
3936 : ObjectIsNotParent);
3937 :
3938 28 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
3939 :
3940 : // outdoor condenser node
3941 28 : if (lAlphaBlanks(5)) {
3942 15 : thisDXCoil.CondenserInletNodeNum(1) = 0;
3943 : } else {
3944 26 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
3945 13 : Alphas(5),
3946 : ErrorsFound,
3947 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
3948 13 : thisDXCoil.Name,
3949 : DataLoopNode::NodeFluidType::Air,
3950 : DataLoopNode::ConnectionType::OutsideAirReference,
3951 : NodeInputManager::CompFluidStream::Primary,
3952 : ObjectIsNotParent);
3953 13 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
3954 4 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3955 8 : ShowContinueError(
3956 8 : state, format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(5), Alphas(5)));
3957 12 : ShowContinueError(
3958 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
3959 : }
3960 : }
3961 :
3962 28 : if ((Util::SameString(Alphas(6), "AirCooled")) || lAlphaBlanks(6)) {
3963 28 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
3964 0 : } else if (Util::SameString(Alphas(6), "EvaporativelyCooled")) {
3965 0 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
3966 0 : thisDXCoil.ReportEvapCondVars = true;
3967 : } else {
3968 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3969 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(6), Alphas(6)));
3970 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
3971 0 : ErrorsFound = true;
3972 : }
3973 :
3974 : // Get Water System tank connections
3975 : // A8, \field Name of Water Storage Tank for Supply
3976 28 : thisDXCoil.EvapWaterSupplyName = Alphas(7);
3977 28 : if (lAlphaBlanks(7)) {
3978 28 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
3979 : } else {
3980 0 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
3981 0 : SetupTankDemandComponent(state,
3982 : thisDXCoil.Name,
3983 : CurrentModuleObject,
3984 : thisDXCoil.EvapWaterSupplyName,
3985 : ErrorsFound,
3986 0 : thisDXCoil.EvapWaterSupTankID,
3987 0 : thisDXCoil.EvapWaterTankDemandARRID);
3988 : }
3989 :
3990 : // A9; \field Name of Water Storage Tank for Condensate Collection
3991 28 : thisDXCoil.CondensateCollectName = Alphas(8);
3992 28 : if (lAlphaBlanks(8)) {
3993 28 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
3994 : } else {
3995 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
3996 0 : SetupTankSupplyComponent(state,
3997 : thisDXCoil.Name,
3998 : CurrentModuleObject,
3999 : thisDXCoil.CondensateCollectName,
4000 : ErrorsFound,
4001 0 : thisDXCoil.CondensateTankID,
4002 0 : thisDXCoil.CondensateTankSupplyARRID);
4003 : }
4004 :
4005 : // Set minimum OAT for compressor operation
4006 28 : thisDXCoil.MinOATCompressor = Numbers(1);
4007 :
4008 : // Set crankcase heater capacity
4009 28 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(2);
4010 28 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
4011 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4012 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(2)));
4013 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(2)));
4014 0 : ErrorsFound = true;
4015 : }
4016 :
4017 : // Set crankcase heater cutout temperature
4018 28 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(3);
4019 :
4020 28 : if (Util::SameString(Alphas(9), "Yes")) {
4021 0 : thisDXCoil.PLRImpact = true;
4022 28 : } else if (Util::SameString(Alphas(9), "No")) {
4023 28 : thisDXCoil.PLRImpact = false;
4024 : } else {
4025 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4026 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(9), Alphas(9)));
4027 0 : ShowContinueError(state, "The allowed choices are Yes or No.");
4028 0 : ErrorsFound = true;
4029 : }
4030 :
4031 28 : if (Util::SameString(Alphas(10), "Yes")) {
4032 0 : thisDXCoil.LatentImpact = true;
4033 28 : } else if (Util::SameString(Alphas(10), "No")) {
4034 28 : thisDXCoil.LatentImpact = false;
4035 : } else {
4036 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4037 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(10), Alphas(10)));
4038 0 : ShowContinueError(state, "The allowed choices are Yes or No.");
4039 0 : ErrorsFound = true;
4040 : }
4041 :
4042 : // Basin heater power as a function of temperature must be greater than or equal to 0
4043 28 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(4);
4044 28 : if (Numbers(4) < 0.0) {
4045 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4046 0 : ShowContinueError(state, format("...{} must be >= 0.0, entered value=[{:.3T}].", cNumericFields(4), Numbers(4)));
4047 0 : ErrorsFound = true;
4048 : }
4049 :
4050 28 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(5);
4051 28 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
4052 0 : if (NumNumbers < 5) {
4053 0 : thisDXCoil.BasinHeaterSetPointTemp = 2.0;
4054 : }
4055 0 : if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
4056 0 : ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4057 0 : ShowContinueError(state, format("...{} is less than 2 {{C}}. Freezing could occur.", cNumericFields(5)));
4058 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(5)));
4059 : }
4060 : }
4061 :
4062 28 : if (!lAlphaBlanks(11)) {
4063 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(11));
4064 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
4065 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(11), Alphas(11)));
4066 0 : ErrorsFound = true;
4067 : } else {
4068 6 : ErrorsFound |= Curve::CheckCurveDims(state,
4069 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
4070 : {1}, // Valid dimensions
4071 : RoutineName, // Routine name
4072 : CurrentModuleObject, // Object Type
4073 : thisDXCoil.Name, // Object Name
4074 2 : cAlphaFields(11)); // Field Name
4075 : }
4076 : }
4077 :
4078 28 : if (!lAlphaBlanks(12)) {
4079 0 : if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(12))) == nullptr) {
4080 0 : ShowWarningItemNotFound(
4081 0 : state, eoh, cAlphaFields(12), Alphas(12), "Basin heater will be available to operate throughout the simulation.");
4082 : }
4083 : }
4084 :
4085 : // A13; \field Fuel type, Validate fuel type input
4086 28 : thisDXCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(13)));
4087 :
4088 28 : thisDXCoil.NumOfSpeeds = Numbers(6); // Number of speeds
4089 28 : if (thisDXCoil.NumOfSpeeds < 2) {
4090 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4091 0 : ShowContinueError(state, format("...{} must be >= 2. entered number is {:.0T}", cNumericFields(6), Numbers(6)));
4092 0 : ErrorsFound = true;
4093 : }
4094 :
4095 : // Allocate arrays based on the number of speeds
4096 28 : thisDXCoil.MSErrIndex.allocate(thisDXCoil.NumOfSpeeds);
4097 28 : thisDXCoil.MSErrIndex = 0;
4098 28 : thisDXCoil.MSRatedTotCap.allocate(thisDXCoil.NumOfSpeeds);
4099 28 : thisDXCoil.MSRatedTotCapDes.allocate(thisDXCoil.NumOfSpeeds);
4100 28 : thisDXCoil.MSRatedSHR.allocate(thisDXCoil.NumOfSpeeds);
4101 28 : thisDXCoil.MSRatedCOP.allocate(thisDXCoil.NumOfSpeeds);
4102 28 : thisDXCoil.MSRatedAirVolFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4103 28 : thisDXCoil.MSRatedAirMassFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4104 28 : thisDXCoil.MSRatedAirMassFlowRate = 1.0; // avoid divide by 0, will get overwritten in InitDXCoil
4105 28 : thisDXCoil.MSCCapFTemp.allocate(thisDXCoil.NumOfSpeeds);
4106 28 : thisDXCoil.MSCCapFFlow.allocate(thisDXCoil.NumOfSpeeds);
4107 28 : thisDXCoil.MSEIRFTemp.allocate(thisDXCoil.NumOfSpeeds);
4108 28 : thisDXCoil.MSEIRFFlow.allocate(thisDXCoil.NumOfSpeeds);
4109 28 : thisDXCoil.MSWasteHeat.allocate(thisDXCoil.NumOfSpeeds);
4110 28 : thisDXCoil.MSEvapCondEffect.allocate(thisDXCoil.NumOfSpeeds);
4111 28 : thisDXCoil.MSEvapCondAirFlow.allocate(thisDXCoil.NumOfSpeeds);
4112 28 : thisDXCoil.MSEvapCondPumpElecNomPower.allocate(thisDXCoil.NumOfSpeeds);
4113 28 : thisDXCoil.MSRatedCBF.allocate(thisDXCoil.NumOfSpeeds);
4114 28 : thisDXCoil.MSWasteHeatFrac.allocate(thisDXCoil.NumOfSpeeds);
4115 28 : thisDXCoil.MSPLFFPLR.allocate(thisDXCoil.NumOfSpeeds);
4116 28 : thisDXCoil.MSTwet_Rated.allocate(thisDXCoil.NumOfSpeeds);
4117 28 : thisDXCoil.MSGamma_Rated.allocate(thisDXCoil.NumOfSpeeds);
4118 28 : thisDXCoil.MSMaxONOFFCyclesperHour.allocate(thisDXCoil.NumOfSpeeds);
4119 28 : thisDXCoil.MSLatentCapacityTimeConstant.allocate(thisDXCoil.NumOfSpeeds);
4120 28 : thisDXCoil.MSFanPowerPerEvapAirFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4121 28 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023.allocate(thisDXCoil.NumOfSpeeds);
4122 :
4123 107 : for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
4124 79 : thisDXCoil.MSRatedTotCap(I) = Numbers(7 + (I - 1) * 14);
4125 79 : thisDXCoil.MSRatedSHR(I) = Numbers(8 + (I - 1) * 14);
4126 79 : thisDXCoil.MSRatedCOP(I) = Numbers(9 + (I - 1) * 14);
4127 79 : thisDXCoil.MSRatedAirVolFlowRate(I) = Numbers(10 + (I - 1) * 14);
4128 79 : thisDXCoil.MSFanPowerPerEvapAirFlowRate(I) = Numbers(11 + (I - 1) * 14);
4129 79 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023(I) = Numbers(12 + (I - 1) * 14);
4130 :
4131 79 : thisDXCoil.MSCCapFTemp(I) = GetCurveIndex(state, Alphas(14 + (I - 1) * 6)); // convert curve name to number
4132 79 : if (thisDXCoil.MSCCapFTemp(I) == 0) {
4133 0 : if (lAlphaBlanks(14 + (I - 1) * 6)) {
4134 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4135 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(14 + (I - 1) * 6)));
4136 : } else {
4137 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4138 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14 + (I - 1) * 6), Alphas(14 + (I - 1) * 6)));
4139 : }
4140 0 : ErrorsFound = true;
4141 : } else {
4142 : // Verify Curve Object, only legal type is BiQuadratic
4143 237 : ErrorsFound |= Curve::CheckCurveDims(state,
4144 79 : thisDXCoil.MSCCapFTemp(I), // Curve index
4145 : {2}, // Valid dimensions
4146 : RoutineName, // Routine name
4147 : CurrentModuleObject, // Object Type
4148 : thisDXCoil.Name, // Object Name
4149 79 : cAlphaFields(14 + (I - 1) * 6)); // Field Name
4150 :
4151 79 : if (!ErrorsFound) {
4152 76 : checkCurveIsNormalizedToOne(state,
4153 228 : std::string{RoutineName} + CurrentModuleObject,
4154 76 : thisDXCoil.Name,
4155 76 : thisDXCoil.MSCCapFTemp(I),
4156 76 : cAlphaFields(14 + (I - 1) * 6),
4157 76 : Alphas(14 + (I - 1) * 6),
4158 : RatedInletWetBulbTemp,
4159 : RatedOutdoorAirTemp);
4160 : }
4161 : }
4162 :
4163 79 : thisDXCoil.MSCCapFFlow(I) = GetCurveIndex(state, Alphas(15 + (I - 1) * 6)); // convert curve name to number
4164 79 : if (thisDXCoil.MSCCapFFlow(I) == 0) {
4165 0 : if (lAlphaBlanks(15 + (I - 1) * 6)) {
4166 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4167 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(15 + (I - 1) * 6)));
4168 : } else {
4169 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4170 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
4171 : }
4172 0 : ErrorsFound = true;
4173 : } else {
4174 : // Verify Curve Object, only legal type is Quadratic
4175 237 : ErrorsFound |= Curve::CheckCurveDims(state,
4176 79 : thisDXCoil.MSCCapFFlow(I), // Curve index
4177 : {1}, // Valid dimensions
4178 : RoutineName, // Routine name
4179 : CurrentModuleObject, // Object Type
4180 : thisDXCoil.Name, // Object Name
4181 79 : cAlphaFields(15 + (I - 1) * 6)); // Field Name
4182 :
4183 79 : if (!ErrorsFound) {
4184 76 : checkCurveIsNormalizedToOne(state,
4185 228 : std::string{RoutineName} + CurrentModuleObject,
4186 76 : thisDXCoil.Name,
4187 76 : thisDXCoil.MSCCapFFlow(I),
4188 76 : cAlphaFields(15 + (I - 1) * 6),
4189 76 : Alphas(15 + (I - 1) * 6),
4190 : 1.0);
4191 : }
4192 : }
4193 :
4194 79 : thisDXCoil.MSEIRFTemp(I) = GetCurveIndex(state, Alphas(16 + (I - 1) * 6)); // convert curve name to number
4195 79 : if (thisDXCoil.MSEIRFTemp(I) == 0) {
4196 0 : if (lAlphaBlanks(16 + (I - 1) * 6)) {
4197 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4198 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(16 + (I - 1) * 6)));
4199 : } else {
4200 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4201 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16 + (I - 1) * 6), Alphas(16 + (I - 1) * 6)));
4202 : }
4203 0 : ErrorsFound = true;
4204 : } else {
4205 : // Verify Curve Object, only legal type is BiQuadratic
4206 237 : ErrorsFound |= Curve::CheckCurveDims(state,
4207 79 : thisDXCoil.MSEIRFTemp(I), // Curve index
4208 : {2}, // Valid dimensions
4209 : RoutineName, // Routine name
4210 : CurrentModuleObject, // Object Type
4211 : thisDXCoil.Name, // Object Name
4212 79 : cAlphaFields(16 + (I - 1) * 6)); // Field Name
4213 :
4214 79 : if (!ErrorsFound) {
4215 76 : checkCurveIsNormalizedToOne(state,
4216 228 : std::string{RoutineName} + CurrentModuleObject,
4217 76 : thisDXCoil.Name,
4218 76 : thisDXCoil.MSEIRFTemp(I),
4219 76 : cAlphaFields(16 + (I - 1) * 6),
4220 76 : Alphas(16 + (I - 1) * 6),
4221 : RatedInletWetBulbTemp,
4222 : RatedOutdoorAirTemp);
4223 : }
4224 : }
4225 :
4226 79 : thisDXCoil.MSEIRFFlow(I) = GetCurveIndex(state, Alphas(17 + (I - 1) * 6)); // convert curve name to number
4227 79 : if (thisDXCoil.MSEIRFFlow(I) == 0) {
4228 0 : if (lAlphaBlanks(17 + (I - 1) * 6)) {
4229 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4230 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(17 + (I - 1) * 6)));
4231 : } else {
4232 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4233 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17 + (I - 1) * 6), Alphas(17 + (I - 1) * 6)));
4234 : }
4235 0 : ErrorsFound = true;
4236 : } else {
4237 : // Verify Curve Object, only legal type is Quadratic
4238 237 : ErrorsFound |= Curve::CheckCurveDims(state,
4239 79 : thisDXCoil.MSEIRFFlow(I), // Curve index
4240 : {1}, // Valid dimensions
4241 : RoutineName, // Routine name
4242 : CurrentModuleObject, // Object Type
4243 : thisDXCoil.Name, // Object Name
4244 79 : cAlphaFields(17 + (I - 1) * 6)); // Field Name
4245 :
4246 79 : if (!ErrorsFound) {
4247 76 : checkCurveIsNormalizedToOne(state,
4248 228 : std::string{RoutineName} + CurrentModuleObject,
4249 76 : thisDXCoil.Name,
4250 76 : thisDXCoil.MSEIRFFlow(I),
4251 76 : cAlphaFields(17 + (I - 1) * 6),
4252 76 : Alphas(17 + (I - 1) * 6),
4253 : 1.0);
4254 : }
4255 : }
4256 :
4257 79 : thisDXCoil.MSPLFFPLR(I) = GetCurveIndex(state, Alphas(18 + (I - 1) * 6)); // convert curve name to number
4258 79 : if (thisDXCoil.MSPLFFPLR(I) == 0) {
4259 4 : if (lAlphaBlanks(18 + (I - 1) * 6)) {
4260 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4261 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(18 + (I - 1) * 6)));
4262 : } else {
4263 4 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4264 4 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(18 + (I - 1) * 6), Alphas(18 + (I - 1) * 6)));
4265 : }
4266 4 : ErrorsFound = true;
4267 : } else {
4268 : // Verify Curve Object, only legal types are Quadratic or Cubic
4269 225 : ErrorsFound |= Curve::CheckCurveDims(state,
4270 75 : thisDXCoil.MSPLFFPLR(I), // Curve index
4271 : {1}, // Valid dimensions
4272 : RoutineName, // Routine name
4273 : CurrentModuleObject, // Object Type
4274 : thisDXCoil.Name, // Object Name
4275 75 : cAlphaFields(18 + (I - 1) * 6)); // Field Name
4276 :
4277 75 : if (!ErrorsFound) {
4278 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
4279 75 : MinCurveVal = 999.0;
4280 75 : MaxCurveVal = -999.0;
4281 75 : CurveInput = 0.0;
4282 7575 : while (CurveInput <= 1.0) {
4283 7500 : CurveVal = CurveValue(state, thisDXCoil.MSPLFFPLR(I), CurveInput);
4284 7500 : if (CurveVal < MinCurveVal) {
4285 75 : MinCurveVal = CurveVal;
4286 75 : MinCurvePLR = CurveInput;
4287 : }
4288 7500 : if (CurveVal > MaxCurveVal) {
4289 6256 : MaxCurveVal = CurveVal;
4290 6256 : MaxCurvePLR = CurveInput;
4291 : }
4292 7500 : CurveInput += 0.01;
4293 : }
4294 75 : if (MinCurveVal < 0.7) {
4295 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4296 0 : ShowContinueError(state,
4297 0 : format("...{} = {} has out of range value.", cAlphaFields2(18 + (I - 1) * 6), Alphas2(18 + (I - 1) * 6)));
4298 0 : ShowContinueError(state,
4299 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
4300 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
4301 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 0.7);
4302 : }
4303 :
4304 75 : if (MaxCurveVal > 1.0) {
4305 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4306 0 : ShowContinueError(state,
4307 0 : format("...{} = {} has out of range value.", cAlphaFields2(18 + (I - 1) * 6), Alphas2(18 + (I - 1) * 6)));
4308 0 : ShowContinueError(state,
4309 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
4310 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
4311 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 1.0);
4312 : }
4313 : }
4314 : }
4315 :
4316 : // read data for latent degradation
4317 79 : thisDXCoil.MSTwet_Rated(I) = Numbers(13 + (I - 1) * 14);
4318 79 : if (thisDXCoil.MSTwet_Rated(I) < 0.0) {
4319 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4320 0 : ShowContinueError(
4321 0 : state, format("...{} cannot be < 0.0, entered value=[{:.4T}].", cNumericFields(13 + (I - 1) * 14), thisDXCoil.MSTwet_Rated(I)));
4322 0 : ErrorsFound = true;
4323 : }
4324 79 : thisDXCoil.MSGamma_Rated(I) = Numbers(14 + (I - 1) * 14);
4325 79 : if (thisDXCoil.MSGamma_Rated(I) < 0.0) {
4326 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4327 0 : ShowContinueError(
4328 0 : state, format("...{} cannot be < 0.0, entered value=[{:.4T}].", cNumericFields(14 + (I - 1) * 14), thisDXCoil.MSGamma_Rated(I)));
4329 0 : ErrorsFound = true;
4330 : }
4331 79 : thisDXCoil.MSMaxONOFFCyclesperHour(I) = Numbers(15 + (I - 1) * 14);
4332 79 : if (thisDXCoil.Gamma_Rated(I) < 0.0) {
4333 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4334 0 : ShowContinueError(state,
4335 0 : format("...{} cannot be < 0.0, entered value=[{:.2T}].",
4336 0 : cNumericFields(15 + (I - 1) * 14),
4337 : thisDXCoil.MSMaxONOFFCyclesperHour(I)));
4338 0 : ErrorsFound = true;
4339 : }
4340 79 : thisDXCoil.MSLatentCapacityTimeConstant(I) = Numbers(16 + (I - 1) * 14);
4341 79 : if (thisDXCoil.Gamma_Rated(I) < 0.0) {
4342 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4343 0 : ShowContinueError(state,
4344 0 : format("...{} cannot be < 0.0, entered value=[{:.2T}].",
4345 0 : cNumericFields(16 + (I - 1) * 14),
4346 : thisDXCoil.MSLatentCapacityTimeConstant(I)));
4347 0 : ErrorsFound = true;
4348 : }
4349 :
4350 79 : thisDXCoil.MSWasteHeatFrac(I) = Numbers(17 + (I - 1) * 14);
4351 :
4352 : // Read waste heat modifier curve name
4353 79 : thisDXCoil.MSWasteHeat(I) = GetCurveIndex(state, Alphas(19 + (I - 1) * 6)); // convert curve name to number
4354 79 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
4355 16 : if (thisDXCoil.MSWasteHeat(I) > 0) {
4356 : // Verify Curve Object, only legal types are BiQuadratic
4357 48 : ErrorsFound |= Curve::CheckCurveDims(state,
4358 16 : thisDXCoil.MSWasteHeat(I), // Curve index
4359 : {2}, // Valid dimensions
4360 : RoutineName, // Routine name
4361 : CurrentModuleObject, // Object Type
4362 : thisDXCoil.Name, // Object Name
4363 16 : cAlphaFields(19 + (I - 1) * 6)); // Field Name
4364 :
4365 16 : if (!ErrorsFound) {
4366 16 : CurveVal = CurveValue(state, thisDXCoil.MSWasteHeat(I), RatedOutdoorAirTemp, RatedInletAirTemp);
4367 16 : if (CurveVal > 1.10 || CurveVal < 0.90) {
4368 0 : ShowWarningError(state, format("{}{}=\"{}\", curve values", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4369 0 : ShowContinueError(state, format("{} = {}", cAlphaFields(19 + (I - 1) * 6), Alphas(19 + (I - 1) * 6)));
4370 0 : ShowContinueError(
4371 0 : state, format("...{} output is not equal to 1.0 (+ or - 10%) at rated conditions.", cAlphaFields(19 + (I - 1) * 6)));
4372 0 : ShowContinueError(state, format("...Curve output at rated conditions = {:.3T}", CurveVal));
4373 : }
4374 : }
4375 : }
4376 : }
4377 :
4378 79 : thisDXCoil.MSEvapCondEffect(I) = Numbers(18 + (I - 1) * 14);
4379 79 : if (thisDXCoil.MSEvapCondEffect(I) < 0.0 || thisDXCoil.MSEvapCondEffect(I) > 1.0) {
4380 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4381 0 : ShowContinueError(
4382 : state,
4383 0 : format("...{} cannot be < 0.0 or > 1.0, entered value=[{:.3T}].", cNumericFields(18 + (I - 1) * 14), Numbers(18 + (I - 1) * 14)));
4384 0 : ErrorsFound = true;
4385 : }
4386 :
4387 79 : thisDXCoil.MSEvapCondAirFlow(I) = Numbers(19 + (I - 1) * 14);
4388 79 : if (thisDXCoil.MSEvapCondAirFlow(I) < 0.0 && thisDXCoil.MSEvapCondAirFlow(I) != AutoSize) {
4389 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4390 0 : ShowContinueError(
4391 0 : state, format("...{} cannot be < 0.0, entered value=[{:.3T}].", cNumericFields(19 + (I - 1) * 14), Numbers(19 + (I - 1) * 14)));
4392 0 : ErrorsFound = true;
4393 : }
4394 :
4395 79 : thisDXCoil.MSEvapCondPumpElecNomPower(I) = Numbers(20 + (I - 1) * 14);
4396 79 : if (thisDXCoil.MSEvapCondPumpElecNomPower(I) < 0.0 && thisDXCoil.MSEvapCondPumpElecNomPower(I) != AutoSize) {
4397 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4398 0 : ShowContinueError(
4399 0 : state, format("...{} cannot be < 0.0, entered value=[{:.3T}].", cNumericFields(20 + (I - 1) * 14), Numbers(20 + (I - 1) * 14)));
4400 0 : ErrorsFound = true;
4401 : }
4402 : }
4403 : // A38; \field Zone Name for Condenser Placement
4404 28 : if (!lAlphaBlanks(38) && NumAlphas > 37) {
4405 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(38), state.dataHeatBal->Zone);
4406 0 : if (thisDXCoil.SecZonePtr > 0) {
4407 0 : SetupZoneInternalGain(state,
4408 : thisDXCoil.SecZonePtr,
4409 : thisDXCoil.Name,
4410 : DataHeatBalance::IntGainType::SecCoolingDXCoilMultiSpeed,
4411 : &thisDXCoil.SecCoilSensibleHeatGainRate);
4412 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
4413 : } else {
4414 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4415 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(38), Alphas(38)));
4416 : }
4417 : }
4418 : }
4419 :
4420 135 : if (ErrorsFound) {
4421 3 : ShowFatalError(state,
4422 3 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
4423 : }
4424 :
4425 : // DX multispeed heating coil
4426 134 : CurrentModuleObject = "Coil:Heating:DX:MultiSpeed";
4427 148 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedHeatCoils; ++DXCoilIndex) {
4428 :
4429 14 : ++DXCoilNum;
4430 :
4431 14 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4432 : CurrentModuleObject,
4433 : DXCoilIndex,
4434 : Alphas,
4435 : NumAlphas,
4436 : Numbers,
4437 : NumNumbers,
4438 : IOStatus,
4439 : lNumericBlanks,
4440 : lAlphaBlanks,
4441 : cAlphaFields,
4442 : cNumericFields);
4443 :
4444 14 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
4445 :
4446 : // *** will have to circle back to this one to fix since the multispeed coil has all fields in this coil object ***
4447 : // allocate single performance mode for numeric field strings used for sizing routine
4448 14 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
4449 14 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
4450 14 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
4451 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
4452 14 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
4453 :
4454 14 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
4455 14 : thisDXCoil.Name = Alphas(1);
4456 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
4457 14 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
4458 14 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
4459 14 : thisDXCoil.DXCoilType = CurrentModuleObject;
4460 14 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_MultiSpeedHeating;
4461 14 : if (lAlphaBlanks(2)) {
4462 8 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
4463 6 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
4464 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
4465 0 : ErrorsFound = true;
4466 : }
4467 :
4468 14 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
4469 14 : Alphas(3),
4470 : ErrorsFound,
4471 : DataLoopNode::ConnectionObjectType::CoilHeatingDXMultiSpeed,
4472 14 : Alphas(1),
4473 : DataLoopNode::NodeFluidType::Air,
4474 : DataLoopNode::ConnectionType::Inlet,
4475 : NodeInputManager::CompFluidStream::Primary,
4476 : ObjectIsNotParent);
4477 :
4478 28 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
4479 14 : Alphas(4),
4480 : ErrorsFound,
4481 : DataLoopNode::ConnectionObjectType::CoilHeatingDXMultiSpeed,
4482 14 : Alphas(1),
4483 : DataLoopNode::NodeFluidType::Air,
4484 : DataLoopNode::ConnectionType::Outlet,
4485 : NodeInputManager::CompFluidStream::Primary,
4486 : ObjectIsNotParent);
4487 :
4488 14 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
4489 :
4490 : // Set minimum OAT for heat pump compressor operation
4491 14 : thisDXCoil.MinOATCompressor = Numbers(1);
4492 :
4493 : // set Minimum Outdoor Dry-Bulb Temperature for Compressor Operation
4494 14 : thisDXCoil.OATempCompressorOn = Numbers(2);
4495 : // Set crankcase heater capacity
4496 14 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(3);
4497 14 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
4498 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4499 0 : ShowContinueError(state, format("...{} cannot be < 0.0, entered value=[{:.2T}].", cNumericFields(3), Numbers(3)));
4500 0 : ErrorsFound = true;
4501 : }
4502 :
4503 : // Set crankcase heater cutout temperature
4504 14 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(4);
4505 :
4506 14 : if (!lAlphaBlanks(5)) {
4507 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
4508 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
4509 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(5), Alphas(5)));
4510 0 : ErrorsFound = true;
4511 : } else {
4512 6 : ErrorsFound |= Curve::CheckCurveDims(state,
4513 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
4514 : {1}, // Valid dimensions
4515 : RoutineName, // Routine name
4516 : CurrentModuleObject, // Object Type
4517 : thisDXCoil.Name, // Object Name
4518 2 : cAlphaFields(5)); // Field Name
4519 : }
4520 : }
4521 :
4522 : // Only required for reverse cycle heat pumps
4523 14 : thisDXCoil.DefrostEIRFT = GetCurveIndex(state, Alphas(6)); // convert curve name to number
4524 14 : if (Util::SameString(Alphas(7), "ReverseCycle")) {
4525 13 : if (thisDXCoil.DefrostEIRFT == 0) {
4526 0 : if (lAlphaBlanks(6)) {
4527 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4528 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
4529 : } else {
4530 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4531 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
4532 : }
4533 0 : ErrorsFound = true;
4534 : } else {
4535 : // Verify Curve Object, only legal type is BiQuadratic
4536 26 : ErrorsFound |= Curve::CheckCurveDims(state,
4537 : thisDXCoil.DefrostEIRFT, // Curve index
4538 : {2}, // Valid dimensions
4539 : RoutineName, // Routine name
4540 : CurrentModuleObject, // Object Type
4541 : thisDXCoil.Name, // Object Name
4542 13 : cAlphaFields(6)); // Field Name
4543 :
4544 13 : if (!ErrorsFound) {
4545 13 : checkCurveIsNormalizedToOne(state,
4546 39 : std::string{RoutineName} + CurrentModuleObject,
4547 13 : thisDXCoil.Name,
4548 : thisDXCoil.DefrostEIRFT,
4549 13 : cAlphaFields(6),
4550 13 : Alphas(6),
4551 : RatedInletWetBulbTempHeat,
4552 : RatedOutdoorAirTempHeat);
4553 : }
4554 : }
4555 : }
4556 :
4557 14 : if (Util::SameString(Alphas(7), "ReverseCycle")) thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
4558 14 : if (Util::SameString(Alphas(7), "Resistive")) thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
4559 14 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
4560 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4561 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(7), Alphas(7)));
4562 0 : ShowContinueError(state, "...valid values for this field are ReverseCycle or Resistive.");
4563 0 : ErrorsFound = true;
4564 : }
4565 :
4566 14 : if (Util::SameString(Alphas(8), "Timed")) thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::Timed;
4567 14 : if (Util::SameString(Alphas(8), "OnDemand")) thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
4568 14 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
4569 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4570 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(8), Alphas(8)));
4571 0 : ShowContinueError(state, "...valid values for this field are Timed or OnDemand.");
4572 0 : ErrorsFound = true;
4573 : }
4574 :
4575 : // Set maximum outdoor temp for defrost to occur
4576 14 : thisDXCoil.MaxOATDefrost = Numbers(5);
4577 :
4578 : // Set defrost time period
4579 14 : thisDXCoil.DefrostTime = Numbers(6);
4580 14 : if (thisDXCoil.DefrostTime == 0.0 && thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
4581 0 : ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4582 0 : ShowContinueError(state, format("...{} = 0.0 for defrost control = TIMED.", cNumericFields(5)));
4583 : }
4584 :
4585 : // Set defrost capacity (for resistive defrost)
4586 14 : thisDXCoil.DefrostCapacity = Numbers(7);
4587 14 : if (thisDXCoil.DefrostCapacity == 0.0 && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
4588 0 : ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4589 0 : ShowContinueError(state, format("...{} = 0.0 for defrost strategy = RESISTIVE.", cNumericFields(7)));
4590 : }
4591 :
4592 14 : if (Util::SameString(Alphas(9), "Yes")) {
4593 0 : thisDXCoil.PLRImpact = true;
4594 14 : } else if (Util::SameString(Alphas(9), "No")) {
4595 14 : thisDXCoil.PLRImpact = false;
4596 : } else {
4597 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4598 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(9), Alphas(9)));
4599 0 : ShowContinueError(state, "The allowed choices are Yes or No.");
4600 0 : ErrorsFound = true;
4601 : }
4602 :
4603 : // A10; \field Fuel type, Validate fuel type input
4604 14 : thisDXCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(10)));
4605 :
4606 14 : thisDXCoil.RegionNum = Numbers(8); // Region Number for HSPF Calc
4607 14 : thisDXCoil.NumOfSpeeds = Numbers(9); // Number of speeds
4608 14 : if (thisDXCoil.NumOfSpeeds < 2) {
4609 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4610 0 : ShowContinueError(state, format("...{} must be >= 2. entered number is {:.0T}", cNumericFields(9), Numbers(9)));
4611 0 : ErrorsFound = true;
4612 : }
4613 :
4614 : // Allocate arrays based on the number of speeds
4615 14 : thisDXCoil.MSErrIndex.allocate(thisDXCoil.NumOfSpeeds);
4616 14 : thisDXCoil.MSErrIndex = 0;
4617 14 : thisDXCoil.MSRatedTotCap.allocate(thisDXCoil.NumOfSpeeds);
4618 14 : thisDXCoil.MSRatedCOP.allocate(thisDXCoil.NumOfSpeeds);
4619 14 : thisDXCoil.MSRatedAirVolFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4620 14 : thisDXCoil.MSRatedAirMassFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4621 14 : thisDXCoil.MSRatedAirMassFlowRate = 1.0; // avoid divide by 0, will get overwritten in InitDXCoil
4622 14 : thisDXCoil.MSCCapFTemp.allocate(thisDXCoil.NumOfSpeeds);
4623 14 : thisDXCoil.MSCCapFFlow.allocate(thisDXCoil.NumOfSpeeds);
4624 14 : thisDXCoil.MSEIRFTemp.allocate(thisDXCoil.NumOfSpeeds);
4625 14 : thisDXCoil.MSEIRFFlow.allocate(thisDXCoil.NumOfSpeeds);
4626 14 : thisDXCoil.MSWasteHeat.allocate(thisDXCoil.NumOfSpeeds);
4627 14 : thisDXCoil.MSPLFFPLR.allocate(thisDXCoil.NumOfSpeeds);
4628 14 : thisDXCoil.MSRatedCBF.allocate(thisDXCoil.NumOfSpeeds);
4629 14 : thisDXCoil.MSWasteHeatFrac.allocate(thisDXCoil.NumOfSpeeds);
4630 14 : thisDXCoil.MSFanPowerPerEvapAirFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4631 14 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023.allocate(thisDXCoil.NumOfSpeeds);
4632 14 : thisDXCoil.MSSecCoilSHRFT.allocate(thisDXCoil.NumOfSpeeds);
4633 14 : thisDXCoil.MSSecCoilSHRFF.allocate(thisDXCoil.NumOfSpeeds);
4634 14 : thisDXCoil.MSSecCoilAirFlow.allocate(thisDXCoil.NumOfSpeeds);
4635 14 : thisDXCoil.MSSecCoilAirFlowScalingFactor.allocate(thisDXCoil.NumOfSpeeds);
4636 14 : thisDXCoil.MSSecCoilRatedSHR.allocate(thisDXCoil.NumOfSpeeds);
4637 :
4638 14 : thisDXCoil.RatedSHR(1) = 1.0;
4639 :
4640 48 : for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
4641 34 : thisDXCoil.MSRatedTotCap(I) = Numbers(10 + (I - 1) * 6);
4642 34 : thisDXCoil.MSRatedCOP(I) = Numbers(11 + (I - 1) * 6);
4643 34 : thisDXCoil.MSRatedAirVolFlowRate(I) = Numbers(12 + (I - 1) * 6);
4644 34 : thisDXCoil.MSFanPowerPerEvapAirFlowRate(I) = Numbers(13 + (I - 1) * 6);
4645 34 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023(I) = Numbers(14 + (I - 1) * 6);
4646 34 : thisDXCoil.MSWasteHeatFrac(I) = Numbers(15 + (I - 1) * 6);
4647 :
4648 34 : thisDXCoil.MSCCapFTemp(I) = GetCurveIndex(state, Alphas(11 + (I - 1) * 6)); // convert curve name to number
4649 34 : if (thisDXCoil.MSCCapFTemp(I) == 0) {
4650 0 : ShowSevereError(state,
4651 0 : format("{}, \"{}\" {} not found:{}",
4652 : CurrentModuleObject,
4653 0 : thisDXCoil.Name,
4654 0 : cAlphaFields(11 + (I - 1) * 6),
4655 0 : Alphas(11 + (I - 1) * 6)));
4656 0 : ErrorsFound = true;
4657 : } else {
4658 : // only legal types are Quadratic, BiQuadratic and Cubic
4659 102 : ErrorsFound |= Curve::CheckCurveDims(state,
4660 34 : thisDXCoil.MSCCapFTemp(I), // Curve index
4661 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
4662 : RoutineName, // Routine name
4663 : CurrentModuleObject, // Object Type
4664 : thisDXCoil.Name, // Object Name
4665 34 : cAlphaFields(11 + (I - 1) * 6)); // Field Name
4666 :
4667 34 : if (!ErrorsFound) {
4668 34 : if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(I))->numDims == 1) {
4669 8 : checkCurveIsNormalizedToOne(state,
4670 24 : std::string{RoutineName} + CurrentModuleObject,
4671 8 : thisDXCoil.Name,
4672 8 : thisDXCoil.MSCCapFTemp(I),
4673 8 : cAlphaFields(11 + (I - 1) * 6),
4674 8 : Alphas(11 + (I - 1) * 6),
4675 : RatedOutdoorAirTempHeat);
4676 : } else {
4677 26 : checkCurveIsNormalizedToOne(state,
4678 78 : std::string{RoutineName} + CurrentModuleObject,
4679 26 : thisDXCoil.Name,
4680 26 : thisDXCoil.MSCCapFTemp(I),
4681 26 : cAlphaFields(11 + (I - 1) * 6),
4682 26 : Alphas(11 + (I - 1) * 6),
4683 : RatedInletAirTempHeat,
4684 : RatedOutdoorAirTempHeat);
4685 : }
4686 : }
4687 : }
4688 :
4689 34 : thisDXCoil.MSCCapFFlow(I) = GetCurveIndex(state, Alphas(12 + (I - 1) * 6)); // convert curve name to number
4690 34 : if (thisDXCoil.MSCCapFFlow(I) == 0) {
4691 0 : if (lAlphaBlanks(12 + (I - 1) * 6)) {
4692 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4693 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(12 + (I - 1) * 6)));
4694 : } else {
4695 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4696 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(12 + (I - 1) * 6), Alphas(12 + (I - 1) * 6)));
4697 : }
4698 0 : ErrorsFound = true;
4699 : } else {
4700 : // Verify Curve Object, only legal type is Quadratic
4701 102 : ErrorsFound |= Curve::CheckCurveDims(state,
4702 34 : thisDXCoil.MSCCapFFlow(I), // Curve index
4703 : {1}, // Valid dimensions
4704 : RoutineName, // Routine name
4705 : CurrentModuleObject, // Object Type
4706 : thisDXCoil.Name, // Object Name
4707 34 : cAlphaFields(12 + (I - 1) * 6)); // Field Name
4708 :
4709 34 : if (!ErrorsFound) {
4710 34 : checkCurveIsNormalizedToOne(state,
4711 102 : std::string{RoutineName} + CurrentModuleObject,
4712 34 : thisDXCoil.Name,
4713 34 : thisDXCoil.MSCCapFFlow(I),
4714 34 : cAlphaFields(12 + (I - 1) * 6),
4715 34 : Alphas(12 + (I - 1) * 6),
4716 : 1.0);
4717 : }
4718 : }
4719 :
4720 34 : thisDXCoil.MSEIRFTemp(I) = GetCurveIndex(state, Alphas(13 + (I - 1) * 6)); // convert curve name to number
4721 34 : if (thisDXCoil.MSEIRFTemp(I) == 0) {
4722 0 : if (lAlphaBlanks(13 + (I - 1) * 6)) {
4723 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4724 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(13 + (I - 1) * 6)));
4725 : } else {
4726 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4727 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(13 + (I - 1) * 6), Alphas(13 + (I - 1) * 6)));
4728 : }
4729 0 : ErrorsFound = true;
4730 : } else {
4731 : // only legal types are Quadratic, BiQuadratic and Cubic
4732 102 : ErrorsFound |= Curve::CheckCurveDims(state,
4733 34 : thisDXCoil.MSEIRFTemp(I), // Curve index
4734 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
4735 : RoutineName, // Routine name
4736 : CurrentModuleObject, // Object Type
4737 : thisDXCoil.Name, // Object Name
4738 34 : cAlphaFields(13 + (I - 1) * 6)); // Field Name
4739 :
4740 34 : if (!ErrorsFound) {
4741 34 : if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(I))->numDims == 1) {
4742 8 : checkCurveIsNormalizedToOne(state,
4743 24 : std::string{RoutineName} + CurrentModuleObject,
4744 8 : thisDXCoil.Name,
4745 8 : thisDXCoil.MSEIRFTemp(I),
4746 8 : cAlphaFields(13 + (I - 1) * 6),
4747 8 : Alphas(13 + (I - 1) * 6),
4748 : RatedOutdoorAirTempHeat);
4749 : } else {
4750 26 : checkCurveIsNormalizedToOne(state,
4751 78 : std::string{RoutineName} + CurrentModuleObject,
4752 26 : thisDXCoil.Name,
4753 26 : thisDXCoil.MSEIRFTemp(I),
4754 26 : cAlphaFields(13 + (I - 1) * 6),
4755 26 : Alphas(13 + (I - 1) * 6),
4756 : RatedInletAirTempHeat,
4757 : RatedOutdoorAirTempHeat);
4758 : }
4759 : }
4760 : }
4761 :
4762 34 : thisDXCoil.MSEIRFFlow(I) = GetCurveIndex(state, Alphas(14 + (I - 1) * 6)); // convert curve name to number
4763 34 : if (thisDXCoil.MSEIRFFlow(I) == 0) {
4764 0 : if (lAlphaBlanks(14 + (I - 1) * 6)) {
4765 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4766 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(14 + (I - 1) * 6)));
4767 : } else {
4768 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4769 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14 + (I - 1) * 6), Alphas(14 + (I - 1) * 6)));
4770 : }
4771 0 : ErrorsFound = true;
4772 : } else {
4773 : // Verify Curve Object, only legal type is Quadratic
4774 102 : ErrorsFound |= Curve::CheckCurveDims(state,
4775 34 : thisDXCoil.MSEIRFFlow(I), // Curve index
4776 : {1}, // Valid dimensions
4777 : RoutineName, // Routine name
4778 : CurrentModuleObject, // Object Type
4779 : thisDXCoil.Name, // Object Name
4780 34 : cAlphaFields(14 + (I - 1) * 6)); // Field Name
4781 :
4782 34 : if (!ErrorsFound) {
4783 34 : checkCurveIsNormalizedToOne(state,
4784 102 : std::string{RoutineName} + CurrentModuleObject,
4785 34 : thisDXCoil.Name,
4786 34 : thisDXCoil.MSEIRFFlow(I),
4787 34 : cAlphaFields(14 + (I - 1) * 6),
4788 34 : Alphas(14 + (I - 1) * 6),
4789 : 1.0);
4790 : }
4791 : }
4792 :
4793 34 : thisDXCoil.MSPLFFPLR(I) = GetCurveIndex(state, Alphas(15 + (I - 1) * 6)); // convert curve name to number
4794 34 : if (thisDXCoil.MSPLFFPLR(I) == 0) {
4795 0 : if (lAlphaBlanks(15 + (I - 1) * 6)) {
4796 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4797 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(15 + (I - 1) * 6)));
4798 : } else {
4799 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4800 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
4801 : }
4802 0 : ErrorsFound = true;
4803 : } else {
4804 : // Verify Curve Object, only legal types are Quadratic or Cubic
4805 102 : ErrorsFound |= Curve::CheckCurveDims(state,
4806 34 : thisDXCoil.MSPLFFPLR(I), // Curve index
4807 : {1}, // Valid dimensions
4808 : RoutineName, // Routine name
4809 : CurrentModuleObject, // Object Type
4810 : thisDXCoil.Name, // Object Name
4811 34 : cAlphaFields(15 + (I - 1) * 6)); // Field Name
4812 :
4813 34 : if (!ErrorsFound) {
4814 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
4815 34 : MinCurveVal = 999.0;
4816 34 : MaxCurveVal = -999.0;
4817 34 : CurveInput = 0.0;
4818 3434 : while (CurveInput <= 1.0) {
4819 3400 : CurveVal = CurveValue(state, thisDXCoil.MSPLFFPLR(I), CurveInput);
4820 3400 : if (CurveVal < MinCurveVal) {
4821 34 : MinCurveVal = CurveVal;
4822 34 : MinCurvePLR = CurveInput;
4823 : }
4824 3400 : if (CurveVal > MaxCurveVal) {
4825 2944 : MaxCurveVal = CurveVal;
4826 2944 : MaxCurvePLR = CurveInput;
4827 : }
4828 3400 : CurveInput += 0.01;
4829 : }
4830 34 : if (MinCurveVal < 0.7) {
4831 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4832 0 : ShowContinueError(state,
4833 0 : format("...{} = {} has out of range value.", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
4834 0 : ShowContinueError(state,
4835 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
4836 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
4837 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 0.7);
4838 : }
4839 :
4840 34 : if (MaxCurveVal > 1.0) {
4841 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4842 0 : ShowContinueError(state,
4843 0 : format("...{} = {} has out of range value.", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
4844 0 : ShowContinueError(state,
4845 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
4846 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
4847 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 1.0);
4848 : }
4849 : }
4850 : }
4851 :
4852 : // Read waste heat modifier curve name
4853 34 : thisDXCoil.MSWasteHeat(I) = GetCurveIndex(state, Alphas(16 + (I - 1) * 6)); // convert curve name to number
4854 34 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
4855 12 : if (thisDXCoil.MSWasteHeat(I) > 0) {
4856 : // Verify Curve Object, only legal types are BiQuadratic
4857 24 : ErrorsFound |= Curve::CheckCurveDims(state,
4858 8 : thisDXCoil.MSWasteHeat(I), // Curve index
4859 : {2}, // Valid dimensions
4860 : RoutineName, // Routine name
4861 : CurrentModuleObject, // Object Type
4862 : thisDXCoil.Name, // Object Name
4863 8 : cAlphaFields(16 + (I - 1) * 6)); // Field Name
4864 :
4865 8 : if (!ErrorsFound) {
4866 8 : checkCurveIsNormalizedToOne(state,
4867 24 : std::string{RoutineName} + CurrentModuleObject,
4868 8 : thisDXCoil.Name,
4869 8 : thisDXCoil.MSWasteHeat(I),
4870 8 : cAlphaFields(16 + (I - 1) * 6),
4871 8 : Alphas(16 + (I - 1) * 6),
4872 : RatedOutdoorAirTempHeat,
4873 : RatedInletAirTempHeat);
4874 : }
4875 : }
4876 : }
4877 : }
4878 : // A35; \field Zone Name for Condenser Placement
4879 14 : if (!lAlphaBlanks(35) && NumAlphas > 34) {
4880 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(35), state.dataHeatBal->Zone);
4881 0 : if (thisDXCoil.SecZonePtr > 0) {
4882 0 : SetupZoneInternalGain(state,
4883 : thisDXCoil.SecZonePtr,
4884 : thisDXCoil.Name,
4885 : DataHeatBalance::IntGainType::SecHeatingDXCoilMultiSpeed,
4886 : &thisDXCoil.SecCoilSensibleHeatRemovalRate,
4887 : nullptr,
4888 : nullptr,
4889 : &thisDXCoil.SecCoilLatentHeatRemovalRate);
4890 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
4891 : } else {
4892 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4893 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(35), Alphas(35)));
4894 : }
4895 : }
4896 14 : if (thisDXCoil.SecZonePtr > 0) {
4897 0 : for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
4898 0 : thisDXCoil.MSSecCoilAirFlow(I) = Numbers(34 + (I - 1) * 3);
4899 0 : thisDXCoil.MSSecCoilAirFlowScalingFactor(I) = Numbers(35 + (I - 1) * 3);
4900 0 : thisDXCoil.MSSecCoilRatedSHR(I) = Numbers(36 + (I - 1) * 3);
4901 : // Read SHR modifier curve function of temperature
4902 0 : if (!lAlphaBlanks(36 + (I - 1) * 2)) {
4903 0 : thisDXCoil.MSSecCoilSHRFT(I) = GetCurveIndex(state, Alphas(36 + (I - 1) * 2)); // convert curve name to number
4904 0 : if (thisDXCoil.MSSecCoilSHRFT(I) == 0) {
4905 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4906 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(36 + (I - 1) * 2), Alphas(36 + (I - 1) * 2)));
4907 : }
4908 : }
4909 : // Read SHR modifier curve function of flow fraction
4910 0 : if (!lAlphaBlanks(36 + (I - 1) * 2)) {
4911 0 : thisDXCoil.MSSecCoilSHRFF(I) = GetCurveIndex(state, Alphas(36 + (I - 1) * 2)); // convert curve name to number
4912 0 : if (thisDXCoil.MSSecCoilSHRFF(I) == 0) {
4913 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4914 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(36 + (I - 1) * 2), Alphas(36 + (I - 1) * 2)));
4915 : }
4916 : }
4917 : }
4918 : }
4919 : }
4920 :
4921 : // Loop over the VRF Cooling Coils and get & load the data
4922 134 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling);
4923 158 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFCoolingCoils; ++DXCoilIndex) {
4924 :
4925 24 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4926 : CurrentModuleObject,
4927 : DXCoilIndex,
4928 : Alphas,
4929 : NumAlphas,
4930 : Numbers,
4931 : NumNumbers,
4932 : IOStatus,
4933 : lNumericBlanks,
4934 : lAlphaBlanks,
4935 : cAlphaFields,
4936 : cNumericFields);
4937 :
4938 24 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
4939 :
4940 24 : ++DXCoilNum;
4941 :
4942 : // allocate single performance mode for numeric field strings used for sizing routine
4943 24 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
4944 24 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
4945 24 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
4946 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
4947 24 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
4948 :
4949 24 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
4950 24 : thisDXCoil.Name = Alphas(1);
4951 24 : thisDXCoil.DXCoilType = CurrentModuleObject;
4952 24 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_Cooling;
4953 :
4954 24 : if (lAlphaBlanks(2)) {
4955 2 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
4956 22 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
4957 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
4958 0 : ErrorsFound = true;
4959 : }
4960 24 : thisDXCoil.RatedTotCap(1) = Numbers(1);
4961 24 : thisDXCoil.RatedSHR(1) = Numbers(2);
4962 24 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(3);
4963 :
4964 24 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(3));
4965 : // Verify Curve Object, only legal type is Linear, Quadratic, Cubic, or BiQuadratic
4966 72 : ErrorsFound |= Curve::CheckCurveDims(state,
4967 24 : thisDXCoil.CCapFTemp(1), // Curve index
4968 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
4969 : RoutineName, // Routine name
4970 : CurrentModuleObject, // Object Type
4971 : thisDXCoil.Name, // Object Name
4972 24 : cAlphaFields(3)); // Field Name
4973 :
4974 24 : if (!ErrorsFound) {
4975 24 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
4976 23 : checkCurveIsNormalizedToOne(state,
4977 69 : std::string{RoutineName} + CurrentModuleObject,
4978 23 : thisDXCoil.Name,
4979 23 : thisDXCoil.CCapFTemp(1),
4980 23 : cAlphaFields(3),
4981 23 : Alphas(3),
4982 : RatedInletWetBulbTemp);
4983 : } else {
4984 1 : checkCurveIsNormalizedToOne(state,
4985 3 : std::string{RoutineName} + CurrentModuleObject,
4986 1 : thisDXCoil.Name,
4987 1 : thisDXCoil.CCapFTemp(1),
4988 1 : cAlphaFields(3),
4989 1 : Alphas(3),
4990 : RatedInletWetBulbTemp,
4991 : RatedOutdoorAirTemp);
4992 : }
4993 : }
4994 :
4995 24 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(4)); // convert curve name to number
4996 24 : if (thisDXCoil.CCapFFlow(1) == 0) {
4997 0 : if (lAlphaBlanks(4)) {
4998 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4999 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(4)));
5000 : } else {
5001 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5002 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(4), Alphas(4)));
5003 : }
5004 0 : ErrorsFound = true;
5005 : } else {
5006 : // Verify Curve Object, only legal type is Linear, Quadratic or Cubic
5007 72 : ErrorsFound |= Curve::CheckCurveDims(state,
5008 24 : thisDXCoil.CCapFFlow(1), // Curve index
5009 : {1}, // Valid dimensions
5010 : RoutineName, // Routine name
5011 : CurrentModuleObject, // Object Type
5012 : thisDXCoil.Name, // Object Name
5013 24 : cAlphaFields(4)); // Field Name
5014 :
5015 24 : if (!ErrorsFound) {
5016 24 : checkCurveIsNormalizedToOne(
5017 96 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(4), Alphas(4), 1.0);
5018 : }
5019 : }
5020 :
5021 24 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5022 24 : Alphas(5),
5023 : ErrorsFound,
5024 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlow,
5025 24 : Alphas(1),
5026 : DataLoopNode::NodeFluidType::Air,
5027 : DataLoopNode::ConnectionType::Inlet,
5028 : NodeInputManager::CompFluidStream::Primary,
5029 : ObjectIsNotParent);
5030 :
5031 48 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5032 24 : Alphas(6),
5033 : ErrorsFound,
5034 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlow,
5035 24 : Alphas(1),
5036 : DataLoopNode::NodeFluidType::Air,
5037 : DataLoopNode::ConnectionType::Outlet,
5038 : NodeInputManager::CompFluidStream::Primary,
5039 : ObjectIsNotParent);
5040 :
5041 24 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(5), Alphas(6), "Air Nodes");
5042 :
5043 24 : thisDXCoil.CondensateCollectName = Alphas(7);
5044 24 : if (lAlphaBlanks(7)) {
5045 24 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
5046 : } else {
5047 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
5048 0 : SetupTankSupplyComponent(state,
5049 : thisDXCoil.Name,
5050 : CurrentModuleObject,
5051 : thisDXCoil.CondensateCollectName,
5052 : ErrorsFound,
5053 0 : thisDXCoil.CondensateTankID,
5054 0 : thisDXCoil.CondensateTankSupplyARRID);
5055 : }
5056 : }
5057 :
5058 134 : if (ErrorsFound) {
5059 0 : ShowFatalError(state,
5060 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5061 : }
5062 :
5063 : // Loop over the VRF Heating Coils and get & load the data
5064 134 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating);
5065 157 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFHeatingCoils; ++DXCoilIndex) {
5066 :
5067 23 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5068 : CurrentModuleObject,
5069 : DXCoilIndex,
5070 : Alphas,
5071 : NumAlphas,
5072 : Numbers,
5073 : NumNumbers,
5074 : IOStatus,
5075 : lNumericBlanks,
5076 : lAlphaBlanks,
5077 : cAlphaFields,
5078 : cNumericFields);
5079 :
5080 23 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
5081 23 : ++DXCoilNum;
5082 :
5083 : // allocate single performance mode for numeric field strings used for sizing routine
5084 23 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
5085 23 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
5086 23 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
5087 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
5088 23 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
5089 :
5090 23 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5091 23 : thisDXCoil.Name = Alphas(1);
5092 23 : thisDXCoil.DXCoilType = CurrentModuleObject;
5093 23 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_Heating;
5094 23 : if (lAlphaBlanks(2)) {
5095 2 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
5096 21 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
5097 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
5098 0 : ErrorsFound = true;
5099 : }
5100 23 : thisDXCoil.RatedTotCap(1) = Numbers(1);
5101 23 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(2);
5102 :
5103 23 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5104 23 : Alphas(3),
5105 : ErrorsFound,
5106 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlow,
5107 23 : Alphas(1),
5108 : DataLoopNode::NodeFluidType::Air,
5109 : DataLoopNode::ConnectionType::Inlet,
5110 : NodeInputManager::CompFluidStream::Primary,
5111 : ObjectIsNotParent);
5112 :
5113 46 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5114 23 : Alphas(4),
5115 : ErrorsFound,
5116 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlow,
5117 23 : Alphas(1),
5118 : DataLoopNode::NodeFluidType::Air,
5119 : DataLoopNode::ConnectionType::Outlet,
5120 : NodeInputManager::CompFluidStream::Primary,
5121 : ObjectIsNotParent);
5122 :
5123 23 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
5124 :
5125 23 : thisDXCoil.CCapFTemp = GetCurveIndex(state, Alphas(5));
5126 23 : if (thisDXCoil.CCapFTemp(1) == 0) {
5127 0 : if (lAlphaBlanks(5)) {
5128 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5129 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
5130 : } else {
5131 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5132 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
5133 : }
5134 0 : ErrorsFound = true;
5135 : } else {
5136 69 : ErrorsFound |= Curve::CheckCurveDims(state,
5137 23 : thisDXCoil.CCapFTemp(1), // Curve index
5138 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
5139 : RoutineName, // Routine name
5140 : CurrentModuleObject, // Object Type
5141 : thisDXCoil.Name, // Object Name
5142 23 : cAlphaFields(5)); // Field Name
5143 :
5144 23 : if (!ErrorsFound) {
5145 23 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
5146 23 : checkCurveIsNormalizedToOne(state,
5147 69 : std::string{RoutineName} + CurrentModuleObject,
5148 23 : thisDXCoil.Name,
5149 23 : thisDXCoil.CCapFTemp(1),
5150 23 : cAlphaFields(5),
5151 23 : Alphas(5),
5152 : RatedInletAirTempHeat);
5153 : } else {
5154 : // 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
5155 : // GetInput.
5156 : }
5157 : }
5158 : }
5159 :
5160 23 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
5161 23 : if (thisDXCoil.CCapFFlow(1) == 0) {
5162 0 : if (lAlphaBlanks(6)) {
5163 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5164 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
5165 : } else {
5166 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5167 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
5168 : }
5169 0 : ErrorsFound = true;
5170 : } else {
5171 : // Verify Curve Object, only legal type is Quadratic
5172 69 : ErrorsFound |= Curve::CheckCurveDims(state,
5173 23 : thisDXCoil.CCapFFlow(1), // Curve index
5174 : {1}, // Valid dimensions
5175 : RoutineName, // Routine name
5176 : CurrentModuleObject, // Object Type
5177 : thisDXCoil.Name, // Object Name
5178 23 : cAlphaFields(6)); // Field Name
5179 :
5180 23 : if (!ErrorsFound) {
5181 23 : checkCurveIsNormalizedToOne(
5182 92 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
5183 : }
5184 : }
5185 : }
5186 :
5187 134 : if (ErrorsFound) {
5188 0 : ShowFatalError(state,
5189 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5190 : }
5191 :
5192 : // Loop over the VRF Cooling Coils for VRF FluidTCtrl Model_zrp 2015
5193 134 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling);
5194 146 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils; ++DXCoilIndex) {
5195 :
5196 12 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5197 : CurrentModuleObject,
5198 : DXCoilIndex,
5199 : Alphas,
5200 : NumAlphas,
5201 : Numbers,
5202 : NumNumbers,
5203 : IOStatus,
5204 : lNumericBlanks,
5205 : lAlphaBlanks,
5206 : cAlphaFields,
5207 : cNumericFields);
5208 :
5209 12 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
5210 12 : ++DXCoilNum;
5211 :
5212 : // allocate single performance mode for numeric field strings used for sizing routine
5213 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
5214 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
5215 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
5216 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
5217 12 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
5218 :
5219 12 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5220 12 : thisDXCoil.Name = Alphas(1);
5221 12 : thisDXCoil.DXCoilType = CurrentModuleObject;
5222 12 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_FluidTCtrl_Cooling;
5223 12 : if (lAlphaBlanks(2)) {
5224 3 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
5225 9 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
5226 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
5227 0 : ErrorsFound = true;
5228 : }
5229 :
5230 12 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5231 12 : Alphas(3),
5232 : ErrorsFound,
5233 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl,
5234 12 : Alphas(1),
5235 : DataLoopNode::NodeFluidType::Air,
5236 : DataLoopNode::ConnectionType::Inlet,
5237 : NodeInputManager::CompFluidStream::Primary,
5238 : ObjectIsNotParent);
5239 24 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5240 12 : Alphas(4),
5241 : ErrorsFound,
5242 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl,
5243 12 : Alphas(1),
5244 : DataLoopNode::NodeFluidType::Air,
5245 : DataLoopNode::ConnectionType::Outlet,
5246 : NodeInputManager::CompFluidStream::Primary,
5247 : ObjectIsNotParent);
5248 12 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
5249 :
5250 12 : thisDXCoil.RatedTotCap(1) = Numbers(1);
5251 12 : thisDXCoil.RatedSHR(1) = Numbers(2);
5252 12 : thisDXCoil.SH = Numbers(3);
5253 : // @@ DXCoil( DXCoilNum ).RateBFVRFIUEvap = 0.0592; there will be a new field for this, which will be handled in a separate issue to
5254 : // update VRF-HP idd. It is not handled here to avoid transition issues for VRF-HP.
5255 :
5256 12 : int indexSHCurve = GetCurveIndex(state, Alphas(5)); // convert curve name to index number
5257 : // Verify curve name and type
5258 12 : if (indexSHCurve == 0) {
5259 0 : if (lAlphaBlanks(5)) {
5260 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5261 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
5262 : } else {
5263 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5264 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
5265 : }
5266 0 : ErrorsFound = true;
5267 : } else {
5268 : {
5269 12 : if (state.dataCurveManager->curves(indexSHCurve)->curveType == Curve::CurveType::Quadratic) {
5270 12 : thisDXCoil.C1Te = state.dataCurveManager->curves(indexSHCurve)->coeff[0];
5271 12 : thisDXCoil.C2Te = state.dataCurveManager->curves(indexSHCurve)->coeff[1];
5272 12 : thisDXCoil.C3Te = state.dataCurveManager->curves(indexSHCurve)->coeff[2];
5273 :
5274 : } else {
5275 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5276 0 : ShowContinueError(state,
5277 0 : format("...illegal {} type for this object = {}",
5278 : cAlphaFields(5),
5279 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexSHCurve)->curveType)]));
5280 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
5281 0 : ErrorsFound = true;
5282 : }
5283 : }
5284 : }
5285 :
5286 12 : thisDXCoil.CondensateCollectName = Alphas(6);
5287 12 : if (lAlphaBlanks(6)) {
5288 12 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
5289 : } else {
5290 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
5291 0 : SetupTankSupplyComponent(state,
5292 : thisDXCoil.Name,
5293 : CurrentModuleObject,
5294 : thisDXCoil.CondensateCollectName,
5295 : ErrorsFound,
5296 0 : thisDXCoil.CondensateTankID,
5297 0 : thisDXCoil.CondensateTankSupplyARRID);
5298 : }
5299 : }
5300 :
5301 134 : if (ErrorsFound) {
5302 0 : ShowFatalError(state,
5303 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5304 : }
5305 :
5306 : // Loop over the VRF Heating Coils for VRF FluidTCtrl Model_zrp 2015
5307 134 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating);
5308 145 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils; ++DXCoilIndex) {
5309 :
5310 11 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5311 : CurrentModuleObject,
5312 : DXCoilIndex,
5313 : Alphas,
5314 : NumAlphas,
5315 : Numbers,
5316 : NumNumbers,
5317 : IOStatus,
5318 : lNumericBlanks,
5319 : lAlphaBlanks,
5320 : cAlphaFields,
5321 : cNumericFields);
5322 :
5323 11 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
5324 11 : ++DXCoilNum;
5325 :
5326 : // allocate single performance mode for numeric field strings used for sizing routine
5327 11 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
5328 11 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
5329 11 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
5330 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
5331 11 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
5332 :
5333 11 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5334 11 : thisDXCoil.Name = Alphas(1);
5335 11 : thisDXCoil.DXCoilType = CurrentModuleObject;
5336 11 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_FluidTCtrl_Heating;
5337 11 : if (lAlphaBlanks(2)) {
5338 2 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
5339 9 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
5340 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
5341 0 : ErrorsFound = true;
5342 : }
5343 :
5344 11 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5345 11 : Alphas(3),
5346 : ErrorsFound,
5347 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl,
5348 11 : Alphas(1),
5349 : DataLoopNode::NodeFluidType::Air,
5350 : DataLoopNode::ConnectionType::Inlet,
5351 : NodeInputManager::CompFluidStream::Primary,
5352 : ObjectIsNotParent);
5353 22 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5354 11 : Alphas(4),
5355 : ErrorsFound,
5356 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl,
5357 11 : Alphas(1),
5358 : DataLoopNode::NodeFluidType::Air,
5359 : DataLoopNode::ConnectionType::Outlet,
5360 : NodeInputManager::CompFluidStream::Primary,
5361 : ObjectIsNotParent);
5362 11 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
5363 :
5364 11 : thisDXCoil.RatedTotCap(1) = Numbers(1);
5365 11 : thisDXCoil.SC = Numbers(2);
5366 : //@@ DXCoil( DXCoilNum ).RateBFVRFIUCond = 0.136;
5367 :
5368 11 : int indexSCCurve = GetCurveIndex(state, Alphas(5)); // convert curve name to index number
5369 : // Verify curve name and type
5370 11 : if (indexSCCurve == 0) {
5371 0 : if (lAlphaBlanks(5)) {
5372 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5373 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
5374 : } else {
5375 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5376 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
5377 : }
5378 0 : ErrorsFound = true;
5379 : } else {
5380 : {
5381 11 : if (state.dataCurveManager->curves(indexSCCurve)->curveType == Curve::CurveType::Quadratic) {
5382 11 : thisDXCoil.C1Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[0];
5383 11 : thisDXCoil.C2Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[1];
5384 11 : thisDXCoil.C3Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[2];
5385 :
5386 : } else {
5387 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5388 0 : ShowContinueError(state,
5389 0 : format("...illegal {} type for this object = {}",
5390 : cAlphaFields(5),
5391 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexSCCurve)->curveType)]));
5392 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
5393 0 : ErrorsFound = true;
5394 : }
5395 : }
5396 : }
5397 : }
5398 :
5399 134 : if (ErrorsFound) {
5400 0 : ShowFatalError(state,
5401 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5402 : }
5403 :
5404 349 : for (DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDXCoils; ++DXCoilNum) {
5405 :
5406 215 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5407 :
5408 215 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
5409 : // Setup Report Variables for Cooling Equipment
5410 : // CurrentModuleObject='Coil:Cooling:DX:SingleSpeed/Coil:Cooling:DX:TwoStageWithHumidityControlMode'
5411 128 : SetupOutputVariable(state,
5412 : "Cooling Coil Total Cooling Rate",
5413 : Constant::Units::W,
5414 64 : thisDXCoil.TotalCoolingEnergyRate,
5415 : OutputProcessor::TimeStepType::System,
5416 : OutputProcessor::StoreType::Average,
5417 64 : thisDXCoil.Name);
5418 128 : SetupOutputVariable(state,
5419 : "Cooling Coil Total Cooling Energy",
5420 : Constant::Units::J,
5421 64 : thisDXCoil.TotalCoolingEnergy,
5422 : OutputProcessor::TimeStepType::System,
5423 : OutputProcessor::StoreType::Sum,
5424 64 : thisDXCoil.Name,
5425 : Constant::eResource::EnergyTransfer,
5426 : OutputProcessor::Group::HVAC,
5427 : OutputProcessor::EndUseCat::CoolingCoils);
5428 128 : SetupOutputVariable(state,
5429 : "Cooling Coil Sensible Cooling Rate",
5430 : Constant::Units::W,
5431 64 : thisDXCoil.SensCoolingEnergyRate,
5432 : OutputProcessor::TimeStepType::System,
5433 : OutputProcessor::StoreType::Average,
5434 64 : thisDXCoil.Name);
5435 128 : SetupOutputVariable(state,
5436 : "Cooling Coil Sensible Cooling Energy",
5437 : Constant::Units::J,
5438 64 : thisDXCoil.SensCoolingEnergy,
5439 : OutputProcessor::TimeStepType::System,
5440 : OutputProcessor::StoreType::Sum,
5441 64 : thisDXCoil.Name);
5442 128 : SetupOutputVariable(state,
5443 : "Cooling Coil Latent Cooling Rate",
5444 : Constant::Units::W,
5445 64 : thisDXCoil.LatCoolingEnergyRate,
5446 : OutputProcessor::TimeStepType::System,
5447 : OutputProcessor::StoreType::Average,
5448 64 : thisDXCoil.Name);
5449 128 : SetupOutputVariable(state,
5450 : "Cooling Coil Latent Cooling Energy",
5451 : Constant::Units::J,
5452 64 : thisDXCoil.LatCoolingEnergy,
5453 : OutputProcessor::TimeStepType::System,
5454 : OutputProcessor::StoreType::Sum,
5455 64 : thisDXCoil.Name);
5456 128 : SetupOutputVariable(state,
5457 : "Cooling Coil Electricity Rate",
5458 : Constant::Units::W,
5459 64 : thisDXCoil.ElecCoolingPower,
5460 : OutputProcessor::TimeStepType::System,
5461 : OutputProcessor::StoreType::Average,
5462 64 : thisDXCoil.Name);
5463 128 : SetupOutputVariable(state,
5464 : "Cooling Coil Electricity Energy",
5465 : Constant::Units::J,
5466 64 : thisDXCoil.ElecCoolingConsumption,
5467 : OutputProcessor::TimeStepType::System,
5468 : OutputProcessor::StoreType::Sum,
5469 64 : thisDXCoil.Name,
5470 : Constant::eResource::Electricity,
5471 : OutputProcessor::Group::HVAC,
5472 : OutputProcessor::EndUseCat::Cooling);
5473 128 : SetupOutputVariable(state,
5474 : "Cooling Coil Runtime Fraction",
5475 : Constant::Units::None,
5476 64 : thisDXCoil.CoolingCoilRuntimeFraction,
5477 : OutputProcessor::TimeStepType::System,
5478 : OutputProcessor::StoreType::Average,
5479 64 : thisDXCoil.Name);
5480 64 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
5481 0 : SetupOutputVariable(state,
5482 : "Secondary Coil Heat Rejection Rate",
5483 : Constant::Units::W,
5484 0 : thisDXCoil.SecCoilSensibleHeatGainRate,
5485 : OutputProcessor::TimeStepType::System,
5486 : OutputProcessor::StoreType::Average,
5487 0 : thisDXCoil.Name);
5488 : }
5489 :
5490 : // do we report these even if no storage tank?
5491 64 : if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
5492 0 : SetupOutputVariable(state,
5493 : "Cooling Coil Condensate Volume Flow Rate",
5494 : Constant::Units::m3_s,
5495 0 : thisDXCoil.CondensateVdot,
5496 : OutputProcessor::TimeStepType::System,
5497 : OutputProcessor::StoreType::Average,
5498 0 : thisDXCoil.Name);
5499 0 : SetupOutputVariable(state,
5500 : "Cooling Coil Condensate Volume",
5501 : Constant::Units::m3,
5502 0 : thisDXCoil.CondensateVol,
5503 : OutputProcessor::TimeStepType::System,
5504 : OutputProcessor::StoreType::Sum,
5505 0 : thisDXCoil.Name,
5506 : Constant::eResource::OnSiteWater,
5507 : OutputProcessor::Group::HVAC,
5508 : OutputProcessor::EndUseCat::Condensate);
5509 : }
5510 :
5511 64 : if (thisDXCoil.ReportEvapCondVars) {
5512 28 : SetupOutputVariable(state,
5513 : "Cooling Coil Condenser Inlet Temperature",
5514 : Constant::Units::C,
5515 14 : thisDXCoil.CondInletTemp,
5516 : OutputProcessor::TimeStepType::System,
5517 : OutputProcessor::StoreType::Average,
5518 14 : thisDXCoil.Name);
5519 28 : SetupOutputVariable(state,
5520 : "Cooling Coil Evaporative Condenser Water Volume",
5521 : Constant::Units::m3,
5522 14 : thisDXCoil.EvapWaterConsump,
5523 : OutputProcessor::TimeStepType::System,
5524 : OutputProcessor::StoreType::Sum,
5525 14 : thisDXCoil.Name,
5526 : Constant::eResource::Water,
5527 : OutputProcessor::Group::HVAC,
5528 : OutputProcessor::EndUseCat::Cooling);
5529 28 : SetupOutputVariable(state,
5530 : "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
5531 : Constant::Units::m3,
5532 14 : thisDXCoil.EvapWaterConsump,
5533 : OutputProcessor::TimeStepType::System,
5534 : OutputProcessor::StoreType::Sum,
5535 14 : thisDXCoil.Name,
5536 : Constant::eResource::MainsWater,
5537 : OutputProcessor::Group::HVAC,
5538 : OutputProcessor::EndUseCat::Cooling);
5539 28 : SetupOutputVariable(state,
5540 : "Cooling Coil Evaporative Condenser Pump Electricity Rate",
5541 : Constant::Units::W,
5542 14 : thisDXCoil.EvapCondPumpElecPower,
5543 : OutputProcessor::TimeStepType::System,
5544 : OutputProcessor::StoreType::Average,
5545 14 : thisDXCoil.Name);
5546 28 : SetupOutputVariable(state,
5547 : "Cooling Coil Evaporative Condenser Pump Electricity Energy",
5548 : Constant::Units::J,
5549 14 : thisDXCoil.EvapCondPumpElecConsumption,
5550 : OutputProcessor::TimeStepType::System,
5551 : OutputProcessor::StoreType::Sum,
5552 14 : thisDXCoil.Name,
5553 : Constant::eResource::Electricity,
5554 : OutputProcessor::Group::HVAC,
5555 : OutputProcessor::EndUseCat::Cooling);
5556 14 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
5557 6 : SetupOutputVariable(state,
5558 : "Cooling Coil Basin Heater Electricity Rate",
5559 : Constant::Units::W,
5560 3 : thisDXCoil.BasinHeaterPower,
5561 : OutputProcessor::TimeStepType::System,
5562 : OutputProcessor::StoreType::Average,
5563 3 : thisDXCoil.Name);
5564 6 : SetupOutputVariable(state,
5565 : "Cooling Coil Basin Heater Electricity Energy",
5566 : Constant::Units::J,
5567 3 : thisDXCoil.BasinHeaterConsumption,
5568 : OutputProcessor::TimeStepType::System,
5569 : OutputProcessor::StoreType::Sum,
5570 3 : thisDXCoil.Name,
5571 : Constant::eResource::Electricity,
5572 : OutputProcessor::Group::HVAC,
5573 : OutputProcessor::EndUseCat::Cooling);
5574 : }
5575 : }
5576 :
5577 64 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
5578 : // Setup Report Variables for Cooling Equipment
5579 : // CurrentModuleObject='Cooling:DX:TwoStageWithHumidityControlMode'
5580 4 : SetupOutputVariable(state,
5581 : "Cooling Coil Stage 2 Runtime Fraction",
5582 : Constant::Units::None,
5583 2 : thisDXCoil.CoolingCoilStg2RuntimeFrac,
5584 : OutputProcessor::TimeStepType::System,
5585 : OutputProcessor::StoreType::Average,
5586 2 : thisDXCoil.Name);
5587 2 : SetupOutputVariable(state,
5588 : "Cooling Coil Dehumidification Mode",
5589 : Constant::Units::None,
5590 2 : (int &)thisDXCoil.DehumidificationMode,
5591 : OutputProcessor::TimeStepType::System,
5592 : OutputProcessor::StoreType::Average,
5593 2 : thisDXCoil.Name);
5594 : }
5595 :
5596 : }
5597 :
5598 151 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5599 : // Setup Report Variables for Heating Equipment
5600 : // CurrentModuleObject='Coil:Heating:DX:SingleSpeed'
5601 24 : SetupOutputVariable(state,
5602 : "Heating Coil Heating Rate",
5603 : Constant::Units::W,
5604 12 : thisDXCoil.TotalHeatingEnergyRate,
5605 : OutputProcessor::TimeStepType::System,
5606 : OutputProcessor::StoreType::Average,
5607 12 : thisDXCoil.Name);
5608 24 : SetupOutputVariable(state,
5609 : "Heating Coil Heating Energy",
5610 : Constant::Units::J,
5611 12 : thisDXCoil.TotalHeatingEnergy,
5612 : OutputProcessor::TimeStepType::System,
5613 : OutputProcessor::StoreType::Sum,
5614 12 : thisDXCoil.Name,
5615 : Constant::eResource::EnergyTransfer,
5616 : OutputProcessor::Group::HVAC,
5617 : OutputProcessor::EndUseCat::HeatingCoils);
5618 24 : SetupOutputVariable(state,
5619 : "Heating Coil Electricity Rate",
5620 : Constant::Units::W,
5621 12 : thisDXCoil.ElecHeatingPower,
5622 : OutputProcessor::TimeStepType::System,
5623 : OutputProcessor::StoreType::Average,
5624 12 : thisDXCoil.Name);
5625 24 : SetupOutputVariable(state,
5626 : "Heating Coil Electricity Energy",
5627 : Constant::Units::J,
5628 12 : thisDXCoil.ElecHeatingConsumption,
5629 : OutputProcessor::TimeStepType::System,
5630 : OutputProcessor::StoreType::Sum,
5631 12 : thisDXCoil.Name,
5632 : Constant::eResource::Electricity,
5633 : OutputProcessor::Group::HVAC,
5634 : OutputProcessor::EndUseCat::Heating);
5635 24 : SetupOutputVariable(state,
5636 : "Heating Coil Defrost Electricity Rate",
5637 : Constant::Units::W,
5638 12 : thisDXCoil.DefrostPower,
5639 : OutputProcessor::TimeStepType::System,
5640 : OutputProcessor::StoreType::Average,
5641 12 : thisDXCoil.Name);
5642 24 : SetupOutputVariable(state,
5643 : "Heating Coil Defrost Electricity Energy",
5644 : Constant::Units::J,
5645 12 : thisDXCoil.DefrostConsumption,
5646 : OutputProcessor::TimeStepType::System,
5647 : OutputProcessor::StoreType::Sum,
5648 12 : thisDXCoil.Name,
5649 : Constant::eResource::Electricity,
5650 : OutputProcessor::Group::HVAC,
5651 : OutputProcessor::EndUseCat::Heating);
5652 24 : SetupOutputVariable(state,
5653 : "Heating Coil Crankcase Heater Electricity Rate",
5654 : Constant::Units::W,
5655 12 : thisDXCoil.CrankcaseHeaterPower,
5656 : OutputProcessor::TimeStepType::System,
5657 : OutputProcessor::StoreType::Average,
5658 12 : thisDXCoil.Name);
5659 24 : SetupOutputVariable(state,
5660 : "Heating Coil Crankcase Heater Electricity Energy",
5661 : Constant::Units::J,
5662 12 : thisDXCoil.CrankcaseHeaterConsumption,
5663 : OutputProcessor::TimeStepType::System,
5664 : OutputProcessor::StoreType::Sum,
5665 12 : thisDXCoil.Name,
5666 : Constant::eResource::Electricity,
5667 : OutputProcessor::Group::HVAC,
5668 : OutputProcessor::EndUseCat::Heating);
5669 24 : SetupOutputVariable(state,
5670 : "Heating Coil Runtime Fraction",
5671 : Constant::Units::None,
5672 12 : thisDXCoil.HeatingCoilRuntimeFraction,
5673 : OutputProcessor::TimeStepType::System,
5674 : OutputProcessor::StoreType::Average,
5675 12 : thisDXCoil.Name);
5676 12 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
5677 0 : SetupOutputVariable(state,
5678 : "Secondary Coil Total Heat Removal Rate",
5679 : Constant::Units::W,
5680 0 : thisDXCoil.SecCoilTotalHeatRemovalRate,
5681 : OutputProcessor::TimeStepType::System,
5682 : OutputProcessor::StoreType::Average,
5683 0 : thisDXCoil.Name);
5684 0 : SetupOutputVariable(state,
5685 : "Secondary Coil Sensible Heat Removal Rate",
5686 : Constant::Units::W,
5687 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate,
5688 : OutputProcessor::TimeStepType::System,
5689 : OutputProcessor::StoreType::Average,
5690 0 : thisDXCoil.Name);
5691 0 : SetupOutputVariable(state,
5692 : "Secondary Coil Latent Heat Removal Rate",
5693 : Constant::Units::W,
5694 0 : thisDXCoil.SecCoilLatentHeatRemovalRate,
5695 : OutputProcessor::TimeStepType::System,
5696 : OutputProcessor::StoreType::Average,
5697 0 : thisDXCoil.Name);
5698 0 : SetupOutputVariable(state,
5699 : "Secondary Coil Sensible Heat Ratio",
5700 : Constant::Units::None,
5701 0 : thisDXCoil.SecCoilSHR,
5702 : OutputProcessor::TimeStepType::System,
5703 : OutputProcessor::StoreType::Average,
5704 0 : thisDXCoil.Name);
5705 0 : SetupOutputVariable(state,
5706 : "Secondary Coil Compressor Part Load Ratio",
5707 : Constant::Units::None,
5708 0 : thisDXCoil.CompressorPartLoadRatio,
5709 : OutputProcessor::TimeStepType::System,
5710 : OutputProcessor::StoreType::Average,
5711 0 : thisDXCoil.Name);
5712 : }
5713 12 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
5714 0 : SetupEMSActuator(state,
5715 : thisDXCoil.DXCoilType,
5716 : thisDXCoil.Name,
5717 : "Frost Heating Capacity Multiplier",
5718 : "[]",
5719 0 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
5720 0 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
5721 :
5722 0 : SetupEMSActuator(state,
5723 : thisDXCoil.DXCoilType,
5724 : thisDXCoil.Name,
5725 : "Frost Heating Input Power Multiplier",
5726 : "[]",
5727 0 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
5728 0 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
5729 : }
5730 : }
5731 :
5732 139 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
5733 : // Setup Report Variables for Cooling Equipment
5734 : // CurrentModuleObject='Coil:Cooling:DX:TwoSpeed'
5735 24 : SetupOutputVariable(state,
5736 : "Cooling Coil Total Cooling Rate",
5737 : Constant::Units::W,
5738 12 : thisDXCoil.TotalCoolingEnergyRate,
5739 : OutputProcessor::TimeStepType::System,
5740 : OutputProcessor::StoreType::Average,
5741 12 : thisDXCoil.Name);
5742 24 : SetupOutputVariable(state,
5743 : "Cooling Coil Total Cooling Energy",
5744 : Constant::Units::J,
5745 12 : thisDXCoil.TotalCoolingEnergy,
5746 : OutputProcessor::TimeStepType::System,
5747 : OutputProcessor::StoreType::Sum,
5748 12 : thisDXCoil.Name,
5749 : Constant::eResource::EnergyTransfer,
5750 : OutputProcessor::Group::HVAC,
5751 : OutputProcessor::EndUseCat::CoolingCoils);
5752 24 : SetupOutputVariable(state,
5753 : "Cooling Coil Sensible Cooling Rate",
5754 : Constant::Units::W,
5755 12 : thisDXCoil.SensCoolingEnergyRate,
5756 : OutputProcessor::TimeStepType::System,
5757 : OutputProcessor::StoreType::Average,
5758 12 : thisDXCoil.Name);
5759 24 : SetupOutputVariable(state,
5760 : "Cooling Coil Sensible Cooling Energy",
5761 : Constant::Units::J,
5762 12 : thisDXCoil.SensCoolingEnergy,
5763 : OutputProcessor::TimeStepType::System,
5764 : OutputProcessor::StoreType::Sum,
5765 12 : thisDXCoil.Name);
5766 24 : SetupOutputVariable(state,
5767 : "Cooling Coil Latent Cooling Rate",
5768 : Constant::Units::W,
5769 12 : thisDXCoil.LatCoolingEnergyRate,
5770 : OutputProcessor::TimeStepType::System,
5771 : OutputProcessor::StoreType::Average,
5772 12 : thisDXCoil.Name);
5773 24 : SetupOutputVariable(state,
5774 : "Cooling Coil Latent Cooling Energy",
5775 : Constant::Units::J,
5776 12 : thisDXCoil.LatCoolingEnergy,
5777 : OutputProcessor::TimeStepType::System,
5778 : OutputProcessor::StoreType::Sum,
5779 12 : thisDXCoil.Name);
5780 24 : SetupOutputVariable(state,
5781 : "Cooling Coil Electricity Rate",
5782 : Constant::Units::W,
5783 12 : thisDXCoil.ElecCoolingPower,
5784 : OutputProcessor::TimeStepType::System,
5785 : OutputProcessor::StoreType::Average,
5786 12 : thisDXCoil.Name);
5787 24 : SetupOutputVariable(state,
5788 : "Cooling Coil Electricity Energy",
5789 : Constant::Units::J,
5790 12 : thisDXCoil.ElecCoolingConsumption,
5791 : OutputProcessor::TimeStepType::System,
5792 : OutputProcessor::StoreType::Sum,
5793 12 : thisDXCoil.Name,
5794 : Constant::eResource::Electricity,
5795 : OutputProcessor::Group::HVAC,
5796 : OutputProcessor::EndUseCat::Cooling);
5797 24 : SetupOutputVariable(state,
5798 : "Cooling Coil Runtime Fraction",
5799 : Constant::Units::None,
5800 12 : thisDXCoil.CoolingCoilRuntimeFraction,
5801 : OutputProcessor::TimeStepType::System,
5802 : OutputProcessor::StoreType::Average,
5803 12 : thisDXCoil.Name);
5804 12 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
5805 0 : SetupOutputVariable(state,
5806 : "Secondary Coil Heat Rejection Rate",
5807 : Constant::Units::W,
5808 0 : thisDXCoil.SecCoilSensibleHeatGainRate,
5809 : OutputProcessor::TimeStepType::System,
5810 : OutputProcessor::StoreType::Average,
5811 0 : thisDXCoil.Name);
5812 : }
5813 :
5814 12 : if (thisDXCoil.ReportEvapCondVars) {
5815 4 : SetupOutputVariable(state,
5816 : "Cooling Coil Condenser Inlet Temperature",
5817 : Constant::Units::C,
5818 2 : thisDXCoil.CondInletTemp,
5819 : OutputProcessor::TimeStepType::System,
5820 : OutputProcessor::StoreType::Average,
5821 2 : thisDXCoil.Name);
5822 4 : SetupOutputVariable(state,
5823 : "Cooling Coil Evaporative Condenser Water Volume",
5824 : Constant::Units::m3,
5825 2 : thisDXCoil.EvapWaterConsump,
5826 : OutputProcessor::TimeStepType::System,
5827 : OutputProcessor::StoreType::Sum,
5828 2 : thisDXCoil.Name,
5829 : Constant::eResource::Water,
5830 : OutputProcessor::Group::HVAC,
5831 : OutputProcessor::EndUseCat::Cooling);
5832 4 : SetupOutputVariable(state,
5833 : "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
5834 : Constant::Units::m3,
5835 2 : thisDXCoil.EvapWaterConsump,
5836 : OutputProcessor::TimeStepType::System,
5837 : OutputProcessor::StoreType::Sum,
5838 2 : thisDXCoil.Name,
5839 : Constant::eResource::MainsWater,
5840 : OutputProcessor::Group::HVAC,
5841 : OutputProcessor::EndUseCat::Cooling);
5842 4 : SetupOutputVariable(state,
5843 : "Cooling Coil Evaporative Condenser Pump Electricity Rate",
5844 : Constant::Units::W,
5845 2 : thisDXCoil.EvapCondPumpElecPower,
5846 : OutputProcessor::TimeStepType::System,
5847 : OutputProcessor::StoreType::Average,
5848 2 : thisDXCoil.Name);
5849 4 : SetupOutputVariable(state,
5850 : "Cooling Coil Evaporative Condenser Pump Electricity Energy",
5851 : Constant::Units::J,
5852 2 : thisDXCoil.EvapCondPumpElecConsumption,
5853 : OutputProcessor::TimeStepType::System,
5854 : OutputProcessor::StoreType::Sum,
5855 2 : thisDXCoil.Name,
5856 : Constant::eResource::Electricity,
5857 : OutputProcessor::Group::HVAC,
5858 : OutputProcessor::EndUseCat::Cooling);
5859 2 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
5860 2 : SetupOutputVariable(state,
5861 : "Cooling Coil Basin Heater Electricity Rate",
5862 : Constant::Units::W,
5863 1 : thisDXCoil.BasinHeaterPower,
5864 : OutputProcessor::TimeStepType::System,
5865 : OutputProcessor::StoreType::Average,
5866 1 : thisDXCoil.Name);
5867 2 : SetupOutputVariable(state,
5868 : "Cooling Coil Basin Heater Electricity Energy",
5869 : Constant::Units::J,
5870 1 : thisDXCoil.BasinHeaterConsumption,
5871 : OutputProcessor::TimeStepType::System,
5872 : OutputProcessor::StoreType::Sum,
5873 1 : thisDXCoil.Name,
5874 : Constant::eResource::Electricity,
5875 : OutputProcessor::Group::HVAC,
5876 : OutputProcessor::EndUseCat::Cooling);
5877 : }
5878 : }
5879 :
5880 : }
5881 :
5882 127 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
5883 118 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
5884 : // Setup Report Variables for Cooling Equipment
5885 : // CurrentModuleObject='Coil:WaterHeating:AirToWaterHeatPump:Pumped'
5886 : // or 'Coil:WaterHeating:AirToWaterHeatPump:Wrapped'
5887 32 : SetupOutputVariable(state,
5888 : "Cooling Coil Total Cooling Rate",
5889 : Constant::Units::W,
5890 16 : thisDXCoil.TotalCoolingEnergyRate,
5891 : OutputProcessor::TimeStepType::System,
5892 : OutputProcessor::StoreType::Average,
5893 16 : thisDXCoil.Name);
5894 :
5895 16 : if (thisDXCoil.IsDXCoilInZone) {
5896 32 : SetupOutputVariable(state,
5897 : "Cooling Coil Total Cooling Energy",
5898 : Constant::Units::J,
5899 16 : thisDXCoil.TotalCoolingEnergy,
5900 : OutputProcessor::TimeStepType::System,
5901 : OutputProcessor::StoreType::Sum,
5902 16 : thisDXCoil.Name,
5903 : Constant::eResource::EnergyTransfer,
5904 : OutputProcessor::Group::HVAC,
5905 : OutputProcessor::EndUseCat::CoolingCoils);
5906 : } else {
5907 0 : SetupOutputVariable(state,
5908 : "Cooling Coil Total Cooling Energy",
5909 : Constant::Units::J,
5910 0 : thisDXCoil.TotalCoolingEnergy,
5911 : OutputProcessor::TimeStepType::System,
5912 : OutputProcessor::StoreType::Sum,
5913 0 : thisDXCoil.Name);
5914 : }
5915 :
5916 32 : SetupOutputVariable(state,
5917 : "Cooling Coil Sensible Cooling Rate",
5918 : Constant::Units::W,
5919 16 : thisDXCoil.SensCoolingEnergyRate,
5920 : OutputProcessor::TimeStepType::System,
5921 : OutputProcessor::StoreType::Average,
5922 16 : thisDXCoil.Name);
5923 32 : SetupOutputVariable(state,
5924 : "Cooling Coil Sensible Cooling Energy",
5925 : Constant::Units::J,
5926 16 : thisDXCoil.SensCoolingEnergy,
5927 : OutputProcessor::TimeStepType::System,
5928 : OutputProcessor::StoreType::Sum,
5929 16 : thisDXCoil.Name);
5930 32 : SetupOutputVariable(state,
5931 : "Cooling Coil Latent Cooling Rate",
5932 : Constant::Units::W,
5933 16 : thisDXCoil.LatCoolingEnergyRate,
5934 : OutputProcessor::TimeStepType::System,
5935 : OutputProcessor::StoreType::Average,
5936 16 : thisDXCoil.Name);
5937 32 : SetupOutputVariable(state,
5938 : "Cooling Coil Latent Cooling Energy",
5939 : Constant::Units::J,
5940 16 : thisDXCoil.LatCoolingEnergy,
5941 : OutputProcessor::TimeStepType::System,
5942 : OutputProcessor::StoreType::Sum,
5943 16 : thisDXCoil.Name);
5944 32 : SetupOutputVariable(state,
5945 : "Cooling Coil Runtime Fraction",
5946 : Constant::Units::None,
5947 16 : thisDXCoil.CoolingCoilRuntimeFraction,
5948 : OutputProcessor::TimeStepType::System,
5949 : OutputProcessor::StoreType::Average,
5950 16 : thisDXCoil.Name);
5951 :
5952 16 : if (thisDXCoil.ReportCoolingCoilCrankcasePower) {
5953 32 : SetupOutputVariable(state,
5954 : "Cooling Coil Crankcase Heater Electricity Rate",
5955 : Constant::Units::W,
5956 16 : thisDXCoil.CrankcaseHeaterPower,
5957 : OutputProcessor::TimeStepType::System,
5958 : OutputProcessor::StoreType::Average,
5959 16 : thisDXCoil.Name);
5960 32 : SetupOutputVariable(state,
5961 : "Cooling Coil Crankcase Heater Electricity Energy",
5962 : Constant::Units::J,
5963 16 : thisDXCoil.CrankcaseHeaterConsumption,
5964 : OutputProcessor::TimeStepType::System,
5965 : OutputProcessor::StoreType::Sum,
5966 16 : thisDXCoil.Name,
5967 : Constant::eResource::Electricity,
5968 : OutputProcessor::Group::Plant,
5969 : OutputProcessor::EndUseCat::WaterSystem); // DHW
5970 : }
5971 :
5972 : // new report variables for a HP water heater DX coil
5973 32 : SetupOutputVariable(state,
5974 : "Cooling Coil Total Water Heating Rate",
5975 : Constant::Units::W,
5976 16 : thisDXCoil.TotalHeatingEnergyRate,
5977 : OutputProcessor::TimeStepType::System,
5978 : OutputProcessor::StoreType::Average,
5979 16 : thisDXCoil.Name);
5980 32 : SetupOutputVariable(state,
5981 : "Cooling Coil Total Water Heating Energy",
5982 : Constant::Units::J,
5983 16 : thisDXCoil.TotalHeatingEnergy,
5984 : OutputProcessor::TimeStepType::System,
5985 : OutputProcessor::StoreType::Sum,
5986 16 : thisDXCoil.Name); //, &
5987 : // ResourceTypeKey='ENERGYTRANSFER',EndUseKey='HEATING',GroupKey='Plant')
5988 32 : SetupOutputVariable(state,
5989 : "Cooling Coil Water Heating Electricity Rate",
5990 : Constant::Units::W,
5991 16 : thisDXCoil.ElecWaterHeatingPower,
5992 : OutputProcessor::TimeStepType::System,
5993 : OutputProcessor::StoreType::Average,
5994 16 : thisDXCoil.Name);
5995 32 : SetupOutputVariable(state,
5996 : "Cooling Coil Water Heating Electricity Energy",
5997 : Constant::Units::J,
5998 16 : thisDXCoil.ElecWaterHeatingConsumption,
5999 : OutputProcessor::TimeStepType::System,
6000 : OutputProcessor::StoreType::Sum,
6001 16 : thisDXCoil.Name,
6002 : Constant::eResource::Electricity,
6003 : OutputProcessor::Group::Plant,
6004 : OutputProcessor::EndUseCat::WaterSystem); // DHW
6005 : }
6006 :
6007 111 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6008 : // Setup Report Variables for Cooling Equipment:
6009 : // CurrentModuleObject='Coil:Cooling:DX:MultiSpeed'
6010 54 : SetupOutputVariable(state,
6011 : "Cooling Coil Total Cooling Rate",
6012 : Constant::Units::W,
6013 27 : thisDXCoil.TotalCoolingEnergyRate,
6014 : OutputProcessor::TimeStepType::System,
6015 : OutputProcessor::StoreType::Average,
6016 27 : thisDXCoil.Name);
6017 54 : SetupOutputVariable(state,
6018 : "Cooling Coil Total Cooling Energy",
6019 : Constant::Units::J,
6020 27 : thisDXCoil.TotalCoolingEnergy,
6021 : OutputProcessor::TimeStepType::System,
6022 : OutputProcessor::StoreType::Sum,
6023 27 : thisDXCoil.Name,
6024 : Constant::eResource::EnergyTransfer,
6025 : OutputProcessor::Group::HVAC,
6026 : OutputProcessor::EndUseCat::CoolingCoils);
6027 54 : SetupOutputVariable(state,
6028 : "Cooling Coil Sensible Cooling Rate",
6029 : Constant::Units::W,
6030 27 : thisDXCoil.SensCoolingEnergyRate,
6031 : OutputProcessor::TimeStepType::System,
6032 : OutputProcessor::StoreType::Average,
6033 27 : thisDXCoil.Name);
6034 54 : SetupOutputVariable(state,
6035 : "Cooling Coil Sensible Cooling Energy",
6036 : Constant::Units::J,
6037 27 : thisDXCoil.SensCoolingEnergy,
6038 : OutputProcessor::TimeStepType::System,
6039 : OutputProcessor::StoreType::Sum,
6040 27 : thisDXCoil.Name);
6041 54 : SetupOutputVariable(state,
6042 : "Cooling Coil Latent Cooling Rate",
6043 : Constant::Units::W,
6044 27 : thisDXCoil.LatCoolingEnergyRate,
6045 : OutputProcessor::TimeStepType::System,
6046 : OutputProcessor::StoreType::Average,
6047 27 : thisDXCoil.Name);
6048 54 : SetupOutputVariable(state,
6049 : "Cooling Coil Latent Cooling Energy",
6050 : Constant::Units::J,
6051 27 : thisDXCoil.LatCoolingEnergy,
6052 : OutputProcessor::TimeStepType::System,
6053 : OutputProcessor::StoreType::Sum,
6054 27 : thisDXCoil.Name);
6055 54 : SetupOutputVariable(state,
6056 : "Cooling Coil Electricity Rate",
6057 : Constant::Units::W,
6058 27 : thisDXCoil.ElecCoolingPower,
6059 : OutputProcessor::TimeStepType::System,
6060 : OutputProcessor::StoreType::Average,
6061 27 : thisDXCoil.Name);
6062 54 : SetupOutputVariable(state,
6063 : "Cooling Coil Electricity Energy",
6064 : Constant::Units::J,
6065 27 : thisDXCoil.ElecCoolingConsumption,
6066 : OutputProcessor::TimeStepType::System,
6067 : OutputProcessor::StoreType::Sum,
6068 27 : thisDXCoil.Name,
6069 : Constant::eResource::Electricity,
6070 : OutputProcessor::Group::HVAC,
6071 : OutputProcessor::EndUseCat::Cooling);
6072 :
6073 27 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
6074 4 : std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
6075 12 : SetupOutputVariable(state,
6076 8 : format("Cooling Coil {} Rate", sFuelType),
6077 : Constant::Units::W,
6078 4 : thisDXCoil.FuelUsed,
6079 : OutputProcessor::TimeStepType::System,
6080 : OutputProcessor::StoreType::Average,
6081 4 : thisDXCoil.Name);
6082 12 : SetupOutputVariable(state,
6083 8 : format("Cooling Coil {} Energy", sFuelType),
6084 : Constant::Units::J,
6085 4 : thisDXCoil.FuelConsumed,
6086 : OutputProcessor::TimeStepType::System,
6087 : OutputProcessor::StoreType::Sum,
6088 4 : thisDXCoil.Name,
6089 4 : Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
6090 : OutputProcessor::Group::HVAC,
6091 : OutputProcessor::EndUseCat::Cooling);
6092 : }
6093 :
6094 54 : SetupOutputVariable(state,
6095 : "Cooling Coil Runtime Fraction",
6096 : Constant::Units::None,
6097 27 : thisDXCoil.CoolingCoilRuntimeFraction,
6098 : OutputProcessor::TimeStepType::System,
6099 : OutputProcessor::StoreType::Average,
6100 27 : thisDXCoil.Name);
6101 :
6102 27 : if (thisDXCoil.ReportEvapCondVars) {
6103 0 : SetupOutputVariable(state,
6104 : "Cooling Coil Condenser Inlet Temperature",
6105 : Constant::Units::C,
6106 0 : thisDXCoil.CondInletTemp,
6107 : OutputProcessor::TimeStepType::System,
6108 : OutputProcessor::StoreType::Average,
6109 0 : thisDXCoil.Name);
6110 0 : SetupOutputVariable(state,
6111 : "Cooling Coil Evaporative Condenser Water Volume",
6112 : Constant::Units::m3,
6113 0 : thisDXCoil.EvapWaterConsump,
6114 : OutputProcessor::TimeStepType::System,
6115 : OutputProcessor::StoreType::Sum,
6116 0 : thisDXCoil.Name,
6117 : Constant::eResource::Water,
6118 : OutputProcessor::Group::HVAC,
6119 : OutputProcessor::EndUseCat::Cooling);
6120 0 : SetupOutputVariable(state,
6121 : "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
6122 : Constant::Units::m3,
6123 0 : thisDXCoil.EvapWaterConsump,
6124 : OutputProcessor::TimeStepType::System,
6125 : OutputProcessor::StoreType::Sum,
6126 0 : thisDXCoil.Name,
6127 : Constant::eResource::MainsWater,
6128 : OutputProcessor::Group::HVAC,
6129 : OutputProcessor::EndUseCat::Cooling);
6130 0 : SetupOutputVariable(state,
6131 : "Cooling Coil Evaporative Condenser Pump Electricity Rate",
6132 : Constant::Units::W,
6133 0 : thisDXCoil.EvapCondPumpElecPower,
6134 : OutputProcessor::TimeStepType::System,
6135 : OutputProcessor::StoreType::Average,
6136 0 : thisDXCoil.Name);
6137 0 : SetupOutputVariable(state,
6138 : "Cooling Coil Evaporative Condenser Pump Electricity Energy",
6139 : Constant::Units::J,
6140 0 : thisDXCoil.EvapCondPumpElecConsumption,
6141 : OutputProcessor::TimeStepType::System,
6142 : OutputProcessor::StoreType::Sum,
6143 0 : thisDXCoil.Name,
6144 : Constant::eResource::Electricity,
6145 : OutputProcessor::Group::HVAC,
6146 : OutputProcessor::EndUseCat::Cooling);
6147 0 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
6148 0 : SetupOutputVariable(state,
6149 : "Cooling Coil Basin Heater Electricity Rate",
6150 : Constant::Units::W,
6151 0 : thisDXCoil.BasinHeaterPower,
6152 : OutputProcessor::TimeStepType::System,
6153 : OutputProcessor::StoreType::Average,
6154 0 : thisDXCoil.Name);
6155 0 : SetupOutputVariable(state,
6156 : "Cooling Coil Basin Heater Electricity Energy",
6157 : Constant::Units::J,
6158 0 : thisDXCoil.BasinHeaterConsumption,
6159 : OutputProcessor::TimeStepType::System,
6160 : OutputProcessor::StoreType::Sum,
6161 0 : thisDXCoil.Name,
6162 : Constant::eResource::Electricity,
6163 : OutputProcessor::Group::HVAC,
6164 : OutputProcessor::EndUseCat::Cooling);
6165 : }
6166 : }
6167 27 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
6168 0 : SetupOutputVariable(state,
6169 : "Secondary Coil Heat Rejection Rate",
6170 : Constant::Units::W,
6171 0 : thisDXCoil.SecCoilSensibleHeatGainRate,
6172 : OutputProcessor::TimeStepType::System,
6173 : OutputProcessor::StoreType::Average,
6174 0 : thisDXCoil.Name);
6175 : }
6176 :
6177 : }
6178 :
6179 84 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6180 : // Setup Report Variables for Heating Equipment:
6181 : // CurrentModuleObject='Coil:Heating:DX:MultiSpeed'
6182 28 : SetupOutputVariable(state,
6183 : "Heating Coil Heating Rate",
6184 : Constant::Units::W,
6185 14 : thisDXCoil.TotalHeatingEnergyRate,
6186 : OutputProcessor::TimeStepType::System,
6187 : OutputProcessor::StoreType::Average,
6188 14 : thisDXCoil.Name);
6189 28 : SetupOutputVariable(state,
6190 : "Heating Coil Heating Energy",
6191 : Constant::Units::J,
6192 14 : thisDXCoil.TotalHeatingEnergy,
6193 : OutputProcessor::TimeStepType::System,
6194 : OutputProcessor::StoreType::Sum,
6195 14 : thisDXCoil.Name,
6196 : Constant::eResource::EnergyTransfer,
6197 : OutputProcessor::Group::HVAC,
6198 : OutputProcessor::EndUseCat::HeatingCoils);
6199 28 : SetupOutputVariable(state,
6200 : "Heating Coil Electricity Rate",
6201 : Constant::Units::W,
6202 14 : thisDXCoil.ElecHeatingPower,
6203 : OutputProcessor::TimeStepType::System,
6204 : OutputProcessor::StoreType::Average,
6205 14 : thisDXCoil.Name);
6206 28 : SetupOutputVariable(state,
6207 : "Heating Coil Electricity Energy",
6208 : Constant::Units::J,
6209 14 : thisDXCoil.ElecHeatingConsumption,
6210 : OutputProcessor::TimeStepType::System,
6211 : OutputProcessor::StoreType::Sum,
6212 14 : thisDXCoil.Name,
6213 : Constant::eResource::Electricity,
6214 : OutputProcessor::Group::HVAC,
6215 : OutputProcessor::EndUseCat::Heating);
6216 :
6217 14 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
6218 3 : std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
6219 9 : SetupOutputVariable(state,
6220 6 : format("Heating Coil {} Rate", sFuelType),
6221 : Constant::Units::W,
6222 3 : thisDXCoil.FuelUsed,
6223 : OutputProcessor::TimeStepType::System,
6224 : OutputProcessor::StoreType::Average,
6225 3 : thisDXCoil.Name);
6226 9 : SetupOutputVariable(state,
6227 6 : format("Heating Coil {} Energy", sFuelType),
6228 : Constant::Units::J,
6229 3 : thisDXCoil.FuelConsumed,
6230 : OutputProcessor::TimeStepType::System,
6231 : OutputProcessor::StoreType::Sum,
6232 3 : thisDXCoil.Name,
6233 3 : Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
6234 : OutputProcessor::Group::HVAC,
6235 : OutputProcessor::EndUseCat::HeatingCoils);
6236 : }
6237 :
6238 14 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
6239 2 : std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
6240 6 : SetupOutputVariable(state,
6241 4 : format("Heating Coil Defrost {} Rate", sFuelType),
6242 : Constant::Units::W,
6243 2 : thisDXCoil.DefrostPower,
6244 : OutputProcessor::TimeStepType::System,
6245 : OutputProcessor::StoreType::Average,
6246 2 : thisDXCoil.Name);
6247 6 : SetupOutputVariable(state,
6248 4 : format("Heating Coil Defrost {} Energy", sFuelType),
6249 : Constant::Units::J,
6250 2 : thisDXCoil.DefrostConsumption,
6251 : OutputProcessor::TimeStepType::System,
6252 : OutputProcessor::StoreType::Sum,
6253 2 : thisDXCoil.Name,
6254 2 : Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
6255 : OutputProcessor::Group::HVAC,
6256 : OutputProcessor::EndUseCat::Heating);
6257 2 : } else {
6258 24 : SetupOutputVariable(state,
6259 : "Heating Coil Defrost Electricity Rate",
6260 : Constant::Units::W,
6261 12 : thisDXCoil.DefrostPower,
6262 : OutputProcessor::TimeStepType::System,
6263 : OutputProcessor::StoreType::Average,
6264 12 : thisDXCoil.Name);
6265 24 : SetupOutputVariable(state,
6266 : "Heating Coil Defrost Electricity Energy",
6267 : Constant::Units::J,
6268 12 : thisDXCoil.DefrostConsumption,
6269 : OutputProcessor::TimeStepType::System,
6270 : OutputProcessor::StoreType::Sum,
6271 12 : thisDXCoil.Name,
6272 : Constant::eResource::Electricity,
6273 : OutputProcessor::Group::HVAC,
6274 : OutputProcessor::EndUseCat::Heating);
6275 : }
6276 :
6277 28 : SetupOutputVariable(state,
6278 : "Heating Coil Crankcase Heater Electricity Rate",
6279 : Constant::Units::W,
6280 14 : thisDXCoil.CrankcaseHeaterPower,
6281 : OutputProcessor::TimeStepType::System,
6282 : OutputProcessor::StoreType::Average,
6283 14 : thisDXCoil.Name);
6284 28 : SetupOutputVariable(state,
6285 : "Heating Coil Crankcase Heater Electricity Energy",
6286 : Constant::Units::J,
6287 14 : thisDXCoil.CrankcaseHeaterConsumption,
6288 : OutputProcessor::TimeStepType::System,
6289 : OutputProcessor::StoreType::Sum,
6290 14 : thisDXCoil.Name,
6291 : Constant::eResource::Electricity,
6292 : OutputProcessor::Group::HVAC,
6293 : OutputProcessor::EndUseCat::Heating);
6294 28 : SetupOutputVariable(state,
6295 : "Heating Coil Runtime Fraction",
6296 : Constant::Units::None,
6297 14 : thisDXCoil.HeatingCoilRuntimeFraction,
6298 : OutputProcessor::TimeStepType::System,
6299 : OutputProcessor::StoreType::Average,
6300 14 : thisDXCoil.Name);
6301 :
6302 14 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
6303 0 : SetupOutputVariable(state,
6304 : "Secondary Coil Total Heat Removal Rate",
6305 : Constant::Units::W,
6306 0 : thisDXCoil.SecCoilTotalHeatRemovalRate,
6307 : OutputProcessor::TimeStepType::System,
6308 : OutputProcessor::StoreType::Average,
6309 0 : thisDXCoil.Name);
6310 0 : SetupOutputVariable(state,
6311 : "Secondary Coil Sensible Heat Removal Rate",
6312 : Constant::Units::W,
6313 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate,
6314 : OutputProcessor::TimeStepType::System,
6315 : OutputProcessor::StoreType::Average,
6316 0 : thisDXCoil.Name);
6317 0 : SetupOutputVariable(state,
6318 : "Secondary Coil Latent Heat Removal Rate",
6319 : Constant::Units::W,
6320 0 : thisDXCoil.SecCoilLatentHeatRemovalRate,
6321 : OutputProcessor::TimeStepType::System,
6322 : OutputProcessor::StoreType::Average,
6323 0 : thisDXCoil.Name);
6324 0 : SetupOutputVariable(state,
6325 : "Secondary Coil Sensible Heat Ratio",
6326 : Constant::Units::None,
6327 0 : thisDXCoil.SecCoilSHR,
6328 : OutputProcessor::TimeStepType::System,
6329 : OutputProcessor::StoreType::Average,
6330 0 : thisDXCoil.Name);
6331 : }
6332 :
6333 14 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
6334 0 : SetupEMSActuator(state,
6335 : thisDXCoil.DXCoilType,
6336 : thisDXCoil.Name,
6337 : "Frost Heating Capacity Multiplier",
6338 : "[]",
6339 0 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
6340 0 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
6341 :
6342 0 : SetupEMSActuator(state,
6343 : thisDXCoil.DXCoilType,
6344 : thisDXCoil.Name,
6345 : "Frost Heating Input Power Multiplier",
6346 : "[]",
6347 0 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
6348 0 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
6349 : }
6350 : }
6351 :
6352 : // VRF cooling coil report variables
6353 70 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
6354 : // Setup Report Variables for Cooling Equipment:
6355 : // CurrentModuleObject='Coil:Cooling:DX:VariableRefrigerantFlow
6356 48 : SetupOutputVariable(state,
6357 : "Cooling Coil Total Cooling Rate",
6358 : Constant::Units::W,
6359 24 : thisDXCoil.TotalCoolingEnergyRate,
6360 : OutputProcessor::TimeStepType::System,
6361 : OutputProcessor::StoreType::Average,
6362 24 : thisDXCoil.Name);
6363 48 : SetupOutputVariable(state,
6364 : "Cooling Coil Total Cooling Energy",
6365 : Constant::Units::J,
6366 24 : thisDXCoil.TotalCoolingEnergy,
6367 : OutputProcessor::TimeStepType::System,
6368 : OutputProcessor::StoreType::Sum,
6369 24 : thisDXCoil.Name,
6370 : Constant::eResource::EnergyTransfer,
6371 : OutputProcessor::Group::HVAC,
6372 : OutputProcessor::EndUseCat::CoolingCoils);
6373 48 : SetupOutputVariable(state,
6374 : "Cooling Coil Sensible Cooling Rate",
6375 : Constant::Units::W,
6376 24 : thisDXCoil.SensCoolingEnergyRate,
6377 : OutputProcessor::TimeStepType::System,
6378 : OutputProcessor::StoreType::Average,
6379 24 : thisDXCoil.Name);
6380 48 : SetupOutputVariable(state,
6381 : "Cooling Coil Sensible Cooling Energy",
6382 : Constant::Units::J,
6383 24 : thisDXCoil.SensCoolingEnergy,
6384 : OutputProcessor::TimeStepType::System,
6385 : OutputProcessor::StoreType::Sum,
6386 24 : thisDXCoil.Name);
6387 48 : SetupOutputVariable(state,
6388 : "Cooling Coil Latent Cooling Rate",
6389 : Constant::Units::W,
6390 24 : thisDXCoil.LatCoolingEnergyRate,
6391 : OutputProcessor::TimeStepType::System,
6392 : OutputProcessor::StoreType::Average,
6393 24 : thisDXCoil.Name);
6394 48 : SetupOutputVariable(state,
6395 : "Cooling Coil Latent Cooling Energy",
6396 : Constant::Units::J,
6397 24 : thisDXCoil.LatCoolingEnergy,
6398 : OutputProcessor::TimeStepType::System,
6399 : OutputProcessor::StoreType::Sum,
6400 24 : thisDXCoil.Name);
6401 48 : SetupOutputVariable(state,
6402 : "Cooling Coil Runtime Fraction",
6403 : Constant::Units::None,
6404 24 : thisDXCoil.CoolingCoilRuntimeFraction,
6405 : OutputProcessor::TimeStepType::System,
6406 : OutputProcessor::StoreType::Average,
6407 24 : thisDXCoil.Name);
6408 24 : if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
6409 0 : SetupOutputVariable(state,
6410 : "Cooling Coil Condensate Volume Flow Rate",
6411 : Constant::Units::m3_s,
6412 0 : thisDXCoil.CondensateVdot,
6413 : OutputProcessor::TimeStepType::System,
6414 : OutputProcessor::StoreType::Average,
6415 0 : thisDXCoil.Name);
6416 0 : SetupOutputVariable(state,
6417 : "Cooling Coil Condensate Volume",
6418 : Constant::Units::m3,
6419 0 : thisDXCoil.CondensateVol,
6420 : OutputProcessor::TimeStepType::System,
6421 : OutputProcessor::StoreType::Sum,
6422 0 : thisDXCoil.Name,
6423 : Constant::eResource::OnSiteWater,
6424 : OutputProcessor::Group::HVAC,
6425 : OutputProcessor::EndUseCat::Condensate);
6426 : }
6427 : }
6428 :
6429 : // VRF heating coil report variables
6430 46 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
6431 : // Setup Report Variables for Heating Equipment:
6432 : // CurrentModuleObject='Coil:Heating:DX:VariableRefrigerantFlow
6433 46 : SetupOutputVariable(state,
6434 : "Heating Coil Heating Rate",
6435 : Constant::Units::W,
6436 23 : thisDXCoil.TotalHeatingEnergyRate,
6437 : OutputProcessor::TimeStepType::System,
6438 : OutputProcessor::StoreType::Average,
6439 23 : thisDXCoil.Name);
6440 46 : SetupOutputVariable(state,
6441 : "Heating Coil Heating Energy",
6442 : Constant::Units::J,
6443 23 : thisDXCoil.TotalHeatingEnergy,
6444 : OutputProcessor::TimeStepType::System,
6445 : OutputProcessor::StoreType::Sum,
6446 23 : thisDXCoil.Name,
6447 : Constant::eResource::EnergyTransfer,
6448 : OutputProcessor::Group::HVAC,
6449 : OutputProcessor::EndUseCat::HeatingCoils);
6450 46 : SetupOutputVariable(state,
6451 : "Heating Coil Runtime Fraction",
6452 : Constant::Units::None,
6453 23 : thisDXCoil.HeatingCoilRuntimeFraction,
6454 : OutputProcessor::TimeStepType::System,
6455 : OutputProcessor::StoreType::Average,
6456 23 : thisDXCoil.Name);
6457 :
6458 23 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
6459 0 : SetupEMSActuator(state,
6460 : thisDXCoil.DXCoilType,
6461 : thisDXCoil.Name,
6462 : "Frost Heating Capacity Multiplier",
6463 : "[]",
6464 0 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
6465 0 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
6466 :
6467 0 : SetupEMSActuator(state,
6468 : thisDXCoil.DXCoilType,
6469 : thisDXCoil.Name,
6470 : "Frost Heating Input Power Multiplier",
6471 : "[]",
6472 0 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
6473 0 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
6474 : }
6475 : }
6476 :
6477 : // VRF cooling coil for FluidTCtrl, report variables
6478 23 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
6479 : // Setup Report Variables for Cooling Equipment:
6480 : // CurrentModuleObject='Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl
6481 24 : SetupOutputVariable(state,
6482 : "Cooling Coil Total Cooling Rate",
6483 : Constant::Units::W,
6484 12 : thisDXCoil.TotalCoolingEnergyRate,
6485 : OutputProcessor::TimeStepType::System,
6486 : OutputProcessor::StoreType::Average,
6487 12 : thisDXCoil.Name);
6488 24 : SetupOutputVariable(state,
6489 : "Cooling Coil Total Cooling Energy",
6490 : Constant::Units::J,
6491 12 : thisDXCoil.TotalCoolingEnergy,
6492 : OutputProcessor::TimeStepType::System,
6493 : OutputProcessor::StoreType::Sum,
6494 12 : thisDXCoil.Name,
6495 : Constant::eResource::EnergyTransfer,
6496 : OutputProcessor::Group::HVAC,
6497 : OutputProcessor::EndUseCat::CoolingCoils);
6498 24 : SetupOutputVariable(state,
6499 : "Cooling Coil Sensible Cooling Rate",
6500 : Constant::Units::W,
6501 12 : thisDXCoil.SensCoolingEnergyRate,
6502 : OutputProcessor::TimeStepType::System,
6503 : OutputProcessor::StoreType::Average,
6504 12 : thisDXCoil.Name);
6505 24 : SetupOutputVariable(state,
6506 : "Cooling Coil Sensible Cooling Energy",
6507 : Constant::Units::J,
6508 12 : thisDXCoil.SensCoolingEnergy,
6509 : OutputProcessor::TimeStepType::System,
6510 : OutputProcessor::StoreType::Sum,
6511 12 : thisDXCoil.Name);
6512 24 : SetupOutputVariable(state,
6513 : "Cooling Coil Latent Cooling Rate",
6514 : Constant::Units::W,
6515 12 : thisDXCoil.LatCoolingEnergyRate,
6516 : OutputProcessor::TimeStepType::System,
6517 : OutputProcessor::StoreType::Average,
6518 12 : thisDXCoil.Name);
6519 24 : SetupOutputVariable(state,
6520 : "Cooling Coil Latent Cooling Energy",
6521 : Constant::Units::J,
6522 12 : thisDXCoil.LatCoolingEnergy,
6523 : OutputProcessor::TimeStepType::System,
6524 : OutputProcessor::StoreType::Sum,
6525 12 : thisDXCoil.Name);
6526 24 : SetupOutputVariable(state,
6527 : "Cooling Coil Runtime Fraction",
6528 : Constant::Units::None,
6529 12 : thisDXCoil.CoolingCoilRuntimeFraction,
6530 : OutputProcessor::TimeStepType::System,
6531 : OutputProcessor::StoreType::Average,
6532 12 : thisDXCoil.Name);
6533 : // Followings for VRF_FluidTCtrl Only
6534 24 : SetupOutputVariable(state,
6535 : "Cooling Coil VRF Evaporating Temperature",
6536 : Constant::Units::C,
6537 12 : thisDXCoil.EvaporatingTemp,
6538 : OutputProcessor::TimeStepType::System,
6539 : OutputProcessor::StoreType::Average,
6540 12 : thisDXCoil.Name);
6541 24 : SetupOutputVariable(state,
6542 : "Cooling Coil VRF Super Heating Degrees",
6543 : Constant::Units::C,
6544 12 : thisDXCoil.ActualSH,
6545 : OutputProcessor::TimeStepType::System,
6546 : OutputProcessor::StoreType::Average,
6547 12 : thisDXCoil.Name);
6548 :
6549 12 : if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
6550 0 : SetupOutputVariable(state,
6551 : "Cooling Coil Condensate Volume Flow Rate",
6552 : Constant::Units::m3_s,
6553 0 : thisDXCoil.CondensateVdot,
6554 : OutputProcessor::TimeStepType::System,
6555 : OutputProcessor::StoreType::Average,
6556 0 : thisDXCoil.Name);
6557 0 : SetupOutputVariable(state,
6558 : "Cooling Coil Condensate Volume",
6559 : Constant::Units::m3,
6560 0 : thisDXCoil.CondensateVol,
6561 : OutputProcessor::TimeStepType::System,
6562 : OutputProcessor::StoreType::Sum,
6563 0 : thisDXCoil.Name,
6564 : Constant::eResource::OnSiteWater,
6565 : OutputProcessor::Group::HVAC,
6566 : OutputProcessor::EndUseCat::Condensate);
6567 : }
6568 : }
6569 :
6570 : // VRF heating coil for FluidTCtrl, report variables
6571 11 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
6572 : // Setup Report Variables for Heating Equipment:
6573 : // CurrentModuleObject='Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl
6574 22 : SetupOutputVariable(state,
6575 : "Heating Coil Heating Rate",
6576 : Constant::Units::W,
6577 11 : thisDXCoil.TotalHeatingEnergyRate,
6578 : OutputProcessor::TimeStepType::System,
6579 : OutputProcessor::StoreType::Average,
6580 11 : thisDXCoil.Name);
6581 22 : SetupOutputVariable(state,
6582 : "Heating Coil Heating Energy",
6583 : Constant::Units::J,
6584 11 : thisDXCoil.TotalHeatingEnergy,
6585 : OutputProcessor::TimeStepType::System,
6586 : OutputProcessor::StoreType::Sum,
6587 11 : thisDXCoil.Name,
6588 : Constant::eResource::EnergyTransfer,
6589 : OutputProcessor::Group::HVAC,
6590 : OutputProcessor::EndUseCat::HeatingCoils);
6591 22 : SetupOutputVariable(state,
6592 : "Heating Coil Runtime Fraction",
6593 : Constant::Units::None,
6594 11 : thisDXCoil.HeatingCoilRuntimeFraction,
6595 : OutputProcessor::TimeStepType::System,
6596 : OutputProcessor::StoreType::Average,
6597 11 : thisDXCoil.Name);
6598 : // Followings for VRF_FluidTCtrl Only
6599 22 : SetupOutputVariable(state,
6600 : "Heating Coil VRF Condensing Temperature",
6601 : Constant::Units::C,
6602 11 : thisDXCoil.CondensingTemp,
6603 : OutputProcessor::TimeStepType::System,
6604 : OutputProcessor::StoreType::Average,
6605 11 : thisDXCoil.Name);
6606 22 : SetupOutputVariable(state,
6607 : "Heating Coil VRF Subcooling Degrees",
6608 : Constant::Units::C,
6609 11 : thisDXCoil.ActualSC,
6610 : OutputProcessor::TimeStepType::System,
6611 : OutputProcessor::StoreType::Average,
6612 11 : thisDXCoil.Name);
6613 : }
6614 : }
6615 :
6616 134 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
6617 : // setup EMS sizing actuators for single speed DX
6618 0 : for (DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDoe2DXCoils; ++DXCoilNum) {
6619 :
6620 0 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
6621 :
6622 0 : SetupEMSActuator(state,
6623 : "Coil:Cooling:DX:SingleSpeed",
6624 : thisDXCoil.Name,
6625 : "Autosized Rated Air Flow Rate",
6626 : "[m3/s]",
6627 : thisDXCoil.RatedAirVolFlowRateEMSOverrideON(1),
6628 0 : thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(1));
6629 :
6630 0 : SetupEMSActuator(state,
6631 : "Coil:Cooling:DX:SingleSpeed",
6632 : thisDXCoil.Name,
6633 : "Autosized Rated Sensible Heat Ratio",
6634 : "[W/W]",
6635 : thisDXCoil.RatedSHREMSOverrideOn(1),
6636 0 : thisDXCoil.RatedSHREMSOverrideValue(1));
6637 :
6638 0 : SetupEMSActuator(state,
6639 : "Coil:Cooling:DX:SingleSpeed",
6640 : thisDXCoil.Name,
6641 : "Autosized Rated Total Cooling Capacity",
6642 : "[W]",
6643 : thisDXCoil.RatedTotCapEMSOverrideOn(1),
6644 0 : thisDXCoil.RatedTotCapEMSOverrideValue(1));
6645 : }
6646 : }
6647 134 : Alphas.deallocate();
6648 134 : cAlphaFields.deallocate();
6649 134 : cNumericFields.deallocate();
6650 134 : Numbers.deallocate();
6651 134 : lAlphaBlanks.deallocate();
6652 134 : lNumericBlanks.deallocate();
6653 :
6654 134 : Alphas2.deallocate();
6655 134 : cAlphaFields2.deallocate();
6656 134 : cNumericFields2.deallocate();
6657 134 : Numbers2.deallocate();
6658 134 : lAlphaBlanks2.deallocate();
6659 134 : lNumericBlanks2.deallocate();
6660 : bool anyEMSRan;
6661 134 : ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyEMSRan, ObjexxFCL::Optional_int_const());
6662 149 : }
6663 :
6664 539063 : void InitDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current DX coil unit being simulated
6665 : {
6666 :
6667 : // SUBROUTINE INFORMATION:
6668 : // AUTHOR Fred Buhl
6669 : // DATE WRITTEN May 2000
6670 : // Feb 2005, M. J. Witte, GARD Analytics, Inc. Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
6671 : // Jul 2005, R. Raustad, FSEC. Add new coil type COIL:DX:HEATPUMPWATERHEATER
6672 : // Jun 2007, L. Gu, FSEC. Add new coil type COIL:DX:MULTISPEED:COOLING and HEATING
6673 : // Aug 2015, R. Zhang, LBNL. Add new coil types for VRF_FluidTCtrl
6674 :
6675 : // PURPOSE OF THIS SUBROUTINE:
6676 : // This subroutine is for initializations of DX Coil Components.
6677 :
6678 : // METHODOLOGY EMPLOYED:
6679 : // Uses the status flags to trigger initializations.
6680 :
6681 : // SUBROUTINE PARAMETER DEFINITIONS:
6682 539063 : constexpr Real64 SmallDifferenceTest(0.00000001);
6683 : static constexpr std::string_view RoutineName("InitDXCoil");
6684 :
6685 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6686 : Real64 RatedHeatPumpIndoorAirTemp; // Indoor dry-bulb temperature to heat pump evaporator at rated conditions [C]
6687 : Real64 RatedHeatPumpIndoorHumRat; // Inlet humidity ratio to heat pump evaporator at rated conditions [kgWater/kgDryAir]
6688 : Real64 RatedVolFlowPerRatedTotCap; // Rated Air Volume Flow Rate divided by Rated Total Capacity [m3/s-W)
6689 : Real64 HPInletAirHumRat; // Rated inlet air humidity ratio for heat pump water heater [kgWater/kgDryAir]
6690 539063 : bool ErrorsFound(false); // TRUE when errors found
6691 : int CapacityStageNum; // Loop index for 1,Number of capacity stages
6692 : int DehumidModeNum; // Loop index for 1,Number of enhanced dehumidification modes
6693 : int Mode; // Performance mode for MultiMode DX coil; Always 1 for other coil types
6694 : int DXCoilNumTemp; // Counter for crankcase heater report variable DO loop
6695 : int AirInletNode; // Air inlet node number
6696 : int SpeedNum; // Speed number for multispeed coils
6697 :
6698 539063 : if (state.dataDXCoils->MyOneTimeFlag) {
6699 : // initialize the environment and sizing flags
6700 68 : state.dataDXCoils->MyEnvrnFlag.dimension(state.dataDXCoils->NumDXCoils, true);
6701 68 : state.dataDXCoils->MySizeFlag.dimension(state.dataDXCoils->NumDXCoils, true);
6702 68 : state.dataDXCoils->MyOneTimeFlag = false;
6703 : }
6704 :
6705 539063 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
6706 :
6707 : // if "ISHundredPercentDOASDXCoil" =.TRUE., then set coil as 100% DOAS dx coil
6708 539063 : state.dataHVACGlobal->DXCT = (thisDXCoil.ISHundredPercentDOASDXCoil) ? HVAC::DXCoilType::DOAS : HVAC::DXCoilType::Regular;
6709 :
6710 1617030 : if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
6711 539224 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
6712 161 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum)) {
6713 :
6714 4 : SizeDXCoil(state, DXCoilNum);
6715 :
6716 4 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(1) / thisDXCoil.RatedTotCap2;
6717 8 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
6718 4 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
6719 0 : ShowWarningError(state,
6720 0 : format("{} \"{}\": Rated air volume flow rate per watt of rated total water heating capacity is out of range",
6721 0 : thisDXCoil.DXCoilType,
6722 0 : thisDXCoil.Name));
6723 0 : ShowContinueError(state,
6724 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
6725 : "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
6726 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
6727 : RatedVolFlowPerRatedTotCap,
6728 0 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
6729 : }
6730 : HPInletAirHumRat =
6731 4 : PsyWFnTdbTwbPb(state, thisDXCoil.RatedInletDBTemp, thisDXCoil.RatedInletWBTemp, DataEnvironment::StdPressureSeaLevel, RoutineName);
6732 4 : state.dataHVACGlobal->HPWHInletDBTemp = thisDXCoil.RatedInletDBTemp;
6733 4 : state.dataHVACGlobal->HPWHInletWBTemp = thisDXCoil.RatedInletWBTemp;
6734 8 : thisDXCoil.RatedAirMassFlowRate(1) =
6735 4 : thisDXCoil.RatedAirVolFlowRate(1) *
6736 4 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, thisDXCoil.RatedInletDBTemp, HPInletAirHumRat, RoutineName);
6737 : // get rated coil bypass factor excluding fan heat
6738 :
6739 : // call CalcHPWHDXCoil to determine DXCoil%RatedTotCap(1) for rated CBF calculation below
6740 4 : CalcHPWHDXCoil(state, DXCoilNum, 1.0);
6741 4 : if (state.dataDXCoils->MySizeFlag(DXCoilNum)) {
6742 4 : SizeDXCoil(state, DXCoilNum);
6743 4 : state.dataDXCoils->MySizeFlag(DXCoilNum) = false;
6744 : }
6745 :
6746 4 : thisDXCoil.RatedCBF(1) = CalcCBF(state,
6747 4 : thisDXCoil.DXCoilType,
6748 4 : thisDXCoil.Name,
6749 : thisDXCoil.RatedInletDBTemp,
6750 : HPInletAirHumRat,
6751 4 : thisDXCoil.RatedTotCap(1),
6752 4 : thisDXCoil.RatedAirVolFlowRate(1),
6753 4 : thisDXCoil.RatedSHR(1),
6754 : true);
6755 4 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum) = false;
6756 : }
6757 :
6758 539513 : if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) &&
6759 450 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum)) {
6760 15 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
6761 4 : if (thisDXCoil.MSHPHeatRecActive) {
6762 5 : for (SpeedNum = 1; SpeedNum <= thisDXCoil.NumOfSpeeds; ++SpeedNum) {
6763 4 : if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
6764 0 : ShowWarningError(
6765 : state,
6766 0 : format("GetDXCoils:{}. The value of Waste Heat Function of Temperature Curve is assumed to be 1. Simulation continues. ",
6767 0 : thisDXCoil.Name));
6768 0 : break;
6769 : }
6770 : }
6771 : }
6772 : }
6773 15 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum) = false;
6774 : }
6775 :
6776 : // Find the companion upstream coil (DX cooling coil) that is used with DX heating coils (HP AC units only)
6777 539063 : if (thisDXCoil.FindCompanionUpStreamCoil) {
6778 135 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6779 40 : thisDXCoil.CompanionUpstreamDXCoil = GetHPCoolingCoilIndex(state, thisDXCoil.DXCoilType, thisDXCoil.Name, DXCoilNum);
6780 40 : if (thisDXCoil.CompanionUpstreamDXCoil > 0) {
6781 9 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).ReportCoolingCoilCrankcasePower = false;
6782 9 : thisDXCoil.FindCompanionUpStreamCoil = false;
6783 : // Copy condenser node number from DX cooling coil when used with a companion DX heating coil
6784 45 : for (Mode = 1; Mode <= MaxModes; ++Mode) {
6785 36 : thisDXCoil.CondenserInletNodeNum(Mode) =
6786 36 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CondenserInletNodeNum(Mode);
6787 : }
6788 : }
6789 : } else {
6790 95 : thisDXCoil.FindCompanionUpStreamCoil = false;
6791 : }
6792 : } // IF(DXCoil(DXCoilNum)%FindCompanionUpStreamCoil)THEN
6793 :
6794 : // CR7308 - Wait for zone and air loop equipment to be simulated, then print out report variables
6795 539063 : if (state.dataDXCoils->CrankcaseHeaterReportVarFlag) {
6796 1258 : if (state.dataAirLoop->AirLoopInputsFilled) {
6797 : // Set report variables for DX cooling coils that will have a crankcase heater (all DX coils not used in a HP AC unit)
6798 90 : for (DXCoilNumTemp = 1; DXCoilNumTemp <= state.dataDXCoils->NumDXCoils; ++DXCoilNumTemp) {
6799 60 : if ((state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) ||
6800 103 : (state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) ||
6801 43 : (state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling)) {
6802 18 : if (state.dataDXCoils->DXCoil(DXCoilNumTemp).ReportCoolingCoilCrankcasePower) {
6803 32 : SetupOutputVariable(state,
6804 : "Cooling Coil Crankcase Heater Electricity Rate",
6805 : Constant::Units::W,
6806 16 : state.dataDXCoils->DXCoil(DXCoilNumTemp).CrankcaseHeaterPower,
6807 : OutputProcessor::TimeStepType::System,
6808 : OutputProcessor::StoreType::Average,
6809 16 : state.dataDXCoils->DXCoil(DXCoilNumTemp).Name);
6810 32 : SetupOutputVariable(state,
6811 : "Cooling Coil Crankcase Heater Electricity Energy",
6812 : Constant::Units::J,
6813 16 : state.dataDXCoils->DXCoil(DXCoilNumTemp).CrankcaseHeaterConsumption,
6814 : OutputProcessor::TimeStepType::System,
6815 : OutputProcessor::StoreType::Sum,
6816 16 : state.dataDXCoils->DXCoil(DXCoilNumTemp).Name,
6817 : Constant::eResource::Electricity,
6818 : OutputProcessor::Group::HVAC,
6819 : OutputProcessor::EndUseCat::Cooling);
6820 16 : state.dataDXCoils->DXCoil(DXCoilNumTemp).ReportCoolingCoilCrankcasePower = false;
6821 : }
6822 : }
6823 : }
6824 30 : state.dataDXCoils->CrankcaseHeaterReportVarFlag = false;
6825 : } //(AirLoopInputsFilled)THEN
6826 : } //(CrankcaseHeaterReportVarFlag)THEN
6827 :
6828 539063 : if (!state.dataGlobal->SysSizingCalc && state.dataDXCoils->MySizeFlag(DXCoilNum)) {
6829 : // for each coil, do the sizing once.
6830 69 : SizeDXCoil(state, DXCoilNum);
6831 69 : state.dataDXCoils->MySizeFlag(DXCoilNum) = false;
6832 :
6833 69 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
6834 35 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
6835 :
6836 47 : Mode = 1;
6837 : // Check for zero capacity or zero max flow rate
6838 47 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
6839 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
6840 0 : ErrorsFound = true;
6841 : }
6842 47 : if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
6843 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
6844 0 : ErrorsFound = true;
6845 : }
6846 47 : if (ErrorsFound) {
6847 0 : ShowFatalError(state, "Preceding condition causes termination.");
6848 : }
6849 :
6850 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
6851 47 : if (thisDXCoil.DXCoilType_Num !=
6852 : HVAC::CoilVRF_FluidTCtrl_Cooling) { // the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil
6853 41 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
6854 82 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
6855 41 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
6856 2 : ShowWarningError(state,
6857 2 : format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range.",
6858 1 : thisDXCoil.DXCoilType,
6859 1 : thisDXCoil.Name));
6860 2 : ShowContinueError(state,
6861 2 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
6862 : "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
6863 1 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
6864 : RatedVolFlowPerRatedTotCap,
6865 1 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
6866 : }
6867 : }
6868 :
6869 94 : thisDXCoil.RatedAirMassFlowRate(Mode) =
6870 47 : thisDXCoil.RatedAirVolFlowRate(Mode) *
6871 47 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
6872 : // get high speed rated coil bypass factor
6873 47 : thisDXCoil.RatedCBF(Mode) = CalcCBF(state,
6874 47 : thisDXCoil.DXCoilType,
6875 47 : thisDXCoil.Name,
6876 : RatedInletAirTemp,
6877 : RatedInletAirHumRat,
6878 47 : thisDXCoil.RatedTotCap(Mode),
6879 47 : thisDXCoil.RatedAirVolFlowRate(Mode),
6880 47 : thisDXCoil.RatedSHR(Mode));
6881 :
6882 : // call coil model with everything set at rating point
6883 47 : thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(Mode);
6884 47 : thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(Mode);
6885 47 : thisDXCoil.InletAirTemp = RatedInletAirTemp;
6886 : Real64 tempInletAirHumRat =
6887 47 : Psychrometrics::PsyWFnTdbTwbPb(state, RatedInletAirTemp, RatedInletWetBulbTemp, DataEnvironment::StdPressureSeaLevel, RoutineName);
6888 : // DXCoil( DXCoilNum ).InletAirHumRat = RatedInletAirHumRat; // this seems inconsistent with dry bulb and wetbulb, filed NREL issue
6889 : // #5934 Real64 tempInletAirWetBulb = Psychrometrics::PsyTwbFnTdbWPb( RatedInletAirTemp, RatedInletAirHumRat,
6890 : // DataEnvironment::StdPressureSeaLevel );
6891 47 : thisDXCoil.InletAirHumRat = tempInletAirHumRat;
6892 47 : thisDXCoil.InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTemp, tempInletAirHumRat);
6893 :
6894 : // store environment data fill back in after rating point calc is over
6895 47 : Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
6896 47 : Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
6897 47 : Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
6898 47 : Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
6899 47 : Real64 ratedOutdoorAirWetBulb = 23.9; // from I/O ref. more precise value?
6900 47 : state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTemp;
6901 47 : state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
6902 47 : state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
6903 94 : state.dataEnvrn->OutHumRat =
6904 47 : Psychrometrics::PsyWFnTdbTwbPb(state, RatedOutdoorAirTemp, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
6905 47 : if (thisDXCoil.CondenserInletNodeNum(1) > 0) { // set condenser inlet node values
6906 14 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = RatedOutdoorAirTemp;
6907 14 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat = state.dataEnvrn->OutHumRat;
6908 14 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb = ratedOutdoorAirWetBulb;
6909 : }
6910 :
6911 : // calculate coil model at rating point
6912 47 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6913 31 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, _, 1.0);
6914 16 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
6915 3 : CalcMultiSpeedDXCoil(state, DXCoilNum, 1.0, 1.0);
6916 13 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
6917 7 : CalcVRFCoolingCoil(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, 1.0, _, _, _);
6918 6 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
6919 6 : CalcVRFCoolingCoil_FluidTCtrl(
6920 : state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, 1.0, _, _, Constant::MaxCap);
6921 : }
6922 :
6923 : // coil outlets
6924 47 : Real64 RatedOutletWetBulb(0.0);
6925 47 : RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
6926 : state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
6927 :
6928 47 : state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
6929 : state,
6930 47 : thisDXCoil.Name,
6931 47 : thisDXCoil.DXCoilType,
6932 : thisDXCoil.TotalCoolingEnergyRate, // this is the report variable
6933 : thisDXCoil.SensCoolingEnergyRate, // this is the report variable
6934 : thisDXCoil.InletAirMassFlowRate,
6935 : thisDXCoil.InletAirTemp,
6936 : thisDXCoil.InletAirHumRat,
6937 : RatedInletWetBulbTemp,
6938 : thisDXCoil.OutletAirTemp,
6939 : thisDXCoil.OutletAirHumRat,
6940 : RatedOutletWetBulb,
6941 : RatedOutdoorAirTemp,
6942 : ratedOutdoorAirWetBulb,
6943 47 : thisDXCoil.RatedCBF(Mode),
6944 : -999.0); // coil effectiveness not define for DX
6945 :
6946 : // now replace the outdoor air conditions set above for one time rating point calc
6947 47 : state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
6948 47 : state.dataEnvrn->OutHumRat = holdOutHumRat;
6949 47 : state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
6950 47 : state.dataEnvrn->OutBaroPress = holdOutBaroPress;
6951 : }
6952 :
6953 69 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
6954 0 : for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
6955 0 : for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
6956 0 : Mode = DehumidModeNum * 2 + CapacityStageNum;
6957 : // Check for zero capacity or zero max flow rate
6958 0 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
6959 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
6960 0 : ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
6961 0 : ErrorsFound = true;
6962 : }
6963 0 : if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
6964 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
6965 0 : ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
6966 0 : ErrorsFound = true;
6967 : }
6968 0 : if (ErrorsFound) {
6969 0 : ShowFatalError(state, "Preceding condition causes termination.");
6970 : }
6971 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
6972 0 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
6973 0 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
6974 0 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
6975 0 : ShowWarningError(
6976 : state,
6977 0 : format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range.",
6978 0 : thisDXCoil.DXCoilType,
6979 0 : thisDXCoil.Name));
6980 0 : ShowContinueError(state,
6981 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
6982 : "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
6983 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
6984 : RatedVolFlowPerRatedTotCap,
6985 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
6986 0 : ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
6987 : }
6988 0 : thisDXCoil.RatedAirMassFlowRate(Mode) =
6989 0 : thisDXCoil.RatedAirVolFlowRate(Mode) *
6990 0 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
6991 : // get rated coil bypass factor
6992 0 : thisDXCoil.RatedCBF(Mode) = CalcCBF(state,
6993 0 : thisDXCoil.CoilPerformanceType(Mode),
6994 0 : thisDXCoil.CoilPerformanceName(Mode),
6995 : RatedInletAirTemp,
6996 : RatedInletAirHumRat,
6997 0 : thisDXCoil.RatedTotCap(Mode),
6998 0 : thisDXCoil.RatedAirVolFlowRate(Mode),
6999 0 : thisDXCoil.RatedSHR(Mode));
7000 : } // End capacity stages loop
7001 : } // End dehumidification modes loop
7002 : }
7003 :
7004 69 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating ||
7005 58 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7006 :
7007 17 : Mode = 1;
7008 17 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
7009 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
7010 0 : ErrorsFound = true;
7011 : }
7012 17 : if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
7013 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
7014 0 : ErrorsFound = true;
7015 : }
7016 17 : if (ErrorsFound) {
7017 0 : ShowFatalError(state, "Preceding condition causes termination.");
7018 : }
7019 17 : RatedHeatPumpIndoorAirTemp = 21.11; // 21.11C or 70F
7020 17 : RatedHeatPumpIndoorHumRat = 0.00881; // Humidity ratio corresponding to 70F dry bulb/60F wet bulb
7021 34 : thisDXCoil.RatedAirMassFlowRate(Mode) =
7022 17 : thisDXCoil.RatedAirVolFlowRate(Mode) *
7023 17 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedHeatPumpIndoorAirTemp, RatedHeatPumpIndoorHumRat, RoutineName);
7024 :
7025 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7026 17 : if (thisDXCoil.DXCoilType_Num !=
7027 : HVAC::CoilVRF_FluidTCtrl_Heating) { // the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil
7028 11 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
7029 22 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7030 11 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7031 2 : ShowWarningError(state,
7032 2 : format("Sizing: {} {}: Rated air volume flow rate per watt of rated total heating capacity is out of range.",
7033 1 : thisDXCoil.DXCoilType,
7034 1 : thisDXCoil.Name));
7035 2 : ShowContinueError(state,
7036 2 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
7037 : "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
7038 1 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7039 : RatedVolFlowPerRatedTotCap,
7040 1 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7041 : }
7042 : }
7043 :
7044 : // call coil model with everything set at rating point
7045 17 : thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(Mode);
7046 17 : thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(Mode);
7047 :
7048 17 : thisDXCoil.InletAirTemp = RatedInletAirTempHeat;
7049 17 : Real64 tempInletAirHumRat = Psychrometrics::PsyWFnTdbTwbPb(
7050 : state, RatedInletAirTempHeat, RatedInletWetBulbTempHeat, DataEnvironment::StdPressureSeaLevel, RoutineName);
7051 17 : thisDXCoil.InletAirHumRat = tempInletAirHumRat;
7052 17 : thisDXCoil.InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTempHeat, tempInletAirHumRat);
7053 :
7054 : // store environment data fill back in after rating point calc is over
7055 17 : Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
7056 17 : Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
7057 17 : Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
7058 17 : Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
7059 :
7060 17 : state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTempHeat;
7061 :
7062 17 : Real64 ratedOutdoorAirWetBulb = 6.11; // from I/O ref. more precise value?
7063 17 : state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
7064 17 : state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
7065 17 : state.dataEnvrn->OutHumRat = Psychrometrics::PsyWFnTdbTwbPb(
7066 : state, RatedOutdoorAirTempHeat, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
7067 :
7068 17 : if (thisDXCoil.CondenserInletNodeNum(1) > 0) { // set condenser inlet node values
7069 6 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = RatedOutdoorAirTempHeat;
7070 6 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat = state.dataEnvrn->OutHumRat;
7071 6 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb = ratedOutdoorAirWetBulb;
7072 : }
7073 :
7074 : // calculate coil model at rating point
7075 17 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
7076 4 : CalcDXHeatingCoil(state, DXCoilNum, 1.0, HVAC::FanOp::Cycling, 1.0);
7077 13 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
7078 7 : CalcDXHeatingCoil(state, DXCoilNum, 1.0, HVAC::FanOp::Cycling, _, _);
7079 6 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7080 6 : CalcVRFHeatingCoil_FluidTCtrl(state, HVAC::CompressorOp::On, DXCoilNum, 1.0, HVAC::FanOp::Cycling, _, _);
7081 : }
7082 : // coil outlets
7083 17 : Real64 RatedOutletWetBulb(0.0);
7084 17 : RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
7085 : state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
7086 :
7087 17 : state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
7088 : state,
7089 17 : thisDXCoil.Name,
7090 17 : thisDXCoil.DXCoilType,
7091 : thisDXCoil.TotalHeatingEnergyRate, // this is the report variable
7092 : thisDXCoil.TotalHeatingEnergyRate, // this is the report variable
7093 : thisDXCoil.InletAirMassFlowRate,
7094 : thisDXCoil.InletAirTemp,
7095 : thisDXCoil.InletAirHumRat,
7096 : RatedInletWetBulbTempHeat,
7097 : thisDXCoil.OutletAirTemp,
7098 : thisDXCoil.OutletAirHumRat,
7099 : RatedOutletWetBulb,
7100 : RatedOutdoorAirTempHeat,
7101 : ratedOutdoorAirWetBulb,
7102 17 : thisDXCoil.RatedCBF(Mode),
7103 : -999.0); // coil effectiveness not define for DX
7104 :
7105 : // now replace the outdoor air conditions set above for one time rating point calc
7106 17 : state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
7107 17 : state.dataEnvrn->OutHumRat = holdOutHumRat;
7108 17 : state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
7109 17 : state.dataEnvrn->OutBaroPress = holdOutBaroPress;
7110 : }
7111 :
7112 69 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7113 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7114 3 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate2 / thisDXCoil.RatedTotCap2;
7115 6 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7116 3 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7117 0 : ShowWarningError(state,
7118 0 : format("Coil:Cooling:DX:TwoSpeed \"{}\": At low speed rated air volume flow rate per watt of rated total cooling "
7119 : "capacity is out of range.",
7120 0 : thisDXCoil.Name));
7121 0 : ShowContinueError(state,
7122 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
7123 : "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
7124 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7125 : RatedVolFlowPerRatedTotCap,
7126 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7127 : }
7128 :
7129 3 : thisDXCoil.RatedAirMassFlowRate2 =
7130 6 : thisDXCoil.RatedAirVolFlowRate2 *
7131 3 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
7132 : // get low speed rated coil bypass factor
7133 6 : thisDXCoil.RatedCBF2 = CalcCBF(state,
7134 3 : thisDXCoil.DXCoilType,
7135 3 : thisDXCoil.Name,
7136 : RatedInletAirTemp,
7137 : RatedInletAirHumRat,
7138 : thisDXCoil.RatedTotCap2,
7139 : thisDXCoil.RatedAirVolFlowRate2,
7140 : thisDXCoil.RatedSHR2);
7141 :
7142 : // call for standard ratings for two-speed DX coil
7143 3 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air) {
7144 2 : CalcTwoSpeedDXCoilStandardRating(state, DXCoilNum);
7145 : }
7146 : }
7147 :
7148 : // Multispeed Cooling
7149 69 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7150 16 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
7151 : // Check for zero capacity or zero max flow rate
7152 11 : if (thisDXCoil.MSRatedTotCap(Mode) <= 0.0) {
7153 0 : ShowSevereError(state,
7154 0 : format("Sizing: {} {} has zero rated total capacity at speed {}", thisDXCoil.DXCoilType, thisDXCoil.Name, Mode));
7155 0 : ErrorsFound = true;
7156 : }
7157 11 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) <= 0.0) {
7158 0 : ShowSevereError(state,
7159 0 : format("Sizing: {} {} has zero rated air flow rate at speed {}", thisDXCoil.DXCoilType, thisDXCoil.Name, Mode));
7160 0 : ErrorsFound = true;
7161 : }
7162 11 : if (ErrorsFound) {
7163 0 : ShowFatalError(state, "Preceding condition causes termination.");
7164 : }
7165 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7166 11 : RatedVolFlowPerRatedTotCap = thisDXCoil.MSRatedAirVolFlowRate(Mode) / thisDXCoil.MSRatedTotCap(Mode);
7167 22 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7168 11 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7169 0 : ShowWarningError(
7170 : state,
7171 0 : format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range at speed {}",
7172 0 : thisDXCoil.DXCoilType,
7173 0 : thisDXCoil.Name,
7174 : Mode));
7175 0 : ShowContinueError(state,
7176 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
7177 : "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
7178 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7179 : RatedVolFlowPerRatedTotCap,
7180 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7181 : }
7182 22 : thisDXCoil.MSRatedAirMassFlowRate(Mode) =
7183 11 : thisDXCoil.MSRatedAirVolFlowRate(Mode) *
7184 11 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
7185 : // get high speed rated coil bypass factor
7186 11 : thisDXCoil.MSRatedCBF(Mode) = CalcCBF(state,
7187 11 : thisDXCoil.DXCoilType,
7188 11 : thisDXCoil.Name,
7189 : RatedInletAirTemp,
7190 : RatedInletAirHumRat,
7191 11 : thisDXCoil.MSRatedTotCap(Mode),
7192 11 : thisDXCoil.MSRatedAirVolFlowRate(Mode),
7193 11 : thisDXCoil.MSRatedSHR(Mode));
7194 : }
7195 : }
7196 :
7197 : // Multispeed Heating
7198 69 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7199 0 : RatedHeatPumpIndoorAirTemp = 21.11; // 21.11C or 70F
7200 0 : RatedHeatPumpIndoorHumRat = 0.00881; // Humidity ratio corresponding to 70F dry bulb/60F wet bulb
7201 0 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
7202 :
7203 0 : thisDXCoil.MSRatedAirMassFlowRate(Mode) =
7204 0 : thisDXCoil.MSRatedAirVolFlowRate(Mode) *
7205 0 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedHeatPumpIndoorAirTemp, RatedHeatPumpIndoorHumRat, RoutineName);
7206 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7207 0 : RatedVolFlowPerRatedTotCap = thisDXCoil.MSRatedAirVolFlowRate(Mode) / thisDXCoil.MSRatedTotCap(Mode);
7208 0 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7209 0 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7210 0 : ShowWarningError(state,
7211 0 : format("Coil:Heating:DX:MultiSpeed {}: Rated air volume flow rate per watt of rated total heating capacity "
7212 : "is out of range at speed {}",
7213 0 : thisDXCoil.Name,
7214 : Mode));
7215 0 : ShowContinueError(state,
7216 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
7217 : "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
7218 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7219 : RatedVolFlowPerRatedTotCap,
7220 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7221 : }
7222 : }
7223 : }
7224 :
7225 : // store fan info for coil
7226 69 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
7227 69 : state, thisDXCoil.Name, thisDXCoil.DXCoilType, thisDXCoil.SupplyFanName, thisDXCoil.supplyFanType, thisDXCoil.SupplyFanIndex);
7228 : }
7229 :
7230 539063 : AirInletNode = thisDXCoil.AirInNode;
7231 :
7232 : // Each iteration, load the coil data structure with the inlet conditions
7233 :
7234 539063 : thisDXCoil.InletAirMassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
7235 539063 : thisDXCoil.InletAirMassFlowRateMax =
7236 539063 : max(state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax, state.dataLoopNodes->Node(AirInletNode).MassFlowRate);
7237 539063 : thisDXCoil.InletAirTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
7238 539063 : thisDXCoil.InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
7239 539063 : thisDXCoil.InletAirEnthalpy = state.dataLoopNodes->Node(AirInletNode).Enthalpy;
7240 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
7241 : // DXCoil(DXCoilNum)%InletAirPressure = Node(AirInletNode)%Press
7242 :
7243 539063 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7244 128165 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
7245 0 : thisDXCoil.EvapInletWetBulb = PsyTwbFnTdbWPb(state,
7246 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr).ZT,
7247 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr).airHumRat,
7248 0 : state.dataEnvrn->OutBaroPress,
7249 : RoutineName);
7250 : }
7251 : }
7252 :
7253 539063 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
7254 161 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
7255 161 : thisDXCoil.ElecWaterHeatingPower = 0.0;
7256 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
7257 : // DXCoil(DXCoilNum)%InletAirPressure = StdBaroPress
7258 :
7259 : // HPWH's that use an inlet air temperature schedule also need to have a valid barometric pressure
7260 : // The DX Coil used in HPWH's does not know if it is using a scheduled inlet temperature so check the node pressure
7261 161 : if (thisDXCoil.CondenserInletNodeNum(1) > 0) {
7262 161 : if (state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press == 0.0) {
7263 2 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press = state.dataEnvrn->StdBaroPress;
7264 : }
7265 : }
7266 : }
7267 539063 : thisDXCoil.BasinHeaterPower = 0.0;
7268 :
7269 539063 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
7270 0 : thisDXCoil.CompressorPartLoadRatio = 0.0;
7271 0 : thisDXCoil.SecCoilSensibleHeatGainRate = 0.0;
7272 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
7273 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
7274 0 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
7275 : }
7276 539063 : }
7277 :
7278 96 : void SizeDXCoil(EnergyPlusData &state, int const DXCoilNum)
7279 : {
7280 :
7281 : // SUBROUTINE INFORMATION:
7282 : // AUTHOR Fred Buhl
7283 : // DATE WRITTEN January 2002
7284 : // Feb 2005, M. J. Witte, GARD Analytics, Inc. Add new coil type COIL:DX:MultiMode:CoolingEmpirical.
7285 : // Jul 2005, R. Raustad, FSEC. Add new coil type COIL:DX:HEATPUMPWATERHEATER
7286 : // Jun 2007, L. Gu, FSEC. Add new coil type COIL:DX:MULTISPEED:COOLING and HEATING
7287 : // Jan 2011, B. Griffith, NREL. add EMS overrides for autosized fields
7288 : // Aug 2013, D. Kang. add component sizing table entries
7289 : // May 2014, R. Raustad, FSEC. moved sizing calculations to common routine
7290 : // Aug 2015, R. Zhang, LBNL. Add new coil types for VRF_FluidTCtrl
7291 : // RE-ENGINEERED na
7292 :
7293 : // PURPOSE OF THIS SUBROUTINE:
7294 : // This subroutine is for sizing DX Coil components for which nominal capacity and air flow rate
7295 : // have not been specified in the input.
7296 :
7297 : // METHODOLOGY EMPLOYED:
7298 : // Obtains cooling capacities and air flow rates from the zone or system sizing arrays.
7299 :
7300 : // Using/Aliasing
7301 : using namespace DataSizing;
7302 : using Curve::CurveValue;
7303 :
7304 : using namespace OutputReportPredefined;
7305 : using StandardRatings::CalcDXCoilStandardRating;
7306 :
7307 : // SUBROUTINE PARAMETER DEFINITIONS:
7308 : static constexpr std::string_view RoutineName("SizeDXCoil");
7309 :
7310 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7311 : Real64 CoilInTemp; // DX coil inlet temperature
7312 : int CapacityStageNum; // Loop index for 1,Number of capacity stages
7313 : int DehumidModeNum; // Loop index for 1,Number of enhanced dehumidification modes
7314 : int Mode; // Operating mode for MultiMode DX coil; Always 1 for other coil types
7315 : int NumOfSpeedCompanion; // Number of speed for a companion cooling coil (Multispeed HO heating coil only
7316 96 : std::string equipName;
7317 : Real64 DefrostCapacityDes; // Design defrost heater capacity for reporting
7318 : Real64 DefrostCapacityUser; // Hard-sized defrost heater capacity for reporting
7319 : Real64 MSRatedAirVolFlowRateDes; // Design multispeed rated air volume flow rate for reporting
7320 : Real64 MSRatedTotCapDesAtMaxSpeed; // Design multispeed rated total capacity for reporting (at maximum speed)
7321 : Real64 MSRatedSHRDes; // Design multispeed rated SHR for reporting
7322 : Real64 MSEvapCondAirFlowDes; // Design evaporative condenser air flow for reporting
7323 : Real64 MSEvapCondAirFlowUser; // Hard-sized evaporative condenser air flow for reporting
7324 : Real64 MSEvapCondPumpElecNomPowerDes; // Design evaporative condenser pump rated power consumption for reporting
7325 : Real64 MSEvapCondPumpElecNomPowerUser; // Hard-sized evaporative condenser pump rated power consumption for reporting
7326 : bool HardSizeNoDesRun; // Indicator to a hard-sized field with no design sizing data
7327 : bool IsAutoSize; // Indicator to autosize for reporting
7328 : bool SizingDesRunThisAirSys; // true if a particular air system had a Sizing:System object and system sizing done
7329 : bool SizingDesRunThisZone; // true if a particular zone had a Sizing:Zone object and zone sizing was done
7330 96 : std::string CompName; // component name
7331 96 : std::string CompType; // component type
7332 96 : std::string SizingString; // input field sizing description (e.g., Nominal Capacity)
7333 96 : bool bPRINT = true; // TRUE if sizing is reported to output (eio)
7334 : Real64 TempSize; // autosized value of coil input field
7335 96 : int FieldNum = 2; // IDD numeric field number where input field description is found
7336 : bool PrintFlag; // TRUE when sizing information is reported in the eio file
7337 : bool SizeSecDXCoil; // if true do sizing calculation for secondary coil
7338 : Real64 SecCoilAirFlowDes; // Design secondary DX coil air flow for reporting
7339 : Real64 SecCoilAirFlowUser; // Hard-sized secondary DX coil air flow for reporting
7340 :
7341 : // Initiate all reporting variables
7342 96 : if (state.dataSize->SysSizingRunDone || state.dataSize->ZoneSizingRunDone) {
7343 72 : HardSizeNoDesRun = false;
7344 : } else {
7345 24 : HardSizeNoDesRun = true;
7346 : }
7347 :
7348 96 : if (state.dataSize->CurSysNum > 0) {
7349 38 : CheckThisAirSystemForSizing(state, state.dataSize->CurSysNum, SizingDesRunThisAirSys);
7350 : } else {
7351 58 : SizingDesRunThisAirSys = false;
7352 : }
7353 96 : if (state.dataSize->CurZoneEqNum > 0) {
7354 43 : CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
7355 : } else {
7356 53 : SizingDesRunThisZone = false;
7357 : }
7358 :
7359 96 : IsAutoSize = false;
7360 96 : SizeSecDXCoil = false;
7361 96 : MSRatedTotCapDesAtMaxSpeed = 0.0;
7362 96 : DefrostCapacityDes = 0.0;
7363 96 : DefrostCapacityUser = 0.0;
7364 96 : MSRatedAirVolFlowRateDes = 0.0;
7365 96 : MSRatedSHRDes = 0.0;
7366 96 : MSEvapCondAirFlowDes = 0.0;
7367 96 : MSEvapCondAirFlowUser = 0.0;
7368 96 : MSEvapCondPumpElecNomPowerDes = 0.0;
7369 96 : MSEvapCondPumpElecNomPowerUser = 0.0;
7370 96 : SecCoilAirFlowDes = 0.0;
7371 96 : SecCoilAirFlowUser = 0.0;
7372 :
7373 : // Sizer classes
7374 96 : CoolingSHRSizer sizerCoolingSHR;
7375 96 : bool ErrorsFound = false;
7376 :
7377 96 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
7378 :
7379 : // NOTE: we are sizing COIL:DX:HeatingEmpirical on the COOLING load. Thus the cooling and
7380 : // and heating capacities of a DX heat pump system will be identical. In real life the AHRI
7381 : // heating and cooling capacities are close but not identical.
7382 192 : for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
7383 192 : for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
7384 96 : Mode = DehumidModeNum * 2 + CapacityStageNum;
7385 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
7386 90 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
7387 8 : if (thisDXCoil.RatedAirVolFlowRate(1) == Constant::AutoCalculate) {
7388 : // report autocalculated sizing
7389 3 : PrintFlag = true;
7390 3 : CompName = thisDXCoil.Name;
7391 3 : CompType = thisDXCoil.DXCoilType;
7392 : // DXCoil( DXCoilNum ).RatedAirVolFlowRate( 1 ) = DXCoil( DXCoilNum ).RatedTotCap2 * 0.00005035
7393 3 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap2;
7394 3 : state.dataSize->DataFractionUsedForSizing = 0.00005035;
7395 3 : TempSize = AutoSize;
7396 3 : AutoCalculateSizer sizerHPRatedAirVolFlow;
7397 3 : std::string stringOverride = "Rated Evaporator Air Flow Rate [m3/s]";
7398 3 : if (state.dataGlobal->isEpJSON) stringOverride = "rated_evaporator_air_flow_rate [m3/s]";
7399 3 : sizerHPRatedAirVolFlow.overrideSizingString(stringOverride);
7400 3 : sizerHPRatedAirVolFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7401 3 : thisDXCoil.RatedAirVolFlowRate(1) = sizerHPRatedAirVolFlow.size(state, TempSize, ErrorsFound);
7402 3 : PrintFlag = false;
7403 3 : }
7404 :
7405 8 : if (thisDXCoil.RatedHPWHCondWaterFlow == Constant::AutoCalculate) {
7406 : // report autocalculated sizing
7407 3 : PrintFlag = true;
7408 3 : CompName = thisDXCoil.Name;
7409 3 : CompType = thisDXCoil.DXCoilType;
7410 : // DXCoil( DXCoilNum ).RatedAirVolFlowRate( 1 ) = DXCoil( DXCoilNum ).RatedTotCap2 * 0.00000004487
7411 3 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap2;
7412 3 : state.dataSize->DataFractionUsedForSizing = 0.00000004487;
7413 3 : TempSize = AutoSize;
7414 3 : AutoCalculateSizer sizerHPWHCondWaterFlow;
7415 3 : std::string stringOverride = "Rated Condenser Water Flow Rate [m3/s]";
7416 3 : if (state.dataGlobal->isEpJSON) stringOverride = "rated_condenser_water_flow_rate [m3/s]";
7417 3 : sizerHPWHCondWaterFlow.overrideSizingString(stringOverride);
7418 3 : sizerHPWHCondWaterFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7419 3 : thisDXCoil.RatedHPWHCondWaterFlow = sizerHPWHCondWaterFlow.size(state, TempSize, ErrorsFound);
7420 3 : PrintFlag = false;
7421 3 : }
7422 8 : } else {
7423 88 : PrintFlag = true;
7424 88 : FieldNum = 0;
7425 88 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7426 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7427 0 : FieldNum = 4;
7428 0 : state.dataSize->DataBypassFrac = thisDXCoil.BypassedFlowFrac(Mode);
7429 88 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
7430 5 : CompName = thisDXCoil.Name;
7431 5 : FieldNum = 3;
7432 : // doesn't look like this is needed for air flow sizing, only for heating capacity sizing
7433 10 : state.dataSize->DataCoolCoilCap =
7434 5 : state.dataSize->DXCoolCap; // pass global variable used only for heat pumps (i.e., DX cooling and heating coils)
7435 5 : if ((thisDXCoil.IsSecondaryDXCoilInZone) &&
7436 0 : (thisDXCoil.CondenserType(1) ==
7437 : DataHeatBalance::RefrigCondenserType::Air)) { // secondary DX coil in secondary zone is specified
7438 0 : SizeSecDXCoil = true;
7439 : }
7440 83 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
7441 7 : CompName = thisDXCoil.Name;
7442 7 : FieldNum = 2;
7443 76 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
7444 7 : CompName = thisDXCoil.Name;
7445 7 : FieldNum = 3;
7446 69 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7447 6 : CompName = thisDXCoil.Name;
7448 63 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7449 6 : CompName = thisDXCoil.Name;
7450 57 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7451 10 : thisDXCoil.RatedAirVolFlowRate(Mode) = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
7452 10 : CompName = thisDXCoil.Name;
7453 10 : PrintFlag = false;
7454 47 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7455 7 : thisDXCoil.RatedAirVolFlowRate(Mode) = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
7456 7 : CompName = thisDXCoil.Name;
7457 7 : PrintFlag = false;
7458 : } else {
7459 40 : CompName = thisDXCoil.Name;
7460 40 : FieldNum = 4;
7461 : }
7462 :
7463 88 : TempSize = thisDXCoil.RatedAirVolFlowRate(Mode);
7464 88 : if (FieldNum > 0) {
7465 59 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [m3/s]";
7466 : } else {
7467 29 : SizingString = "Rated Air Flow Rate [m3/s]";
7468 : }
7469 88 : CompType = thisDXCoil.DXCoilType;
7470 88 : state.dataSize->DataIsDXCoil = true;
7471 88 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
7472 88 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
7473 88 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating ||
7474 75 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
7475 25 : bool errorsFound = false;
7476 25 : HeatingAirFlowSizer sizingHeatingAirFlow;
7477 25 : sizingHeatingAirFlow.overrideSizingString(SizingString);
7478 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7479 25 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7480 25 : thisDXCoil.RatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
7481 25 : } else {
7482 63 : bool errorsFound = false;
7483 63 : CoolingAirFlowSizer sizingCoolingAirFlow;
7484 63 : sizingCoolingAirFlow.overrideSizingString(SizingString);
7485 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7486 63 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7487 63 : thisDXCoil.RatedAirVolFlowRate(Mode) = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7488 63 : }
7489 88 : state.dataSize->DataIsDXCoil = false;
7490 88 : state.dataSize->DataEMSOverrideON = false;
7491 88 : state.dataSize->DataEMSOverride = 0.0;
7492 88 : state.dataSize->DataBypassFrac = 0.0;
7493 : }
7494 :
7495 96 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
7496 : // get autosized air flow for capacity calc's if capacity is not autosized
7497 : // *** RAR this if block is a last minute addition to correct capacity reporting when not autosized and a sizing run is done. Test
7498 : // suite was not run with this code included. *** The question here is if the autosized air flow rate or the user specified air flow
7499 : // rate should be used to calculate capacity removing this for now until more is known
7500 : // if ( DXCoil( DXCoilNum ).RatedTotCap( Mode ) != AutoSize && ( ( SysSizingRunDone && CurSysNum > 0 ) ||
7501 : //( ZoneSizingRunDone && CurZoneEqNum > 0 ) ) ) { if ( DXCoil( DXCoilNum ).DXCoilType_Num ==
7502 : // HVAC::CoilDX_CoolingTwoStageWHumControl ) { SizingMethod = CoolingAirflowSizing;
7503 : // DataBypassFrac = DXCoil ( DXCoilNum ).BypassedFlowFrac ( Mode );
7504 : // } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical ) {
7505 : // SizingMethod = HeatingAirflowSizing;
7506 : //// DataCoolCoilCap = DXCoolCap; // pass global variable used only for heat pumps (i.e.,
7507 : /// DX cooling and heating coils)
7508 : // } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilVRF_Heating ) {
7509 : // SizingMethod = HeatingAirflowSizing;
7510 : // } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilVRF_Cooling ) {
7511 : // SizingMethod = CoolingAirflowSizing;
7512 : // } else {
7513 : // SizingMethod = CoolingAirflowSizing;
7514 : // }
7515 : // CompName = DXCoil( DXCoilNum ).Name;
7516 : // TempSize = AutoSize;
7517 : // SizingString.clear(); // don't care
7518 : // CompType = DXCoil( DXCoilNum ).DXCoilType;
7519 : // DataIsDXCoil = true;
7520 : // DataEMSOverrideON = DXCoil ( DXCoilNum ).RatedAirVolFlowRateEMSOverrideON ( Mode );
7521 : // DataEMSOverride = DXCoil( DXCoilNum ).RatedAirVolFlowRateEMSOverrideValue( Mode );
7522 : // CoolingAirFlowSizer sizingCoolingAirFlow;
7523 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7524 : // sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
7525 : // DataAirFlowUsedForSizing = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7526 : // DataIsDXCoil = false; // don't need this and next 2, they are just overwritten below. Delete
7527 : // on next pass so testing will show problems if any. DataEMSOverrideON = false;
7528 : // DataEMSOverride = 0.0;
7529 : // DataBypassFrac = 0.0;
7530 : // }
7531 96 : PrintFlag = true;
7532 96 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.CCapFTemp(Mode);
7533 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7534 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7535 0 : FieldNum = 1;
7536 0 : TempSize = thisDXCoil.RatedTotCap(Mode);
7537 0 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7538 96 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating ||
7539 84 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7540 18 : CompName = thisDXCoil.Name;
7541 18 : FieldNum = 1;
7542 18 : TempSize = thisDXCoil.RatedTotCap(Mode);
7543 18 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7544 18 : state.dataSize->DataCoolCoilCap = state.dataSize->DXCoolCap;
7545 78 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
7546 72 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
7547 8 : CompName = thisDXCoil.Name;
7548 8 : FieldNum = 1;
7549 8 : TempSize = thisDXCoil.RatedTotCap(Mode);
7550 8 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7551 8 : PrintFlag = false;
7552 8 : state.dataLoopNodes->Node(thisDXCoil.WaterInNode).Temp =
7553 8 : thisDXCoil.RatedInletWaterTemp; // set the rated water inlet node for HPWHs for use in CalcHPWHDXCoil
7554 70 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7555 6 : CompName = thisDXCoil.Name;
7556 6 : FieldNum = 1;
7557 6 : TempSize = thisDXCoil.RatedTotCap(Mode);
7558 6 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7559 6 : if (state.dataSize->CurZoneEqNum > 0) {
7560 6 : CoilInTemp =
7561 6 : state.dataSize->ZoneSizingRunDone ? state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp : 26;
7562 : } else {
7563 0 : if (state.dataSize->CurOASysNum > 0) {
7564 0 : CoilInTemp =
7565 0 : state.dataSize->SysSizingRunDone ? state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).OutTempAtCoolPeak : 32;
7566 : } else {
7567 0 : CoilInTemp =
7568 0 : state.dataSize->SysSizingRunDone ? state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).MixTempAtCoolPeak : 26;
7569 : }
7570 : }
7571 6 : CalcVRFCoilCapModFac(state, 0, _, CompName, CoilInTemp, _, _, _, state.dataSize->DataTotCapCurveValue);
7572 64 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7573 10 : CompName = thisDXCoil.Name;
7574 10 : FieldNum = 7 + (thisDXCoil.NumOfSpeeds - 1) * 13;
7575 10 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(thisDXCoil.NumOfSpeeds);
7576 10 : TempSize = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
7577 10 : PrintFlag = false;
7578 10 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7579 54 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7580 7 : CompName = thisDXCoil.Name;
7581 7 : FieldNum = 10 + (thisDXCoil.NumOfSpeeds - 1) * 6;
7582 7 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(thisDXCoil.NumOfSpeeds);
7583 7 : TempSize = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
7584 7 : PrintFlag = false;
7585 7 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7586 : } else {
7587 47 : CompName = thisDXCoil.Name;
7588 47 : FieldNum = 1;
7589 47 : TempSize = thisDXCoil.RatedTotCap(Mode);
7590 47 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7591 : }
7592 96 : CompType = thisDXCoil.DXCoilType;
7593 96 : state.dataSize->DataIsDXCoil = true;
7594 96 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
7595 96 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
7596 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical ||
7597 84 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7598 25 : HeatingCapacitySizer sizerHeatingCapacity;
7599 25 : sizerHeatingCapacity.overrideSizingString(SizingString);
7600 25 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7601 25 : thisDXCoil.RatedTotCap(Mode) = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
7602 25 : } else {
7603 71 : CoolingCapacitySizer sizerCoolingCapacity;
7604 71 : sizerCoolingCapacity.overrideSizingString(SizingString);
7605 71 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7606 71 : thisDXCoil.RatedTotCap(Mode) = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
7607 71 : }
7608 96 : state.dataSize->DataIsDXCoil = false;
7609 96 : state.dataSize->DataFlowUsedForSizing = 0.0;
7610 96 : state.dataSize->DataCoolCoilCap = 0.0;
7611 96 : state.dataSize->DataTotCapCurveIndex = 0;
7612 96 : state.dataSize->DataEMSOverrideON = false;
7613 96 : state.dataSize->DataEMSOverride = 0.0;
7614 96 : state.dataSize->DataConstantUsedForSizing = 0.0;
7615 96 : state.dataSize->DataFractionUsedForSizing = 0.0;
7616 96 : state.dataSize->DataTotCapCurveValue = 0.0;
7617 :
7618 : // Cooling coil capacity
7619 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7620 56 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling ||
7621 49 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7622 53 : state.dataSize->DXCoolCap = thisDXCoil.RatedTotCap(Mode);
7623 : }
7624 :
7625 : // Sizing DX cooling coil SHR
7626 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7627 56 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling ||
7628 49 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7629 :
7630 53 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7631 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7632 : } else {
7633 53 : CompName = thisDXCoil.Name;
7634 : }
7635 53 : CompType = thisDXCoil.DXCoilType;
7636 53 : TempSize = thisDXCoil.RatedSHR(Mode);
7637 53 : state.dataSize->DataDXSpeedNum = Mode;
7638 53 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
7639 53 : state.dataSize->DataCapacityUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7640 53 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedSHREMSOverrideOn(Mode);
7641 53 : state.dataSize->DataEMSOverride = thisDXCoil.RatedSHREMSOverrideValue(Mode);
7642 53 : bool ErrorsFound = false;
7643 53 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7644 53 : thisDXCoil.RatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
7645 53 : state.dataSize->DataDXSpeedNum = 0;
7646 53 : state.dataSize->DataFlowUsedForSizing = 0.0;
7647 53 : state.dataSize->DataCapacityUsedForSizing = 0.0;
7648 53 : state.dataSize->DataEMSOverrideON = false;
7649 53 : state.dataSize->DataEMSOverride = 0.0;
7650 :
7651 : } // End of Rated SHR
7652 :
7653 : // Sizing evaporator condenser air flow
7654 98 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondAirFlow(Mode) != 0.0 &&
7655 2 : (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7656 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
7657 :
7658 2 : AutoCalculateSizer sizerEvapCondAirFlow;
7659 2 : std::string stringOverride = "Evaporative Condenser Air Flow Rate [m3/s]";
7660 2 : if (state.dataGlobal->isEpJSON) stringOverride = "evaporative_condenser_air_flow_rate [m3/s]";
7661 2 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7662 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7663 : } else {
7664 2 : CompName = thisDXCoil.Name;
7665 2 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7666 1 : stringOverride = "High Speed Evaporative Condenser Air Flow Rate [m3/s]";
7667 1 : if (state.dataGlobal->isEpJSON) stringOverride = "high_speed_evaporative_condenser_air_flow_rate [m3/s]";
7668 : } else {
7669 1 : stringOverride = "Evaporative Condenser Air Flow Rate [m3/s]";
7670 1 : if (state.dataGlobal->isEpJSON) stringOverride = "evaporative_condenser_air_flow_rate [m3/s]";
7671 : }
7672 : }
7673 2 : CompType = thisDXCoil.DXCoilType;
7674 : // Auto-size condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
7675 2 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7676 2 : state.dataSize->DataFractionUsedForSizing = 0.000114;
7677 2 : TempSize = thisDXCoil.EvapCondAirFlow(Mode);
7678 2 : sizerEvapCondAirFlow.overrideSizingString(stringOverride);
7679 2 : sizerEvapCondAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7680 2 : thisDXCoil.EvapCondAirFlow(Mode) = sizerEvapCondAirFlow.size(state, TempSize, ErrorsFound);
7681 2 : }
7682 :
7683 96 : if (SizeSecDXCoil) { // autosize secondary coil air flow rate for AirCooled condenser type
7684 0 : IsAutoSize = false;
7685 0 : if (thisDXCoil.SecCoilAirFlow == AutoSize) {
7686 0 : IsAutoSize = true;
7687 : }
7688 : // Autosize Primary Coil Air Flow * Secondary Coil Scaling Factor
7689 0 : SecCoilAirFlowDes = thisDXCoil.RatedAirVolFlowRate(1) * thisDXCoil.SecCoilAirFlowScalingFactor;
7690 0 : if (IsAutoSize) {
7691 0 : thisDXCoil.SecCoilAirFlow = SecCoilAirFlowDes;
7692 0 : BaseSizer::reportSizerOutput(
7693 : state, thisDXCoil.DXCoilType, thisDXCoil.Name, "Design Size Secondary Coil Air Flow Rate [m3/s]", SecCoilAirFlowDes);
7694 : } else {
7695 0 : if (thisDXCoil.SecCoilAirFlow > 0.0 && SecCoilAirFlowDes > 0.0 && !HardSizeNoDesRun) {
7696 0 : SecCoilAirFlowUser = thisDXCoil.SecCoilAirFlow;
7697 0 : BaseSizer::reportSizerOutput(state,
7698 : thisDXCoil.DXCoilType,
7699 : thisDXCoil.Name,
7700 : "Design Size Secondary Coil Air Flow Rate [m3/s]",
7701 : SecCoilAirFlowDes,
7702 : "User-Specified Secondary Coil Air Flow Rate [m3/s]",
7703 : SecCoilAirFlowUser);
7704 0 : if (state.dataGlobal->DisplayExtraWarnings) {
7705 0 : if ((std::abs(SecCoilAirFlowDes - SecCoilAirFlowUser) / SecCoilAirFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
7706 0 : ShowMessage(
7707 : state,
7708 0 : format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
7709 0 : ShowContinueError(state, format("User-Specified Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowUser));
7710 0 : ShowContinueError(
7711 0 : state, format("differs from Design Size Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowDes));
7712 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
7713 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
7714 : }
7715 : }
7716 : }
7717 : }
7718 : }
7719 :
7720 : // Sizing evaporative condenser air flow 2
7721 96 : PrintFlag = true;
7722 97 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondAirFlow2 != 0.0 &&
7723 1 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7724 1 : CompName = thisDXCoil.Name;
7725 1 : FieldNum = 15; // Low Speed Evaporative Condenser Air Flow Rate
7726 1 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [m3/s]";
7727 1 : CompType = thisDXCoil.DXCoilType;
7728 : // Autosize low speed condenser air flow to 1/3 Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
7729 1 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7730 1 : state.dataSize->DataFractionUsedForSizing = 0.000114 * 0.3333;
7731 1 : TempSize = thisDXCoil.EvapCondAirFlow2;
7732 1 : AutoCalculateSizer sizerEvapCondAirFlow2;
7733 1 : std::string stringOverride = "Low Speed Evaporative Condenser Air Flow Rate [m3/s]";
7734 1 : if (state.dataGlobal->isEpJSON) stringOverride = "low_speed_evaporative_condenser_air_flow_rate [m3/s]";
7735 1 : sizerEvapCondAirFlow2.overrideSizingString(stringOverride);
7736 1 : sizerEvapCondAirFlow2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7737 1 : thisDXCoil.EvapCondAirFlow2 = sizerEvapCondAirFlow2.size(state, TempSize, ErrorsFound);
7738 1 : }
7739 :
7740 : // Sizing evaporative condenser pump electric nominal power
7741 108 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondPumpElecNomPower(Mode) != 0.0 &&
7742 12 : (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7743 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
7744 :
7745 12 : AutoCalculateSizer sizerEvapCondPumpPower;
7746 12 : std::string stringOverride = "Evaporative Condenser Pump Rated Power Consumption [W]";
7747 12 : if (state.dataGlobal->isEpJSON) stringOverride = "evaporative_condenser_pump_rated_power_consumption [W]";
7748 12 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7749 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7750 : } else {
7751 12 : CompName = thisDXCoil.Name;
7752 12 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7753 1 : stringOverride = "High Speed Evaporative Condenser Pump Rated Power Consumption [W]";
7754 1 : if (state.dataGlobal->isEpJSON) stringOverride = "high_speed_evaporative_condenser_pump_rated_power_consumption [W]";
7755 : } else {
7756 11 : stringOverride = "Evaporative Condenser Pump Rated Power Consumption [W]";
7757 11 : if (state.dataGlobal->isEpJSON) stringOverride = "evaporative_condenser_pump_rated_power_consumption [W]";
7758 : }
7759 : }
7760 12 : CompType = thisDXCoil.DXCoilType;
7761 : // Autosize high speed evap condenser pump power to Total Capacity * 0.004266 w/w (15 w/ton)
7762 12 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7763 12 : state.dataSize->DataFractionUsedForSizing = 0.004266;
7764 12 : TempSize = thisDXCoil.EvapCondPumpElecNomPower(Mode);
7765 12 : sizerEvapCondPumpPower.overrideSizingString(stringOverride);
7766 12 : sizerEvapCondPumpPower.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7767 12 : thisDXCoil.EvapCondPumpElecNomPower(Mode) = sizerEvapCondPumpPower.size(state, TempSize, ErrorsFound);
7768 12 : }
7769 :
7770 : // Sizing low speed evaporative condenser pump electric nominal power
7771 97 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondPumpElecNomPower2 != 0.0 &&
7772 1 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7773 1 : CompName = thisDXCoil.Name;
7774 1 : CompType = thisDXCoil.DXCoilType;
7775 : // Autosize low speed evap condenser pump power to 1/3 Total Capacity * 0.004266 w/w (15 w/ton)
7776 1 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7777 1 : state.dataSize->DataFractionUsedForSizing = 0.004266 * 0.3333;
7778 1 : TempSize = thisDXCoil.EvapCondPumpElecNomPower2;
7779 1 : AutoCalculateSizer sizerEvapCondPumpPower2;
7780 1 : std::string stringOverride = "Low Speed Evaporative Condenser Pump Rated Power Consumption [W]";
7781 1 : if (state.dataGlobal->isEpJSON) stringOverride = "low_speed_evaporative_condenser_pump_rated_power_consumption [W]";
7782 1 : sizerEvapCondPumpPower2.overrideSizingString(stringOverride);
7783 1 : sizerEvapCondPumpPower2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7784 1 : thisDXCoil.EvapCondPumpElecNomPower2 = sizerEvapCondPumpPower2.size(state, TempSize, ErrorsFound);
7785 1 : }
7786 :
7787 : // // Sizing rated low speed air flow rate
7788 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7789 4 : CompName = thisDXCoil.Name;
7790 4 : CompType = thisDXCoil.DXCoilType;
7791 : // Autosize low speed air flow rate to 1/3 high speed air flow rate
7792 4 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
7793 4 : state.dataSize->DataFractionUsedForSizing = 0.3333;
7794 4 : TempSize = thisDXCoil.RatedAirVolFlowRate2;
7795 4 : AutoCalculateSizer sizerLowSpdAirFlow;
7796 4 : std::string stringOverride = "Low Speed Rated Air Flow Rate [m3/s]";
7797 4 : if (state.dataGlobal->isEpJSON) stringOverride = "low_speed_rated_air_flow_rate [m3/s]";
7798 4 : sizerLowSpdAirFlow.overrideSizingString(stringOverride);
7799 4 : sizerLowSpdAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7800 4 : thisDXCoil.RatedAirVolFlowRate2 = sizerLowSpdAirFlow.size(state, TempSize, ErrorsFound);
7801 4 : }
7802 :
7803 : // // Sizing rated low speed total cooling capacity
7804 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7805 4 : CompName = thisDXCoil.Name;
7806 4 : CompType = thisDXCoil.DXCoilType;
7807 : // Autosize low speed capacity to 1/3 high speed capacity
7808 4 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7809 4 : state.dataSize->DataFractionUsedForSizing = 0.3333;
7810 4 : TempSize = thisDXCoil.RatedTotCap2;
7811 4 : AutoCalculateSizer sizerLowSpdCap;
7812 4 : std::string stringOverride = "Low Speed Gross Rated Total Cooling Capacity [W]";
7813 4 : if (state.dataGlobal->isEpJSON) stringOverride = "low_speed_gross_rated_total_cooling_capacity [W]";
7814 4 : sizerLowSpdCap.overrideSizingString(stringOverride);
7815 4 : sizerLowSpdCap.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7816 4 : thisDXCoil.RatedTotCap2 = sizerLowSpdCap.size(state, TempSize, ErrorsFound);
7817 4 : }
7818 :
7819 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7820 4 : if (thisDXCoil.EvapCondAirFlow2 > thisDXCoil.EvapCondAirFlow(Mode)) {
7821 0 : ShowSevereError(
7822 : state,
7823 0 : format("SizeDXCoil: {} {}, Evaporative Condenser low speed air flow must be less than or equal to high speed air flow.",
7824 0 : thisDXCoil.DXCoilType,
7825 0 : thisDXCoil.Name));
7826 0 : ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.EvapCondAirFlow2, thisDXCoil.EvapCondAirFlow(Mode)));
7827 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7828 : }
7829 :
7830 4 : if (thisDXCoil.EvapCondPumpElecNomPower2 > thisDXCoil.EvapCondPumpElecNomPower(Mode)) {
7831 0 : ShowSevereError(
7832 : state,
7833 0 : format("SizeDXCoil: {} {}, Evaporative Condenser low speed pump power must be less than or equal to high speed pump power.",
7834 0 : thisDXCoil.DXCoilType,
7835 0 : thisDXCoil.Name));
7836 0 : ShowContinueError(
7837 0 : state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.EvapCondPumpElecNomPower2, thisDXCoil.EvapCondPumpElecNomPower(Mode)));
7838 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7839 : }
7840 :
7841 4 : if (thisDXCoil.RatedTotCap2 > thisDXCoil.RatedTotCap(Mode)) {
7842 0 : ShowSevereError(state,
7843 0 : format("SizeDXCoil: {} {}, Rated Total Cooling Capacity, Low Speed must be less than or equal to Rated Total "
7844 : "Cooling Capacity, High Speed.",
7845 0 : thisDXCoil.DXCoilType,
7846 0 : thisDXCoil.Name));
7847 0 : ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.RatedTotCap2, thisDXCoil.RatedTotCap(Mode)));
7848 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7849 : }
7850 :
7851 4 : if (thisDXCoil.RatedAirVolFlowRate2 > thisDXCoil.RatedAirVolFlowRate(Mode)) {
7852 0 : ShowFatalError(state,
7853 0 : format("SizeDXCoil: {} {}, Rated Air Volume Flow Rate, low speed must be less than or equal to Rated Air Volume "
7854 : "Flow Rate, high speed.",
7855 0 : thisDXCoil.DXCoilType,
7856 0 : thisDXCoil.Name));
7857 0 : ShowContinueError(state,
7858 0 : format("Instead, {:.2R} > {:.2R}", thisDXCoil.RatedAirVolFlowRate2, thisDXCoil.RatedAirVolFlowRate(Mode)));
7859 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7860 : }
7861 : }
7862 :
7863 : // // Sizing rated low speed SHR2
7864 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7865 4 : CompName = thisDXCoil.Name;
7866 4 : FieldNum = 7;
7867 4 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum);
7868 4 : CompType = thisDXCoil.DXCoilType;
7869 : // Autosize low speed SHR to be the same as high speed SHR
7870 4 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedSHR(Mode);
7871 4 : state.dataSize->DataFractionUsedForSizing = 1.0;
7872 4 : state.dataSize->DataDXSpeedNum = 2; // refers to low speed in sizer
7873 4 : bool ErrorsFound = false;
7874 4 : TempSize = thisDXCoil.RatedSHR2;
7875 4 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7876 4 : thisDXCoil.RatedSHR2 = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
7877 4 : state.dataSize->DataConstantUsedForSizing = 0.0;
7878 4 : state.dataSize->DataFractionUsedForSizing = 0.0;
7879 4 : state.dataSize->DataDXSpeedNum = 0;
7880 : }
7881 :
7882 : // // Sizing resistive defrost heater capacity
7883 96 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating &&
7884 83 : thisDXCoil.DXCoilType_Num != HVAC::CoilDX_MultiSpeedHeating) {
7885 : // IF (DXCoil(DXCoilNum)%DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating .OR. &
7886 : // DXCoil(DXCoilNum)%DXCoilType_Num == Coil_HeatingAirToAirVariableSpeed) THEN
7887 76 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
7888 3 : CompName = thisDXCoil.Name;
7889 3 : CompType = thisDXCoil.DXCoilType;
7890 : // Autosize low speed capacity to 1/3 high speed capacity
7891 3 : state.dataSize->DataConstantUsedForSizing = state.dataSize->DXCoolCap;
7892 3 : state.dataSize->DataFractionUsedForSizing = 1.0;
7893 3 : TempSize = thisDXCoil.DefrostCapacity;
7894 3 : AutoCalculateSizer sizerResDefCap;
7895 3 : std::string stringOverride = "Resistive Defrost Heater Capacity [W]";
7896 3 : if (state.dataGlobal->isEpJSON) stringOverride = "resistive_defrost_heater_capacity [W]";
7897 3 : sizerResDefCap.overrideSizingString(stringOverride);
7898 3 : sizerResDefCap.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7899 3 : thisDXCoil.DefrostCapacity = sizerResDefCap.size(state, TempSize, ErrorsFound);
7900 3 : } else {
7901 73 : thisDXCoil.DefrostCapacity = 0.0;
7902 : }
7903 : }
7904 :
7905 : } // End capacity stages loop
7906 : } // End dehumidification modes loop
7907 :
7908 : // Autosizing for multispeed cooling coil
7909 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7910 : // flow rate autosize
7911 31 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
7912 : // Sizing multispeed air volume flow rate
7913 21 : IsAutoSize = false;
7914 21 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) == AutoSize) {
7915 15 : IsAutoSize = true;
7916 : }
7917 21 : state.dataSize->DataIsDXCoil = true;
7918 21 : CompName = thisDXCoil.Name;
7919 21 : CompType = thisDXCoil.DXCoilType;
7920 21 : if (Mode == thisDXCoil.NumOfSpeeds) {
7921 10 : FieldNum = 10 + (Mode - 1) * 14;
7922 10 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
7923 10 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
7924 10 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
7925 10 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
7926 10 : bool errorsFound = false;
7927 10 : CoolingAirFlowSizer sizingCoolingAirFlow;
7928 10 : sizingCoolingAirFlow.overrideSizingString(SizingString);
7929 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7930 10 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7931 10 : TempSize = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7932 10 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = TempSize;
7933 10 : state.dataSize->DataEMSOverrideON = false;
7934 10 : state.dataSize->DataEMSOverride = 0.0;
7935 10 : if (!IsAutoSize && !HardSizeNoDesRun) {
7936 1 : TempSize = AutoSize;
7937 1 : bPRINT = false;
7938 1 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
7939 1 : MSRatedAirVolFlowRateDes = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7940 1 : bPRINT = true;
7941 : }
7942 10 : if (IsAutoSize) {
7943 7 : MSRatedAirVolFlowRateDes = TempSize;
7944 : }
7945 10 : } else {
7946 11 : FieldNum = 10 + (Mode - 1) * 14;
7947 11 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
7948 11 : if (IsAutoSize || !HardSizeNoDesRun) {
7949 : // Autosize low speed flow to fraction of the highest speed flow
7950 9 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
7951 9 : if (!IsAutoSize && !HardSizeNoDesRun) state.dataSize->DataConstantUsedForSizing = MSRatedAirVolFlowRateDes;
7952 9 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
7953 : }
7954 11 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
7955 11 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
7956 11 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
7957 11 : bool errorsFound = false;
7958 11 : CoolingAirFlowSizer sizingCoolingAirFlow;
7959 11 : sizingCoolingAirFlow.overrideSizingString(SizingString);
7960 11 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
7961 11 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7962 11 : }
7963 21 : state.dataSize->DataEMSOverride = 0.0;
7964 21 : state.dataSize->DataEMSOverrideON = false;
7965 21 : state.dataSize->DataIsDXCoil = false;
7966 21 : state.dataSize->DataTotCapCurveIndex = 0;
7967 21 : state.dataSize->DataConstantUsedForSizing = 0.0;
7968 21 : state.dataSize->DataFractionUsedForSizing = 0.0;
7969 : }
7970 :
7971 : // Ensure flow rate at lower speed must be lower or equal to the flow rate at higher speed. Otherwise, a severe error is issued.
7972 21 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
7973 11 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) > thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)) {
7974 0 : ShowWarningError(state,
7975 0 : format("SizeDXCoil: {} {}, Speed {} Rated Air Flow Rate must be less than or equal to Speed {} Rated Air Flow Rate.",
7976 0 : thisDXCoil.DXCoilType,
7977 0 : thisDXCoil.Name,
7978 : Mode,
7979 0 : Mode + 1));
7980 0 : ShowContinueError(
7981 0 : state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedAirVolFlowRate(Mode), thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)));
7982 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7983 : }
7984 : }
7985 :
7986 : // Sizing multispeed rated total cooling capacity
7987 31 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
7988 21 : IsAutoSize = false;
7989 21 : if (thisDXCoil.MSRatedTotCap(Mode) == AutoSize) {
7990 15 : IsAutoSize = true;
7991 : }
7992 21 : CompName = thisDXCoil.Name;
7993 21 : CompType = thisDXCoil.DXCoilType;
7994 21 : state.dataSize->DataIsDXCoil = true;
7995 21 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(Mode);
7996 21 : if (Mode == thisDXCoil.NumOfSpeeds) {
7997 10 : PrintFlag = true;
7998 10 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(Mode);
7999 10 : FieldNum = 7 + (Mode - 1) * 14;
8000 10 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8001 10 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8002 10 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8003 10 : MSRatedTotCapDesAtMaxSpeed = thisDXCoil.MSRatedTotCap(Mode);
8004 10 : if (!HardSizeNoDesRun) {
8005 8 : PrintFlag = false;
8006 8 : TempSize = DataSizing::AutoSize;
8007 : // Auto-size capacity at the highest speed
8008 8 : CoolingCapacitySizer sizerCoolingCapacity;
8009 8 : sizerCoolingCapacity.overrideSizingString(SizingString);
8010 8 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8011 8 : TempSize = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
8012 8 : state.dataSize->DataConstantUsedForSizing = TempSize;
8013 8 : state.dataSize->DataFractionUsedForSizing = 1.0;
8014 8 : MSRatedTotCapDesAtMaxSpeed = TempSize;
8015 8 : thisDXCoil.MSRatedTotCapDes(Mode) = TempSize;
8016 8 : PrintFlag = true;
8017 8 : }
8018 10 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8019 10 : CoolingCapacitySizer sizerCoolingCapacity2;
8020 10 : sizerCoolingCapacity2.overrideSizingString(SizingString);
8021 10 : sizerCoolingCapacity2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8022 10 : TempSize = sizerCoolingCapacity2.size(state, TempSize, ErrorsFound);
8023 10 : thisDXCoil.MSRatedTotCap(Mode) = TempSize;
8024 10 : if (IsAutoSize) {
8025 7 : MSRatedTotCapDesAtMaxSpeed = TempSize;
8026 7 : thisDXCoil.MSRatedTotCapDes(Mode) = TempSize;
8027 : }
8028 10 : } else {
8029 : // cooling capacity at lower speeds
8030 11 : PrintFlag = true;
8031 11 : FieldNum = 7 + (Mode - 1) * 14;
8032 11 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8033 11 : if (IsAutoSize || !HardSizeNoDesRun) {
8034 : // autosize low speed capacity to fraction of the highest speed capacity
8035 9 : if (!HardSizeNoDesRun) {
8036 9 : state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8037 : } else {
8038 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
8039 : }
8040 9 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8041 9 : thisDXCoil.MSRatedTotCapDes(Mode) = state.dataSize->DataConstantUsedForSizing * state.dataSize->DataFractionUsedForSizing;
8042 : }
8043 11 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8044 11 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8045 11 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8046 11 : CoolingCapacitySizer sizerCoolingCapacity;
8047 11 : sizerCoolingCapacity.overrideSizingString(SizingString);
8048 11 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8049 11 : thisDXCoil.MSRatedTotCap(Mode) = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
8050 11 : }
8051 21 : state.dataSize->DataEMSOverride = 0.0;
8052 21 : state.dataSize->DataEMSOverrideON = false;
8053 21 : state.dataSize->DataIsDXCoil = false;
8054 21 : state.dataSize->DataCoolCoilCap = 0.0;
8055 21 : state.dataSize->DataTotCapCurveIndex = 0;
8056 21 : state.dataSize->DataConstantUsedForSizing = 0.0;
8057 21 : state.dataSize->DataFractionUsedForSizing = 0.0;
8058 : }
8059 :
8060 : // Ensure capacity at lower speed must be lower or equal to the capacity at higher speed.
8061 21 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8062 11 : if (thisDXCoil.MSRatedTotCap(Mode) > thisDXCoil.MSRatedTotCap(Mode + 1)) {
8063 0 : ShowWarningError(state,
8064 0 : format("SizeDXCoil: {} {}, Speed {} Rated Total Cooling Capacity must be less than or equal to Speed {} Rated "
8065 : "Total Cooling Capacity.",
8066 0 : thisDXCoil.DXCoilType,
8067 0 : thisDXCoil.Name,
8068 : Mode,
8069 0 : Mode + 1));
8070 0 : ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedTotCap(Mode), thisDXCoil.MSRatedTotCap(Mode + 1)));
8071 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8072 : }
8073 : }
8074 :
8075 : // Rated SHR
8076 31 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8077 21 : IsAutoSize = false;
8078 21 : if (thisDXCoil.MSRatedSHR(Mode) == AutoSize) {
8079 15 : IsAutoSize = true;
8080 : }
8081 21 : if (Mode == thisDXCoil.NumOfSpeeds) {
8082 10 : CompType = thisDXCoil.DXCoilType;
8083 10 : CompName = thisDXCoil.Name;
8084 10 : TempSize = thisDXCoil.MSRatedSHR(Mode);
8085 10 : state.dataSize->DataFlowUsedForSizing = MSRatedAirVolFlowRateDes;
8086 10 : state.dataSize->DataCapacityUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8087 10 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedSHREMSOverrideOn(Mode);
8088 10 : state.dataSize->DataEMSOverride = thisDXCoil.RatedSHREMSOverrideValue(Mode);
8089 10 : bool ErrorsFound = false;
8090 10 : state.dataSize->DataDXSpeedNum = Mode;
8091 10 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8092 10 : thisDXCoil.MSRatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
8093 : // added for rated sensible cooling capacity estimate for html reporting, issue #7381
8094 10 : thisDXCoil.RatedSHR(1) = thisDXCoil.MSRatedSHR(Mode);
8095 : // design SHR value at the maximum speed calculated above was supposed to be used for all speeds
8096 : // Now user specified SHR value is used when the SHR field is not autosized and design day run is
8097 : // set to yes unless the code below is commented out
8098 10 : MSRatedSHRDes = thisDXCoil.MSRatedSHR(Mode);
8099 : } else {
8100 11 : TempSize = thisDXCoil.MSRatedSHR(Mode);
8101 11 : bool ErrorsFound = false;
8102 11 : state.dataSize->DataDXSpeedNum = Mode;
8103 11 : state.dataSize->DataFractionUsedForSizing = MSRatedSHRDes;
8104 11 : state.dataSize->DataConstantUsedForSizing = 1.0;
8105 11 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8106 11 : thisDXCoil.MSRatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
8107 : }
8108 : }
8109 10 : state.dataSize->DataFlowUsedForSizing = 0.0;
8110 10 : state.dataSize->DataCapacityUsedForSizing = 0.0;
8111 10 : state.dataSize->DataEMSOverrideON = false;
8112 10 : state.dataSize->DataEMSOverride = 0.0;
8113 10 : state.dataSize->DataDXSpeedNum = 0;
8114 10 : state.dataSize->DataFractionUsedForSizing = 0.0;
8115 10 : state.dataSize->DataConstantUsedForSizing = 0.0;
8116 :
8117 : // Rated Evaporative condenser airflow rates
8118 31 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8119 21 : IsAutoSize = false;
8120 21 : if (thisDXCoil.MSEvapCondAirFlow(Mode) == AutoSize) {
8121 16 : IsAutoSize = true;
8122 : }
8123 21 : if (IsAutoSize || !HardSizeNoDesRun) {
8124 : // Autosize condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
8125 21 : MSEvapCondAirFlowDes = ((float)Mode / thisDXCoil.NumOfSpeeds) * MSRatedTotCapDesAtMaxSpeed * 0.000114;
8126 : } else {
8127 : // this is done to duplicate any existing calc method
8128 0 : MSEvapCondAirFlowDes = thisDXCoil.MSRatedTotCap(Mode) * 0.000114;
8129 : }
8130 21 : if (IsAutoSize) {
8131 16 : thisDXCoil.MSEvapCondAirFlow(Mode) = MSEvapCondAirFlowDes;
8132 48 : BaseSizer::reportSizerOutput(state,
8133 : thisDXCoil.DXCoilType,
8134 : thisDXCoil.Name,
8135 32 : format("Design Size Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
8136 : MSEvapCondAirFlowDes);
8137 : } else {
8138 5 : if (thisDXCoil.MSEvapCondAirFlow(Mode) > 0.0 && MSEvapCondAirFlowDes > 0.0 && !HardSizeNoDesRun) {
8139 2 : MSEvapCondAirFlowUser = thisDXCoil.MSEvapCondAirFlow(Mode);
8140 6 : BaseSizer::reportSizerOutput(state,
8141 : thisDXCoil.DXCoilType,
8142 : thisDXCoil.Name,
8143 4 : format("Design Size Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
8144 : MSEvapCondAirFlowDes,
8145 4 : format("User-Specified Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
8146 : MSEvapCondAirFlowUser);
8147 2 : if (state.dataGlobal->DisplayExtraWarnings) {
8148 0 : if ((std::abs(MSEvapCondAirFlowDes - MSEvapCondAirFlowUser) / MSEvapCondAirFlowUser) >
8149 0 : state.dataSize->AutoVsHardSizingThreshold) {
8150 0 : ShowMessage(
8151 0 : state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
8152 0 : ShowContinueError(state,
8153 0 : format("User-Specified Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", MSEvapCondAirFlowUser));
8154 0 : ShowContinueError(
8155 0 : state, format("differs from Design Size Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", MSEvapCondAirFlowDes));
8156 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8157 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8158 : }
8159 : }
8160 : }
8161 : }
8162 : }
8163 :
8164 : // Ensure evaporative condenser airflow rate at lower speed must be lower or equal to one at higher speed.
8165 21 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8166 11 : if (thisDXCoil.MSEvapCondAirFlow(Mode) > thisDXCoil.MSEvapCondAirFlow(Mode + 1)) {
8167 0 : ShowWarningError(state,
8168 0 : format("SizeDXCoil: {} {}, Speed {} Evaporative Condenser Air Flow Rate must be less than or equal to Speed {} "
8169 : "Evaporative Condenser Air Flow Rate.",
8170 0 : thisDXCoil.DXCoilType,
8171 0 : thisDXCoil.Name,
8172 : Mode,
8173 0 : Mode + 1));
8174 0 : ShowContinueError(state,
8175 0 : format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSEvapCondAirFlow(Mode), thisDXCoil.MSEvapCondAirFlow(Mode + 1)));
8176 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8177 : }
8178 : }
8179 :
8180 : // Sizing multispeed rated evaporative condenser pump power
8181 31 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8182 21 : IsAutoSize = false;
8183 21 : if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) == AutoSize) {
8184 16 : IsAutoSize = true;
8185 : }
8186 :
8187 21 : if (IsAutoSize || !HardSizeNoDesRun) {
8188 : // Autosize low speed evap condenser pump power to 1/3 Total Capacity * 0.004266 w/w (15 w/ton)
8189 21 : MSEvapCondPumpElecNomPowerDes = ((float)Mode / thisDXCoil.NumOfSpeeds) * MSRatedTotCapDesAtMaxSpeed * 0.004266;
8190 : } else {
8191 : // this is done to duplicate any existing calc method
8192 0 : MSEvapCondPumpElecNomPowerDes = thisDXCoil.MSRatedTotCap(Mode) * 0.004266;
8193 : }
8194 : // Design Size data is always available
8195 21 : if (IsAutoSize) {
8196 16 : thisDXCoil.MSEvapCondPumpElecNomPower(Mode) = MSEvapCondPumpElecNomPowerDes;
8197 48 : BaseSizer::reportSizerOutput(state,
8198 : thisDXCoil.DXCoilType,
8199 : thisDXCoil.Name,
8200 32 : format("Design Size Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
8201 : MSEvapCondPumpElecNomPowerDes);
8202 : } else {
8203 5 : if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) > 0.0 && MSEvapCondPumpElecNomPowerDes > 0.0 && !HardSizeNoDesRun) {
8204 2 : MSEvapCondPumpElecNomPowerUser = thisDXCoil.MSEvapCondPumpElecNomPower(Mode);
8205 6 : BaseSizer::reportSizerOutput(state,
8206 : thisDXCoil.DXCoilType,
8207 : thisDXCoil.Name,
8208 4 : format("Design Size Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
8209 : MSEvapCondPumpElecNomPowerDes,
8210 4 : format("User-Specified Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
8211 : MSEvapCondPumpElecNomPowerUser);
8212 2 : if (state.dataGlobal->DisplayExtraWarnings) {
8213 0 : if ((std::abs(MSEvapCondPumpElecNomPowerDes - MSEvapCondPumpElecNomPowerUser) / MSEvapCondPumpElecNomPowerUser) >
8214 0 : state.dataSize->AutoVsHardSizingThreshold) {
8215 0 : ShowMessage(
8216 0 : state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
8217 0 : ShowContinueError(state,
8218 0 : format("User-Specified Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]",
8219 : MSEvapCondPumpElecNomPowerUser));
8220 0 : ShowContinueError(state,
8221 0 : format("differs from Design Size Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]",
8222 : MSEvapCondPumpElecNomPowerDes));
8223 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8224 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8225 : }
8226 : }
8227 : }
8228 : }
8229 : }
8230 :
8231 : // Ensure evaporative condenser pump power at lower speed must be lower or equal to one at higher speed.
8232 21 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8233 11 : if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) > thisDXCoil.MSEvapCondPumpElecNomPower(Mode + 1)) {
8234 0 : ShowWarningError(state,
8235 0 : format("SizeDXCoil: {} {}, Speed {} Rated Evaporative Condenser Pump Power Consumption must be less than or "
8236 : "equal to Speed {} Rated Evaporative Condenser Pump Power Consumption.",
8237 0 : thisDXCoil.DXCoilType,
8238 0 : thisDXCoil.Name,
8239 : Mode,
8240 0 : Mode + 1));
8241 0 : ShowContinueError(
8242 : state,
8243 0 : format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSEvapCondPumpElecNomPower(Mode), thisDXCoil.MSEvapCondPumpElecNomPower(Mode + 1)));
8244 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8245 : }
8246 : }
8247 : }
8248 :
8249 : // Autosizing for multispeed heating coil
8250 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
8251 : // flow rate autosize
8252 23 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8253 16 : IsAutoSize = false;
8254 16 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) == AutoSize) {
8255 12 : IsAutoSize = true;
8256 : }
8257 16 : state.dataSize->DataIsDXCoil = true;
8258 16 : CompName = thisDXCoil.Name;
8259 16 : CompType = thisDXCoil.DXCoilType;
8260 : // Sizing rated air flow rate
8261 16 : if (Mode == thisDXCoil.NumOfSpeeds) {
8262 7 : FieldNum = 12 + (Mode - 1) * 6;
8263 7 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
8264 7 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8265 7 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
8266 7 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
8267 7 : bool errorsFound = false;
8268 7 : HeatingAirFlowSizer sizingHeatingAirFlow;
8269 7 : sizingHeatingAirFlow.overrideSizingString(SizingString);
8270 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8271 7 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8272 7 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
8273 7 : if (!IsAutoSize && !HardSizeNoDesRun) {
8274 0 : TempSize = AutoSize;
8275 0 : bPRINT = false;
8276 0 : errorsFound = false;
8277 0 : HeatingAirFlowSizer sizingHeatingAirFlow2;
8278 0 : sizingHeatingAirFlow2.overrideSizingString(SizingString);
8279 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8280 0 : sizingHeatingAirFlow2.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8281 0 : MSRatedAirVolFlowRateDes = sizingHeatingAirFlow2.size(state, TempSize, errorsFound);
8282 0 : bPRINT = true;
8283 0 : }
8284 7 : } else {
8285 9 : FieldNum = 12 + (Mode - 1) * 6;
8286 9 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
8287 9 : if (IsAutoSize || !HardSizeNoDesRun) {
8288 : // Auto-size low speed flow to fraction of the highest speed capacity
8289 7 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
8290 7 : if (!IsAutoSize && !HardSizeNoDesRun) state.dataSize->DataConstantUsedForSizing = MSRatedAirVolFlowRateDes;
8291 7 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8292 : }
8293 9 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8294 9 : bool errorsFound = false;
8295 9 : HeatingAirFlowSizer sizingHeatingAirFlow;
8296 9 : sizingHeatingAirFlow.overrideSizingString(SizingString);
8297 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8298 9 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8299 9 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
8300 9 : }
8301 16 : state.dataSize->DataEMSOverride = 0.0;
8302 16 : state.dataSize->DataEMSOverrideON = false;
8303 16 : state.dataSize->DataIsDXCoil = false;
8304 16 : state.dataSize->DataTotCapCurveIndex = 0;
8305 16 : state.dataSize->DataConstantUsedForSizing = 0.0;
8306 16 : state.dataSize->DataFractionUsedForSizing = 0.0;
8307 : }
8308 :
8309 : // Ensure flow rate at lower speed must be lower or equal to the flow rate at higher speed. Otherwise, a severe error is issued.
8310 16 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8311 9 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) > thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)) {
8312 0 : ShowWarningError(state,
8313 0 : format("SizeDXCoil: {} {}, Speed {} Rated Air Flow Rate must be less than or equal to Speed {} Rated Air Flow Rate.",
8314 0 : thisDXCoil.DXCoilType,
8315 0 : thisDXCoil.Name,
8316 : Mode,
8317 0 : Mode + 1));
8318 0 : ShowContinueError(
8319 0 : state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedAirVolFlowRate(Mode), thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)));
8320 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8321 : }
8322 : }
8323 : // Rated Secondary Coil Airflow Rates for AirCooled condenser type
8324 7 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
8325 0 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8326 0 : IsAutoSize = false;
8327 0 : if (thisDXCoil.MSSecCoilAirFlow(Mode) == AutoSize) {
8328 0 : IsAutoSize = true;
8329 : }
8330 : // Autosize Primary Coil air flow * Secondary Coil Scaling Factor
8331 0 : SecCoilAirFlowDes = thisDXCoil.MSRatedAirVolFlowRate(Mode) * thisDXCoil.MSSecCoilAirFlowScalingFactor(Mode);
8332 0 : if (IsAutoSize) {
8333 0 : thisDXCoil.MSSecCoilAirFlow(Mode) = SecCoilAirFlowDes;
8334 0 : BaseSizer::reportSizerOutput(state,
8335 : thisDXCoil.DXCoilType,
8336 : thisDXCoil.Name,
8337 0 : format("Design Size Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
8338 : SecCoilAirFlowDes);
8339 : } else {
8340 0 : if (thisDXCoil.MSSecCoilAirFlow(Mode) > 0.0 && SecCoilAirFlowDes > 0.0 && !HardSizeNoDesRun) {
8341 0 : SecCoilAirFlowUser = thisDXCoil.MSSecCoilAirFlow(Mode);
8342 0 : BaseSizer::reportSizerOutput(state,
8343 : thisDXCoil.DXCoilType,
8344 : thisDXCoil.Name,
8345 0 : format("Design Size Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
8346 : SecCoilAirFlowDes,
8347 0 : format("User-Specified Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
8348 : SecCoilAirFlowUser);
8349 0 : if (state.dataGlobal->DisplayExtraWarnings) {
8350 0 : if ((std::abs(SecCoilAirFlowDes - SecCoilAirFlowUser) / SecCoilAirFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
8351 0 : ShowMessage(
8352 : state,
8353 0 : format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
8354 0 : ShowContinueError(state, format("User-Specified Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowUser));
8355 0 : ShowContinueError(
8356 0 : state, format("differs from Design Size Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowDes));
8357 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8358 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8359 : }
8360 : }
8361 : }
8362 : }
8363 : }
8364 : }
8365 :
8366 : // Sizing rated total heating capacity
8367 23 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8368 16 : IsAutoSize = false;
8369 16 : if (thisDXCoil.MSRatedTotCap(Mode) == AutoSize) {
8370 12 : IsAutoSize = true;
8371 : }
8372 16 : state.dataSize->DataIsDXCoil = true;
8373 16 : CompName = thisDXCoil.Name;
8374 16 : CompType = thisDXCoil.DXCoilType;
8375 16 : if (Mode == thisDXCoil.NumOfSpeeds) {
8376 7 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8377 7 : FieldNum = 10 + (Mode - 1) * 6;
8378 7 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8379 7 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(Mode);
8380 7 : if (IsAutoSize || !HardSizeNoDesRun) {
8381 : // Heating capacity is assumed to be equal to the cooling capacity
8382 5 : PrintFlag = false;
8383 5 : state.dataSize->DataFractionUsedForSizing = 1.0;
8384 5 : if (thisDXCoil.CompanionUpstreamDXCoil > 0) {
8385 1 : NumOfSpeedCompanion = state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).NumOfSpeeds;
8386 1 : state.dataSize->DataConstantUsedForSizing =
8387 1 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).MSRatedTotCapDes(NumOfSpeedCompanion);
8388 : } else {
8389 4 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(1); // sized above
8390 : }
8391 5 : TempSize = DataSizing::AutoSize;
8392 5 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8393 5 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8394 5 : HeatingCapacitySizer sizerHeatingCapacity;
8395 5 : sizerHeatingCapacity.overrideSizingString(SizingString);
8396 5 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8397 5 : MSRatedTotCapDesAtMaxSpeed = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
8398 5 : state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8399 5 : state.dataSize->DataFractionUsedForSizing = 1.0;
8400 5 : }
8401 7 : PrintFlag = true;
8402 7 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8403 7 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8404 7 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8405 7 : HeatingCapacitySizer sizerHeatingCapacity;
8406 7 : sizerHeatingCapacity.overrideSizingString(SizingString);
8407 7 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8408 7 : TempSize = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
8409 7 : thisDXCoil.MSRatedTotCap(Mode) = TempSize;
8410 7 : if (IsAutoSize) {
8411 5 : MSRatedTotCapDesAtMaxSpeed = TempSize;
8412 : }
8413 7 : } else {
8414 9 : PrintFlag = true;
8415 9 : FieldNum = 10 + (Mode - 1) * 6;
8416 9 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8417 9 : if (IsAutoSize || !HardSizeNoDesRun) {
8418 : // autosize low speed capacity to fraction of the highest speed capacity
8419 7 : if (!HardSizeNoDesRun) {
8420 7 : state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8421 : } else {
8422 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
8423 : }
8424 7 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8425 : }
8426 9 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8427 9 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8428 9 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8429 9 : HeatingCapacitySizer sizerHeatingCapacity;
8430 9 : sizerHeatingCapacity.overrideSizingString(SizingString);
8431 9 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8432 9 : TempSize = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
8433 9 : thisDXCoil.MSRatedTotCap(Mode) = TempSize;
8434 9 : }
8435 16 : PrintFlag = false;
8436 16 : state.dataSize->DataEMSOverrideON = false;
8437 16 : state.dataSize->DataEMSOverride = 0.0;
8438 16 : state.dataSize->DataIsDXCoil = false;
8439 16 : state.dataSize->DataFlowUsedForSizing = 0.0;
8440 16 : state.dataSize->DataCoolCoilCap = 0.0;
8441 16 : state.dataSize->DataTotCapCurveIndex = 0;
8442 16 : state.dataSize->DataConstantUsedForSizing = 0.0;
8443 16 : state.dataSize->DataFractionUsedForSizing = 0.0;
8444 : }
8445 : // Ensure capacity at lower speed must be lower or equal to the capacity at higher speed.
8446 16 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8447 9 : if (thisDXCoil.MSRatedTotCap(Mode) > thisDXCoil.MSRatedTotCap(Mode + 1)) {
8448 0 : ShowWarningError(state,
8449 0 : format("SizeDXCoil: {} {}, Speed {} Rated Total Heating Capacity must be less than or equal to Speed {} Rated "
8450 : "Total Heating Capacity.",
8451 0 : thisDXCoil.DXCoilType,
8452 0 : thisDXCoil.Name,
8453 : Mode,
8454 0 : Mode + 1));
8455 0 : ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedTotCap(Mode), thisDXCoil.MSRatedTotCap(Mode + 1)));
8456 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8457 : }
8458 : }
8459 :
8460 : // Resistive Defrost Heater Capacity = capacity at the first stage
8461 : // Sizing defrost heater capacity
8462 7 : IsAutoSize = false;
8463 7 : if (thisDXCoil.DefrostCapacity == AutoSize) {
8464 6 : IsAutoSize = true;
8465 : }
8466 7 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
8467 2 : DefrostCapacityDes = thisDXCoil.MSRatedTotCap(1);
8468 : } else {
8469 5 : DefrostCapacityDes = 0.0;
8470 : }
8471 7 : if (IsAutoSize) {
8472 6 : thisDXCoil.DefrostCapacity = DefrostCapacityDes;
8473 6 : BaseSizer::reportSizerOutput(
8474 : state, thisDXCoil.DXCoilType, thisDXCoil.Name, "Design Size Resistive Defrost Heater Capacity", DefrostCapacityDes);
8475 : } else {
8476 1 : if (thisDXCoil.DefrostCapacity > 0.0 && DefrostCapacityDes > 0.0 && !HardSizeNoDesRun) {
8477 0 : DefrostCapacityUser = thisDXCoil.DefrostCapacity;
8478 0 : BaseSizer::reportSizerOutput(state,
8479 : thisDXCoil.DXCoilType,
8480 : thisDXCoil.Name,
8481 : "Design Size Resistive Defrost Heater Capacity",
8482 : DefrostCapacityDes,
8483 : "User-Specified Resistive Defrost Heater Capacity",
8484 : DefrostCapacityUser);
8485 0 : if (state.dataGlobal->DisplayExtraWarnings) {
8486 0 : if ((std::abs(DefrostCapacityDes - DefrostCapacityUser) / DefrostCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8487 0 : ShowWarningMessage(
8488 0 : state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
8489 0 : ShowContinueError(state, format("User-Specified Resistive Defrost Heater Capacity of {:.2R}[W]", DefrostCapacityUser));
8490 0 : ShowContinueError(state,
8491 0 : format("differs from Design Size Resistive Defrost Heater Capacity of {:.2R}[W]", DefrostCapacityDes));
8492 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8493 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8494 : }
8495 : }
8496 : }
8497 : }
8498 : }
8499 :
8500 : // Call routine that computes AHRI certified rating for single-speed DX Coils
8501 228 : if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed &&
8502 36 : (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air ||
8503 192 : thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap)) ||
8504 60 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
8505 82 : CalcDXCoilStandardRating(state,
8506 41 : thisDXCoil.Name,
8507 41 : thisDXCoil.DXCoilType,
8508 : thisDXCoil.DXCoilType_Num,
8509 : 1,
8510 41 : thisDXCoil.RatedTotCap(1),
8511 41 : thisDXCoil.RatedCOP(1),
8512 41 : thisDXCoil.CCapFFlow(1),
8513 41 : thisDXCoil.CCapFTemp(1),
8514 41 : thisDXCoil.EIRFFlow(1),
8515 41 : thisDXCoil.EIRFTemp(1),
8516 41 : thisDXCoil.PLFFPLR(1),
8517 41 : thisDXCoil.RatedAirVolFlowRate(1),
8518 41 : thisDXCoil.FanPowerPerEvapAirFlowRate(1),
8519 41 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1),
8520 41 : thisDXCoil.CondenserType,
8521 41 : thisDXCoil.RegionNum,
8522 41 : thisDXCoil.MinOATCompressor,
8523 41 : thisDXCoil.OATempCompressorOn,
8524 41 : thisDXCoil.OATempCompressorOnOffBlank,
8525 41 : thisDXCoil.DefrostControl,
8526 41 : thisDXCoil.ASHRAE127StdRprt);
8527 : }
8528 : // Call routine that computes AHRI certified rating for multi-speed DX cooling Coils
8529 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
8530 68 : CalcDXCoilStandardRating(state,
8531 17 : thisDXCoil.Name,
8532 17 : thisDXCoil.DXCoilType,
8533 : thisDXCoil.DXCoilType_Num,
8534 : thisDXCoil.NumOfSpeeds,
8535 : thisDXCoil.MSRatedTotCap,
8536 : thisDXCoil.MSRatedCOP,
8537 : thisDXCoil.MSCCapFFlow,
8538 : thisDXCoil.MSCCapFTemp,
8539 : thisDXCoil.MSEIRFFlow,
8540 : thisDXCoil.MSEIRFTemp,
8541 : thisDXCoil.MSPLFFPLR,
8542 : thisDXCoil.MSRatedAirVolFlowRate,
8543 : thisDXCoil.MSFanPowerPerEvapAirFlowRate,
8544 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023,
8545 17 : thisDXCoil.CondenserType,
8546 17 : thisDXCoil.RegionNum,
8547 17 : thisDXCoil.MinOATCompressor,
8548 17 : thisDXCoil.OATempCompressorOn,
8549 17 : thisDXCoil.OATempCompressorOnOffBlank,
8550 17 : thisDXCoil.DefrostControl,
8551 34 : ObjexxFCL::Optional_bool_const());
8552 : }
8553 :
8554 98 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed && (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air ||
8555 2 : thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap)) {
8556 8 : StandardRatings::CalcTwoSpeedDXCoilRating(state,
8557 4 : thisDXCoil.Name,
8558 4 : thisDXCoil.DXCoilType,
8559 : thisDXCoil.DXCoilType_Num,
8560 : thisDXCoil.RatedTotCap,
8561 : thisDXCoil.RatedTotCap2,
8562 : thisDXCoil.RatedCOP,
8563 : thisDXCoil.RatedCOP2,
8564 : thisDXCoil.CCapFFlow, // High Speed
8565 : thisDXCoil.CCapFTemp,
8566 : thisDXCoil.CCapFTemp2,
8567 : thisDXCoil.EIRFFlow, // High Speed
8568 : thisDXCoil.EIRFTemp,
8569 : thisDXCoil.EIRFTemp2,
8570 : thisDXCoil.RatedAirVolFlowRate,
8571 : thisDXCoil.RatedAirVolFlowRate2,
8572 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023,
8573 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023_LowSpeed,
8574 4 : thisDXCoil.CondenserType,
8575 4 : thisDXCoil.PLFFPLR(1));
8576 : }
8577 :
8578 : // create predefined report entries
8579 96 : equipName = thisDXCoil.Name;
8580 : // put tables for cooling and heating separate
8581 96 : switch (thisDXCoil.DXCoilType_Num) {
8582 50 : case HVAC::CoilDX_CoolingSingleSpeed:
8583 : case HVAC::CoilDX_CoolingTwoSpeed:
8584 : case HVAC::CoilDX_CoolingTwoStageWHumControl:
8585 : case HVAC::CoilDX_MultiSpeedCooling: {
8586 50 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilType, equipName, thisDXCoil.DXCoilType);
8587 50 : if (thisDXCoil.NumOfSpeeds == 0) {
8588 40 : if (thisDXCoil.NumCapacityStages == 1) {
8589 40 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.RatedTotCap(1));
8590 80 : PreDefTableEntry(
8591 40 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1));
8592 80 : PreDefTableEntry(state,
8593 40 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
8594 : equipName,
8595 40 : thisDXCoil.RatedTotCap(1) - thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1));
8596 40 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.RatedSHR(1));
8597 40 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.RatedCOP(1));
8598 : } else {
8599 0 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.RatedTotCap(2));
8600 0 : PreDefTableEntry(
8601 0 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.RatedTotCap(2) * thisDXCoil.RatedSHR(2));
8602 0 : PreDefTableEntry(state,
8603 0 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
8604 : equipName,
8605 0 : thisDXCoil.RatedTotCap(2) - thisDXCoil.RatedTotCap(2) * thisDXCoil.RatedSHR(2));
8606 0 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.RatedSHR(2));
8607 0 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.RatedCOP(2));
8608 : }
8609 : } else {
8610 31 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8611 21 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.MSRatedTotCap(Mode));
8612 42 : PreDefTableEntry(
8613 21 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.MSRatedTotCap(Mode) * thisDXCoil.MSRatedSHR(Mode));
8614 42 : PreDefTableEntry(state,
8615 21 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
8616 : equipName,
8617 21 : thisDXCoil.MSRatedTotCap(Mode) - thisDXCoil.MSRatedTotCap(Mode) * thisDXCoil.MSRatedSHR(Mode));
8618 21 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.MSRatedSHR(Mode));
8619 21 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.MSRatedCOP(Mode));
8620 : }
8621 : }
8622 100 : addFootNoteSubTable(state,
8623 50 : state.dataOutRptPredefined->pdstCoolCoil,
8624 : "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
8625 50 : } break;
8626 20 : case HVAC::CoilDX_HeatingEmpirical:
8627 : case HVAC::CoilDX_MultiSpeedHeating:
8628 : case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
8629 : case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
8630 20 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilType, equipName, thisDXCoil.DXCoilType);
8631 20 : if (thisDXCoil.NumOfSpeeds == 0) {
8632 13 : if (thisDXCoil.NumCapacityStages == 1) {
8633 13 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.RatedTotCap(1));
8634 13 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.RatedCOP(1));
8635 : } else {
8636 0 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.RatedTotCap(2));
8637 0 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.RatedCOP(2));
8638 : }
8639 : } else {
8640 23 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8641 16 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.MSRatedTotCap(Mode));
8642 16 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.MSRatedCOP(Mode));
8643 : }
8644 : }
8645 40 : addFootNoteSubTable(state,
8646 20 : state.dataOutRptPredefined->pdstHeatCoil,
8647 : "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
8648 :
8649 : // std 229 existing table DX Heating coil new reporting variables
8650 40 : OutputReportPredefined::PreDefTableEntry(
8651 20 : state, state.dataOutRptPredefined->pdchDXHeatCoilMinOADBTforCompOp, equipName, thisDXCoil.MinOATCompressor);
8652 40 : OutputReportPredefined::PreDefTableEntry(state,
8653 20 : state.dataOutRptPredefined->pdchDXHeatCoilAirloopName,
8654 : equipName,
8655 60 : thisDXCoil.AirLoopNum > 0 ? state.dataAirSystemsData->PrimaryAirSystems(thisDXCoil.AirLoopNum).Name
8656 : : "N/A");
8657 : // std 229 existing table DX Heating coil 2023 AHRI new reporting variables
8658 40 : OutputReportPredefined::PreDefTableEntry(
8659 20 : state, state.dataOutRptPredefined->pdchDXHeatCoilMinOADBTforCompOp_2023, equipName, thisDXCoil.MinOATCompressor);
8660 40 : OutputReportPredefined::PreDefTableEntry(state,
8661 20 : state.dataOutRptPredefined->pdchDXHeatCoilAirloopName_2023,
8662 : equipName,
8663 60 : thisDXCoil.AirLoopNum > 0 ? state.dataAirSystemsData->PrimaryAirSystems(thisDXCoil.AirLoopNum).Name
8664 : : "N/A");
8665 20 : } break;
8666 26 : default:
8667 26 : break;
8668 : }
8669 96 : }
8670 :
8671 178 : void CalcHPWHDXCoil(EnergyPlusData &state,
8672 : int const DXCoilNum, // the number of the DX coil to be simulated
8673 : Real64 const PartLoadRatio // sensible water heating load / full load sensible water heating capacity
8674 : )
8675 : {
8676 :
8677 : // SUBROUTINE INFORMATION:
8678 : // AUTHOR Richard Raustad
8679 : // DATE WRITTEN May 2005
8680 :
8681 : // PURPOSE OF THIS SUBROUTINE:
8682 : // Calculates the gross cooling capacity of a heat pump water heater evaporator and
8683 : // heating capacity of the condenser coil given the rated heating capacity and COP.
8684 :
8685 : // METHODOLOGY EMPLOYED:
8686 : // The routine requires the user to enter the total heating capacity and COP for the
8687 : // heat pump water heater along with logicals defining if fan and condenser pump are included.
8688 : // Since manufacturer's can rate their HPWH equipment with or without including condenser
8689 : // pump heat, this information is required to accurately determine the condenser's leaving
8690 : // water temperature. In addition, knowledge of the fan heat is required to back into
8691 : // a compressor COP.
8692 :
8693 : // Using/Aliasing
8694 : using Curve::CurveValue;
8695 :
8696 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8697 : Real64 RatedHeatingCapacity; // Water heating rated capacity with or without condenser water pump heat (W)
8698 : Real64 RatedHeatingCOP; // Water heating rated COP with or without evap fan and cond water pump heat (W/W)
8699 : Real64 OperatingHeatingCapacity; // Water heating operating capacity including the impact of capacity and COP curves (W)
8700 : Real64 OperatingHeatingCOP; // Water heating operating COP including the impact of capacity and COP curves (W/W)
8701 : Real64 OperatingHeatingPower; // Water heating operating Power (W)
8702 : Real64 CompressorPower; // Power consumed by compressor only (W)
8703 :
8704 : Real64 TotalTankHeatingCapacity; // Water heating capacity corrected for condenser water pump heat (W)
8705 : Real64 TankHeatingCOP; // Water heating COP corrected for fan and condenser water pump power (W/W)
8706 : // (these previous 2 variables also include the impact of capacity and COP curves)
8707 : Real64 EvapCoolingCapacity; // Air cooling capacity corrected for evap fan and cond water pump heat (W)
8708 : Real64 InletWaterTemp; // Condenser water inlet temperature (C)
8709 : Real64 OutletWaterTemp; // Condenser water outlet temperature (C)
8710 : Real64 EvapInletMassFlowRate; // Evaporator air inlet mass flow rate (m3/s)
8711 : Real64 CondInletMassFlowRate; // Condenser water inlet mass flow rate (m3/s)
8712 : Real64 CpWater; // Specific heat of condenser inlet water (J/Kg/k)
8713 : Real64 InletAirTemp; // HPWH inlet air temperature (dry-bulb or wet-bulb) (C)
8714 : Real64 HeatCapFTemp; // Output of HPWH Heating Capacity as a Function of Temperature curve
8715 : Real64 HeatCapFAirFlow; // Output of HPWH Heating Capacity as a Function of Air Flow Rate Ratio curve
8716 : Real64 HeatCapFWaterFlow; // Output of HPWH Heating Capacity as a Function of Water Flow Rate Ratio curve
8717 : Real64 HeatCOPFTemp; // Output of HPWH COP as a Function of Temperature curve
8718 : Real64 HeatCOPFAirFlow; // Output of HPWH COP as a Function of Air Flow Rate Ratio curve
8719 : Real64 HeatCOPFWaterFlow; // Output of HPWH COP as a Function of Water Flow Rate Ratio curve
8720 : Real64 AirFlowRateRatio; // Ratio of evaporator inlet air mass flow rate to rated mass flow rate
8721 : Real64 WaterFlowRateRatio; // Ratio of evaporator inlet water mass flow rate to rated mass flow rate
8722 : Real64 PartLoadFraction; // Output of Part Load Fraction as a Function of Part Load Ratio curve
8723 : Real64 PumpHeatToWater; // Amount of pump heat attributed to heating water
8724 : Real64 HPRTF; // Heat pump run time fraction
8725 :
8726 : // References to Coil and Node struct
8727 178 : DXCoilData &Coil = state.dataDXCoils->DXCoil(DXCoilNum);
8728 178 : NodeData &AirInletNode = state.dataLoopNodes->Node(Coil.AirInNode);
8729 178 : NodeData &WaterInletNode = state.dataLoopNodes->Node(Coil.WaterInNode);
8730 178 : NodeData &WaterOutletNode = state.dataLoopNodes->Node(Coil.WaterOutNode);
8731 :
8732 : // If heat pump water heater is OFF, set outlet to inlet and RETURN
8733 : // Also set the heating energy rate to zero
8734 178 : if (PartLoadRatio == 0.0) {
8735 8 : WaterOutletNode = WaterInletNode;
8736 8 : Coil.TotalHeatingEnergyRate = 0.0;
8737 8 : return;
8738 : } else {
8739 170 : RatedHeatingCapacity = Coil.RatedTotCap2;
8740 170 : RatedHeatingCOP = Coil.RatedCOP(1);
8741 170 : InletWaterTemp = WaterInletNode.Temp;
8742 170 : CondInletMassFlowRate = WaterInletNode.MassFlowRate / PartLoadRatio;
8743 170 : EvapInletMassFlowRate = AirInletNode.MassFlowRate / PartLoadRatio;
8744 170 : CpWater = CPHW(InletWaterTemp);
8745 170 : CompressorPower = 0.0;
8746 170 : OperatingHeatingPower = 0.0;
8747 170 : TankHeatingCOP = 0.0;
8748 : }
8749 :
8750 : // determine inlet air temperature type for curve objects
8751 170 : if (Coil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
8752 170 : InletAirTemp = state.dataHVACGlobal->HPWHInletWBTemp;
8753 : } else {
8754 0 : InletAirTemp = state.dataHVACGlobal->HPWHInletDBTemp;
8755 : }
8756 :
8757 : // get output of Heating Capacity and Heating COP curves (curves default to 1 if user has not specified curve name)
8758 170 : if (Coil.HCapFTemp > 0) {
8759 170 : if (state.dataCurveManager->curves(Coil.HCapFTemp)->numDims == 1) {
8760 0 : HeatCapFTemp = CurveValue(state, Coil.HCapFTemp, InletAirTemp);
8761 : } else {
8762 170 : HeatCapFTemp = CurveValue(state, Coil.HCapFTemp, InletAirTemp, InletWaterTemp);
8763 : }
8764 : // Warn user if curve output goes negative
8765 170 : if (HeatCapFTemp < 0.0) {
8766 0 : if (Coil.HCapFTempErrorIndex == 0) {
8767 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8768 0 : ShowContinueError(
8769 0 : state, format(" HPWH Heating Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", HeatCapFTemp));
8770 0 : if (state.dataCurveManager->curves(Coil.HCapFTemp)->numDims == 2) {
8771 0 : ShowContinueError(
8772 : state,
8773 0 : format(" Negative value occurs using an inlet air temperature of {:.1T} and an inlet water temperature of {:.1T}.",
8774 : InletAirTemp,
8775 : InletWaterTemp));
8776 : } else {
8777 0 : ShowContinueError(state, format(" Negative value occurs using an inlet air temperature of {:.1T}.", InletAirTemp));
8778 : }
8779 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8780 : }
8781 0 : ShowRecurringWarningErrorAtEnd(
8782 : state,
8783 0 : Coil.DXCoilType + " \"" + Coil.Name +
8784 : "\": HPWH Heating Capacity Modifier curve (function of temperature) output is negative warning continues...",
8785 0 : Coil.HCapFTempErrorIndex,
8786 : HeatCapFTemp,
8787 : HeatCapFTemp,
8788 : _,
8789 : "[C]",
8790 : "[C]");
8791 0 : HeatCapFTemp = 0.0;
8792 : }
8793 : } else {
8794 0 : HeatCapFTemp = 1.0;
8795 : }
8796 :
8797 170 : if (Coil.HCOPFTemp > 0) {
8798 170 : if (state.dataCurveManager->curves(Coil.HCOPFTemp)->numDims == 1) {
8799 0 : HeatCOPFTemp = CurveValue(state, Coil.HCOPFTemp, InletAirTemp);
8800 : } else {
8801 170 : HeatCOPFTemp = CurveValue(state, Coil.HCOPFTemp, InletAirTemp, InletWaterTemp);
8802 : }
8803 : // Warn user if curve output goes negative
8804 170 : if (HeatCOPFTemp < 0.0) {
8805 0 : if (Coil.HCOPFTempErrorIndex == 0) {
8806 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8807 0 : ShowContinueError(state,
8808 0 : format(" HPWH Heating COP Modifier curve (function of temperature) output is negative ({:.3T}).", HeatCOPFTemp));
8809 0 : if (state.dataCurveManager->curves(Coil.HCOPFTemp)->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 COP Modifier curve (function of temperature) output is negative warning continues...",
8824 0 : Coil.HCOPFTempErrorIndex,
8825 : HeatCOPFTemp,
8826 : HeatCOPFTemp,
8827 : _,
8828 : "[C]",
8829 : "[C]");
8830 0 : HeatCOPFTemp = 0.0;
8831 : }
8832 : } else {
8833 0 : HeatCOPFTemp = 1.0;
8834 : }
8835 :
8836 170 : if (Coil.HCapFAirFlow > 0) {
8837 0 : AirFlowRateRatio = EvapInletMassFlowRate / (Coil.RatedAirMassFlowRate(1));
8838 0 : HeatCapFAirFlow = CurveValue(state, Coil.HCapFAirFlow, AirFlowRateRatio);
8839 : // Warn user if curve output goes negative
8840 0 : if (HeatCapFAirFlow < 0.0) {
8841 0 : if (Coil.HCapFAirFlowErrorIndex == 0) {
8842 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8843 0 : ShowContinueError(
8844 : state,
8845 0 : format(" HPWH Heating Capacity Modifier curve (function of air flow fraction) output is negative ({:.3T}).", HeatCapFAirFlow));
8846 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirFlowRateRatio));
8847 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8848 : }
8849 0 : ShowRecurringWarningErrorAtEnd(
8850 : state,
8851 0 : Coil.DXCoilType + " \"" + Coil.Name +
8852 : "\": HPWH Heating Capacity Modifier curve (function of air flow fraction) output is negative warning continues...",
8853 0 : Coil.HCapFAirFlowErrorIndex,
8854 : HeatCapFAirFlow,
8855 : HeatCapFAirFlow);
8856 0 : HeatCapFAirFlow = 0.0;
8857 : }
8858 : } else {
8859 170 : HeatCapFAirFlow = 1.0;
8860 : }
8861 :
8862 170 : if (Coil.HCOPFAirFlow > 0) {
8863 0 : AirFlowRateRatio = EvapInletMassFlowRate / (Coil.RatedAirMassFlowRate(1));
8864 0 : HeatCOPFAirFlow = CurveValue(state, Coil.HCOPFAirFlow, AirFlowRateRatio);
8865 : // Warn user if curve output goes negative
8866 0 : if (HeatCOPFAirFlow < 0.0) {
8867 0 : if (Coil.HCOPFAirFlowErrorIndex == 0) {
8868 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8869 0 : ShowContinueError(
8870 0 : state, format(" HPWH Heating COP Modifier curve (function of air flow fraction) output is negative ({:.3T}).", HeatCOPFAirFlow));
8871 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirFlowRateRatio));
8872 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8873 : }
8874 0 : ShowRecurringWarningErrorAtEnd(
8875 : state,
8876 0 : Coil.DXCoilType + " \"" + Coil.Name +
8877 : "\": HPWH Heating COP Modifier curve (function of air flow fraction) output is negative warning continues...",
8878 0 : Coil.HCOPFAirFlowErrorIndex,
8879 : HeatCOPFAirFlow,
8880 : HeatCOPFAirFlow);
8881 0 : HeatCOPFAirFlow = 0.0;
8882 : }
8883 : } else {
8884 170 : HeatCOPFAirFlow = 1.0;
8885 : }
8886 :
8887 170 : if (Coil.HCapFWaterFlow > 0) {
8888 0 : WaterFlowRateRatio = CondInletMassFlowRate / (Coil.RatedHPWHCondWaterFlow * RhoH2O(InletWaterTemp));
8889 0 : HeatCapFWaterFlow = CurveValue(state, Coil.HCapFWaterFlow, WaterFlowRateRatio);
8890 : // Warn user if curve output goes negative
8891 0 : if (HeatCapFWaterFlow < 0.0) {
8892 0 : if (Coil.HCapFWaterFlowErrorIndex == 0) {
8893 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8894 0 : ShowContinueError(state,
8895 0 : format(" HPWH Heating Capacity Modifier curve (function of water flow fraction) output is negative ({:.3T}).",
8896 : HeatCapFWaterFlow));
8897 0 : ShowContinueError(state, format(" Negative value occurs using a water flow fraction of {:.3T}.", WaterFlowRateRatio));
8898 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8899 : }
8900 0 : ShowRecurringWarningErrorAtEnd(
8901 : state,
8902 0 : Coil.DXCoilType + " \"" + Coil.Name +
8903 : "\": HPWH Heating Capacity Modifier curve (function of water flow fraction) output is negative warning continues...",
8904 0 : Coil.HCapFWaterFlowErrorIndex,
8905 : HeatCapFWaterFlow,
8906 : HeatCapFWaterFlow);
8907 0 : HeatCapFWaterFlow = 0.0;
8908 : }
8909 : } else {
8910 170 : HeatCapFWaterFlow = 1.0;
8911 : }
8912 :
8913 170 : if (Coil.HCOPFWaterFlow > 0) {
8914 0 : WaterFlowRateRatio = CondInletMassFlowRate / (Coil.RatedHPWHCondWaterFlow * RhoH2O(InletWaterTemp));
8915 0 : HeatCOPFWaterFlow = CurveValue(state, Coil.HCOPFWaterFlow, WaterFlowRateRatio);
8916 : // Warn user if curve output goes negative
8917 0 : if (HeatCOPFWaterFlow < 0.0) {
8918 0 : if (Coil.HCOPFWaterFlowErrorIndex == 0) {
8919 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8920 0 : ShowContinueError(
8921 : state,
8922 0 : format(" HPWH Heating COP Modifier curve (function of water flow fraction) output is negative ({:.3T}).", HeatCOPFWaterFlow));
8923 0 : ShowContinueError(state, format(" Negative value occurs using a water flow fraction of {:.3T}.", WaterFlowRateRatio));
8924 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8925 : }
8926 0 : ShowRecurringWarningErrorAtEnd(
8927 : state,
8928 0 : Coil.DXCoilType + " \"" + Coil.Name +
8929 : "\": HPWH Heating COP Modifier curve (function of water flow fraction) output is negative warning continues...",
8930 0 : Coil.HCOPFWaterFlowErrorIndex,
8931 : HeatCOPFWaterFlow,
8932 : HeatCOPFWaterFlow);
8933 0 : HeatCOPFWaterFlow = 0.0;
8934 : }
8935 : } else {
8936 170 : HeatCOPFWaterFlow = 1.0;
8937 : }
8938 :
8939 : // adjust Heating Capacity and COP for off-design conditions
8940 170 : OperatingHeatingCapacity = RatedHeatingCapacity * HeatCapFTemp * HeatCapFAirFlow * HeatCapFWaterFlow;
8941 170 : OperatingHeatingCOP = RatedHeatingCOP * HeatCOPFTemp * HeatCOPFAirFlow * HeatCOPFWaterFlow;
8942 :
8943 170 : if (OperatingHeatingCOP > 0.0) OperatingHeatingPower = OperatingHeatingCapacity / OperatingHeatingCOP;
8944 :
8945 170 : PumpHeatToWater = Coil.HPWHCondPumpElecNomPower * Coil.HPWHCondPumpFracToWater;
8946 170 : TankHeatingCOP = OperatingHeatingCOP;
8947 :
8948 : // account for pump heat if not included in total water heating capacity
8949 170 : if (Coil.CondPumpHeatInCapacity) {
8950 0 : TotalTankHeatingCapacity = OperatingHeatingCapacity;
8951 : } else {
8952 170 : TotalTankHeatingCapacity = OperatingHeatingCapacity + PumpHeatToWater;
8953 : }
8954 :
8955 : // find part load fraction to calculate RTF
8956 170 : if (Coil.PLFFPLR(1) > 0) {
8957 162 : PartLoadFraction = max(0.7, CurveValue(state, Coil.PLFFPLR(1), PartLoadRatio));
8958 : } else {
8959 8 : PartLoadFraction = 1.0;
8960 : }
8961 :
8962 170 : HPRTF = min(1.0, (PartLoadRatio / PartLoadFraction));
8963 :
8964 170 : Real64 locFanElecPower = state.dataFans->fans(Coil.SupplyFanIndex)->totalPower;
8965 :
8966 : // calculate evaporator total cooling capacity
8967 170 : if (HPRTF > 0.0) {
8968 170 : if (Coil.FanPowerIncludedInCOP) {
8969 8 : if (Coil.CondPumpPowerInCOP) {
8970 : // make sure fan power is full load fan power
8971 0 : CompressorPower = OperatingHeatingPower - locFanElecPower / HPRTF - Coil.HPWHCondPumpElecNomPower;
8972 0 : if (OperatingHeatingPower > 0.0) TankHeatingCOP = TotalTankHeatingCapacity / OperatingHeatingPower;
8973 : } else {
8974 8 : CompressorPower = OperatingHeatingPower - locFanElecPower / HPRTF;
8975 8 : if ((OperatingHeatingPower + Coil.HPWHCondPumpElecNomPower) > 0.0)
8976 8 : TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + Coil.HPWHCondPumpElecNomPower);
8977 : }
8978 : } else {
8979 162 : if (Coil.CondPumpPowerInCOP) {
8980 : // make sure fan power is full load fan power
8981 0 : CompressorPower = OperatingHeatingPower - Coil.HPWHCondPumpElecNomPower;
8982 0 : if ((OperatingHeatingPower + locFanElecPower / HPRTF) > 0.0)
8983 0 : TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + locFanElecPower / HPRTF);
8984 : } else {
8985 162 : CompressorPower = OperatingHeatingPower;
8986 162 : if ((OperatingHeatingPower + locFanElecPower / HPRTF + Coil.HPWHCondPumpElecNomPower) > 0.0)
8987 162 : TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + locFanElecPower / HPRTF + Coil.HPWHCondPumpElecNomPower);
8988 : }
8989 : }
8990 : }
8991 :
8992 170 : if (Coil.CondPumpHeatInCapacity) {
8993 0 : EvapCoolingCapacity = TotalTankHeatingCapacity - PumpHeatToWater - CompressorPower;
8994 : } else {
8995 170 : EvapCoolingCapacity = TotalTankHeatingCapacity - CompressorPower;
8996 : }
8997 :
8998 : // set evaporator total cooling capacity prior to CalcDOE2DXCoil subroutine
8999 170 : Coil.RatedTotCap(1) = EvapCoolingCapacity;
9000 :
9001 : // determine condenser water inlet/outlet condition at full capacity
9002 170 : if (CondInletMassFlowRate == 0.0) {
9003 8 : OutletWaterTemp = InletWaterTemp;
9004 : } else {
9005 162 : OutletWaterTemp = InletWaterTemp + TotalTankHeatingCapacity / (CpWater * CondInletMassFlowRate);
9006 : }
9007 :
9008 170 : WaterOutletNode.Temp = OutletWaterTemp;
9009 :
9010 170 : WaterOutletNode.MassFlowRate = WaterInletNode.MassFlowRate;
9011 :
9012 : // send heating capacity and COP to water heater module for standards rating calculation
9013 : // total heating capacity including condenser pump
9014 170 : state.dataDXCoils->HPWHHeatingCapacity = TotalTankHeatingCapacity;
9015 : // total heating COP including compressor, fan, and condenser pump
9016 170 : state.dataDXCoils->HPWHHeatingCOP = TankHeatingCOP;
9017 :
9018 : // send DX coil total cooling capacity to HPWH for reporting
9019 170 : state.dataHVACGlobal->DXCoilTotalCapacity = EvapCoolingCapacity;
9020 :
9021 170 : Coil.TotalHeatingEnergyRate = TotalTankHeatingCapacity * PartLoadRatio;
9022 :
9023 : // calculate total compressor plus condenser pump power, fan power reported in fan module
9024 170 : Coil.ElecWaterHeatingPower = (CompressorPower + Coil.HPWHCondPumpElecNomPower) * HPRTF;
9025 : }
9026 :
9027 331312 : void CalcDoe2DXCoil(EnergyPlusData &state,
9028 : int const DXCoilNum, // the number of the DX coil to be simulated
9029 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
9030 : bool const FirstHVACIteration, // true if this is the first iteration of HVAC
9031 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
9032 : HVAC::FanOp const fanOp, // Allows parent object to control fan operation
9033 : ObjexxFCL::Optional_int_const PerfMode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
9034 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
9035 : ObjexxFCL::Optional<Real64 const> CoolingHeatingPLR // used for cycling fan RH control
9036 : )
9037 : {
9038 :
9039 : // SUBROUTINE INFORMATION:
9040 : // AUTHOR Fred Buhl
9041 : // DATE WRITTEN May 2000
9042 : // MODIFIED Shirey, Feb/October 2001, Feb/Mar 2004
9043 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
9044 : // Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
9045 : // April 2010 Chandan Sharma, FSEC, Added basin heater
9046 : // RE-ENGINEERED Don Shirey, Aug/Sept 2000
9047 :
9048 : // PURPOSE OF THIS SUBROUTINE:
9049 : // Calculates the air-side performance and electrical energy use of a direct-
9050 : // expansion, air-cooled cooling unit.
9051 :
9052 : // METHODOLOGY EMPLOYED:
9053 : // This routine simulates the performance of air-cooled DX cooling equipment.
9054 : // The routine requires the user to enter the total cooling capacity, sensible heat ratio,
9055 : // and COP for the unit at ARI 210/240 rating conditions (26.67C [80F] dry-bulb, 19.44C [67F]
9056 : // wet-bulb air entering the cooling coil, 35C [95F] dry-bulb air entering the outdoor
9057 : // condenser. Since different manufacturer's rate their equipment at different air flow rates,
9058 : // the supply air flow rate corresponding to the rated capacities and rated COP must also be
9059 : // entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information entered by
9060 : // the user should NOT include the thermal or electrical impacts of the supply air fan, as
9061 : // this is addressed by another module.
9062 :
9063 : // With the rated performance data entered by the user, the model employs some of the
9064 : // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
9065 : // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
9066 : // does NOT employ the exact same methodology to calculate performance as DOE-2, although
9067 : // some of the DOE-2 curve fits are employed by this model.
9068 :
9069 : // The model checks for coil dryout conditions, and adjusts the calculated performance
9070 : // appropriately.
9071 :
9072 : // REFERENCES:
9073 : // ASHRAE HVAC 2 Toolkit page 4-81.
9074 : // Henderson, H.I. Jr., K. Rengarajan and D.B. Shirey, III. 1992.The impact of comfort
9075 : // control on air conditioner energy use in humid climates. ASHRAE Transactions 98(2):
9076 : // 104-113.
9077 : // Henderson, H.I. Jr., Danny Parker and Y.J. Huang. 2000.Improving DOE-2's RESYS routine:
9078 : // User Defined Functions to Provide More Accurate Part Load Energy Use and Humidity
9079 : // Predictions. Proceedings of ACEEE Conference.
9080 :
9081 : // Using/Aliasing
9082 : using Curve::CurveValue;
9083 331312 : Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
9084 331312 : Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
9085 : using General::CreateSysTimeIntervalString;
9086 :
9087 : // SUBROUTINE PARAMETER DEFINITIONS:
9088 : static constexpr std::string_view RoutineName("CalcDoe2DXCoil: ");
9089 : static constexpr std::string_view calcDoe2DXCoil("CalcDoe2DXCoil");
9090 :
9091 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9092 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
9093 : Real64 AirMassFlowRatio; // Ratio of actual air mass flow to rated air mass flow (adjusted for bypass if any)
9094 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
9095 : // (average flow if cycling fan, full flow if constant fan)
9096 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
9097 : Real64 BypassFlowFraction; // Fraction of total flow which is bypassed around the cooling coil
9098 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
9099 : Real64 TotCapTempModFac; // Total capacity modifier (function of entering wetbulb, outside drybulb)
9100 : Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs rated flow)
9101 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
9102 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
9103 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
9104 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
9105 : Real64 InletAirHumRatTemp; // inlet air humidity ratio used in ADP/BF loop [kg/kg]
9106 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9107 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
9108 : Real64 RatedCBF; // coil bypass factor at rated conditions
9109 : Real64 SHR; // Sensible Heat Ratio (sensible/total) of the cooling coil
9110 : Real64 CBF; // coil bypass factor at off rated conditions
9111 : Real64 A0; // NTU * air mass flow rate, used in CBF calculation
9112 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
9113 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
9114 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
9115 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
9116 : Real64 tADP; // Apparatus dew point temperature [C]
9117 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
9118 : Real64 FullLoadOutAirEnth; // outlet full load enthalpy [J/kg]
9119 : Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
9120 : Real64 FullLoadOutAirTemp; // outlet air temperature at full load [C]
9121 : Real64 EIRTempModFac; // EIR modifier (function of entering wetbulb, outside drybulb)
9122 : Real64 EIRFlowModFac; // EIR modifier (function of actual supply air flow vs rated flow)
9123 : Real64 EIR; // EIR at part load and off rated conditions
9124 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
9125 : Real64 QLatActual; // operating latent capacity of DX coil
9126 : Real64 QLatRated; // Rated latent capacity of DX coil
9127 : Real64 SHRUnadjusted; // SHR prior to latent degradation effective SHR calculation
9128 : int Counter; // Counter for dry evaporator iterations
9129 : int MaxIter; // Maximum number of iterations for dry evaporator calculations
9130 : Real64 RF; // Relaxation factor for dry evaporator iterations
9131 : Real64 Tolerance; // Error tolerance for dry evaporator iterations
9132 : Real64 werror; // Deviation of humidity ratio in dry evaporator iteration loop
9133 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
9134 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
9135 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
9136 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
9137 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
9138 : Real64 RhoAir; // Density of air [kg/m3]
9139 : Real64 RhoWater; // Density of water [kg/m3]
9140 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
9141 331312 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
9142 : Real64 AirFlowRatio; // ratio of compressor on airflow to average timestep airflow
9143 : // used when constant fan mode yields different air flow rates when compressor is ON and OFF
9144 : // (e.g. Packaged Terminal Heat Pump)
9145 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
9146 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
9147 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
9148 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
9149 :
9150 : int Mode; // Performance mode for Multimode DX coil; Always 1 for other coil types
9151 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
9152 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
9153 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
9154 : Real64 ADiff; // Used for exponential
9155 : Real64 DXcoolToHeatPLRRatio; // ratio of cooling PLR to heating PLR, used for cycling fan RH control
9156 : Real64 HeatRTF; // heating coil part-load ratio, used for cycling fan RH control
9157 : Real64 HeatingCoilPLF; // heating coil PLF (function of PLR), used for cycling fan RH control
9158 :
9159 : // If Performance mode not present, then set to 1. Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
9160 331312 : if (present(PerfMode)) {
9161 0 : Mode = PerfMode;
9162 : } else {
9163 331312 : Mode = 1;
9164 : }
9165 :
9166 : // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
9167 : // during cooling and when no cooling is required (constant fan, fan speed changes)
9168 331312 : if (present(OnOffAirFlowRatio)) {
9169 247143 : AirFlowRatio = OnOffAirFlowRatio;
9170 : } else {
9171 84169 : AirFlowRatio = 1.0;
9172 : }
9173 :
9174 : // If CoolingHeatingPLR not present, then set to 1. Used for cycling fan systems where
9175 : // heating PLR is greater than cooling PLR, otherwise CoolingHeatingPLR = 1.
9176 331312 : if (present(CoolingHeatingPLR)) {
9177 59945 : DXcoolToHeatPLRRatio = CoolingHeatingPLR;
9178 : } else {
9179 271367 : DXcoolToHeatPLRRatio = 1.0;
9180 : }
9181 :
9182 331312 : MaxIter = 30;
9183 331312 : RF = 0.4;
9184 331312 : Counter = 0;
9185 331312 : Tolerance = 0.01;
9186 331312 : CondInletTemp = 0.0;
9187 331312 : CondInletHumRat = 0.0;
9188 :
9189 331312 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
9190 :
9191 331312 : BypassFlowFraction = thisDXCoil.BypassedFlowFrac(Mode);
9192 331312 : AirMassFlow = thisDXCoil.InletAirMassFlowRate * (1.0 - BypassFlowFraction);
9193 331312 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
9194 331312 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
9195 331312 : InletAirHumRat = thisDXCoil.InletAirHumRat;
9196 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9197 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
9198 331312 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
9199 331312 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
9200 331312 : thisDXCoil.PartLoadRatio = 0.0;
9201 331312 : thisDXCoil.BasinHeaterPower = 0.0;
9202 :
9203 331312 : if (thisDXCoil.CondenserType(Mode) != DataHeatBalance::RefrigCondenserType::WaterHeater) {
9204 331149 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
9205 117452 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
9206 : // If node is not connected to anything, pressure = default, use weather data
9207 117452 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
9208 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
9209 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
9210 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9211 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
9212 : } else {
9213 117452 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
9214 117452 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
9215 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
9216 117452 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
9217 : }
9218 : } else {
9219 213697 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
9220 213697 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
9221 213697 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9222 213697 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
9223 : }
9224 331149 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
9225 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
9226 0 : OutdoorDryBulb = secZoneHB.ZT;
9227 0 : OutdoorHumRat = secZoneHB.airHumRat;
9228 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
9229 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9230 : }
9231 : } else {
9232 163 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
9233 163 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
9234 : // If node is not connected to anything, pressure = default, use weather data
9235 163 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press)
9236 163 : OutdoorPressure = state.dataEnvrn->OutBaroPress; // node not connected
9237 : } else {
9238 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9239 : }
9240 : }
9241 :
9242 331312 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
9243 263297 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
9244 263297 : CompAmbTemp = OutdoorDryBulb;
9245 263297 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
9246 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
9247 0 : CondInletTemp = secZoneHB.ZT;
9248 0 : CompAmbTemp = CondInletTemp; // assumes compressor is in same location as secondary coil
9249 0 : OutdoorDryBulb = CondInletTemp;
9250 0 : OutdoorHumRat = secZoneHB.airHumRat;
9251 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
9252 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9253 : }
9254 68015 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
9255 67852 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
9256 67852 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
9257 : // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
9258 67852 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
9259 67852 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
9260 67852 : CompAmbTemp = OutdoorDryBulb;
9261 163 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::WaterHeater) {
9262 163 : CompAmbTemp = state.dataHVACGlobal->HPWHCrankcaseDBTemp; // Temperature at HP water heater compressor
9263 163 : CondInletTemp = state.dataHVACGlobal->HPWHCrankcaseDBTemp; // Temperature at HP water heater compressor
9264 : }
9265 :
9266 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
9267 : // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
9268 331312 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
9269 82507 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
9270 82507 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
9271 3 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
9272 : }
9273 : } else {
9274 248805 : CrankcaseHeatingPower = 0.0;
9275 : }
9276 :
9277 : // calculate end time of current time step to determine if error messages should be printed
9278 331312 : state.dataDXCoils->CurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
9279 :
9280 : // Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
9281 : // Wait for next time step to print warnings. If simulation iterates, print out
9282 : // the warning for the last iteration only. Must wait for next time step to accomplish this.
9283 : // If a warning occurs and the simulation down shifts, the warning is not valid.
9284 :
9285 331312 : if (thisDXCoil.PrintLowAmbMessage) { // .AND. &
9286 240 : if (state.dataDXCoils->CurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
9287 0 : if (thisDXCoil.LowAmbErrIndex == 0) {
9288 0 : ShowWarningMessage(state, format("{}{}", RoutineName, thisDXCoil.LowAmbBuffer1));
9289 0 : ShowContinueError(state, thisDXCoil.LowAmbBuffer2);
9290 0 : ShowContinueError(state, "... Operation at low ambient temperatures may require special performance curves.");
9291 : }
9292 0 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
9293 0 : ShowRecurringWarningErrorAtEnd(state,
9294 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9295 : "\" - Low condenser dry-bulb temperature error continues...",
9296 0 : thisDXCoil.LowAmbErrIndex,
9297 0 : thisDXCoil.LowTempLast,
9298 0 : thisDXCoil.LowTempLast,
9299 : _,
9300 : "[C]",
9301 : "[C]");
9302 : } else {
9303 0 : ShowRecurringWarningErrorAtEnd(state,
9304 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9305 : "\" - Low condenser wet-bulb temperature error continues...",
9306 0 : thisDXCoil.LowAmbErrIndex,
9307 0 : thisDXCoil.LowTempLast,
9308 0 : thisDXCoil.LowTempLast,
9309 : _,
9310 : "[C]",
9311 : "[C]");
9312 : }
9313 : }
9314 : }
9315 :
9316 331312 : if (thisDXCoil.PrintLowOutTempMessage) {
9317 1017 : if (state.dataDXCoils->CurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
9318 376 : if (thisDXCoil.LowOutletTempIndex == 0) {
9319 4 : ShowWarningMessage(state, format("{}{}", RoutineName, thisDXCoil.LowOutTempBuffer1));
9320 4 : ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
9321 8 : ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
9322 8 : ShowContinueError(state,
9323 8 : format(" 1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
9324 4 : thisDXCoil.FullLoadInletAirTempLast));
9325 8 : ShowContinueError(state, " 2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
9326 12 : ShowContinueError(state,
9327 : " 3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
9328 : }
9329 3008 : ShowRecurringWarningErrorAtEnd(state,
9330 1128 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9331 : "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
9332 : "Outlet air temperature statistics follow:",
9333 376 : thisDXCoil.LowOutletTempIndex,
9334 376 : thisDXCoil.FullLoadOutAirTempLast,
9335 376 : thisDXCoil.FullLoadOutAirTempLast);
9336 : }
9337 : }
9338 :
9339 : // save last system time step and last end time of current time step (used to determine if warning is valid)
9340 331312 : thisDXCoil.TimeStepSysLast = TimeStepSys;
9341 331312 : thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CurrentEndTime;
9342 331312 : thisDXCoil.PrintLowAmbMessage = false;
9343 331312 : thisDXCoil.PrintLowOutTempMessage = false;
9344 :
9345 269753 : if ((AirMassFlow > 0.0) &&
9346 269908 : (thisDXCoil.availSched->getCurrentVal() > 0.0 || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9347 3 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
9348 771102 : (PartLoadRatio > 0.0) && (compressorOp == HVAC::CompressorOp::On) &&
9349 170037 : CompAmbTemp > thisDXCoil.MinOATCompressor) { // criteria for coil operation
9350 170031 : if (fanOp == HVAC::FanOp::Cycling) {
9351 57669 : AirMassFlow /= (PartLoadRatio / DXcoolToHeatPLRRatio);
9352 112362 : } else if (fanOp == HVAC::FanOp::Continuous && thisDXCoil.DXCoilType_Num != HVAC::CoilDX_CoolingTwoSpeed) {
9353 112362 : AirMassFlow *= AirFlowRatio;
9354 : } else {
9355 0 : AirMassFlow = thisDXCoil.RatedAirMassFlowRate(Mode);
9356 : }
9357 :
9358 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton)
9359 :
9360 : // for some reason there are diff's when using coil inlet air pressure
9361 : // these lines (more to follow) are commented out for the time being
9362 :
9363 170031 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
9364 170031 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
9365 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9366 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
9367 : // AirVolumeFlowRate = AirMassFlow/ PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
9368 170031 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
9369 0 : ShowFatalError(
9370 0 : state, format("{}{}=\"{}\" - Rated total cooling capacity is zero or less.", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9371 : }
9372 170031 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9373 169884 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9374 147 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap2;
9375 : } else {
9376 169884 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
9377 : }
9378 81326 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag && thisDXCoil.DXCoilType_Num != HVAC::CoilDX_HeatPumpWaterHeaterPumped &&
9379 263161 : thisDXCoil.DXCoilType_Num != HVAC::CoilDX_HeatPumpWaterHeaterWrapped &&
9380 11804 : ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
9381 10710 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
9382 1095 : if (thisDXCoil.ErrIndex1 == 0) {
9383 8 : ShowWarningMessage(
9384 : state,
9385 8 : format("{}{}=\"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at {:.3R} m3/s/W.",
9386 : RoutineName,
9387 4 : thisDXCoil.DXCoilType,
9388 4 : thisDXCoil.Name,
9389 : VolFlowperRatedTotCap));
9390 8 : ShowContinueErrorTimeStamp(state, "");
9391 8 : ShowContinueError(state,
9392 8 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
9393 4 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
9394 4 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
9395 8 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components,");
9396 12 : ShowContinueError(state, "or variable air volume [VAV] system using incorrect coil type.");
9397 : }
9398 8760 : ShowRecurringWarningErrorAtEnd(
9399 : state,
9400 3285 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9401 : "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
9402 1095 : thisDXCoil.ErrIndex1,
9403 : VolFlowperRatedTotCap,
9404 : VolFlowperRatedTotCap);
9405 168936 : } else if (!state.dataGlobal->WarmupFlag &&
9406 22954 : (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9407 191890 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
9408 49 : ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
9409 49 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
9410 0 : if (thisDXCoil.ErrIndex1 == 0) {
9411 0 : ShowWarningMessage(
9412 : state,
9413 0 : format("{}{}=\"{}\" - Air volume flow rate per watt of rated total water heating capacity is out of range at {:.2R} m3/s/W.",
9414 : RoutineName,
9415 0 : thisDXCoil.DXCoilType,
9416 0 : thisDXCoil.Name,
9417 : VolFlowperRatedTotCap));
9418 0 : ShowContinueErrorTimeStamp(state, "");
9419 0 : ShowContinueError(state,
9420 0 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
9421 0 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
9422 0 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
9423 0 : ShowContinueError(state,
9424 : "Possible causes may be that the parent object is calling for an actual supply air flow rate that is much "
9425 : "higher or lower than the DX coil rated supply air flow rate.");
9426 : }
9427 0 : ShowRecurringWarningErrorAtEnd(
9428 : state,
9429 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9430 : "\" - Air volume flow rate per watt of rated total water heating capacity is out of range error continues...",
9431 0 : thisDXCoil.ErrIndex1,
9432 : VolFlowperRatedTotCap,
9433 : VolFlowperRatedTotCap);
9434 : }
9435 : // Adjust coil bypass factor for actual air flow rate. Use relation CBF = exp(-NTU) where
9436 : // NTU = A0/(m*cp). Relationship models the cooling coil as a heat exchanger with Cmin/Cmax = 0.
9437 :
9438 170031 : RatedCBF = thisDXCoil.RatedCBF(Mode);
9439 170031 : if (RatedCBF > 0.0) {
9440 170031 : A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
9441 : } else {
9442 0 : A0 = 0.0;
9443 : }
9444 170031 : ADiff = -A0 / AirMassFlow;
9445 170031 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
9446 166270 : CBF = std::exp(ADiff);
9447 : } else {
9448 3761 : CBF = 0.0;
9449 : }
9450 :
9451 : // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
9452 170031 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
9453 127084 : if (OutdoorDryBulb < 0.0 && !state.dataGlobal->WarmupFlag) { // Same threshold as for air-cooled electric chiller
9454 0 : thisDXCoil.PrintLowAmbMessage = true;
9455 0 : thisDXCoil.LowTempLast = OutdoorDryBulb;
9456 0 : if (thisDXCoil.LowAmbErrIndex == 0) {
9457 : thisDXCoil.LowAmbBuffer1 =
9458 0 : format("{} \"{}\" - Air-cooled condenser inlet dry-bulb temperature below 0 C. Outdoor dry-bulb temperature = {:.2R}",
9459 0 : thisDXCoil.DXCoilType,
9460 0 : thisDXCoil.Name,
9461 0 : OutdoorDryBulb);
9462 0 : thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
9463 0 : CreateSysTimeIntervalString(state);
9464 : }
9465 : }
9466 42947 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
9467 42800 : if (OutdoorWetBulb < 10.0 && !state.dataGlobal->WarmupFlag) { // Same threshold as for evap-cooled electric chiller
9468 240 : thisDXCoil.PrintLowAmbMessage = true;
9469 240 : thisDXCoil.LowTempLast = OutdoorWetBulb;
9470 240 : if (thisDXCoil.LowAmbErrIndex == 0) {
9471 : thisDXCoil.LowAmbBuffer1 =
9472 480 : format("{} \"{}\" - Evap-cooled condenser inlet wet-bulb temperature below 10 C. Outdoor wet-bulb temperature = {:.2R}",
9473 240 : thisDXCoil.DXCoilType,
9474 240 : thisDXCoil.Name,
9475 240 : OutdoorWetBulb);
9476 480 : thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
9477 720 : CreateSysTimeIntervalString(state);
9478 : }
9479 : }
9480 : }
9481 :
9482 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
9483 : // InletAirHumRat may be modified in this ADP/BF loop, use temporary variable for calculations
9484 170031 : InletAirHumRatTemp = InletAirHumRat;
9485 170031 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
9486 : while (true) {
9487 199692 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9488 199545 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9489 : // Coil:DX:HeatPumpWaterHeater does not have total cooling capacity as a function of temp or flow curve
9490 147 : TotCapTempModFac = 1.0;
9491 147 : TotCapFlowModFac = 1.0;
9492 : } else {
9493 199545 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
9494 199504 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC, CondInletTemp);
9495 : } else {
9496 41 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), CondInletTemp);
9497 : }
9498 :
9499 : // Warn user if curve output goes negative
9500 199545 : if (TotCapTempModFac < 0.0) {
9501 0 : if (thisDXCoil.CCapFTempErrorIndex == 0) {
9502 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9503 0 : ShowContinueError(state,
9504 0 : format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).",
9505 : TotCapTempModFac));
9506 0 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
9507 0 : ShowContinueError(state,
9508 0 : format(" Negative value occurs using a condenser inlet air temperature of {:.1T} and an inlet air "
9509 : "wet-bulb temperature of {:.1T}.",
9510 : CondInletTemp,
9511 : InletAirWetBulbC));
9512 : } else {
9513 0 : ShowContinueError(state,
9514 0 : format(" Negative value occurs using a condenser inlet air temperature of {:.1T}.", CondInletTemp));
9515 : }
9516 0 : if (Mode > 1) {
9517 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
9518 : }
9519 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
9520 : }
9521 0 : ShowRecurringWarningErrorAtEnd(
9522 : state,
9523 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
9524 : "\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
9525 0 : thisDXCoil.CCapFTempErrorIndex,
9526 : TotCapTempModFac,
9527 : TotCapTempModFac);
9528 0 : TotCapTempModFac = 0.0;
9529 : }
9530 :
9531 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
9532 199545 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
9533 : // Warn user if curve output goes negative
9534 199545 : if (TotCapFlowModFac < 0.0) {
9535 0 : if (thisDXCoil.CCapFFlowErrorIndex == 0) {
9536 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9537 0 : ShowContinueError(state,
9538 0 : format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).",
9539 : TotCapFlowModFac));
9540 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
9541 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
9542 0 : if (Mode > 1) {
9543 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
9544 : }
9545 : }
9546 0 : ShowRecurringWarningErrorAtEnd(
9547 : state,
9548 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
9549 : "\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
9550 0 : thisDXCoil.CCapFFlowErrorIndex,
9551 : TotCapFlowModFac,
9552 : TotCapFlowModFac);
9553 0 : TotCapFlowModFac = 0.0;
9554 : }
9555 : }
9556 199692 : TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
9557 : // if user specified SHR modifier curves are available calculate the SHR as follows:
9558 199692 : if (thisDXCoil.UserSHRCurveExists) {
9559 0 : SHR = CalcSHRUserDefinedCurves(state,
9560 : InletAirDryBulbTemp,
9561 : InletAirWetBulbC,
9562 : AirMassFlowRatio,
9563 0 : thisDXCoil.SHRFTemp(Mode),
9564 0 : thisDXCoil.SHRFFlow(Mode),
9565 0 : thisDXCoil.RatedSHR(Mode));
9566 0 : hDelta = TotCap / AirMassFlow;
9567 0 : break;
9568 : } else {
9569 : // Calculate apparatus dew point conditions using TotCap and CBF
9570 199692 : hDelta = TotCap / AirMassFlow;
9571 199692 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
9572 199692 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, calcDoe2DXCoil);
9573 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9574 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
9575 199692 : wADP = PsyWFnTdbH(state, tADP, hADP, calcDoe2DXCoil);
9576 199692 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
9577 199692 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
9578 199692 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
9579 : } else {
9580 0 : SHR = 1.0;
9581 : }
9582 : // Check for dry evaporator conditions (win < wadp)
9583 199692 : if (wADP > InletAirHumRatTemp || (Counter >= 1 && Counter < MaxIter)) {
9584 34640 : if (InletAirHumRatTemp == 0.0) InletAirHumRatTemp = 0.00001;
9585 34640 : werror = (InletAirHumRatTemp - wADP) / InletAirHumRatTemp;
9586 : // Increase InletAirHumRatTemp at constant InletAirTemp to find coil dry-out point. Then use the
9587 : // capacity at the dry-out point to determine exiting conditions from coil. This is required
9588 : // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
9589 34640 : InletAirHumRatTemp = RF * wADP + (1.0 - RF) * InletAirHumRatTemp;
9590 34640 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRatTemp, OutdoorPressure);
9591 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment
9592 : // line InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRatTemp,InletAirPressure)
9593 34640 : ++Counter;
9594 34640 : if (std::abs(werror) > Tolerance) continue; // Recalculate with modified inlet conditions
9595 4979 : break;
9596 : } else {
9597 : break;
9598 : }
9599 : }
9600 : } // end of DO iteration loop
9601 :
9602 170031 : if (thisDXCoil.PLFFPLR(Mode) > 0) {
9603 170031 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PartLoadRatio); // Calculate part-load factor
9604 : } else {
9605 0 : PLF = 1.0;
9606 : }
9607 :
9608 170031 : if (PLF < 0.7) {
9609 0 : if (thisDXCoil.ErrIndex2 == 0) {
9610 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9611 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9612 0 : ShowWarningMessage(state, format("{}{}=\"{}\", PLF curve value", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9613 0 : ShowContinueError(state, format("The PLF curve value = {:.3T} for part-load ratio = {:.3T}", PLF, PartLoadRatio));
9614 0 : ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
9615 0 : ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
9616 : } else {
9617 0 : ShowWarningMessage(state, format("{}{}=\"{}\", PLF curve value", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9618 0 : ShowContinueError(state, format("The PLF curve value = {:.3T} for part-load ratio = {:.3T}", PLF, PartLoadRatio));
9619 0 : ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
9620 0 : ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
9621 : }
9622 : }
9623 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9624 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9625 0 : ShowRecurringWarningErrorAtEnd(
9626 0 : state, thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
9627 : } else {
9628 0 : ShowRecurringWarningErrorAtEnd(
9629 0 : state, thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
9630 : }
9631 0 : PLF = 0.7;
9632 : }
9633 :
9634 170031 : thisDXCoil.PartLoadRatio = PartLoadRatio;
9635 170031 : thisDXCoil.CoolingCoilRuntimeFraction = PartLoadRatio / PLF;
9636 170031 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
9637 0 : if (thisDXCoil.ErrIndex3 == 0) {
9638 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9639 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9640 0 : ShowWarningMessage(state, format("{}{}=\"{}\", runtime fraction", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9641 0 : ShowWarningMessage(state, format("The runtime fraction exceeded 1.0. [{:.4R}].", thisDXCoil.CoolingCoilRuntimeFraction));
9642 0 : ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
9643 0 : ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
9644 0 : ShowContinueErrorTimeStamp(state, "");
9645 : } else {
9646 0 : ShowWarningMessage(state, format("{}{}=\"{}\", runtime fraction", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9647 0 : ShowWarningMessage(state, format("The runtime fraction exceeded 1.0. [{:.4R}].", thisDXCoil.CoolingCoilRuntimeFraction));
9648 0 : ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
9649 0 : ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
9650 0 : ShowContinueErrorTimeStamp(state, "");
9651 : }
9652 : }
9653 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9654 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9655 0 : ShowRecurringWarningErrorAtEnd(state,
9656 0 : thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " runtime fraction > 1.0 warning continues...",
9657 0 : thisDXCoil.ErrIndex3,
9658 0 : thisDXCoil.CoolingCoilRuntimeFraction,
9659 0 : thisDXCoil.CoolingCoilRuntimeFraction);
9660 : } else {
9661 0 : ShowRecurringWarningErrorAtEnd(state,
9662 0 : thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " runtime fraction > 1.0 warning continues...",
9663 0 : thisDXCoil.ErrIndex3,
9664 0 : thisDXCoil.CoolingCoilRuntimeFraction,
9665 0 : thisDXCoil.CoolingCoilRuntimeFraction);
9666 : }
9667 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
9668 170031 : } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
9669 5482 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
9670 : }
9671 :
9672 : // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
9673 170031 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
9674 :
9675 : // Calculate full load output conditions
9676 170031 : if (thisDXCoil.UserSHRCurveExists) {
9677 0 : FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
9678 0 : if (SHR < 1.0) {
9679 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9680 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9681 0 : if (FullLoadOutAirHumRat <= 0.0) {
9682 0 : FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
9683 : }
9684 : } else {
9685 0 : SHR = 1.0;
9686 0 : FullLoadOutAirHumRat = InletAirHumRat;
9687 : }
9688 : } else {
9689 170031 : if (SHR > 1.0 || Counter > 0) SHR = 1.0;
9690 170031 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
9691 170031 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9692 170031 : if (SHR < 1.0) {
9693 165052 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9694 : } else {
9695 4979 : FullLoadOutAirHumRat = InletAirHumRat;
9696 : }
9697 : }
9698 170031 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
9699 :
9700 : // Check for saturation error and modify temperature at constant enthalpy
9701 170031 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure)) {
9702 17527 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
9703 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9704 : // IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
9705 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
9706 17527 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
9707 : }
9708 :
9709 : // Store actual outlet conditions when DX coil is ON for use in heat recovery module
9710 170031 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = FullLoadOutAirTemp;
9711 170031 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = FullLoadOutAirHumRat;
9712 :
9713 : // Add warning message for cold cooling coil (FullLoadOutAirTemp < 2 C)
9714 170031 : if (FullLoadOutAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
9715 1018 : thisDXCoil.PrintLowOutTempMessage = true;
9716 1018 : thisDXCoil.FullLoadOutAirTempLast = FullLoadOutAirTemp;
9717 1018 : if (thisDXCoil.LowOutletTempIndex == 0) {
9718 8 : thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
9719 16 : thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
9720 : "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
9721 8 : thisDXCoil.DXCoilType,
9722 8 : thisDXCoil.Name,
9723 8 : FullLoadOutAirTemp);
9724 16 : thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
9725 24 : CreateSysTimeIntervalString(state);
9726 : }
9727 : }
9728 :
9729 : // If constant fan with cycling compressor, call function to determine "effective SHR"
9730 : // which includes the part-load degradation on latent capacity
9731 170031 : if (fanOp == HVAC::FanOp::Continuous) {
9732 112362 : QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode));
9733 112362 : QLatActual = TotCap * (1.0 - SHR);
9734 112362 : SHRUnadjusted = SHR;
9735 112362 : SHR = CalcEffectiveSHR(
9736 : state, DXCoilNum, SHR, thisDXCoil.CoolingCoilRuntimeFraction, QLatRated, QLatActual, InletAirDryBulbTemp, InletAirWetBulbC, Mode);
9737 : // For multimode coil, if stage-2 operation (modes 2 or 4), adjust Stage1&2 SHR to account for
9738 : // Stage 1 operating at full load, so there is no degradation for that portion
9739 : // Use the stage 1 bypass fraction to allocate
9740 112362 : if (Mode == 2 || Mode == 4) {
9741 0 : SHR = SHRUnadjusted * (1.0 - thisDXCoil.BypassedFlowFrac(Mode - 1)) + SHR * thisDXCoil.BypassedFlowFrac(Mode - 1);
9742 : }
9743 :
9744 : // Calculate full load output conditions
9745 112362 : if (thisDXCoil.UserSHRCurveExists) {
9746 0 : FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
9747 0 : if (SHR < 1.0) {
9748 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9749 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9750 0 : if (FullLoadOutAirHumRat <= 0.0) {
9751 0 : FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
9752 : }
9753 : } else {
9754 0 : SHR = 1.0;
9755 0 : FullLoadOutAirHumRat = InletAirHumRat;
9756 : }
9757 : } else {
9758 112362 : if (SHR > 1.0 || Counter > 0) SHR = 1.0;
9759 112362 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
9760 112362 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9761 112362 : if (SHR < 1.0) {
9762 102175 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9763 : } else {
9764 10187 : FullLoadOutAirHumRat = InletAirHumRat;
9765 : }
9766 : }
9767 112362 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
9768 :
9769 : // apply latent degradation model to cycling fan when RH control is desired and heating coil operates
9770 : // longer than the cooling coil. DXcoolToHeatPLRRatio = Cooling coil PLR / Heating coil PLR.
9771 57669 : } else if (fanOp == HVAC::FanOp::Cycling) {
9772 57669 : if (DXcoolToHeatPLRRatio < 1.0) {
9773 0 : QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode));
9774 0 : QLatActual = TotCap * (1.0 - SHR);
9775 0 : HeatRTF = PartLoadRatio / DXcoolToHeatPLRRatio;
9776 0 : if (thisDXCoil.HeatingCoilPLFCurvePTR > 0) {
9777 0 : HeatingCoilPLF = CurveValue(state, thisDXCoil.HeatingCoilPLFCurvePTR, HeatRTF);
9778 0 : if (HeatingCoilPLF > 0) HeatRTF /= HeatingCoilPLF;
9779 : }
9780 0 : SHRUnadjusted = SHR;
9781 0 : SHR = CalcEffectiveSHR(state,
9782 : DXCoilNum,
9783 : SHR,
9784 : thisDXCoil.CoolingCoilRuntimeFraction,
9785 : QLatRated,
9786 : QLatActual,
9787 : InletAirDryBulbTemp,
9788 : InletAirWetBulbC,
9789 : Mode,
9790 : HeatRTF);
9791 : // Calculate full load output conditions
9792 0 : if (thisDXCoil.UserSHRCurveExists) {
9793 0 : FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
9794 0 : if (SHR < 1.0) {
9795 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9796 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9797 0 : if (FullLoadOutAirHumRat <= 0.0) {
9798 0 : FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
9799 : }
9800 : } else {
9801 0 : SHR = 1.0;
9802 0 : FullLoadOutAirHumRat = InletAirHumRat;
9803 : }
9804 : } else {
9805 0 : if (SHR > 1.0 || Counter > 0) SHR = 1.0;
9806 0 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
9807 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9808 0 : if (SHR < 1.0) {
9809 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9810 : } else {
9811 0 : FullLoadOutAirHumRat = InletAirHumRat;
9812 : }
9813 : }
9814 0 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
9815 : }
9816 : }
9817 :
9818 : // Calculate actual outlet conditions for the input part load ratio
9819 : // Actual outlet conditions are "average" for time step
9820 :
9821 : // For multimode coil, if stage-2 operation (modes 2 or 4), return "full load" outlet conditions
9822 170031 : if (((fanOp == HVAC::FanOp::Continuous) && (Mode == 1)) || (Mode == 3)) {
9823 : // Continuous fan, cycling compressor
9824 112362 : OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
9825 112362 : OutletAirHumRat = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirHumRat + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirHumRat);
9826 112362 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
9827 : } else {
9828 : // Default to cycling fan, cycling compressor
9829 : // Also return this result for stage 2 operation of multimode coil
9830 : // Cycling fan typically provides full outlet conditions. When RH control is used, account for additional
9831 : // heating run time by using cooling/heating ratio the same as constant fan (otherwise PLRRatio = 1).
9832 57669 : OutletAirEnthalpy = FullLoadOutAirEnth * DXcoolToHeatPLRRatio + InletAirEnthalpy * (1.0 - DXcoolToHeatPLRRatio);
9833 57669 : OutletAirHumRat = FullLoadOutAirHumRat * DXcoolToHeatPLRRatio + InletAirHumRat * (1.0 - DXcoolToHeatPLRRatio);
9834 57669 : OutletAirTemp = FullLoadOutAirTemp * DXcoolToHeatPLRRatio + InletAirDryBulbTemp * (1.0 - DXcoolToHeatPLRRatio);
9835 : }
9836 :
9837 : // Check for saturation error and modify temperature at constant enthalpy
9838 170031 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, calcDoe2DXCoil)) {
9839 10242 : OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
9840 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9841 : // IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
9842 : // OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
9843 10242 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
9844 : }
9845 :
9846 : // Mix with air that was bypassed around coil, if any
9847 170031 : if (BypassFlowFraction > 0.0) {
9848 0 : OutletAirEnthalpy = (1.0 - BypassFlowFraction) * OutletAirEnthalpy + BypassFlowFraction * InletAirEnthalpy;
9849 0 : OutletAirHumRat = (1.0 - BypassFlowFraction) * OutletAirHumRat + BypassFlowFraction * InletAirHumRat;
9850 0 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
9851 : // Check for saturation error and modify temperature at constant enthalpy
9852 0 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) {
9853 0 : OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
9854 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9855 : // IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
9856 : // OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
9857 0 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
9858 : }
9859 : }
9860 :
9861 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
9862 170031 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9863 169884 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9864 : // Coil:DX:HeatPumpWaterHeater does not have EIR temp or flow curves
9865 147 : EIRTempModFac = 1.0;
9866 147 : EIRFlowModFac = 1.0;
9867 : } else {
9868 169884 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirWetBulbC, CondInletTemp);
9869 :
9870 : // Warn user if curve output goes negative
9871 169884 : if (EIRTempModFac < 0.0) {
9872 0 : if (thisDXCoil.EIRFTempErrorIndex == 0) {
9873 0 : ShowWarningMessage(state, format("{}{}=\"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9874 0 : ShowContinueError(
9875 0 : state, format(" Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).", EIRTempModFac));
9876 0 : if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 2) {
9877 0 : ShowContinueError(state,
9878 0 : format(" Negative value occurs using a condenser inlet air temperature of {:.1T} and an inlet air "
9879 : "wet-bulb temperature of {:.1T}.",
9880 : CondInletTemp,
9881 : InletAirWetBulbC));
9882 : } else {
9883 0 : ShowContinueError(state, format(" Negative value occurs using a condenser inlet air temperature of {:.1T}.", CondInletTemp));
9884 : }
9885 0 : if (Mode > 1) {
9886 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
9887 : }
9888 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
9889 : }
9890 0 : ShowRecurringWarningErrorAtEnd(
9891 : state,
9892 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9893 : "\": Energy Input Ratio Modifier curve (function of temperature) output is negative warning continues...",
9894 0 : thisDXCoil.EIRFTempErrorIndex,
9895 : EIRTempModFac,
9896 : EIRTempModFac);
9897 0 : EIRTempModFac = 0.0;
9898 : }
9899 :
9900 169884 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
9901 :
9902 : // Warn user if curve output goes negative
9903 169884 : if (EIRFlowModFac < 0.0) {
9904 0 : if (thisDXCoil.EIRFFlowErrorIndex == 0) {
9905 0 : ShowWarningMessage(state, format("{}{}=\"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9906 0 : ShowContinueError(
9907 0 : state, format(" Energy Input Ratio Modifier curve (function of flow fraction) output is negative ({:.3T}).", EIRFlowModFac));
9908 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
9909 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
9910 0 : if (Mode > 1) {
9911 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
9912 : }
9913 : }
9914 0 : ShowRecurringWarningErrorAtEnd(
9915 : state,
9916 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9917 : "\": Energy Input Ratio Modifier curve (function of flow fraction) output is negative warning continues...",
9918 0 : thisDXCoil.EIRFFlowErrorIndex,
9919 : EIRFlowModFac,
9920 : EIRFlowModFac);
9921 0 : EIRFlowModFac = 0.0;
9922 : }
9923 : }
9924 :
9925 170031 : EIR = thisDXCoil.RatedEIR(Mode) * EIRFlowModFac * EIRTempModFac;
9926 :
9927 : // For multimode coil, if stage-2 operation (Modes 2 or 4), return "full load" power adjusted for PLF
9928 170031 : if (Mode == 1 || Mode == 3) {
9929 170031 : thisDXCoil.ElecCoolingPower = TotCap * EIR * thisDXCoil.CoolingCoilRuntimeFraction;
9930 : } else {
9931 0 : thisDXCoil.ElecCoolingPower = TotCap * EIR * thisDXCoil.CoolingCoilRuntimeFraction / PartLoadRatio;
9932 : }
9933 :
9934 : // Reset AirMassFlow to inlet node air mass flow for final total, sensible and latent calculations
9935 : // since AirMassFlow might have been modified above (in this subroutine):
9936 : // IF (FanOpMode .EQ. FanOp::Cycling) AirMassFlow = AirMassFlow / PartLoadRatio
9937 : // For multimode coil, this should be full flow including bypassed fraction
9938 170031 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
9939 170031 : CalcComponentSensibleLatentOutput(AirMassFlow,
9940 : InletAirDryBulbTemp,
9941 : InletAirHumRat,
9942 : OutletAirTemp,
9943 : OutletAirHumRat,
9944 170031 : thisDXCoil.SensCoolingEnergyRate,
9945 170031 : thisDXCoil.LatCoolingEnergyRate,
9946 170031 : thisDXCoil.TotalCoolingEnergyRate);
9947 :
9948 : // Set DataHeatGlobal heat reclaim variable for use by heat reclaim coil (part load ratio is accounted for)
9949 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
9950 170031 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
9951 :
9952 : // Calculate crankcase heater power using the runtime fraction for this DX cooling coil only if there is no companion DX coil.
9953 : // Else use the largest runtime fraction of this DX cooling coil and the companion DX heating coil.
9954 170031 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
9955 170031 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
9956 : } else {
9957 0 : thisDXCoil.CrankcaseHeaterPower =
9958 0 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.CoolingCoilRuntimeFraction,
9959 0 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction));
9960 : }
9961 :
9962 170031 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
9963 : //******************
9964 : // WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
9965 : // H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
9966 : // /RhoWater [kgWater/m3]
9967 : //******************
9968 42800 : RhoWater = RhoH2O(OutdoorDryBulb);
9969 42800 : thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater * thisDXCoil.CoolingCoilRuntimeFraction;
9970 42800 : thisDXCoil.EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower(Mode) * thisDXCoil.CoolingCoilRuntimeFraction;
9971 : // Calculate basin heater power
9972 42800 : CalcBasinHeaterPower(state,
9973 : thisDXCoil.BasinHeaterPowerFTempDiff,
9974 : thisDXCoil.basinHeaterSched,
9975 : thisDXCoil.BasinHeaterSetPointTemp,
9976 42800 : thisDXCoil.BasinHeaterPower);
9977 42800 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
9978 42800 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
9979 : }
9980 : }
9981 :
9982 170031 : thisDXCoil.OutletAirTemp = OutletAirTemp;
9983 170031 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
9984 170031 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
9985 :
9986 : } else {
9987 :
9988 : // DX coil is off; just pass through conditions
9989 161281 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
9990 161281 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
9991 161281 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
9992 :
9993 161281 : thisDXCoil.ElecCoolingPower = 0.0;
9994 161281 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
9995 161281 : thisDXCoil.SensCoolingEnergyRate = 0.0;
9996 161281 : thisDXCoil.LatCoolingEnergyRate = 0.0;
9997 161281 : thisDXCoil.EvapCondPumpElecPower = 0.0;
9998 161281 : thisDXCoil.EvapWaterConsumpRate = 0.0;
9999 :
10000 : // Reset globals when DX coil is OFF for use in heat recovery module
10001 161281 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
10002 161281 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
10003 :
10004 : // Calculate crankcase heater power using the runtime fraction for this DX cooling coil (here DXCoolingCoilRTF=0) if
10005 : // there is no companion DX coil, or the runtime fraction of the companion DX heating coil (here DXHeatingCoilRTF>=0).
10006 161281 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
10007 161281 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
10008 : } else {
10009 0 : thisDXCoil.CrankcaseHeaterPower =
10010 0 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction);
10011 : }
10012 :
10013 : // Calculate basin heater power
10014 161281 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
10015 1 : if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
10016 0 : CalcBasinHeaterPower(state,
10017 : thisDXCoil.BasinHeaterPowerFTempDiff,
10018 : thisDXCoil.basinHeaterSched,
10019 : thisDXCoil.BasinHeaterSetPointTemp,
10020 0 : thisDXCoil.BasinHeaterPower);
10021 : }
10022 : } else {
10023 161280 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
10024 25052 : CalcBasinHeaterPower(state,
10025 : thisDXCoil.BasinHeaterPowerFTempDiff,
10026 : thisDXCoil.basinHeaterSched,
10027 : thisDXCoil.BasinHeaterSetPointTemp,
10028 25052 : thisDXCoil.BasinHeaterPower);
10029 : }
10030 : }
10031 :
10032 : } // end of on/off if - else
10033 :
10034 : // set water system demand request (if needed)
10035 331312 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
10036 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
10037 0 : thisDXCoil.EvapWaterConsumpRate;
10038 : }
10039 :
10040 331312 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
10041 331312 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
10042 331312 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
10043 331312 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
10044 331312 : thisDXCoil.CondInletTemp = CondInletTemp;
10045 :
10046 : // set outlet node conditions
10047 331312 : int airOutletNode = thisDXCoil.AirOutNode;
10048 331312 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
10049 331312 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
10050 :
10051 : // calc secondary coil if specified
10052 331312 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
10053 0 : CalcSecondaryDXCoils(state, DXCoilNum);
10054 : }
10055 331312 : }
10056 :
10057 49499 : void CalcVRFCoolingCoil(EnergyPlusData &state,
10058 : int const DXCoilNum, // the number of the DX coil to be simulated
10059 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
10060 : bool const FirstHVACIteration, // true if this is the first iteration of HVAC
10061 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
10062 : HVAC::FanOp const fanOp, // Allows parent object to control fan operation
10063 : Real64 const CompCycRatio, // cycling ratio of VRF condenser
10064 : ObjexxFCL::Optional_int_const PerfMode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
10065 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
10066 : ObjexxFCL::Optional<Real64 const> MaxCoolCap // maximum capacity of DX coil
10067 : )
10068 : {
10069 :
10070 : // SUBROUTINE INFORMATION:
10071 : // AUTHOR Richard Raustad
10072 : // DATE WRITTEN August 2010
10073 :
10074 : // PURPOSE OF THIS SUBROUTINE:
10075 : // Calculates the air-side performance of a direct-expansion, air-cooled
10076 : // VRF terminal unit cooling coil.
10077 : // A new subroutine was created in case this DX coil model is significantly
10078 : // different from the existing CalcDoe2DXCoil subroutine. The VRF heating coil
10079 : // uses the existing DX heating coil subroutine (CalcDXHeatingCoil).
10080 :
10081 : // METHODOLOGY EMPLOYED:
10082 : // This routine simulates the performance of a variable refrigerant flow cooling coil.
10083 : // The routine requires the user to enter the total cooling capacity and sensible heat ratio.
10084 : // Since different manufacturer's rate their equipment at different air flow rates,
10085 : // the supply air flow rate corresponding to the rated capacities must also be
10086 : // entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information entered by
10087 : // the user should NOT include the thermal or electrical impacts of the supply air fan, as
10088 : // this is addressed by another module.
10089 :
10090 : // With the rated performance data entered by the user, the model employs some of the
10091 : // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
10092 : // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
10093 : // does NOT employ the exact same methodology to calculate performance as DOE-2.
10094 : // This VRF cooling coil model adjusts the rated total cooling capacity by the CAPFT
10095 : // and CAP function of flow curve/model currently used by the existing DX coil model.
10096 : // The part-load ratio is then applied to the total operating capacity to find the capacity
10097 : // required to meet the load. This VRF model then uses the ADP/bypass method to find the
10098 : // SHR and resulting outlet conditions given that total capacity (or delta H).
10099 :
10100 : // The model checks for coil dryout conditions, and adjusts the calculated performance
10101 : // appropriately.
10102 :
10103 : // Using/Aliasing
10104 : using Curve::CurveValue;
10105 49499 : Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
10106 49499 : Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
10107 : using General::CreateSysTimeIntervalString;
10108 :
10109 : // SUBROUTINE ARGUMENT DEFINITIONS:
10110 : // REAL(r64), INTENT(IN), OPTIONAL :: CoolingHeatingPLR ! used for cycling fan RH control
10111 :
10112 : // SUBROUTINE PARAMETER DEFINITIONS:
10113 : static constexpr std::string_view RoutineName("CalcVRFCoolingCoil");
10114 :
10115 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10116 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
10117 : Real64 AirMassFlowRatio; // Ratio of actual air mass flow to rated air mass flow (adjusted for bypass if any)
10118 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
10119 : // (average flow if cycling fan, full flow if constant fan)
10120 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
10121 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
10122 : Real64 TotCapTempModFac; // Total capacity modifier (function of entering wetbulb, outside drybulb)
10123 : Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs rated flow)
10124 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
10125 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
10126 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
10127 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
10128 : Real64 InletAirHumRatTemp; // inlet air humidity ratio used in ADP/BF loop [kg/kg]
10129 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10130 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
10131 : Real64 RatedCBF; // coil bypass factor at rated conditions
10132 : Real64 SHR; // Sensible Heat Ratio (sensible/total) of the cooling coil
10133 : Real64 CBF; // coil bypass factor at off rated conditions
10134 : Real64 A0; // NTU * air mass flow rate, used in CBF calculation
10135 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
10136 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
10137 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
10138 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
10139 : Real64 tADP; // Apparatus dew point temperature [C]
10140 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
10141 : Real64 FullLoadOutAirEnth; // outlet full load enthalpy [J/kg]
10142 : Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
10143 : Real64 FullLoadOutAirTemp; // outlet air temperature at full load [C]
10144 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
10145 : Real64 QLatActual; // operating latent capacity of DX coil
10146 : Real64 QLatRated; // Rated latent capacity of DX coil
10147 : Real64 SHRUnadjusted; // SHR prior to latent degradation effective SHR calculation
10148 : int Counter; // Counter for dry evaporator iterations
10149 : int MaxIter; // Maximum number of iterations for dry evaporator calculations
10150 : Real64 RF; // Relaxation factor for dry evaporator iterations
10151 : Real64 Tolerance; // Error tolerance for dry evaporator iterations
10152 : Real64 werror; // Deviation of humidity ratio in dry evaporator iteration loop
10153 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
10154 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
10155 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
10156 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
10157 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
10158 : Real64 RhoAir; // Density of air [kg/m3]
10159 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
10160 49499 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
10161 : Real64 AirFlowRatio; // ratio of compressor on airflow to average timestep airflow
10162 : // used when constant fan mode yields different air flow rates when compressor is ON and OFF
10163 : // (e.g. Packaged Terminal Heat Pump)
10164 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
10165 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
10166 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
10167 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
10168 :
10169 : int Mode; // Performance mode for Multimode DX coil; Always 1 for other coil types
10170 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
10171 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
10172 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
10173 : Real64 ADiff; // Used for exponential
10174 :
10175 : // If Performance mode not present, then set to 1. Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
10176 49499 : if (present(PerfMode)) {
10177 0 : Mode = PerfMode;
10178 : } else {
10179 49499 : Mode = 1;
10180 : }
10181 :
10182 : // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
10183 : // during cooling and when no cooling is required (constant fan, fan speed changes)
10184 49499 : if (present(OnOffAirFlowRatio)) {
10185 49492 : AirFlowRatio = OnOffAirFlowRatio;
10186 : } else {
10187 7 : AirFlowRatio = 1.0;
10188 : }
10189 :
10190 49499 : MaxIter = 30;
10191 49499 : RF = 0.4;
10192 49499 : Counter = 0;
10193 49499 : Tolerance = 0.01;
10194 49499 : CondInletTemp = 0.0;
10195 49499 : CondInletHumRat = 0.0;
10196 :
10197 49499 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
10198 :
10199 49499 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10200 49499 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
10201 49499 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10202 49499 : InletAirHumRat = thisDXCoil.InletAirHumRat;
10203 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10204 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
10205 49499 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
10206 49499 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
10207 49499 : thisDXCoil.PartLoadRatio = 0.0;
10208 49499 : thisDXCoil.BasinHeaterPower = 0.0;
10209 :
10210 49499 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
10211 49438 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
10212 49438 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
10213 32 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10214 32 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10215 32 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10216 : } else {
10217 49406 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
10218 : // If node is not connected to anything, pressure = default, use weather data
10219 49406 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
10220 94 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10221 94 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10222 94 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10223 94 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10224 : } else {
10225 49312 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
10226 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
10227 49312 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
10228 : }
10229 : }
10230 : } else {
10231 61 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10232 61 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10233 61 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10234 61 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10235 : }
10236 :
10237 49499 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
10238 0 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
10239 0 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
10240 : // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
10241 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
10242 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
10243 0 : CompAmbTemp = OutdoorDryBulb;
10244 : } else { // for air or water-cooled, inlet temp is stored in OutdoorDryBulb temp
10245 49499 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp or water inlet temp
10246 49499 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
10247 32 : CompAmbTemp = state.dataEnvrn->OutDryBulbTemp; // for crankcase heater use actual outdoor temp for water-cooled
10248 : } else {
10249 49467 : CompAmbTemp = OutdoorDryBulb;
10250 : }
10251 : }
10252 :
10253 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
10254 : // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
10255 49499 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
10256 71 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
10257 71 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
10258 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
10259 : }
10260 : } else {
10261 49428 : CrankcaseHeatingPower = 0.0;
10262 : }
10263 :
10264 : // calculate end time of current time step to determine if error messages should be printed
10265 49499 : state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
10266 :
10267 : // Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
10268 : // Wait for next time step to print warnings. If simulation iterates, print out
10269 : // the warning for the last iteration only. Must wait for next time step to accomplish this.
10270 : // If a warning occurs and the simulation down shifts, the warning is not valid.
10271 49499 : if (thisDXCoil.PrintLowAmbMessage) { // .AND. &
10272 0 : if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
10273 0 : if (thisDXCoil.LowAmbErrIndex == 0) {
10274 0 : ShowWarningMessage(state, thisDXCoil.LowAmbBuffer1);
10275 0 : ShowContinueError(state, thisDXCoil.LowAmbBuffer2);
10276 0 : ShowContinueError(state, "... Operation at low inlet temperatures may require special performance curves.");
10277 : }
10278 0 : ShowRecurringWarningErrorAtEnd(state,
10279 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10280 : "\" - Low condenser inlet temperature error continues...",
10281 0 : thisDXCoil.LowAmbErrIndex,
10282 0 : thisDXCoil.LowTempLast,
10283 0 : thisDXCoil.LowTempLast,
10284 : _,
10285 : "[C]",
10286 : "[C]");
10287 : }
10288 : }
10289 :
10290 49499 : if (thisDXCoil.PrintHighAmbMessage) { // .AND. &
10291 60 : if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
10292 0 : if (thisDXCoil.HighAmbErrIndex == 0) {
10293 0 : ShowWarningMessage(state, thisDXCoil.HighAmbBuffer1);
10294 0 : ShowContinueError(state, thisDXCoil.HighAmbBuffer2);
10295 0 : ShowContinueError(state, "... Operation at high inlet temperatures may require special performance curves.");
10296 : }
10297 0 : ShowRecurringWarningErrorAtEnd(state,
10298 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10299 : "\" - High condenser inlet temperature error continues...",
10300 0 : thisDXCoil.HighAmbErrIndex,
10301 0 : thisDXCoil.HighTempLast,
10302 0 : thisDXCoil.HighTempLast,
10303 : _,
10304 : "[C]",
10305 : "[C]");
10306 : }
10307 : }
10308 :
10309 49499 : if (thisDXCoil.PrintLowOutTempMessage) {
10310 0 : if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
10311 0 : if (thisDXCoil.LowOutletTempIndex == 0) {
10312 0 : ShowWarningMessage(state, thisDXCoil.LowOutTempBuffer1);
10313 0 : ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
10314 0 : ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
10315 0 : ShowContinueError(state,
10316 0 : format(" 1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
10317 0 : thisDXCoil.FullLoadInletAirTempLast));
10318 0 : ShowContinueError(state, " 2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
10319 0 : ShowContinueError(state,
10320 : " 3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
10321 : }
10322 0 : ShowRecurringWarningErrorAtEnd(state,
10323 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10324 : "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
10325 : "Outlet air temperature statistics follow:",
10326 0 : thisDXCoil.LowOutletTempIndex,
10327 0 : thisDXCoil.FullLoadOutAirTempLast,
10328 0 : thisDXCoil.FullLoadOutAirTempLast);
10329 : }
10330 : }
10331 :
10332 : // save last system time step and last end time of current time step (used to determine if warning is valid)
10333 49499 : thisDXCoil.TimeStepSysLast = TimeStepSys;
10334 49499 : thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime;
10335 49499 : thisDXCoil.PrintLowAmbMessage = false;
10336 49499 : thisDXCoil.PrintLowOutTempMessage = false;
10337 :
10338 49499 : if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
10339 : (compressorOp == HVAC::CompressorOp::On)) { // for cycling fan, reset mass flow to full on rate
10340 21285 : if (fanOp == HVAC::FanOp::Cycling) {
10341 43 : AirMassFlow /= PartLoadRatio;
10342 21242 : } else if (fanOp == HVAC::FanOp::Continuous) {
10343 21242 : AirMassFlow *= AirFlowRatio;
10344 : } else {
10345 0 : AirMassFlow = thisDXCoil.RatedAirMassFlowRate(Mode);
10346 : }
10347 :
10348 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton)
10349 :
10350 : // for some reason there are diff's when using coil inlet air pressure
10351 : // these lines (more to follow) are commented out for the time being
10352 :
10353 21285 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
10354 21285 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
10355 21285 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
10356 :
10357 21285 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
10358 0 : ShowFatalError(state, format("{} \"{}\" - Rated total cooling capacity is zero or less.", thisDXCoil.DXCoilType, thisDXCoil.Name));
10359 : }
10360 :
10361 23678 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag &&
10362 2393 : ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
10363 2393 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
10364 0 : if (thisDXCoil.ErrIndex1 == 0) {
10365 0 : ShowWarningMessage(
10366 : state,
10367 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at {:.3R} m3/s/W.",
10368 0 : thisDXCoil.DXCoilType,
10369 0 : thisDXCoil.Name,
10370 : VolFlowperRatedTotCap));
10371 0 : ShowContinueErrorTimeStamp(state, "");
10372 0 : ShowContinueError(state,
10373 0 : format("...Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
10374 0 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
10375 0 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
10376 0 : ShowContinueError(state, "...Possible causes include inconsistent air flow rates in system components,");
10377 0 : ShowContinueError(state, "...or mixing manual inputs with autosize inputs. Also check the following values and calculations.");
10378 0 : ShowContinueError(state, "...Volume Flow Rate per Rated Total Capacity = Volume Flow Rate / Rated Total Capacity");
10379 0 : ShowContinueError(state, "...Volume Flow Rate = Air Mass Flow Rate / Air Density");
10380 0 : ShowContinueError(state, "...Data used for calculations:");
10381 0 : ShowContinueError(state, format("...Rated Total Capacity = {:.2R} W.", thisDXCoil.RatedTotCap(Mode)));
10382 0 : ShowContinueError(state, "...Volume Flow Rate = Air Mass Flow Rate / Air Density");
10383 0 : ShowContinueError(state, format("...Volume Flow Rate = {:.8R} m3/s.", AirVolumeFlowRate));
10384 0 : ShowContinueError(state, format("...Air Mass Flow Rate = {:.8R} kg/s.", AirMassFlow));
10385 0 : ShowContinueError(
10386 : state,
10387 0 : format("...Air Density = {:.8R} kg/m3.", PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat)));
10388 0 : ShowContinueError(state, "...Data used for air density calculation:");
10389 0 : ShowContinueError(state, format("...Outdoor Air Pressure = {:.3R} Pa.", OutdoorPressure));
10390 0 : ShowContinueError(state, format("...Inlet Air Dry-Bulb Temp = {:.3R} C.", InletAirDryBulbTemp));
10391 0 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.8R} kgWater/kgDryAir.", InletAirHumRat));
10392 : }
10393 0 : ShowRecurringWarningErrorAtEnd(
10394 : state,
10395 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10396 : "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
10397 0 : thisDXCoil.ErrIndex1,
10398 : VolFlowperRatedTotCap,
10399 : VolFlowperRatedTotCap);
10400 : }
10401 : // Adjust coil bypass factor for actual air flow rate. Use relation CBF = exp(-NTU) where
10402 : // NTU = A0/(m*cp). Relationship models the cooling coil as a heat exchanger with Cmin/Cmax = 0.
10403 :
10404 21285 : RatedCBF = thisDXCoil.RatedCBF(Mode);
10405 21285 : if (RatedCBF > 0.0) {
10406 21285 : A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
10407 : } else {
10408 0 : A0 = 0.0;
10409 : }
10410 21285 : ADiff = -A0 / AirMassFlow;
10411 21285 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
10412 21285 : CBF = std::exp(ADiff);
10413 : } else {
10414 0 : CBF = 0.0;
10415 : }
10416 :
10417 : // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
10418 21285 : if (OutdoorDryBulb < thisDXCoil.MinOATCompressor && !state.dataGlobal->WarmupFlag) {
10419 0 : thisDXCoil.PrintLowAmbMessage = true;
10420 0 : thisDXCoil.LowTempLast = OutdoorDryBulb;
10421 0 : if (thisDXCoil.LowAmbErrIndex == 0) {
10422 0 : thisDXCoil.LowAmbBuffer1 = format("{} \"{}\" - Condenser inlet temperature below {:.2R} C. Condenser inlet temperature = {:.2R}",
10423 0 : thisDXCoil.DXCoilType,
10424 0 : thisDXCoil.Name,
10425 0 : thisDXCoil.MinOATCompressor,
10426 0 : OutdoorDryBulb);
10427 0 : thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
10428 0 : CreateSysTimeIntervalString(state);
10429 : }
10430 : }
10431 :
10432 : // check boundary for high ambient temperature and post warnings to individual DX coil buffers to print at end of time step
10433 21285 : if (OutdoorDryBulb > thisDXCoil.MaxOATCompressor && !state.dataGlobal->WarmupFlag) {
10434 27 : thisDXCoil.PrintHighAmbMessage = true;
10435 27 : thisDXCoil.HighTempLast = OutdoorDryBulb;
10436 27 : if (thisDXCoil.HighAmbErrIndex == 0) {
10437 54 : thisDXCoil.HighAmbBuffer1 = format("{} \"{}\" - Condenser inlet temperature above {:.2R} C. Condenser temperature = {:.2R}",
10438 27 : thisDXCoil.DXCoilType,
10439 27 : thisDXCoil.Name,
10440 27 : thisDXCoil.MaxOATCompressor,
10441 27 : OutdoorDryBulb);
10442 54 : thisDXCoil.HighAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
10443 81 : CreateSysTimeIntervalString(state);
10444 : }
10445 : }
10446 :
10447 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
10448 : // InletAirHumRat may be modified in this ADP/BF loop, use temporary variable for calculations
10449 21285 : InletAirHumRatTemp = InletAirHumRat;
10450 :
10451 21285 : Label50:;
10452 21285 : switch (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims) {
10453 21285 : case 1:
10454 21285 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC);
10455 21285 : break;
10456 0 : case 2:
10457 : default: // this default allows the simulation to continue, but will issue a warning, should be removed eventually
10458 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC, CondInletTemp);
10459 0 : break;
10460 : }
10461 :
10462 : // Warn user if curve output goes negative
10463 21285 : if (TotCapTempModFac < 0.0) {
10464 0 : if (thisDXCoil.CCapFTempErrorIndex == 0) {
10465 0 : ShowWarningMessage(state, format("{} \"{}\":", thisDXCoil.DXCoilType, thisDXCoil.Name));
10466 0 : ShowContinueError(
10467 0 : state, format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
10468 0 : ShowContinueError(
10469 : state,
10470 0 : format(" Negative value occurs using a condenser inlet temperature of {:.1T} and an inlet air wet-bulb temperature of {:.1T}.",
10471 : CondInletTemp,
10472 : InletAirWetBulbC));
10473 0 : if (Mode > 1) {
10474 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
10475 : }
10476 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
10477 : }
10478 0 : ShowRecurringWarningErrorAtEnd(
10479 : state,
10480 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10481 : "\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
10482 0 : thisDXCoil.CCapFTempErrorIndex,
10483 : TotCapTempModFac,
10484 : TotCapTempModFac);
10485 0 : TotCapTempModFac = 0.0;
10486 : }
10487 :
10488 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
10489 21285 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
10490 21285 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
10491 :
10492 : // Warn user if curve output goes negative
10493 21285 : if (TotCapFlowModFac < 0.0) {
10494 0 : if (thisDXCoil.CCapFFlowErrorIndex == 0) {
10495 0 : ShowWarningMessage(state, format("{} \"{}\":", thisDXCoil.DXCoilType, thisDXCoil.Name));
10496 0 : ShowContinueError(
10497 : state,
10498 0 : format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).", TotCapFlowModFac));
10499 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
10500 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
10501 0 : if (Mode > 1) {
10502 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
10503 : }
10504 : }
10505 0 : ShowRecurringWarningErrorAtEnd(
10506 : state,
10507 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10508 : "\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
10509 0 : thisDXCoil.CCapFFlowErrorIndex,
10510 : TotCapFlowModFac,
10511 : TotCapFlowModFac);
10512 0 : TotCapFlowModFac = 0.0;
10513 : }
10514 :
10515 21285 : if (present(MaxCoolCap)) {
10516 21278 : TotCap = min(MaxCoolCap, thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac);
10517 : } else {
10518 7 : TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
10519 : }
10520 :
10521 21285 : TotCap *= PartLoadRatio;
10522 :
10523 : // Calculate apparatus dew point conditions using TotCap and CBF
10524 21285 : hDelta = TotCap / AirMassFlow;
10525 : // there is an issue here with using CBF to calculate the ADP enthalpy.
10526 : // at low loads the bypass factor increases significantly.
10527 21285 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
10528 21285 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
10529 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10530 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
10531 21285 : wADP = min(InletAirHumRat, PsyWFnTdbH(state, tADP, hADP, RoutineName));
10532 21285 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
10533 21285 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
10534 18971 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
10535 : } else {
10536 2314 : SHR = 1.0;
10537 : }
10538 : // Check for dry evaporator conditions (win < wadp)
10539 21285 : if (wADP > InletAirHumRatTemp || (Counter >= 1 && Counter < MaxIter)) {
10540 0 : if (InletAirHumRatTemp == 0.0) InletAirHumRatTemp = 0.00001;
10541 0 : werror = (InletAirHumRatTemp - wADP) / InletAirHumRatTemp;
10542 : // Increase InletAirHumRatTemp at constant InletAirTemp to find coil dry-out point. Then use the
10543 : // capacity at the dry-out point to determine exiting conditions from coil. This is required
10544 : // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
10545 0 : InletAirHumRatTemp = RF * wADP + (1.0 - RF) * InletAirHumRatTemp;
10546 0 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRatTemp, OutdoorPressure);
10547 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10548 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRatTemp,InletAirPressure)
10549 0 : ++Counter;
10550 0 : if (std::abs(werror) > Tolerance) goto Label50; // Recalculate with modified inlet conditions
10551 : }
10552 :
10553 21285 : if (thisDXCoil.PLFFPLR(Mode) > 0 && CompCycRatio < 1.0) {
10554 26 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CompCycRatio); // Calculate part-load factor
10555 : } else {
10556 21259 : PLF = 1.0;
10557 : }
10558 :
10559 21285 : if (PLF < 0.7) {
10560 0 : if (thisDXCoil.ErrIndex2 == 0) {
10561 0 : ShowWarningMessage(
10562 : state,
10563 0 : format(
10564 0 : "The PLF curve value for the DX cooling coil {} ={:.3R} for part-load ratio ={:.3R}", thisDXCoil.Name, PLF, PartLoadRatio));
10565 0 : ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
10566 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
10567 : }
10568 0 : ShowRecurringWarningErrorAtEnd(
10569 0 : state, thisDXCoil.Name + ", DX cooling coil PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
10570 0 : PLF = 0.7;
10571 : }
10572 :
10573 21285 : thisDXCoil.PartLoadRatio = PartLoadRatio;
10574 21285 : thisDXCoil.CoolingCoilRuntimeFraction = CompCycRatio / PLF;
10575 21285 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
10576 0 : if (thisDXCoil.ErrIndex3 == 0) {
10577 0 : ShowWarningMessage(state,
10578 0 : format("The runtime fraction for DX cooling coil {} exceeded 1.0. [{:.4R}].",
10579 0 : thisDXCoil.Name,
10580 0 : thisDXCoil.CoolingCoilRuntimeFraction));
10581 0 : ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
10582 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
10583 0 : ShowContinueErrorTimeStamp(state, "");
10584 : }
10585 0 : ShowRecurringWarningErrorAtEnd(state,
10586 0 : thisDXCoil.Name + ", DX cooling coil runtime fraction > 1.0 warning continues...",
10587 0 : thisDXCoil.ErrIndex3,
10588 0 : thisDXCoil.CoolingCoilRuntimeFraction,
10589 0 : thisDXCoil.CoolingCoilRuntimeFraction);
10590 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
10591 21285 : } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
10592 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
10593 : }
10594 :
10595 : // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
10596 21285 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
10597 :
10598 : // Calculate full load output conditions
10599 : // if ( SHR > 1.0 || Counter > 0 ) SHR = 1.0;
10600 21285 : if (SHR > 1.0) SHR = 1.0;
10601 21285 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
10602 21285 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
10603 21285 : if (SHR < 1.0) {
10604 12378 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
10605 : } else {
10606 8907 : FullLoadOutAirHumRat = InletAirHumRat;
10607 : }
10608 21285 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
10609 :
10610 : // Check for saturation error and modify temperature at constant enthalpy
10611 21285 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure)) {
10612 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
10613 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10614 : // IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
10615 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
10616 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
10617 : }
10618 :
10619 : // Store actual outlet conditions when DX coil is ON for use in heat recovery module
10620 21285 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = FullLoadOutAirTemp;
10621 21285 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = FullLoadOutAirHumRat;
10622 :
10623 : // Add warning message for cold cooling coil (FullLoadOutAirTemp < 2 C)
10624 21285 : if (FullLoadOutAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
10625 0 : thisDXCoil.PrintLowOutTempMessage = true;
10626 0 : thisDXCoil.FullLoadOutAirTempLast = FullLoadOutAirTemp;
10627 0 : if (thisDXCoil.LowOutletTempIndex == 0) {
10628 0 : thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
10629 0 : thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
10630 : "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
10631 0 : thisDXCoil.DXCoilType,
10632 0 : thisDXCoil.Name,
10633 0 : FullLoadOutAirTemp);
10634 0 : thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
10635 0 : CreateSysTimeIntervalString(state);
10636 : }
10637 : }
10638 :
10639 : // If constant fan with cycling compressor, call function to determine "effective SHR"
10640 : // which includes the part-load degradation on latent capacity
10641 21285 : if (fanOp == HVAC::FanOp::Continuous && CompCycRatio < 1.0) {
10642 3662 : QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode)); // always the same number
10643 3662 : QLatActual = TotCap * (1.0 - SHR);
10644 3662 : SHRUnadjusted = SHR;
10645 3662 : SHR = CalcEffectiveSHR(
10646 : state, DXCoilNum, SHR, thisDXCoil.CoolingCoilRuntimeFraction, QLatRated, QLatActual, InletAirDryBulbTemp, InletAirWetBulbC, Mode);
10647 :
10648 : // Calculate full load output conditions
10649 : // if ( SHR > 1.0 || Counter > 0 ) SHR = 1.0;
10650 3662 : if (SHR > 1.0) SHR = 1.0;
10651 3662 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
10652 3662 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
10653 3662 : if (SHR < 1.0) {
10654 3180 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
10655 : } else {
10656 482 : FullLoadOutAirHumRat = InletAirHumRat;
10657 : }
10658 3662 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
10659 : }
10660 :
10661 : // Calculate actual outlet conditions for the input part load ratio
10662 : // Actual outlet conditions are "average" for time step when compressor cycles
10663 :
10664 21285 : if (fanOp == HVAC::FanOp::Continuous && CompCycRatio < 1.0) {
10665 : // Continuous fan, cycling compressor
10666 : // hmmm ... this seems wrong. PLR * AirFlowRatio = 1. So we get FullLoadOutAirEnth all this time. This is OK since above TotCap *=
10667 : // PLR.
10668 3662 : OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
10669 3662 : OutletAirHumRat = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirHumRat + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirHumRat);
10670 3662 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
10671 : } else {
10672 : // Default to cycling fan, cycling compressor
10673 17623 : OutletAirEnthalpy = FullLoadOutAirEnth;
10674 17623 : OutletAirHumRat = FullLoadOutAirHumRat;
10675 17623 : OutletAirTemp = FullLoadOutAirTemp;
10676 : }
10677 :
10678 : // Check for saturation error and modify temperature at constant enthalpy
10679 21285 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, RoutineName)) {
10680 436 : OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
10681 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10682 : // IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
10683 : // OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
10684 436 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
10685 : }
10686 :
10687 : // Reset AirMassFlow to inlet node air mass flow for final total, sensible and latent calculations
10688 : // since AirMassFlow might have been modified above (in this subroutine):
10689 : // IF (FanOpMode .EQ. FanOp::Cycling) AirMassFlow = AirMassFlow / PartLoadRatio
10690 : // For multimode coil, this should be full flow including bypassed fraction
10691 21285 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10692 :
10693 : // Coil total/sensible/latent cooling rates
10694 21285 : CalcComponentSensibleLatentOutput(AirMassFlow,
10695 : InletAirDryBulbTemp,
10696 : InletAirHumRat,
10697 : OutletAirTemp,
10698 : OutletAirHumRat,
10699 21285 : thisDXCoil.SensCoolingEnergyRate,
10700 21285 : thisDXCoil.LatCoolingEnergyRate,
10701 21285 : thisDXCoil.TotalCoolingEnergyRate);
10702 :
10703 21285 : thisDXCoil.OutletAirTemp = OutletAirTemp;
10704 21285 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
10705 21285 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
10706 :
10707 : } else {
10708 :
10709 : // DX coil is off; just pass through conditions
10710 28214 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10711 28214 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
10712 28214 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
10713 :
10714 28214 : thisDXCoil.ElecCoolingPower = 0.0;
10715 28214 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
10716 28214 : thisDXCoil.SensCoolingEnergyRate = 0.0;
10717 28214 : thisDXCoil.LatCoolingEnergyRate = 0.0;
10718 28214 : thisDXCoil.EvapCondPumpElecPower = 0.0;
10719 28214 : thisDXCoil.EvapWaterConsumpRate = 0.0;
10720 :
10721 : // Reset globals when DX coil is OFF for use in heat recovery module
10722 28214 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
10723 28214 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
10724 :
10725 : } // end of on/off if - else
10726 :
10727 : // set water system demand request (if needed)
10728 49499 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
10729 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
10730 0 : thisDXCoil.EvapWaterConsumpRate;
10731 : }
10732 :
10733 49499 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
10734 49499 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
10735 49499 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
10736 49499 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
10737 49499 : thisDXCoil.CondInletTemp = CondInletTemp;
10738 49499 : state.dataDXCoils->DXCoilTotalCooling(DXCoilNum) = thisDXCoil.TotalCoolingEnergyRate;
10739 49499 : state.dataDXCoils->DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
10740 :
10741 : // set outlet node conditions
10742 49499 : int airOutletNode = thisDXCoil.AirOutNode;
10743 49499 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
10744 49499 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
10745 49499 : }
10746 :
10747 177475 : void CalcDXHeatingCoil(EnergyPlusData &state,
10748 : int const DXCoilNum, // the number of the DX heating coil to be simulated
10749 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
10750 : HVAC::FanOp const fanOp, // Allows parent object to control fan mode
10751 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
10752 : ObjexxFCL::Optional<Real64 const> MaxHeatCap // maximum allowed heating capacity
10753 : )
10754 : {
10755 :
10756 : // SUBROUTINE INFORMATION:
10757 : // AUTHOR Richard Raustad
10758 : // DATE WRITTEN October 2001
10759 : // MODIFIED Raustad/Shirey Mar 2004
10760 : // Kenneth Tang 2004 (Sensitivity of TotCapTempModFac & EIRTempModFac to indoor dry bulb temp)
10761 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
10762 : // Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
10763 :
10764 : // PURPOSE OF THIS SUBROUTINE:
10765 : // Calculates the air-side heating performance and electrical heating energy
10766 : // use of a direct-expansion, air-cooled heat pump unit.
10767 :
10768 : // METHODOLOGY EMPLOYED:
10769 : // This routine simulates the performance of air-cooled DX heating equipment.
10770 : // The routine requires the user to enter the total heating capacity
10771 : // and COP for the unit at ARI 210/240 rating conditions (21.11C [70F] dry-bulb,
10772 : // 15.55C [60F] wet-bulb air entering the heating coil, 8.33C [47F] dry-bulb,
10773 : // 6.11C [43F] wet-bulb air entering the outdoor condenser. Since different
10774 : // manufacturer's rate their equipment at different air flow rates, the supply
10775 : // air flow rate corresponding to the rated capacities and rated COP must also
10776 : // be entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information
10777 : // entered by the user should NOT include the thermal or electrical impacts of the
10778 : // supply air fan, as this is addressed by another module.
10779 :
10780 : // With the rated performance data entered by the user, the model employs some of the
10781 : // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
10782 : // of outdoor air temperatures and supply air flow rate (actual vs rated flow). The
10783 : // model does NOT employ the exact same methodology to calculate performance as DOE-2,
10784 : // although some of the DOE-2 curve fits are employed by this model.
10785 :
10786 : // REFERENCES:
10787 : // Winkelmann, F.C., Birdsall, B.E., Buhl W.F., Ellington, K.L., Erdem, A.E. 1993.
10788 : // DOE-2 Supplement Version 2.1E. Energy and Environment Division, Lawrence Berkeley
10789 : // Laboratory.
10790 : // Henderson, H.I. Jr., Y.J. Huang and Danny Parker. 1999. Residential Equipment Part
10791 : // Load Curves for Use in DOE-2. Environmental Energy Technologies Division, Ernest
10792 : // Orlando Lawrence Berkeley National Laboratory.
10793 :
10794 : // Using/Aliasing
10795 : using Curve::CurveValue;
10796 :
10797 : // SUBROUTINE PARAMETER DEFINITIONS:
10798 : static constexpr std::string_view RoutineNameFullLoad("CalcDXHeatingCoil:fullload");
10799 :
10800 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10801 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
10802 : Real64 AirMassFlowRatio; // Ratio of actual air mass flow to rated air mass flow
10803 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s]
10804 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W]
10805 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
10806 : Real64 TotCapAdj; // adjusted total cooling capacity at off-rated conditions [W]
10807 : Real64 TotCapTempModFac; // Total capacity modifier (function of entering drybulb, outside drybulb) depending
10808 : // on the type of curve
10809 : Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs rated flow)
10810 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
10811 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
10812 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
10813 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
10814 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10815 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
10816 : Real64 FullLoadOutAirEnth; // outlet full load enthalpy [J/kg]
10817 : Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
10818 : Real64 FullLoadOutAirTemp; // outlet air temperature at full load [C]
10819 : Real64 FullLoadOutAirRH; // outlet air relative humidity at full load
10820 177475 : Real64 EIRTempModFac(0.0); // EIR modifier (function of entering drybulb, outside drybulb) depending on the
10821 : // type of curve
10822 : Real64 DefrostEIRTempModFac; // EIR modifier for defrost (function of entering wetbulb, outside drybulb)
10823 : Real64 EIRFlowModFac; // EIR modifier (function of actual supply air flow vs rated flow)
10824 : Real64 EIR; // EIR at part load and off rated conditions
10825 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup
10826 : Real64 PLRHeating; // PartLoadRatio in heating
10827 : Real64 OutdoorCoilT; // Outdoor coil temperature (C)
10828 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
10829 : Real64 FractionalDefrostTime; // Fraction of time step system is in defrost
10830 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
10831 : Real64 InputPowerMultiplier; // Multiplier for power when system is in defrost
10832 : Real64 LoadDueToDefrost; // Additional load due to defrost
10833 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
10834 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
10835 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
10836 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
10837 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
10838 177475 : constexpr int Mode(1); // Performance mode for MultiMode DX coil; Always 1 for other coil types
10839 : Real64 AirFlowRatio; // Ratio of compressor on airflow to average timestep airflow
10840 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
10841 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
10842 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
10843 177475 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
10844 :
10845 177475 : if (present(OnOffAirFlowRatio)) {
10846 177462 : AirFlowRatio = OnOffAirFlowRatio;
10847 : } else {
10848 13 : AirFlowRatio = 1.0;
10849 : }
10850 :
10851 177475 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
10852 : // Get condenser outdoor node info from DX Heating Coil
10853 177475 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
10854 49438 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp;
10855 49438 : CompAmbTemp = OutdoorDryBulb;
10856 49438 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
10857 32 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10858 32 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10859 32 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10860 32 : CompAmbTemp = state.dataEnvrn->OutDryBulbTemp;
10861 : } else {
10862 49406 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press;
10863 : // If node is not connected to anything, pressure = default, use weather data
10864 49406 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
10865 94 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10866 94 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10867 94 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10868 94 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10869 : } else {
10870 49312 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat;
10871 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
10872 49312 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb;
10873 : }
10874 49406 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
10875 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
10876 0 : OutdoorDryBulb = secZoneHB.ZT;
10877 0 : OutdoorHumRat = secZoneHB.airHumRat;
10878 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
10879 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10880 0 : CompAmbTemp = OutdoorDryBulb;
10881 : }
10882 : }
10883 128037 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
10884 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
10885 0 : OutdoorDryBulb = secZoneHB.ZT;
10886 0 : OutdoorHumRat = secZoneHB.airHumRat;
10887 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
10888 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10889 0 : CompAmbTemp = OutdoorDryBulb;
10890 : } else {
10891 128037 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10892 128037 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10893 128037 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10894 128037 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10895 128037 : CompAmbTemp = OutdoorDryBulb;
10896 : }
10897 :
10898 177475 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10899 177475 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
10900 177475 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10901 177475 : InletAirHumRat = thisDXCoil.InletAirHumRat;
10902 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10903 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
10904 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
10905 177475 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
10906 177475 : PLRHeating = 0.0;
10907 177475 : thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
10908 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
10909 177475 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
10910 40005 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
10911 40005 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
10912 2 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
10913 : }
10914 : } else {
10915 137470 : CrankcaseHeatingPower = 0.0;
10916 : }
10917 :
10918 220922 : if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
10919 43447 : OutdoorDryBulb > thisDXCoil.MinOATCompressor) {
10920 : // for cycling fan, reset mass flow to full on rate
10921 14022 : if (fanOp == HVAC::FanOp::Cycling) AirMassFlow /= PartLoadRatio;
10922 14022 : if (fanOp == HVAC::FanOp::Continuous) AirMassFlow *= AirFlowRatio;
10923 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton)
10924 14022 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
10925 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10926 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
10927 14022 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
10928 :
10929 28044 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
10930 14022 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
10931 1 : if (thisDXCoil.ErrIndex1 == 0) {
10932 2 : ShowWarningMessage(
10933 : state,
10934 2 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at {:.3R} m3/s/W.",
10935 1 : thisDXCoil.DXCoilType,
10936 1 : thisDXCoil.Name,
10937 : VolFlowperRatedTotCap));
10938 2 : ShowContinueErrorTimeStamp(state, "");
10939 2 : ShowContinueError(state,
10940 2 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
10941 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
10942 1 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
10943 2 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
10944 3 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
10945 : }
10946 8 : ShowRecurringWarningErrorAtEnd(
10947 : state,
10948 2 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10949 : "\" - Air volume flow rate per watt of rated total heating capacity is out of range error continues...",
10950 1 : thisDXCoil.ErrIndex1,
10951 : VolFlowperRatedTotCap,
10952 : VolFlowperRatedTotCap);
10953 : }
10954 :
10955 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
10956 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
10957 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
10958 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
10959 14022 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
10960 15 : switch (thisDXCoil.HeatingPerformanceOATType) {
10961 15 : case HVAC::OATType::DryBulb: {
10962 15 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
10963 15 : } break;
10964 0 : case HVAC::OATType::WetBulb: {
10965 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp, OutdoorWetBulb);
10966 0 : } break;
10967 0 : default: {
10968 0 : TotCapTempModFac = 1.0;
10969 0 : } break;
10970 : }
10971 : } else {
10972 14007 : switch (thisDXCoil.HeatingPerformanceOATType) {
10973 14 : case HVAC::OATType::DryBulb: {
10974 14 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
10975 3 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), OutdoorDryBulb);
10976 : } else {
10977 11 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp);
10978 : }
10979 14 : } break;
10980 13993 : case HVAC::OATType::WetBulb: {
10981 13993 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
10982 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), OutdoorWetBulb);
10983 : } else {
10984 13993 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp);
10985 : }
10986 13993 : } break;
10987 0 : default: {
10988 0 : TotCapTempModFac = 1.0;
10989 0 : } break;
10990 : }
10991 : }
10992 :
10993 14022 : if (TotCapTempModFac < 0.0) {
10994 0 : if (thisDXCoil.CAPFTErrIndex == 0) {
10995 0 : ShowWarningMessage(state,
10996 0 : format("The TotCapTempModFac curve value for DX heating coil {} ={:.2R}", thisDXCoil.Name, TotCapTempModFac));
10997 0 : ShowContinueError(state,
10998 : "TotCapTempModFac curve value must be > 0. TotCapTempModFac curve value has been reset to 0.0 and "
10999 : "simulation is continuing.");
11000 0 : ShowContinueError(state, format("Check the IO reference manual for TotCapTempModFac curve guidance [ {} ].", thisDXCoil.DXCoilType));
11001 0 : ShowContinueErrorTimeStamp(state, "");
11002 : }
11003 0 : ShowRecurringWarningErrorAtEnd(state,
11004 : "DX heating coil TotCapTempModFac curve value < 0 warning continues... ",
11005 0 : thisDXCoil.CAPFTErrIndex,
11006 : TotCapTempModFac,
11007 : TotCapTempModFac);
11008 0 : TotCapTempModFac = 0.0;
11009 : }
11010 :
11011 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
11012 14022 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
11013 14022 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
11014 :
11015 : // Calculate total heating capacity for off-rated conditions
11016 14022 : TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
11017 :
11018 : // Calculating adjustment factors for defrost
11019 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
11020 14022 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
11021 14022 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
11022 :
11023 : // Initializing defrost adjustment factors
11024 14022 : LoadDueToDefrost = 0.0;
11025 14022 : HeatingCapacityMultiplier = 1.0;
11026 14022 : FractionalDefrostTime = 0.0;
11027 14022 : InputPowerMultiplier = 1.0;
11028 :
11029 : // Check outdoor temperature to determine of defrost is active
11030 14022 : if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost && thisDXCoil.CondenserType(Mode) != DataHeatBalance::RefrigCondenserType::Water) {
11031 : // Calculate defrost adjustment factors depending on defrost control type
11032 37 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
11033 37 : FractionalDefrostTime = thisDXCoil.DefrostTime;
11034 37 : if (FractionalDefrostTime > 0.0) {
11035 37 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
11036 1 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
11037 1 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
11038 : } else {
11039 36 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
11040 36 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
11041 36 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
11042 0 : ShowWarningMessage(state,
11043 0 : format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
11044 : "actuator must be both provided for DX heating coil {}",
11045 0 : thisDXCoil.Name));
11046 0 : ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
11047 : }
11048 : }
11049 : }
11050 : } else { // else defrost control is on-demand
11051 0 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
11052 0 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
11053 0 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
11054 0 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
11055 : } else {
11056 0 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
11057 0 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
11058 0 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
11059 0 : ShowWarningMessage(state,
11060 0 : format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
11061 : "actuator must be both provided for DX heating coil {}",
11062 0 : thisDXCoil.Name));
11063 0 : ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
11064 : }
11065 : }
11066 : }
11067 :
11068 37 : if (FractionalDefrostTime > 0.0) {
11069 : // Calculate defrost adjustment factors depending on defrost control strategy
11070 37 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
11071 32 : LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.RatedTotCap(Mode) / 1.01667);
11072 32 : DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
11073 32 : thisDXCoil.DefrostPower = DefrostEIRTempModFac * (thisDXCoil.RatedTotCap(Mode) / 1.01667) * FractionalDefrostTime;
11074 : } else { // Defrost strategy is resistive
11075 5 : thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
11076 : }
11077 : } else { // Defrost is not active because (FractionalDefrostTime .EQ. 0.0)
11078 0 : thisDXCoil.DefrostPower = 0.0;
11079 : }
11080 : }
11081 :
11082 : // Modify total heating capacity based on defrost heating capacity multiplier
11083 : // MaxHeatCap passed from parent object VRF Condenser and is used to limit capacity of TU's to that available from condenser
11084 14022 : if (present(MaxHeatCap)) {
11085 13997 : TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
11086 13997 : TotCap = min(MaxHeatCap, TotCap);
11087 : } else {
11088 25 : TotCapAdj = TotCap * HeatingCapacityMultiplier;
11089 : }
11090 :
11091 : // Calculate full load outlet conditions
11092 14022 : FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
11093 14022 : FullLoadOutAirHumRat = InletAirHumRat;
11094 14022 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
11095 14022 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
11096 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11097 : // FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
11098 14022 : if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
11099 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
11100 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11101 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
11102 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
11103 : }
11104 :
11105 : // Calculate actual outlet conditions for the input part load ratio
11106 : // Actual outlet conditions are "average" for time step
11107 14022 : if (fanOp == HVAC::FanOp::Continuous) {
11108 : // continuous fan, cycling compressor
11109 13990 : OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
11110 13990 : OutletAirHumRat = (PartLoadRatio * FullLoadOutAirHumRat + (1.0 - PartLoadRatio) * InletAirHumRat);
11111 13990 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11112 : } else {
11113 : // default to cycling fan, cycling compressor
11114 32 : OutletAirEnthalpy = FullLoadOutAirEnth;
11115 32 : OutletAirHumRat = FullLoadOutAirHumRat;
11116 32 : OutletAirTemp = FullLoadOutAirTemp;
11117 : }
11118 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
11119 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
11120 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
11121 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
11122 14022 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
11123 18 : if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 1) {
11124 2 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), OutdoorDryBulb);
11125 : } else {
11126 16 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
11127 : }
11128 18 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
11129 : } else {
11130 14004 : EIRTempModFac = 1.0;
11131 14004 : EIRFlowModFac = 1.0;
11132 : }
11133 :
11134 14022 : if (EIRTempModFac < 0.0) {
11135 0 : if (thisDXCoil.EIRFTErrIndex == 0) {
11136 0 : ShowWarningMessage(state, format("The EIRTempModFac curve value for DX heating coil {} ={:.2R}", thisDXCoil.Name, EIRTempModFac));
11137 0 : ShowContinueError(
11138 : state, "EIRTempModFac curve value must be > 0. EIRTempModFac curve value has been reset to 0.0 and simulation is continuing.");
11139 0 : ShowContinueError(state, format("Check the IO reference manual for EIRTempModFac curve guidance [ {} ].", thisDXCoil.DXCoilType));
11140 0 : ShowContinueErrorTimeStamp(state, "");
11141 : }
11142 0 : ShowRecurringWarningErrorAtEnd(state,
11143 : "DX heating coil EIRTempModFac curve value < 0.0 warning continues... ",
11144 0 : thisDXCoil.EIRFTErrIndex,
11145 : EIRTempModFac,
11146 : EIRTempModFac);
11147 0 : EIRTempModFac = 0.0;
11148 : }
11149 :
11150 14022 : EIR = thisDXCoil.RatedEIR(Mode) * EIRTempModFac * EIRFlowModFac;
11151 : // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
11152 14022 : if (TotCapAdj > 0.0) {
11153 14021 : PLRHeating = min(1.0, (PartLoadRatio + (LoadDueToDefrost * PartLoadRatio) / TotCapAdj));
11154 : } else {
11155 1 : PLRHeating = 0.0;
11156 : }
11157 14022 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating) {
11158 18 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PLRHeating); // Calculate part-load factor
11159 : } else {
11160 14004 : PLF = 1.0;
11161 : }
11162 :
11163 14022 : if (PLF < 0.7) {
11164 1 : if (thisDXCoil.PLRErrIndex == 0) {
11165 2 : ShowWarningMessage(
11166 : state,
11167 2 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
11168 2 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
11169 2 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
11170 3 : ShowContinueErrorTimeStamp(state, "");
11171 : }
11172 7 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
11173 1 : PLF = 0.7;
11174 : }
11175 :
11176 14022 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
11177 14022 : if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
11178 0 : if (thisDXCoil.ErrIndex4 == 0) {
11179 0 : ShowWarningMessage(state,
11180 0 : format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
11181 0 : thisDXCoil.Name,
11182 0 : thisDXCoil.HeatingCoilRuntimeFraction));
11183 0 : ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
11184 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
11185 0 : ShowContinueErrorTimeStamp(state, "");
11186 : }
11187 0 : ShowRecurringWarningErrorAtEnd(state,
11188 0 : thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
11189 0 : thisDXCoil.ErrIndex4,
11190 0 : thisDXCoil.HeatingCoilRuntimeFraction,
11191 0 : thisDXCoil.HeatingCoilRuntimeFraction);
11192 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
11193 14022 : } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
11194 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
11195 : }
11196 : // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
11197 14022 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
11198 14022 : thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
11199 :
11200 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
11201 : // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
11202 :
11203 14022 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
11204 14017 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
11205 : } else {
11206 5 : thisDXCoil.CrankcaseHeaterPower =
11207 5 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
11208 5 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
11209 : }
11210 :
11211 14022 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
11212 14022 : thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy);
11213 : // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
11214 : // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
11215 14022 : thisDXCoil.DefrostPower *= thisDXCoil.HeatingCoilRuntimeFraction;
11216 :
11217 14022 : thisDXCoil.OutletAirTemp = OutletAirTemp;
11218 14022 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
11219 14022 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
11220 14022 : thisDXCoil.CompressorPartLoadRatio = PartLoadRatio;
11221 :
11222 : } else {
11223 :
11224 : // DX coil is off; just pass through conditions
11225 163453 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
11226 163453 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
11227 163453 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
11228 :
11229 163453 : thisDXCoil.ElecHeatingPower = 0.0;
11230 163453 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
11231 163453 : thisDXCoil.DefrostPower = 0.0;
11232 :
11233 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
11234 : // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
11235 163453 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
11236 35512 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
11237 : } else {
11238 127941 : thisDXCoil.CrankcaseHeaterPower =
11239 127941 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
11240 : }
11241 163453 : thisDXCoil.CompressorPartLoadRatio = 0.0;
11242 :
11243 : } // end of on/off if - else
11244 :
11245 177475 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
11246 177475 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
11247 177475 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
11248 177475 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
11249 177475 : state.dataDXCoils->DXCoilTotalHeating(DXCoilNum) = thisDXCoil.TotalHeatingEnergyRate;
11250 177475 : state.dataDXCoils->DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
11251 177475 : state.dataDXCoils->DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;
11252 :
11253 : // set outlet node conditions
11254 177475 : int airOutletNode = thisDXCoil.AirOutNode;
11255 177475 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
11256 177475 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
11257 :
11258 : // calc secondary coil if specified
11259 177475 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
11260 0 : CalcSecondaryDXCoils(state, DXCoilNum);
11261 : }
11262 177475 : }
11263 :
11264 36791 : void CalcMultiSpeedDXCoil(EnergyPlusData &state,
11265 : int const DXCoilNum, // the number of the DX heating coil to be simulated
11266 : Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
11267 : Real64 const CycRatio, // cycling part load ratio
11268 : ObjexxFCL::Optional_bool_const ForceOn)
11269 : {
11270 :
11271 : // SUBROUTINE INFORMATION:
11272 : // AUTHOR Fred Buhl
11273 : // DATE WRITTEN September 2002
11274 : // MODIFIED Raustad/Shirey, Feb 2004
11275 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
11276 : // Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
11277 : // April 2010, Chandan sharma, FSEC, added basin heater
11278 :
11279 : // PURPOSE OF THIS SUBROUTINE:
11280 : // Calculates the air-side performance and electrical energy use of a direct-
11281 : // expansion, air-cooled cooling unit with a 2 speed or variable speed compressor.
11282 :
11283 : // METHODOLOGY EMPLOYED:
11284 : // Uses the same methodology as the single speed DX unit model (SUBROUTINE CalcDoe2DXCoil).
11285 : // In addition it assumes that the unit performance is obtained by interpolating between
11286 : // the performance at high speed and that at low speed. If the output needed is below
11287 : // that produced at low speed, the compressor cycles between off and low speed.
11288 :
11289 : // Using/Aliasing
11290 : using Curve::CurveValue;
11291 :
11292 : // SUBROUTINE ARGUMENT DEFINITIONS:
11293 : // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
11294 :
11295 : // SUBROUTINE PARAMETER DEFINITIONS:
11296 : static constexpr std::string_view RoutineNameHighSpeedOutlet("CalcMultiSpeedDXCoil:highspeedoutlet");
11297 : static constexpr std::string_view RoutineNameLowSpeedOutlet("CalcMultiSpeedDXCoil:lowspeedoutlet");
11298 : static constexpr std::string_view RoutineNameNewDewPointConditions("CalcMultiSpeedDXCoil:newdewpointconditions");
11299 :
11300 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11301 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
11302 : Real64 AirMassFlowRatio; // Ratio of max air mass flow to rated air mass flow
11303 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
11304 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
11305 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
11306 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
11307 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11308 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
11309 : Real64 OutletAirDryBulbTemp; // outlet air dry bulb temperature [C]
11310 : Real64 OutletAirEnthalpy; // outlet air enthalpy [J/kg]
11311 : Real64 OutletAirHumRat; // outlet air humidity ratio [kg/kg]
11312 : Real64 OutletAirDryBulbTempSat; // outlet air dry bulb temp at saturation at the outlet enthalpy [C]
11313 : Real64 LSOutletAirDryBulbTemp; // low speed outlet air dry bulb temperature [C]
11314 : Real64 LSOutletAirEnthalpy; // low speed outlet air enthalpy [J/kg]
11315 : Real64 LSOutletAirHumRat; // low speed outlet air humidity ratio [kg/kg]
11316 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
11317 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
11318 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
11319 : Real64 tADP; // Apparatus dew point temperature [C]
11320 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
11321 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
11322 : Real64 RatedCBFHS; // coil bypass factor at rated conditions (high speed)
11323 : Real64 CBFHS; // coil bypass factor at max flow (high speed)
11324 : Real64 TotCapHS; // total capacity at high speed [W]
11325 : Real64 SHRHS; // sensible heat ratio at high speed
11326 : Real64 TotCapLS; // total capacity at low speed [W]
11327 : Real64 SHRLS; // sensible heat ratio at low speed
11328 : Real64 EIRTempModFacHS; // EIR modifier (function of entering wetbulb, outside drybulb) (high speed)
11329 : Real64 EIRFlowModFacHS; // EIR modifier (function of actual supply air flow vs rated flow) (high speed)
11330 : Real64 EIRHS; // EIR at off rated conditions (high speed)
11331 : Real64 EIRTempModFacLS; // EIR modifier (function of entering wetbulb, outside drybulb) (low speed)
11332 : Real64 EIRLS; // EIR at off rated conditions (low speed)
11333 : Real64 TotCap; // total capacity at current speed [W]
11334 : Real64 SHR; // sensible heat ratio at current speed
11335 : Real64 EIR; // EIR at current speed
11336 : Real64 AirMassFlowNom; // speed ratio weighted average of high and low speed air mass flow rates [kg/s]
11337 : Real64 CBFNom; // coil bypass factor corresponding to AirMassFlowNom and SpeedRatio
11338 : Real64 CBF; // CBFNom adjusted for actual air mass flow rate
11339 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in
11340 : // power calculation
11341 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
11342 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
11343 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
11344 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
11345 : Real64 RhoAir; // Density of air [kg/m3]
11346 : Real64 RhoWater; // Density of water [kg/m3]
11347 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
11348 : Real64 EvapCondPumpElecPower; // Evaporative condenser electric pump power [W]
11349 36791 : constexpr int Mode(1); // Performance mode for MultiMode DX coil; Always 1 for other coil types
11350 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
11351 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
11352 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
11353 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
11354 : bool LocalForceOn;
11355 : Real64 AirMassFlowRatio2; // Ratio of low speed air mass flow to rated air mass flow
11356 36791 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
11357 :
11358 36791 : if (present(ForceOn)) {
11359 3306 : LocalForceOn = true;
11360 : } else {
11361 33485 : LocalForceOn = false;
11362 : }
11363 :
11364 36791 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
11365 :
11366 36791 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
11367 0 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
11368 : // If node is not connected to anything, pressure = default, use weather data
11369 0 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
11370 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
11371 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
11372 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11373 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
11374 : } else {
11375 0 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
11376 0 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
11377 0 : OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure);
11378 : }
11379 0 : CompAmbTemp = OutdoorDryBulb;
11380 0 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
11381 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
11382 0 : OutdoorDryBulb = secZoneHB.ZT;
11383 0 : OutdoorHumRat = secZoneHB.airHumRat;
11384 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
11385 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11386 0 : CompAmbTemp = OutdoorDryBulb;
11387 : }
11388 36791 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
11389 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
11390 0 : OutdoorDryBulb = secZoneHB.ZT;
11391 0 : OutdoorHumRat = secZoneHB.airHumRat;
11392 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
11393 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11394 0 : CompAmbTemp = OutdoorDryBulb;
11395 : } else {
11396 36791 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
11397 36791 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
11398 36791 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11399 36791 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
11400 36791 : CompAmbTemp = OutdoorDryBulb;
11401 : }
11402 :
11403 36791 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
11404 36791 : AirMassFlowRatio = thisDXCoil.InletAirMassFlowRateMax / thisDXCoil.RatedAirMassFlowRate(Mode);
11405 36791 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
11406 36791 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
11407 36791 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
11408 36791 : InletAirHumRat = thisDXCoil.InletAirHumRat;
11409 36791 : AirMassFlowRatio2 = 1.0; // DXCoil(DXCoilNum)%RatedAirMassFlowRate2 / DXCoil(DXCoilNum)%RatedAirMassFlowRate(Mode)
11410 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11411 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
11412 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
11413 36791 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
11414 36791 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
11415 36780 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
11416 11 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11417 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
11418 11 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
11419 11 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
11420 : }
11421 :
11422 58329 : if ((AirMassFlow > 0.0 && CompAmbTemp >= thisDXCoil.MinOATCompressor) && ((thisDXCoil.availSched->getCurrentVal() > 0.0) || (LocalForceOn)) &&
11423 21538 : (SpeedRatio > 0.0 || CycRatio > 0.0)) {
11424 :
11425 29226 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
11426 29226 : if (SpeedRatio > 0.0) {
11427 : // Adjust high speed coil bypass factor for actual maximum air flow rate.
11428 15248 : RatedCBFHS = thisDXCoil.RatedCBF(Mode);
11429 15248 : CBFHS = AdjustCBF(RatedCBFHS, thisDXCoil.RatedAirMassFlowRate(Mode), thisDXCoil.InletAirMassFlowRateMax);
11430 : // get high speed total capacity and SHR at current conditions
11431 45744 : CalcTotCapSHR(state,
11432 : InletAirDryBulbTemp,
11433 : InletAirHumRat,
11434 : InletAirEnthalpy,
11435 : InletAirWetBulbC,
11436 : AirMassFlowRatio,
11437 : thisDXCoil.InletAirMassFlowRateMax,
11438 15248 : thisDXCoil.RatedTotCap(Mode),
11439 : CBFHS,
11440 15248 : thisDXCoil.CCapFTemp(Mode),
11441 15248 : thisDXCoil.CCapFFlow(Mode),
11442 : TotCapHS,
11443 : SHRHS,
11444 : CondInletTemp,
11445 : OutdoorPressure,
11446 15248 : thisDXCoil.capModFacTotal);
11447 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11448 : // CondInletTemp, Node(DXCoil(DXCoilNum)%AirInNode)%Press)
11449 : // get the high speed SHR from user specified SHR modifier curves
11450 15248 : if (thisDXCoil.UserSHRCurveExists) {
11451 0 : SHRHS = CalcSHRUserDefinedCurves(state,
11452 : InletAirDryBulbTemp,
11453 : InletAirWetBulbC,
11454 : AirMassFlowRatio,
11455 0 : thisDXCoil.SHRFTemp(Mode),
11456 0 : thisDXCoil.SHRFFlow(Mode),
11457 0 : thisDXCoil.RatedSHR(Mode));
11458 : }
11459 : // get low speed total capacity and SHR at current conditions
11460 15248 : CalcTotCapSHR(state,
11461 : InletAirDryBulbTemp,
11462 : InletAirHumRat,
11463 : InletAirEnthalpy,
11464 : InletAirWetBulbC,
11465 : 1.0,
11466 : thisDXCoil.RatedAirMassFlowRate2,
11467 : thisDXCoil.RatedTotCap2,
11468 : thisDXCoil.RatedCBF2,
11469 : thisDXCoil.CCapFTemp2,
11470 15248 : thisDXCoil.CCapFFlow(Mode),
11471 : TotCapLS,
11472 : SHRLS,
11473 : CondInletTemp,
11474 : OutdoorPressure,
11475 15248 : thisDXCoil.capModFacTotal);
11476 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11477 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)
11478 : // get the low speed SHR from user specified SHR modifier curves
11479 15248 : if (thisDXCoil.UserSHRCurveExists) {
11480 0 : SHRLS = CalcSHRUserDefinedCurves(state,
11481 : InletAirDryBulbTemp,
11482 : InletAirWetBulbC,
11483 : AirMassFlowRatio2,
11484 : thisDXCoil.SHRFTemp2,
11485 : thisDXCoil.SHRFFlow2,
11486 : thisDXCoil.RatedSHR2);
11487 : }
11488 : // get high speed EIR at current conditions
11489 15248 : EIRTempModFacHS = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirWetBulbC, CondInletTemp);
11490 15248 : EIRFlowModFacHS = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
11491 15248 : EIRHS = thisDXCoil.RatedEIR(Mode) * EIRFlowModFacHS * EIRTempModFacHS;
11492 : // get low speed EIR at current conditions
11493 : // EIRTempModFacLS = CurveValue(state, DXCoil(DXCoilNum)%EIRFTemp(Mode),InletAirWetBulbC,CondInletTemp)
11494 : // CR7307 changed EIRTempModFacLS calculation to that shown below.
11495 15248 : EIRTempModFacLS = CurveValue(state, thisDXCoil.EIRFTemp2, InletAirWetBulbC, CondInletTemp);
11496 15248 : EIRLS = thisDXCoil.RatedEIR2 * EIRTempModFacLS;
11497 :
11498 : // get current total capacity, SHR, EIR
11499 15248 : if (SpeedRatio >= 1.0) {
11500 5106 : TotCap = TotCapHS;
11501 5106 : SHR = SHRHS;
11502 5106 : EIR = EIRHS;
11503 5106 : CBFNom = CBFHS;
11504 5106 : AirMassFlowNom = thisDXCoil.InletAirMassFlowRateMax;
11505 5106 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
11506 5106 : EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower(Mode);
11507 : } else {
11508 10142 : TotCap = SpeedRatio * TotCapHS + (1.0 - SpeedRatio) * TotCapLS;
11509 10142 : EIR = SpeedRatio * EIRHS + (1.0 - SpeedRatio) * EIRLS;
11510 10142 : CBFNom = SpeedRatio * CBFHS + (1.0 - SpeedRatio) * thisDXCoil.RatedCBF2;
11511 10142 : AirMassFlowNom = SpeedRatio * thisDXCoil.InletAirMassFlowRateMax + (1.0 - SpeedRatio) * thisDXCoil.RatedAirMassFlowRate2;
11512 10142 : CondAirMassFlow = RhoAir * (SpeedRatio * thisDXCoil.EvapCondAirFlow(Mode) + (1.0 - SpeedRatio) * thisDXCoil.EvapCondAirFlow2);
11513 10142 : EvapCondPumpElecPower =
11514 10142 : SpeedRatio * thisDXCoil.EvapCondPumpElecNomPower(Mode) + (1.0 - SpeedRatio) * thisDXCoil.EvapCondPumpElecNomPower2;
11515 : }
11516 15248 : hDelta = TotCap / AirMassFlow;
11517 15248 : if (thisDXCoil.UserSHRCurveExists) {
11518 0 : if (SpeedRatio >= 1.0) {
11519 0 : SHR = SHRHS;
11520 : } else {
11521 0 : SHR = min(SpeedRatio * SHRHS + (1.0 - SpeedRatio) * SHRLS, 1.0);
11522 : }
11523 0 : OutletAirEnthalpy = InletAirEnthalpy - hDelta;
11524 0 : if (SHR < 1.0) {
11525 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11526 0 : OutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11527 0 : if (OutletAirHumRat <= 0.0) {
11528 0 : OutletAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
11529 : }
11530 : } else {
11531 0 : SHR = 1.0;
11532 0 : OutletAirHumRat = InletAirHumRat;
11533 : }
11534 0 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11535 0 : OutletAirDryBulbTempSat = PsyTdpFnWPb(state, OutletAirHumRat, OutdoorPressure, RoutineNameHighSpeedOutlet);
11536 0 : if (OutletAirDryBulbTempSat > OutletAirDryBulbTemp) {
11537 0 : OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11538 0 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy, RoutineNameHighSpeedOutlet);
11539 : }
11540 :
11541 : } else {
11542 : // Adjust CBF for off-nominal flow
11543 15248 : CBF = AdjustCBF(CBFNom, AirMassFlowNom, AirMassFlow);
11544 : // Calculate new apparatus dew point conditions
11545 15248 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
11546 15248 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure);
11547 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11548 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
11549 15248 : wADP = PsyWFnTdbH(state, tADP, hADP);
11550 15248 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
11551 : // get corresponding SHR
11552 15248 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
11553 15248 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
11554 : } else {
11555 0 : SHR = 1.0;
11556 : }
11557 :
11558 : // cr8918 SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
11559 15248 : OutletAirEnthalpy = InletAirEnthalpy - hDelta;
11560 : // get outlet conditions
11561 15248 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11562 15248 : OutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11563 :
11564 15248 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11565 15248 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
11566 15248 : if (OutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
11567 12 : OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11568 12 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy);
11569 : }
11570 : }
11571 : // Coil total/sensible/latent cooling rates and electrical power
11572 15248 : CalcComponentSensibleLatentOutput(AirMassFlow,
11573 : InletAirDryBulbTemp,
11574 : InletAirHumRat,
11575 : OutletAirDryBulbTemp,
11576 : OutletAirHumRat,
11577 15248 : thisDXCoil.SensCoolingEnergyRate,
11578 15248 : thisDXCoil.LatCoolingEnergyRate,
11579 15248 : thisDXCoil.TotalCoolingEnergyRate);
11580 15248 : thisDXCoil.ElecCoolingPower = TotCap * EIR;
11581 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
11582 15248 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
11583 15248 : thisDXCoil.PartLoadRatio = 1.0;
11584 15248 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0;
11585 :
11586 15248 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
11587 15248 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
11588 15248 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
11589 :
11590 13978 : } else if (CycRatio > 0.0) {
11591 :
11592 13978 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11593 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
11594 2 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect2);
11595 2 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
11596 : }
11597 :
11598 : // Adjust low speed coil bypass factor for actual flow rate.
11599 : // CBF = AdjustCBF(DXCoil(DXCoilNum)%RatedCBF2,DXCoil(DXCoilNum)%RatedAirMassFlowRate2,AirMassFlow)
11600 : // get low speed total capacity and SHR at current conditions
11601 13978 : CalcTotCapSHR(state,
11602 : InletAirDryBulbTemp,
11603 : InletAirHumRat,
11604 : InletAirEnthalpy,
11605 : InletAirWetBulbC,
11606 : 1.0,
11607 : thisDXCoil.RatedAirMassFlowRate2,
11608 : thisDXCoil.RatedTotCap2,
11609 : thisDXCoil.RatedCBF2,
11610 : thisDXCoil.CCapFTemp2,
11611 13978 : thisDXCoil.CCapFFlow(Mode),
11612 : TotCapLS,
11613 : SHRLS,
11614 : CondInletTemp,
11615 : OutdoorPressure,
11616 13978 : thisDXCoil.capModFacTotal);
11617 : // get the low speed SHR from user specified SHR modifier curves
11618 13978 : if (thisDXCoil.UserSHRCurveExists) {
11619 0 : SHRLS = CalcSHRUserDefinedCurves(
11620 : state, InletAirDryBulbTemp, InletAirWetBulbC, 1.0, thisDXCoil.SHRFTemp2, thisDXCoil.SHRFFlow2, thisDXCoil.RatedSHR2);
11621 : }
11622 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11623 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)
11624 13978 : hDelta = TotCapLS / AirMassFlow;
11625 13978 : if (thisDXCoil.UserSHRCurveExists) {
11626 0 : SHR = SHRLS;
11627 0 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
11628 0 : if (SHR < 1.0) {
11629 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11630 0 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11631 0 : if (LSOutletAirHumRat <= 0.0) {
11632 0 : LSOutletAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
11633 : }
11634 : } else {
11635 0 : SHR = 1.0;
11636 0 : LSOutletAirHumRat = InletAirHumRat;
11637 : }
11638 0 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
11639 0 : OutletAirDryBulbTempSat = PsyTdpFnWPb(state, LSOutletAirHumRat, OutdoorPressure, RoutineNameLowSpeedOutlet);
11640 0 : if (OutletAirDryBulbTempSat > LSOutletAirDryBulbTemp) {
11641 0 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11642 0 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineNameLowSpeedOutlet);
11643 : }
11644 :
11645 : } else {
11646 : // Adjust CBF for off-nominal flow
11647 13978 : CBF = AdjustCBF(thisDXCoil.RatedCBF2, thisDXCoil.RatedAirMassFlowRate2, AirMassFlow);
11648 : // Calculate new apparatus dew point conditions
11649 13978 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
11650 13978 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineNameNewDewPointConditions);
11651 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11652 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
11653 13978 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineNameNewDewPointConditions);
11654 13978 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
11655 : // get corresponding SHR
11656 13978 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
11657 13978 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
11658 : } else {
11659 0 : SHR = 1.0;
11660 : }
11661 : // cr8918 SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
11662 : // get low speed outlet conditions
11663 13978 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
11664 13978 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11665 13978 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11666 13978 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
11667 13978 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineNameLowSpeedOutlet);
11668 13978 : if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
11669 6 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11670 6 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineNameLowSpeedOutlet);
11671 : }
11672 : }
11673 : // outlet conditions are average of inlet and low speed weighted by CycRatio
11674 13978 : OutletAirEnthalpy = CycRatio * LSOutletAirEnthalpy + (1.0 - CycRatio) * InletAirEnthalpy;
11675 13978 : OutletAirHumRat = CycRatio * LSOutletAirHumRat + (1.0 - CycRatio) * InletAirHumRat;
11676 13978 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11677 : // get low speed EIR at current conditions
11678 : // EIRTempModFacLS = CurveValue(state, DXCoil(DXCoilNum)%EIRFTemp(Mode),InletAirWetBulbC,CondInletTemp)
11679 : // CR7307 changed EIRTempModFacLS calculation to that shown below.
11680 13978 : EIRTempModFacLS = CurveValue(state, thisDXCoil.EIRFTemp2, InletAirWetBulbC, CondInletTemp);
11681 13978 : EIRLS = thisDXCoil.RatedEIR2 * EIRTempModFacLS;
11682 : // get the part load factor that will account for cycling losses
11683 13978 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CycRatio);
11684 13978 : if (PLF < 0.7) {
11685 0 : PLF = 0.7;
11686 : }
11687 : // calculate the run time fraction
11688 13978 : thisDXCoil.CoolingCoilRuntimeFraction = CycRatio / PLF;
11689 13978 : thisDXCoil.PartLoadRatio = CycRatio;
11690 13978 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
11691 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
11692 : }
11693 : // get the electrical power consumption
11694 13978 : thisDXCoil.ElecCoolingPower = TotCapLS * EIRLS * thisDXCoil.CoolingCoilRuntimeFraction;
11695 :
11696 : // Coil total/sensible/latent cooling rates and electrical power
11697 13978 : CalcComponentSensibleLatentOutput(AirMassFlow,
11698 : InletAirDryBulbTemp,
11699 : InletAirHumRat,
11700 : OutletAirDryBulbTemp,
11701 : OutletAirHumRat,
11702 13978 : thisDXCoil.SensCoolingEnergyRate,
11703 13978 : thisDXCoil.LatCoolingEnergyRate,
11704 13978 : thisDXCoil.TotalCoolingEnergyRate);
11705 13978 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
11706 13978 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
11707 13978 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
11708 13978 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
11709 13978 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow2 * thisDXCoil.CoolingCoilRuntimeFraction;
11710 13978 : EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower2 * thisDXCoil.CoolingCoilRuntimeFraction;
11711 : }
11712 :
11713 29226 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11714 : //******************
11715 : // WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
11716 : // H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
11717 : // /RhoWater [kgWater/m3]
11718 : //******************
11719 9 : RhoWater = RhoH2O(OutdoorDryBulb);
11720 9 : thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater;
11721 9 : thisDXCoil.EvapCondPumpElecPower = EvapCondPumpElecPower;
11722 : // set water system demand request (if needed)
11723 9 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
11724 :
11725 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
11726 0 : thisDXCoil.EvapWaterConsumpRate;
11727 : }
11728 :
11729 : // Calculate basin heater power
11730 9 : CalcBasinHeaterPower(state,
11731 : thisDXCoil.BasinHeaterPowerFTempDiff,
11732 : thisDXCoil.basinHeaterSched,
11733 : thisDXCoil.BasinHeaterSetPointTemp,
11734 9 : thisDXCoil.BasinHeaterPower);
11735 9 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
11736 : }
11737 :
11738 : } else {
11739 :
11740 : // DX coil is off; just pass through conditions
11741 7565 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
11742 7565 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
11743 7565 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
11744 :
11745 7565 : thisDXCoil.ElecCoolingPower = 0.0;
11746 7565 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
11747 7565 : thisDXCoil.SensCoolingEnergyRate = 0.0;
11748 7565 : thisDXCoil.LatCoolingEnergyRate = 0.0;
11749 7565 : thisDXCoil.EvapCondPumpElecPower = 0.0;
11750 7565 : thisDXCoil.EvapWaterConsumpRate = 0.0;
11751 :
11752 : // Calculate basin heater power
11753 7565 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11754 2 : CalcBasinHeaterPower(state,
11755 : thisDXCoil.BasinHeaterPowerFTempDiff,
11756 : thisDXCoil.basinHeaterSched,
11757 : thisDXCoil.BasinHeaterSetPointTemp,
11758 2 : thisDXCoil.BasinHeaterPower);
11759 : }
11760 : }
11761 :
11762 36791 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
11763 36791 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
11764 36791 : thisDXCoil.CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure
11765 :
11766 : // set outlet node conditions
11767 36791 : int airOutletNode = thisDXCoil.AirOutNode;
11768 36791 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
11769 36791 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
11770 :
11771 : // calc secondary coil if specified
11772 36791 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
11773 0 : CalcSecondaryDXCoils(state, DXCoilNum);
11774 : }
11775 36791 : }
11776 :
11777 0 : void CalcBasinHeaterPowerForMultiModeDXCoil(EnergyPlusData &state,
11778 : int const DXCoilNum, // Index of coil being simulated
11779 : HVAC::CoilMode const DehumidMode // Dehumidification mode (0=normal, 1=enhanced)
11780 : )
11781 : {
11782 :
11783 : // SUBROUTINE INFORMATION:
11784 : // AUTHOR Chandan Sharma, FSEC
11785 : // DATE WRITTEN May 2010
11786 :
11787 : // PURPOSE OF THIS SUBROUTINE:
11788 : // To calculate the basin heater power for multi mode DX cooling coil
11789 :
11790 : // METHODOLOGY EMPLOYED:
11791 : // The methodology employed is as follows:
11792 : // 1) If the number of capacity stages is equal to 1 and the CondenserType for stage 1
11793 : // is EvapCooled, then the basin heater power is calculated for (1-runtimefractionstage1) of DX coil
11794 : // 2) If the number of capacity stages is greater than 1, then
11795 : // a) If the CondenserType for stage 1 is EvapCooled, then the basin heater power is calculated for
11796 : // (1-runtimefractionofstage1) of DX coil
11797 : // b) Elseif the CondenserType for stage 2 is EvapCooled, then the basin heater power is calculated for
11798 : // (1-runtimefractionofstage2) of DX coil
11799 :
11800 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11801 : int PerfMode; // Performance mode for MultiMode DX coil; Always 1 for other coil types
11802 : // 1-2=normal mode: 1=stage 1 only, 2=stage 1&2
11803 : // 3-4=enhanced dehumidification mode: 3=stage 1 only, 4=stage 1&2
11804 :
11805 0 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
11806 :
11807 0 : if (thisDXCoil.NumCapacityStages == 1) {
11808 0 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
11809 : } else {
11810 0 : PerfMode = (int)DehumidMode * 2 + 1;
11811 0 : if (thisDXCoil.CondenserType(PerfMode) == DataHeatBalance::RefrigCondenserType::Evap) {
11812 0 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
11813 0 : } else if (thisDXCoil.CondenserType(PerfMode + 1) == DataHeatBalance::RefrigCondenserType::Evap) {
11814 0 : CalcBasinHeaterPower(state,
11815 : thisDXCoil.BasinHeaterPowerFTempDiff,
11816 : thisDXCoil.basinHeaterSched,
11817 : thisDXCoil.BasinHeaterSetPointTemp,
11818 0 : thisDXCoil.BasinHeaterPower);
11819 0 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilStg2RuntimeFrac);
11820 : }
11821 : }
11822 0 : }
11823 :
11824 59001 : Real64 AdjustCBF(Real64 const CBFNom, // nominal coil bypass factor
11825 : Real64 const AirMassFlowRateNom, // nominal air mass flow rate [kg/s]
11826 : Real64 const AirMassFlowRate // actual air mass flow rate [kg/s]
11827 : )
11828 : {
11829 :
11830 : // FUNCTION INFORMATION:
11831 : // AUTHOR Fred Buhl using Don Shirey's code
11832 : // DATE WRITTEN September 2002
11833 :
11834 : // PURPOSE OF THIS FUNCTION:
11835 : // Adjust coil bypass factor for actual air flow rate.
11836 :
11837 : // METHODOLOGY EMPLOYED:
11838 : // Uses relation CBF = exp(-NTU) whereNTU = A0/(m*cp). Relationship models the cooling coil
11839 : // as a heat exchanger with Cmin/Cmax = 0.
11840 :
11841 : // Return value
11842 : Real64 CBFAdj; // the result - the adjusted coil bypass factor
11843 :
11844 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
11845 : Real64 A0; // intermediate variable
11846 : Real64 ADiff; // intermediate variable
11847 :
11848 59001 : if (CBFNom > 0.0) {
11849 58998 : A0 = -std::log(CBFNom) * AirMassFlowRateNom;
11850 : } else {
11851 3 : A0 = 0.0;
11852 : }
11853 59001 : ADiff = -A0 / AirMassFlowRate;
11854 59001 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
11855 58541 : CBFAdj = std::exp(ADiff);
11856 : } else {
11857 460 : CBFAdj = 1.0e-6;
11858 : }
11859 :
11860 59001 : return CBFAdj;
11861 : }
11862 :
11863 3120 : Real64 CalcCBF(EnergyPlusData &state,
11864 : std::string const &UnitType,
11865 : std::string const &UnitName,
11866 : Real64 const InletAirTemp, // inlet air temperature [C]
11867 : Real64 const InletAirHumRat, // inlet air humidity ratio [kg water / kg dry air]
11868 : Real64 const TotCap, // total cooling capacity [Watts]
11869 : Real64 const AirVolFlowRate, // the air volume flow rate at the given capacity [m3/s]
11870 : Real64 const SHR, // sensible heat ratio at the given capacity and flow rate
11871 : bool const PrintFlag // flag used to print warnings if desired
11872 : )
11873 : {
11874 :
11875 : // FUNCTION INFORMATION:
11876 : // AUTHOR Fred Buhl using Don Shirey's code
11877 : // DATE WRITTEN September 2002
11878 :
11879 : // PURPOSE OF THIS FUNCTION:
11880 : // Calculate the coil bypass factor for a coil given the total capacity at the entering conditions,
11881 : // air mass flow rate at the entering conditions, and the sensible heat ratio (SHR) at the
11882 : // entering conditions. Standard barometric pressure is used for this model parameter.
11883 :
11884 : // METHODOLOGY EMPLOYED:
11885 : // calculate SlopeRated (deltahumrat/deltaT) using rated unit information provided by
11886 : // user. Then hunt along saturation curve of psychrometric chart until the slope of the line
11887 : // between the saturation point and rated inlet air humidity ratio and T is the same as SlopeRated.
11888 : // When the slopes are equal, then we have located the apparatus dewpoint of the coil at rated
11889 : // conditions. From this information, coil bypass factor is calculated.
11890 :
11891 : // Using/Aliasing
11892 :
11893 : // Return value
11894 3120 : Real64 CBF(0.0); // the result - the coil bypass factor
11895 :
11896 : // FUNCTION PARAMETER DEFINITIONS:
11897 : static constexpr std::string_view RoutineName("CalcCBF");
11898 3120 : constexpr Real64 SmallDifferenceTest(0.00000001);
11899 :
11900 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
11901 : Real64 InletAirEnthalpy; // Enthalpy of inlet air to evaporator at given conditions [J/kg]
11902 3120 : Real64 DeltaH(0.0); // Enthalpy drop across evaporator at given conditions [J/kg]
11903 3120 : Real64 DeltaT(0.0); // Temperature drop across evaporator at given conditions [C]
11904 3120 : Real64 DeltaHumRat(0.0); // Humidity ratio drop across evaporator at given conditions [kg/kg]
11905 3120 : Real64 OutletAirTemp(InletAirTemp); // Outlet dry-bulb temperature from evaporator at given conditions [C]
11906 3120 : Real64 OutletAirTempSat(InletAirTemp); // Saturation dry-bulb temperature from evaporator at outlet air enthalpy [C]
11907 : Real64 OutletAirEnthalpy; // Enthalpy of outlet air at given conditions [J/kg]
11908 3120 : Real64 OutletAirHumRat(InletAirHumRat); // Outlet humidity ratio from evaporator at given conditions [kg/kg]
11909 : Real64 OutletAirRH; // relative humidity of the outlet air
11910 : Real64 Error; // Error term used in given coil bypass factor (CBF) calculations
11911 : Real64 ErrorLast; // Error term, from previous iteration
11912 : int Iter; // Iteration loop counter in CBF calculations
11913 3120 : int IterMax(50); // Maximum number of iterations in CBF calculations
11914 : Real64 ADPTemp; // Apparatus dewpoint temperature used in CBF calculations [C]
11915 : Real64 ADPHumRat; // Apparatus dewpoint humidity used in CBF calculations [kg/kg]
11916 : Real64 ADPEnthalpy; // Air enthalpy at apparatus dew point [J/kg]
11917 : Real64 DeltaADPTemp; // Change in Apparatus Dew Point used in CBF calculations [C]
11918 3120 : Real64 SlopeAtConds(0.0); // Slope (DeltaHumRat/DeltaT) at given conditions
11919 3120 : Real64 Slope(0.0); // Calculated Slope used while hunting for Tadp
11920 : Real64 Tolerance; // Convergence tolerance for CBF calculations
11921 : Real64 HTinHumRatOut; // Air enthalpy at inlet air temp and outlet air humidity ratio [J/kg]
11922 : Real64 AirMassFlowRate; // the standard air mass flow rate at the given capacity [kg/s]
11923 : Real64 adjustedSHR; // SHR calculated using adjusted outlet air properties []
11924 3120 : bool CBFErrors(false); // Set to true if errors in CBF calculation, fatal at end of routine
11925 :
11926 3120 : if (AirVolFlowRate <= 0.0 || TotCap <= 0.0) { // Coil not running or has no capacity, don't calculate CBF
11927 5 : return CBF;
11928 : }
11929 :
11930 3115 : AirMassFlowRate = AirVolFlowRate * PsyRhoAirFnPbTdbW(state, DataEnvironment::StdPressureSeaLevel, InletAirTemp, InletAirHumRat, RoutineName);
11931 3115 : DeltaH = TotCap / AirMassFlowRate;
11932 3115 : InletAirEnthalpy = PsyHFnTdbW(InletAirTemp, InletAirHumRat);
11933 3115 : HTinHumRatOut = InletAirEnthalpy - (1.0 - SHR) * DeltaH;
11934 3115 : OutletAirHumRat = PsyWFnTdbH(state, InletAirTemp, HTinHumRatOut);
11935 3115 : DeltaHumRat = InletAirHumRat - OutletAirHumRat;
11936 3115 : OutletAirEnthalpy = InletAirEnthalpy - DeltaH;
11937 3115 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11938 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11939 : // Pressure will have to be pass into this subroutine to fix this one
11940 3115 : OutletAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
11941 3115 : if (OutletAirRH >= 1.0 && PrintFlag) {
11942 16 : ShowWarningError(state, format("For object = {}, name = \"{}\"", UnitType, UnitName));
11943 32 : ShowContinueError(state, "Calculated outlet air relative humidity greater than 1. The combination of");
11944 32 : ShowContinueError(state, "rated air volume flow rate, total cooling capacity and sensible heat ratio yields coil exiting");
11945 32 : ShowContinueError(state, "air conditions above the saturation curve. Possible fixes are to reduce the rated total cooling");
11946 32 : ShowContinueError(state, "capacity, increase the rated air volume flow rate, or reduce the rated sensible heat ratio for this coil.");
11947 32 : ShowContinueError(state, "If autosizing, it is recommended that all three of these values be autosized.");
11948 32 : ShowContinueError(state, "...Inputs used for calculating cooling coil bypass factor.");
11949 16 : ShowContinueError(state, format("...Inlet Air Temperature = {:.2R} C", InletAirTemp));
11950 16 : ShowContinueError(state, format("...Outlet Air Temperature = {:.2R} C", OutletAirTemp));
11951 16 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", InletAirHumRat));
11952 16 : ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
11953 16 : ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
11954 16 : ShowContinueError(state, format("...Air Mass Flow Rate used in calculation = {:.6R} kg/s", AirMassFlowRate));
11955 16 : ShowContinueError(state, format("...Air Volume Flow Rate used in calculation = {:.6R} m3/s", AirVolFlowRate));
11956 16 : if (TotCap > 0.0) {
11957 28 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
11958 12 : ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
11959 12 : ShowContinueError(state,
11960 12 : format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
11961 12 : AirVolFlowRate / TotCap));
11962 : }
11963 : }
11964 32 : ShowContinueErrorTimeStamp(state, "");
11965 16 : OutletAirTempSat = PsyTsatFnHPb(state, OutletAirEnthalpy, DataEnvironment::StdPressureSeaLevel, RoutineName);
11966 16 : if (OutletAirTemp < OutletAirTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
11967 16 : OutletAirTemp = OutletAirTempSat + 0.005;
11968 16 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy, RoutineName);
11969 16 : DeltaHumRat = InletAirHumRat - OutletAirHumRat;
11970 16 : HTinHumRatOut = PsyHFnTdbW(InletAirTemp, OutletAirHumRat);
11971 16 : adjustedSHR = (HTinHumRatOut - OutletAirEnthalpy) / DeltaH;
11972 32 : ShowContinueError(state, "CalcCBF: SHR adjusted to achieve valid outlet air properties and the simulation continues.");
11973 16 : ShowContinueError(state, format("CalcCBF: initial SHR = {:.5R}", SHR));
11974 16 : ShowContinueError(state, format("CalcCBF: adjusted SHR = {:.5R}", adjustedSHR));
11975 : }
11976 : }
11977 3115 : DeltaT = InletAirTemp - OutletAirTemp;
11978 3115 : if (DeltaT <= 0.0) {
11979 0 : ShowSevereError(state, format("For object = {}, name = \"{}\"", UnitType, UnitName));
11980 0 : ShowContinueError(state, "Calculated coil delta T is less than or equal to 0. The combination of");
11981 0 : ShowContinueError(state, "rated air volume flow rate, total cooling capacity and sensible heat ratio yields coil exiting");
11982 0 : ShowContinueError(state, "air conditions that are not reasonable. Possible fixes are to adjust the rated total cooling");
11983 0 : ShowContinueError(state, "capacity, rated air volume flow rate, or rated sensible heat ratio for this coil.");
11984 0 : ShowContinueError(state, "If autosizing, it is recommended that all three of these values be autosized.");
11985 0 : ShowContinueError(state, "...Inputs used for calculating cooling coil bypass factor.");
11986 0 : ShowContinueError(state, format("...Inlet Air Temperature = {:.2R} C", InletAirTemp));
11987 0 : ShowContinueError(state, format("...Outlet Air Temperature = {:.2R} C", OutletAirTemp));
11988 0 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", InletAirHumRat));
11989 0 : ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
11990 0 : ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
11991 0 : ShowContinueError(state, format("...Air Mass Flow Rate used in calculation = {:.6R} kg/s", AirMassFlowRate));
11992 0 : ShowContinueError(state, format("...Air Volume Flow Rate used in calculation = {:.6R} m3/s", AirVolFlowRate));
11993 0 : if (TotCap > 0.0) {
11994 0 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
11995 0 : ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
11996 0 : ShowContinueError(state,
11997 0 : format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
11998 0 : AirVolFlowRate / TotCap));
11999 : }
12000 : }
12001 0 : ShowContinueErrorTimeStamp(state, "");
12002 0 : ShowFatalError(state, "Check and revise the input data for this coil before rerunning the simulation.");
12003 : }
12004 : // Calculate slope at given conditions
12005 3115 : if (DeltaT > 0.0) SlopeAtConds = DeltaHumRat / DeltaT;
12006 :
12007 : // IF (SlopeAtConds .le. .0000001d0 .or. OutletAirHumRat .le. 0.0d0) THEN
12008 3115 : if (SlopeAtConds < 0.0 || OutletAirHumRat <= 0.0) {
12009 : // Invalid conditions, slope can't be less than zero (SHR > 1) or
12010 : // outlet air humidity ratio can't be less than zero.
12011 0 : ShowSevereError(state, format("{} \"{}\"", UnitType, UnitName));
12012 0 : ShowContinueError(state, "...Invalid slope or outlet air condition when calculating cooling coil bypass factor.");
12013 0 : ShowContinueError(state, format("...Slope = {:.8R}", SlopeAtConds));
12014 0 : ShowContinueError(state, format("...Inlet Air Temperature = {:.2R} C", InletAirTemp));
12015 0 : ShowContinueError(state, format("...Outlet Air Temperature = {:.2R} C", OutletAirTemp));
12016 0 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", InletAirHumRat));
12017 0 : ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
12018 0 : ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
12019 0 : ShowContinueError(state, format("...Air Mass Flow Rate used in calculation = {:.6R} kg/s", AirMassFlowRate));
12020 0 : ShowContinueError(state, format("...Air Volume Flow Rate used in calculation = {:.6R} m3/s", AirVolFlowRate));
12021 0 : if (TotCap > 0.0) {
12022 0 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
12023 0 : ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
12024 0 : ShowContinueError(state,
12025 0 : format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
12026 0 : AirVolFlowRate / TotCap));
12027 : }
12028 : }
12029 0 : ShowContinueErrorTimeStamp(state, "");
12030 0 : CBFErrors = true;
12031 0 : CBF = 0.0; //? Added: Is this what should be returned
12032 : } else {
12033 :
12034 : // First guess for Tadp is outlet air dew point
12035 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12036 : // Pressure will have to be pass into this subroutine to fix this one
12037 3115 : ADPTemp = PsyTdpFnWPb(state, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel);
12038 :
12039 3115 : Tolerance = 1.0; // initial conditions for iteration
12040 3115 : ErrorLast = 100.0;
12041 3115 : Iter = 0;
12042 3115 : DeltaADPTemp = 5.0;
12043 51003 : while ((Iter <= IterMax) && (Tolerance > 0.001)) {
12044 : // Do for IterMax iterations or until the error gets below .1%
12045 47888 : if (Iter > 0) ADPTemp += DeltaADPTemp;
12046 47888 : ++Iter;
12047 :
12048 : // Find new slope using guessed Tadp
12049 :
12050 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12051 : // Pressure will have to be pass into this subroutine to fix this one
12052 47888 : ADPHumRat = min(OutletAirHumRat, PsyWFnTdpPb(state, ADPTemp, DataEnvironment::StdPressureSeaLevel));
12053 47888 : Slope = (InletAirHumRat - ADPHumRat) / max(0.001, (InletAirTemp - ADPTemp));
12054 :
12055 : // check for convergence (slopes are equal to within error tolerance)
12056 :
12057 47888 : Error = (Slope - SlopeAtConds) / SlopeAtConds;
12058 47888 : if ((Error > 0.0) && (ErrorLast < 0.0)) {
12059 11633 : DeltaADPTemp = -DeltaADPTemp / 2.0;
12060 36255 : } else if ((Error < 0.0) && (ErrorLast > 0.0)) {
12061 13158 : DeltaADPTemp = -DeltaADPTemp / 2.0;
12062 23097 : } else if (std::abs(Error) > std::abs(ErrorLast)) {
12063 2957 : DeltaADPTemp = -DeltaADPTemp / 2.0;
12064 : }
12065 47888 : ErrorLast = Error;
12066 :
12067 47888 : Tolerance = std::abs(Error);
12068 : }
12069 :
12070 : // Calculate Bypass Factor from Enthalpies
12071 :
12072 3115 : InletAirEnthalpy = PsyHFnTdbW(InletAirTemp, InletAirHumRat);
12073 3115 : OutletAirEnthalpy = PsyHFnTdbW(OutletAirTemp, OutletAirHumRat);
12074 3115 : ADPEnthalpy = PsyHFnTdbW(ADPTemp, ADPHumRat);
12075 3115 : CBF = min(1.0, (OutletAirEnthalpy - ADPEnthalpy) / (InletAirEnthalpy - ADPEnthalpy));
12076 3115 : if (Iter > IterMax && PrintFlag) {
12077 0 : ShowSevereError(state, format("{} \"{}\" -- coil bypass factor calculation did not converge after max iterations.", UnitType, UnitName));
12078 0 : ShowContinueError(state, format("The RatedSHR of [{:.3R}], entered by the user or autosized (see *.eio file),", SHR));
12079 0 : ShowContinueError(state, "may be causing this. The line defined by the coil rated inlet air conditions");
12080 0 : ShowContinueError(state, "(26.7C drybulb and 19.4C wetbulb) and the RatedSHR (i.e., slope of the line) must intersect");
12081 0 : ShowContinueError(state, "the saturation curve of the psychrometric chart. If the RatedSHR is too low, then this");
12082 0 : ShowContinueError(state, "intersection may not occur and the coil bypass factor calculation will not converge.");
12083 0 : ShowContinueError(state, "If autosizing the SHR, recheck the design supply air humidity ratio and design supply air");
12084 0 : ShowContinueError(state, "temperature values in the Sizing:System and Sizing:Zone objects. In general, the temperatures");
12085 0 : ShowContinueError(state, "and humidity ratios specified in these two objects should be the same for each system");
12086 0 : ShowContinueError(state, "and the zones that it serves.");
12087 0 : ShowContinueErrorTimeStamp(state, "");
12088 0 : CBFErrors = true; // Didn't converge within MaxIter iterations
12089 : }
12090 3115 : if (CBF < 0.0 && PrintFlag) {
12091 0 : ShowSevereError(state, format("{} \"{}\" -- negative coil bypass factor calculated.", UnitType, UnitName));
12092 0 : ShowContinueErrorTimeStamp(state, "");
12093 0 : CBFErrors = true; // Negative CBF not valid
12094 : }
12095 : }
12096 :
12097 : // Show fatal error for specific coil that caused a CBF error
12098 3115 : if (CBFErrors) {
12099 0 : ShowFatalError(state, format("{} \"{}\" Errors found in calculating coil bypass factors", UnitType, UnitName));
12100 : }
12101 :
12102 3115 : return CBF;
12103 : }
12104 :
12105 90 : Real64 ValidateADP(EnergyPlusData &state,
12106 : std::string const &UnitType, // component name
12107 : std::string const &UnitName, // component type
12108 : Real64 const RatedInletAirTemp, // coil inlet air temperature [C]
12109 : Real64 const RatedInletAirHumRat, // coil inlet air humidity ratio [kg/kg]
12110 : Real64 const TotCap, // coil total capacity [W]
12111 : Real64 const AirVolFlowRate, // coil air volume flow rate [m3/s]
12112 : Real64 const InitialSHR, // coil sensible heat ratio []
12113 : std::string const &CallingRoutine // function name calling this routine
12114 : )
12115 : {
12116 :
12117 : // FUNCTION INFORMATION:
12118 : // AUTHOR Richard Raustad, FSEC
12119 : // DATE WRITTEN December 2015
12120 :
12121 : // PURPOSE OF THIS FUNCTION:
12122 : // Validates that the calculated bypass factor represents valid SHR based on total capacity and air mass flow rate.
12123 :
12124 : // METHODOLOGY EMPLOYED:
12125 : // With model parameters autosized by the user, the SHR is selected based on an empirical model.
12126 : // This can sometimes lead to an SHR that does not cross the saturation curve, or one that crosses excessively where
12127 : // the coil outlet air conditions exceed the saturation curve (i.e., RH > 1).
12128 : // This function checks to see if the ADP based on coil delta T and calculated bypass factor and the ADP based
12129 : // on coil delta W and calculated bypass factor land on the saturation curve at the same place within a tolerance.
12130 : // The result is passed back to the sizing routine as the new value for SHR.
12131 : // If the SHR is not autosized, this routine will still adjust the design SHR appropriately, however, the hard-sized SHR will not
12132 : // change.
12133 :
12134 : // Return value
12135 90 : Real64 SHR(0.0); // the result - the adjusted design SHR
12136 :
12137 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
12138 90 : Real64 CBF_calculated(0.0); // coil bypass factor based on TotCap, AirFlow, SHR, and BaroPress
12139 90 : Real64 InletAirEnthalpy(0.0); // Enthalpy of inlet air to evaporator at given conditions [J/kg]
12140 90 : Real64 DeltaH(0.0); // Enthalpy drop across evaporator at given conditions [J/kg]
12141 90 : Real64 HTinHumRatOut(0.0); // Air enthalpy at inlet air temp and outlet air humidity ratio [J/kg]
12142 90 : Real64 DeltaHumRat(0.0); // Humidity ratio drop across evaporator at given conditions [kg/kg]
12143 90 : Real64 OutletAirTemp(0.0); // Outlet dry-bulb temperature from evaporator at given conditions [C]
12144 90 : Real64 OutletAirEnthalpy(0.0); // Enthalpy of outlet air at given conditions [J/kg]
12145 90 : Real64 OutletAirHumRat(0.0); // Outlet humidity ratio from evaporator at given conditions [kg/kg]
12146 90 : Real64 OutletAirRH(0.0); // relative humidity of the outlet air
12147 90 : Real64 CalcADPTemp(0.0); // actual ADP temperature based on bypass factor [C]
12148 90 : Real64 CalcADPHumRat(0.0); // actual ADP humidity ratio based on bypass factor [kg/kg]
12149 90 : Real64 CalcADPTempFnHR(0.0); // actual ADP temperature as a function of humidity ratio based on bypass factor [C]
12150 90 : Real64 ADPerror(0.0); // difference between ADP function of temperature and humidity ratio [deltaC]
12151 90 : Real64 AirMassFlow(0.0); // air mass flow rate based on standard barometric pressure [kg/s]
12152 90 : bool bStillValidating(true); // while loop flag
12153 90 : bool bNoReporting(false); // don't report specific warnings in calcCBF while iterating on result
12154 90 : bool bReversePerturb(false); // identifies when SHR is being lowered based on outlet air RH
12155 :
12156 90 : SHR = InitialSHR;
12157 90 : AirMassFlow =
12158 90 : AirVolFlowRate * PsyRhoAirFnPbTdbW(state, DataEnvironment::StdPressureSeaLevel, RatedInletAirTemp, RatedInletAirHumRat, CallingRoutine);
12159 3059 : while (bStillValidating) {
12160 2969 : CBF_calculated = max(0.0, CalcCBF(state, UnitType, UnitName, RatedInletAirTemp, RatedInletAirHumRat, TotCap, AirMassFlow, SHR, bNoReporting));
12161 2969 : DeltaH = TotCap / AirMassFlow;
12162 2969 : InletAirEnthalpy = PsyHFnTdbW(RatedInletAirTemp, RatedInletAirHumRat);
12163 2969 : HTinHumRatOut = InletAirEnthalpy - (1.0 - SHR) * DeltaH;
12164 2969 : OutletAirHumRat = PsyWFnTdbH(state, RatedInletAirTemp, HTinHumRatOut, CallingRoutine);
12165 2969 : DeltaHumRat = RatedInletAirHumRat - OutletAirHumRat;
12166 2969 : OutletAirEnthalpy = InletAirEnthalpy - DeltaH;
12167 2969 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
12168 2969 : OutletAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, CallingRoutine);
12169 2969 : if (CBF_calculated < 1) {
12170 2969 : CalcADPTemp = RatedInletAirTemp - ((RatedInletAirTemp - OutletAirTemp) / (1 - CBF_calculated));
12171 2969 : CalcADPHumRat = RatedInletAirHumRat - ((DeltaHumRat) / (1 - CBF_calculated));
12172 2969 : CalcADPTempFnHR = PsyTdpFnWPb(state, CalcADPHumRat, DataEnvironment::StdPressureSeaLevel, CallingRoutine);
12173 2969 : ADPerror = CalcADPTemp - CalcADPTempFnHR;
12174 : } else {
12175 0 : ADPerror = 0; // might be able to check for RH >= 1 and reduce SHR, need defect file for that since can't create one
12176 : }
12177 :
12178 2969 : if (std::abs(ADPerror) > 0.012) {
12179 2969 : if (OutletAirRH >= 1.0) { // if RH > 1, reduce SHR until it crosses the saturation curve
12180 344 : SHR -= 0.001;
12181 344 : bReversePerturb = true;
12182 344 : if (SHR < 0.5)
12183 0 : bStillValidating = false; // have to stop somewhere, this is lower than the lower limit of SHR empirical model (see
12184 : // Autosizing/CoolingSHRSizing)
12185 : } else {
12186 2625 : if (bReversePerturb) {
12187 60 : bStillValidating = false; // stop iterating once SHR causes ADP to cross back under saturation curve, take what you get
12188 : } else {
12189 2565 : SHR += 0.001; // increase SHR slowly until ADP temps are resolved
12190 : }
12191 : }
12192 2969 : if (SHR > 0.8)
12193 30 : bStillValidating = false; // have to stop somewhere, this is the upper limit of SHR empirical model (see Autosizing/CoolingSHRSizing)
12194 : } else {
12195 0 : bStillValidating = false; // ADP temps are close enough. Normal input files hit this on first pass
12196 : }
12197 : }
12198 :
12199 90 : return SHR;
12200 : }
12201 :
12202 116065 : Real64 CalcEffectiveSHR(EnergyPlusData &state,
12203 : int const DXCoilNum, // Index number for cooling coil
12204 : Real64 const SHRss, // Steady-state sensible heat ratio
12205 : Real64 const RTF, // Compressor run-time fraction
12206 : Real64 const QLatRated, // Rated latent capacity
12207 : Real64 const QLatActual, // Actual latent capacity
12208 : Real64 const EnteringDB, // Entering air dry-bulb temperature
12209 : Real64 const EnteringWB, // Entering air wet-bulb temperature
12210 : ObjexxFCL::Optional_int_const Mode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
12211 : ObjexxFCL::Optional<Real64 const> HeatingRTF // Used to recalculate Toff for cycling fan systems
12212 : )
12213 : {
12214 :
12215 : // FUNCTION INFORMATION:
12216 : // AUTHOR Richard Raustad, FSEC
12217 : // DATE WRITTEN September 2003
12218 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
12219 : // Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
12220 : // Nov 2008 R. Raustad, FSEC
12221 : // Modified to allow latent degradation with cycling fan
12222 :
12223 : // PURPOSE OF THIS FUNCTION:
12224 : // Adjust sensible heat ratio to account for degradation of DX coil latent
12225 : // capacity at part-load (cycling) conditions.
12226 :
12227 : // METHODOLOGY EMPLOYED:
12228 : // With model parameters entered by the user, the part-load latent performance
12229 : // of a DX cooling coil is determined for a constant air flow system with
12230 : // a cooling coil that cycles on/off. The model calculates the time
12231 : // required for condensate to begin falling from the cooling coil.
12232 : // Runtimes greater than this are integrated to a "part-load" latent
12233 : // capacity which is used to determine the "part-load" sensible heat ratio.
12234 : // See reference below for additional details (linear decay model, Eq. 8b).
12235 : // REFERENCES:
12236 : // "A Model to Predict the Latent Capacity of Air Conditioners and
12237 : // Heat Pumps at Part-Load Conditions with Constant Fan Operation"
12238 : // 1996 ASHRAE Transactions, Volume 102, Part 1, Pp. 266 - 274,
12239 : // Hugh I. Henderson, Jr., P.E., Kannan Rengarajan, P.E.
12240 :
12241 : // Return value
12242 : Real64 SHReff; // Effective sensible heat ratio, includes degradation due to cycling effects
12243 :
12244 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
12245 : Real64 Twet; // Nominal time for condensate to begin leaving the coil's condensate drain line
12246 : // at the current operating conditions (sec)
12247 : Real64 Gamma; // Initial moisture evaporation rate divided by steady-state AC latent capacity
12248 : // at the current operating conditions
12249 : Real64 Twet_Rated; // Twet at rated conditions (coil air flow rate and air temperatures), sec
12250 : Real64 Gamma_Rated; // Gamma at rated conditions (coil air flow rate and air temperatures)
12251 : Real64 Twet_max; // Maximum allowed value for Twet
12252 : Real64 Nmax; // Maximum ON/OFF cycles per hour for the compressor (cycles/hr)
12253 : Real64 Tcl; // Time constant for latent capacity to reach steady state after startup (sec)
12254 : Real64 Ton; // Coil on time (sec)
12255 : Real64 Toff; // Coil off time (sec)
12256 : Real64 Toffa; // Actual coil off time (sec). Equations valid for Toff <= (2.0 * Twet/Gamma)
12257 : Real64 aa; // Intermediate variable
12258 : Real64 To1; // Intermediate variable (first guess at To). To = time to the start of moisture removal
12259 : Real64 To2; // Intermediate variable (second guess at To). To = time to the start of moisture removal
12260 : Real64 Error; // Error for iteration (DO) loop
12261 : Real64 LHRmult; // Latent Heat Ratio (LHR) multiplier. The effective latent heat ratio LHR = (1-SHRss)*LHRmult
12262 : Real64 Ton_heating;
12263 : Real64 Toff_heating;
12264 :
12265 116065 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
12266 :
12267 116065 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilDX_MultiSpeedCooling) {
12268 116024 : Twet_Rated = thisDXCoil.Twet_Rated(Mode);
12269 116024 : Gamma_Rated = thisDXCoil.Gamma_Rated(Mode);
12270 116024 : Nmax = thisDXCoil.MaxONOFFCyclesperHour(Mode);
12271 116024 : Tcl = thisDXCoil.LatentCapacityTimeConstant(Mode);
12272 : } else {
12273 41 : Twet_Rated = thisDXCoil.MSTwet_Rated(Mode);
12274 41 : Gamma_Rated = thisDXCoil.MSGamma_Rated(Mode);
12275 41 : Nmax = thisDXCoil.MSMaxONOFFCyclesperHour(Mode);
12276 41 : Tcl = thisDXCoil.MSLatentCapacityTimeConstant(Mode);
12277 : }
12278 :
12279 : // No moisture evaporation (latent degradation) occurs for runtime fraction of 1.0
12280 : // All latent degradation model parameters cause divide by 0.0 if not greater than 0.0
12281 : // Latent degradation model parameters initialize to 0.0 meaning no evaporation model used.
12282 116065 : if (RTF >= 1.0 || Twet_Rated <= 0.0 || Gamma_Rated <= 0.0 || Nmax <= 0.0 || Tcl <= 0.0) {
12283 107135 : SHReff = SHRss;
12284 107135 : return SHReff;
12285 : }
12286 :
12287 8930 : Twet_max = 9999.0; // high limit for Twet
12288 :
12289 : // Calculate the model parameters at the actual operating conditions
12290 8930 : Twet = min(Twet_Rated * QLatRated / (QLatActual + 1.e-10), Twet_max);
12291 8930 : Gamma = Gamma_Rated * QLatRated * (EnteringDB - EnteringWB) / ((26.7 - 19.4) * QLatActual + 1.e-10);
12292 :
12293 : // Calculate the compressor on and off times using a conventional thermostat curve
12294 8930 : Ton = 3600.0 / (4.0 * Nmax * (1.0 - RTF)); // duration of cooling coil on-cycle (sec)
12295 8930 : Toff = 3600.0 / (4.0 * Nmax * RTF); // duration of cooling coil off-cycle (sec)
12296 :
12297 : // Cap Toff to meet the equation restriction
12298 8930 : if (Gamma > 0.0) {
12299 8930 : Toffa = min(Toff, 2.0 * Twet / Gamma);
12300 : } else {
12301 0 : Toffa = Toff;
12302 : }
12303 :
12304 : // Need to include the reheat coil operation to account for actual fan run time. E+ uses a
12305 : // separate heating coil for heating and reheat (to separate the heating and reheat loads)
12306 : // and real world applications would use a single heating coil for both purposes, the actual
12307 : // fan operation is based on HeatingPLR + ReheatPLR. For cycling fan RH control, latent
12308 : // degradation only occurs when a heating load exists, in this case the reheat load is
12309 : // equal to and opposite in magnitude to the cooling coil sensible output but the reheat
12310 : // coil is not always active. This additional fan run time has not been accounted for at this time.
12311 : // Recalculate Toff for cycling fan systems when heating is active
12312 8930 : if (present(HeatingRTF)) {
12313 0 : if (HeatingRTF < 1.0 && HeatingRTF > RTF) {
12314 0 : Ton_heating = 3600.0 / (4.0 * Nmax * (1.0 - HeatingRTF));
12315 0 : Toff_heating = 3600.0 / (4.0 * Nmax * HeatingRTF);
12316 : // add additional heating coil operation during cooling coil off cycle (due to cycling rate difference of coils)
12317 0 : Ton_heating += max(0.0, min(Ton_heating, (Ton + Toffa) - (Ton_heating + Toff_heating)));
12318 0 : Toffa = min(Toffa, Ton_heating - Ton);
12319 : }
12320 : }
12321 :
12322 : // Use successive substitution to solve for To
12323 8930 : aa = (Gamma * Toffa) - (0.25 / Twet) * pow_2(Gamma) * pow_2(Toffa);
12324 8930 : To1 = aa + Tcl;
12325 8930 : Error = 1.0;
12326 19126 : while (Error > 0.001) {
12327 10196 : To2 = aa - Tcl * (std::exp(-To1 / Tcl) - 1.0);
12328 10196 : Error = std::abs((To2 - To1) / To1);
12329 10196 : To1 = To2;
12330 : }
12331 :
12332 : // Adjust Sensible Heat Ratio (SHR) using Latent Heat Ratio (LHR) multiplier
12333 : // Floating underflow errors occur when -Ton/Tcl is a large negative number.
12334 : // Cap lower limit at -700 to avoid the underflow errors.
12335 8930 : aa = std::exp(max(-700.0, -Ton / Tcl));
12336 : // Calculate latent heat ratio multiplier
12337 8930 : LHRmult = max(((Ton - To2) / (Ton + Tcl * (aa - 1.0))), 0.0);
12338 :
12339 : // Calculate part-load or "effective" sensible heat ratio
12340 8930 : SHReff = 1.0 - (1.0 - SHRss) * LHRmult;
12341 :
12342 8930 : if (SHReff < SHRss) SHReff = SHRss; // Effective SHR can be less than the steady-state SHR
12343 8930 : if (SHReff > 1.0) SHReff = 1.0; // Effective sensible heat ratio can't be greater than 1.0
12344 :
12345 8930 : return SHReff;
12346 : }
12347 :
12348 44594 : void CalcTotCapSHR(EnergyPlusData &state,
12349 : Real64 const InletDryBulb, // inlet air dry bulb temperature [C]
12350 : Real64 const InletHumRat, // inlet air humidity ratio [kg water / kg dry air]
12351 : Real64 const InletEnthalpy, // inlet air specific enthalpy [J/kg]
12352 : Real64 const InletWetBulb, // inlet air wet bulb temperature [C]
12353 : Real64 const AirMassFlowRatio, // Ratio of actual air mass flow to nominal air mass flow
12354 : Real64 const AirMassFlow, // actual mass flow for capacity and SHR calculation
12355 : Real64 const TotCapNom, // nominal total capacity [W]
12356 : Real64 const CBF, // coil bypass factor
12357 : int const CCapFTemp, // capacity modifier curve index, function of entering wetbulb
12358 : int const CCapFFlow, // capacity modifier curve, function of actual flow vs rated flow
12359 : Real64 &TotCap, // total capacity at the given conditions [W]
12360 : Real64 &SHR, // sensible heat ratio at the given conditions
12361 : Real64 const CondInletTemp, // Condenser inlet temperature [C]
12362 : Real64 const Pressure, // air pressure [Pa]
12363 : Real64 &TotCapModFac // capacity modification factor, func of temp and func of flow
12364 : )
12365 : {
12366 :
12367 : // SUBROUTINE INFORMATION:
12368 : // AUTHOR Fred Buhl using Don Shirey's code
12369 : // DATE WRITTEN September 2002
12370 :
12371 : // PURPOSE OF THIS SUBROUTINE:
12372 : // Calculates total capacity and sensible heat ratio of a DX coil at the specified conditions
12373 :
12374 : // METHODOLOGY EMPLOYED:
12375 : // With the rated performance data entered by the user, the model employs some of the
12376 : // DOE-2.1E curve fits to adjust the capacity and SHR of the unit as a function
12377 : // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
12378 : // does NOT employ the exact same methodology to calculate performance as DOE-2, although
12379 : // some of the DOE-2 curve fits are employed by this model.
12380 :
12381 : // The model checks for coil dryout conditions, and adjusts the calculated performance
12382 : // appropriately.
12383 :
12384 : // REFERENCES:
12385 : // ASHRAE HVAC 2 Toolkit page 4-81.
12386 : // Henderson, H.I. Jr., K. Rengarajan and D.B. Shirey, III. 1992.The impact of comfort
12387 : // control on air conditioner energy use in humid climates. ASHRAE Transactions 98(2):
12388 : // 104-113.
12389 : // Henderson, H.I. Jr., Danny Parker and Y.J. Huang. 2000.Improving DOE-2's RESYS routine:
12390 : // User Defined Functions to Provide More Accurate Part Load Energy Use and Humidity
12391 : // Predictions. Proceedings of ACEEE Conference.
12392 :
12393 : // Using/Aliasing
12394 : using Curve::CurveValue;
12395 :
12396 : // Locals
12397 : // SUBROUTINE ARGUMENT DEFINITIONS:
12398 : // and outside drybulb
12399 :
12400 : // SUBROUTINE PARAMETER DEFINITIONS:
12401 44594 : constexpr int MaxIter(30); // Maximum number of iterations for dry evaporator calculations
12402 44594 : constexpr Real64 RF(0.4); // Relaxation factor for dry evaporator iterations
12403 44594 : constexpr Real64 Tolerance(0.01); // Error tolerance for dry evaporator iterations
12404 44594 : constexpr Real64 MinHumRatCalc(0.00001); // Error tolerance for dry evaporator iterations
12405 :
12406 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12407 : Real64 InletWetBulbCalc; // calculated inlet wetbulb temperature used for finding dry coil point [C]
12408 : Real64 InletHumRatCalc; // calculated inlet humidity ratio used for finding dry coil point [kg water / kg dry air]
12409 : Real64 TotCapTempModFac; // Total capacity modifier (function of entering wetbulb, outside drybulb)
12410 : Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs nominal flow)
12411 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
12412 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
12413 : Real64 tADP; // Apparatus dew point temperature [C]
12414 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
12415 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
12416 : Real64 SHRCalc; // temporary calculated value of SHR
12417 : Real64 TotCapCalc; // temporary calculated value of total capacity [W]
12418 : int Counter; // Counter for dry evaporator iterations
12419 : Real64 werror; // Deviation of humidity ratio in dry evaporator iteration loop
12420 :
12421 : // MaxIter = 30
12422 : // RF = 0.4d0
12423 44594 : Counter = 0;
12424 : // Tolerance = 0.01d0
12425 44594 : werror = 0.0;
12426 :
12427 44594 : InletWetBulbCalc = InletWetBulb;
12428 44594 : InletHumRatCalc = InletHumRat;
12429 :
12430 44594 : if (AirMassFlow <= 0.00001) {
12431 3 : TotCap = 0.0;
12432 3 : SHR = 0.0;
12433 3 : return;
12434 : }
12435 :
12436 : // DO WHILE (ABS(werror) .gt. Tolerance .OR. Counter == 0)
12437 : // Get capacity modifying factor (function of inlet wetbulb & outside drybulb) for off-rated conditions
12438 : while (true) {
12439 158090 : TotCapTempModFac = CurveValue(state, CCapFTemp, InletWetBulbCalc, CondInletTemp);
12440 : // Get capacity modifying factor (function of mass flow) for off-rated conditions
12441 158090 : TotCapFlowModFac = CurveValue(state, CCapFFlow, AirMassFlowRatio);
12442 : // Get total capacity
12443 158090 : TotCapCalc = TotCapNom * TotCapFlowModFac * TotCapTempModFac;
12444 :
12445 : // Calculate apparatus dew point conditions using TotCap and CBF
12446 158090 : hDelta = TotCapCalc / AirMassFlow;
12447 158090 : hADP = InletEnthalpy - hDelta / (1.0 - CBF);
12448 158090 : tADP = PsyTsatFnHPb(state, hADP, Pressure);
12449 158090 : wADP = PsyWFnTdbH(state, tADP, hADP);
12450 158090 : hTinwADP = PsyHFnTdbW(InletDryBulb, wADP);
12451 158090 : if ((InletEnthalpy - hADP) > 1.e-10) {
12452 158090 : SHRCalc = min((hTinwADP - hADP) / (InletEnthalpy - hADP), 1.0);
12453 : } else {
12454 0 : SHRCalc = 1.0;
12455 : }
12456 : // Check for dry evaporator conditions (win < wadp)
12457 158090 : if (wADP > InletHumRatCalc || (Counter >= 1 && Counter < MaxIter)) {
12458 128338 : if (InletHumRatCalc == 0.0) InletHumRatCalc = MinHumRatCalc;
12459 : // InletHumRatCalc=MAX(InletHumRatCalc,MinHumRatCalc) ! proposed.
12460 :
12461 128338 : werror = (InletHumRatCalc - wADP) / InletHumRatCalc;
12462 : // Increase InletHumRatCalc at constant inlet air temp to find coil dry-out point. Then use the
12463 : // capacity at the dry-out point to determine exiting conditions from coil. This is required
12464 : // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
12465 128338 : InletHumRatCalc = RF * wADP + (1.0 - RF) * InletHumRatCalc;
12466 128338 : InletWetBulbCalc = PsyTwbFnTdbWPb(state, InletDryBulb, InletHumRatCalc, Pressure);
12467 128338 : ++Counter;
12468 128338 : if (std::abs(werror) > Tolerance) continue; // Recalculate with modified inlet conditions
12469 14839 : break; // conditions are satisfied
12470 : } else {
12471 : break; // conditions are satisfied
12472 : }
12473 : }
12474 :
12475 : // END DO
12476 :
12477 : // Calculate full load output conditions
12478 44591 : if (SHRCalc > 1.0 || Counter > 0) SHRCalc = 1.0;
12479 :
12480 44591 : SHR = SHRCalc;
12481 44591 : TotCap = TotCapCalc;
12482 44591 : TotCapModFac = TotCapTempModFac * TotCapFlowModFac;
12483 : }
12484 :
12485 265 : void CalcMultiSpeedDXCoilCooling(EnergyPlusData &state,
12486 : int const DXCoilNum, // the number of the DX heating coil to be simulated
12487 : Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
12488 : Real64 const CycRatio, // cycling part load ratio
12489 : int const SpeedNum, // Speed number
12490 : HVAC::FanOp const fanOp, // Sets fan control to FanOp::Cycling or FanOp::Continuous
12491 : HVAC::CompressorOp const compressorOp, // Compressor on/off; 1=on, 0=off
12492 : int const SingleMode // Single mode operation Yes/No; 1=Yes, 0=No
12493 : )
12494 : {
12495 :
12496 : // SUBROUTINE INFORMATION:
12497 : // AUTHOR Lixing Gu, FSEC
12498 : // DATE WRITTEN June 2007
12499 : // MODIFIED April 2010, Chandan sharma, FSEC, added basin heater
12500 : // RE-ENGINEERED Revised based on CalcMultiSpeedDXCoil
12501 :
12502 : // PURPOSE OF THIS SUBROUTINE:
12503 : // Calculates the air-side performance and electrical energy use of a direct-
12504 : // expansion, air-cooled cooling unit with a multispeed compressor.
12505 :
12506 : // METHODOLOGY EMPLOYED:
12507 : // Uses the same methodology as the single speed DX unit model (SUBROUTINE CalcDoe2DXCoil).
12508 : // In addition it assumes that the unit performance is obtained by interpolating between
12509 : // the performance at high speed and that at low speed. If the output needed is below
12510 : // that produced at low speed, the compressor cycles between off and low speed.
12511 :
12512 : // Using/Aliasing
12513 : using Curve::CurveValue;
12514 265 : Real64 MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
12515 265 : Real64 MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
12516 265 : auto &MSHPWasteHeat = state.dataHVACGlobal->MSHPWasteHeat;
12517 :
12518 : // Locals
12519 : // SUBROUTINE ARGUMENT DEFINITIONS:
12520 : // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
12521 :
12522 : // SUBROUTINE PARAMETER DEFINITIONS:
12523 : static constexpr std::string_view RoutineName("CalcMultiSpeedDXCoilCooling");
12524 : static constexpr std::string_view RoutineNameHighSpeedAlt("CalcMultiSpeedDXCoilCooling highspeed");
12525 :
12526 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12527 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
12528 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
12529 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
12530 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
12531 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
12532 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12533 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
12534 : Real64 OutletAirDryBulbTemp; // outlet air dry bulb temperature [C]
12535 : Real64 OutletAirEnthalpy; // outlet air enthalpy [J/kg]
12536 : Real64 OutletAirHumRat; // outlet air humidity ratio [kg/kg]
12537 : Real64 OutletAirDryBulbTempSat; // outlet air dry bulb temp at saturation at the outlet enthalpy [C]
12538 : Real64 LSOutletAirDryBulbTemp; // low speed outlet air dry bulb temperature [C]
12539 : Real64 LSOutletAirEnthalpy; // low speed outlet air enthalpy [J/kg]
12540 : Real64 LSOutletAirHumRat; // low speed outlet air humidity ratio [kg/kg]
12541 : Real64 HSOutletAirDryBulbTemp; // high speed outlet air dry bulb temperature [C]
12542 : Real64 HSOutletAirEnthalpy; // high speed outlet air enthalpy [J/kg]
12543 : Real64 HSOutletAirHumRat; // high speed outlet air humidity ratio [kg/kg]
12544 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
12545 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
12546 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
12547 : Real64 tADP; // Apparatus dew point temperature [C]
12548 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
12549 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
12550 : Real64 RatedCBFHS; // coil bypass factor at rated conditions (high speed)
12551 : Real64 CBFHS; // coil bypass factor at max flow (high speed)
12552 : Real64 RatedCBFLS; // coil bypass factor at rated conditions (low speed)
12553 : Real64 CBFLS; // coil bypass factor at max flow (low speed)
12554 : Real64 TotCapHS; // total capacity at high speed [W]
12555 : Real64 SHRHS; // sensible heat ratio at high speed
12556 : Real64 TotCapLS; // total capacity at low speed [W]
12557 : Real64 SHRLS; // sensible heat ratio at low speed
12558 : Real64 EIRTempModFacHS; // EIR modifier (function of entering wetbulb, outside drybulb) (high speed)
12559 : Real64 EIRFlowModFacHS; // EIR modifier (function of actual supply air flow vs rated flow) (high speed)
12560 : Real64 EIRHS; // EIR at off rated conditions (high speed)
12561 : Real64 EIRTempModFacLS; // EIR modifier (function of entering wetbulb, outside drybulb) (low speed)
12562 : Real64 EIRFlowModFacLS; // EIR modifier (function of actual supply air flow vs rated flow) (low speed)
12563 : Real64 EIRLS; // EIR at off rated conditions (low speed)
12564 : Real64 SHR; // sensible heat ratio at current speed
12565 : Real64 EIR; // EIR at current speed
12566 : Real64 CBF; // CBFNom adjusted for actual air mass flow rate
12567 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in
12568 : // power calculation
12569 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
12570 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
12571 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
12572 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
12573 : Real64 RhoAir; // Density of air [kg/m3]
12574 : Real64 RhoWater; // Density of water [kg/m3]
12575 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
12576 : Real64 EvapCondPumpElecPower; // Evaporative condenser electric pump power [W]
12577 265 : constexpr int DXMode(1); // Performance mode for MultiMode DX coil; Always 1 for other coil types
12578 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
12579 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
12580 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
12581 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
12582 : int SpeedNumHS; // High speed number
12583 : int SpeedNumLS; // Low speed number
12584 : Real64 SHRUnadjusted; // Temp SHR
12585 : Real64 QLatRated; // Qlatent at rated conditions of indoor(TDB,TWB)=(26.7C,19.4C)
12586 : Real64 QLatActual; // Qlatent at actual operating conditions
12587 : Real64 AirMassFlowRatioLS; // airflow ratio at low speed
12588 : Real64 AirMassFlowRatioHS; // airflow ratio at high speed
12589 : Real64 WasteHeatLS; // Waste heat at low speed
12590 : Real64 WasteHeatHS; // Waste heat at high speed
12591 : Real64 LSElecCoolingPower; // low speed power [W]
12592 : Real64 HSElecCoolingPower; // high speed power [W]
12593 : Real64 CrankcaseHeatingPower; // Power due to crank case heater
12594 : Real64 AirVolumeFlowRate; // Air volume flow rate across the heating coil
12595 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total heating capacity
12596 :
12597 265 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
12598 :
12599 265 : if (thisDXCoil.CondenserInletNodeNum(DXMode) != 0) {
12600 74 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).Press;
12601 : // If node is not connected to anything, pressure = default, use weather data
12602 74 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
12603 74 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12604 74 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
12605 74 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12606 74 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
12607 : } else {
12608 0 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).Temp;
12609 0 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).HumRat;
12610 0 : OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, RoutineName);
12611 : }
12612 74 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
12613 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
12614 0 : OutdoorDryBulb = secZoneHB.ZT;
12615 0 : OutdoorHumRat = secZoneHB.airHumRat;
12616 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
12617 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12618 : }
12619 191 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
12620 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
12621 0 : OutdoorDryBulb = secZoneHB.ZT;
12622 0 : OutdoorHumRat = secZoneHB.airHumRat;
12623 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
12624 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12625 : } else {
12626 191 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12627 191 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
12628 191 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12629 191 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
12630 : }
12631 :
12632 265 : if (SpeedNum > 1) {
12633 59 : SpeedNumLS = SpeedNum - 1;
12634 59 : SpeedNumHS = SpeedNum;
12635 59 : if (SpeedNum > thisDXCoil.NumOfSpeeds) {
12636 0 : SpeedNumLS = thisDXCoil.NumOfSpeeds - 1;
12637 0 : SpeedNumHS = thisDXCoil.NumOfSpeeds;
12638 : }
12639 : } else {
12640 206 : SpeedNumLS = 1;
12641 206 : SpeedNumHS = 1;
12642 : }
12643 :
12644 265 : MSHPWasteHeat = 0.0;
12645 265 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
12646 265 : AirMassFlowRatioLS = MSHPMassFlowRateLow / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS);
12647 265 : AirMassFlowRatioHS = MSHPMassFlowRateHigh / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS);
12648 265 : if ((AirMassFlow > 0.0) && (CycRatio > 0.0) && (MSHPMassFlowRateHigh == 0.0)) {
12649 0 : ShowSevereError(
12650 : state,
12651 0 : format("CalcMultiSpeedDXCoilCooling: {} \"{} Developer error - inconsistent airflow rates.", thisDXCoil.DXCoilType, thisDXCoil.Name));
12652 0 : if (MSHPMassFlowRateLow == 0.0 && SpeedNum > 1) {
12653 0 : ShowContinueError(state,
12654 : "When AirMassFlow > 0.0 and CycRatio > 0.0 and SpeedNum > 1, then MSHPMassFlowRateLow and MSHPMassFlowRateHigh "
12655 : "must also be > 0.0");
12656 0 : ShowContinueErrorTimeStamp(state, "");
12657 0 : ShowContinueError(state,
12658 0 : format("AirMassFlow={:.3R},CycRatio={:.3R},SpeedNum={:.0R}, MSHPMassFlowRateLow={:.3R}, MSHPMassFlowRateHigh={:.3R}",
12659 : AirMassFlow,
12660 0 : double(SpeedNum),
12661 : CycRatio,
12662 : MSHPMassFlowRateLow,
12663 : MSHPMassFlowRateHigh));
12664 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
12665 : } else {
12666 0 : ShowContinueError(state, "When AirMassFlow > 0.0 and CycRatio > 0.0, then MSHPMassFlowRateHigh must also be > 0.0");
12667 0 : ShowContinueErrorTimeStamp(state, "");
12668 0 : ShowContinueError(state,
12669 0 : format("AirMassFlow={:.3R},CycRatio={:.3R}, MSHPMassFlowRateHigh={:.3R}", AirMassFlow, CycRatio, MSHPMassFlowRateHigh));
12670 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
12671 : }
12672 265 : } else if (CycRatio > 1.0 || SpeedRatio > 1.0) {
12673 0 : ShowSevereError(
12674 : state,
12675 0 : format("CalcMultiSpeedDXCoilCooling: {} \"{} Developer error - inconsistent speed ratios.", thisDXCoil.DXCoilType, thisDXCoil.Name));
12676 0 : ShowContinueError(state, "CycRatio and SpeedRatio must be between 0.0 and 1.0");
12677 0 : ShowContinueErrorTimeStamp(state, "");
12678 0 : ShowContinueError(state, format("CycRatio={:.1R}, SpeedRatio = {:.1R}", CycRatio, SpeedRatio));
12679 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
12680 : }
12681 :
12682 265 : thisDXCoil.PartLoadRatio = 0.0;
12683 265 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
12684 265 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
12685 265 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
12686 265 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
12687 265 : InletAirHumRat = thisDXCoil.InletAirHumRat;
12688 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12689 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
12690 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
12691 265 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure, RoutineName);
12692 265 : if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Air) {
12693 265 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
12694 0 : } else if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
12695 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
12696 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.MSEvapCondEffect(SpeedNumHS));
12697 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure, RoutineName);
12698 : }
12699 265 : if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
12700 168 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
12701 168 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
12702 2 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
12703 : }
12704 : } else {
12705 97 : CrankcaseHeatingPower = 0.0;
12706 : }
12707 :
12708 230 : if ((AirMassFlow > 0.0 && CondInletTemp >= thisDXCoil.MinOATCompressor) && (thisDXCoil.availSched->getCurrentVal() > 0.0) &&
12709 495 : ((SpeedRatio > 0.0 && SingleMode == 0) || CycRatio > 0.0) && (compressorOp == HVAC::CompressorOp::On)) {
12710 :
12711 99 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat, RoutineName);
12712 99 : if (SpeedNum > 1 && SingleMode == 0) {
12713 :
12714 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at low speed
12715 21 : AirVolumeFlowRate = MSHPMassFlowRateLow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
12716 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12717 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
12718 21 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumLS);
12719 21 : if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
12720 26 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
12721 5 : state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
12722 5 : if (thisDXCoil.MSErrIndex(SpeedNumLS) == 0) {
12723 2 : ShowWarningMessage(
12724 : state,
12725 2 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
12726 1 : thisDXCoil.DXCoilType,
12727 1 : thisDXCoil.Name,
12728 : SpeedNumLS));
12729 2 : ShowContinueErrorTimeStamp(state, "");
12730 2 : ShowContinueError(state,
12731 2 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
12732 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12733 1 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12734 : VolFlowperRatedTotCap));
12735 2 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
12736 3 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
12737 : }
12738 40 : ShowRecurringWarningErrorAtEnd(state,
12739 10 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
12740 : "at speed {} error continues...",
12741 5 : thisDXCoil.DXCoilType,
12742 5 : thisDXCoil.Name,
12743 : SpeedNumLS),
12744 : thisDXCoil.MSErrIndex(SpeedNumLS),
12745 : VolFlowperRatedTotCap,
12746 : VolFlowperRatedTotCap);
12747 : }
12748 :
12749 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at high speed
12750 21 : AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
12751 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12752 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
12753 21 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumHS);
12754 21 : if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
12755 21 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
12756 0 : state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
12757 0 : if (thisDXCoil.MSErrIndex(SpeedNumHS) == 0) {
12758 0 : ShowWarningMessage(
12759 : state,
12760 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
12761 0 : thisDXCoil.DXCoilType,
12762 0 : thisDXCoil.Name,
12763 : SpeedNumHS));
12764 0 : ShowContinueErrorTimeStamp(state, "");
12765 0 : ShowContinueError(state,
12766 0 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
12767 0 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12768 0 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12769 : VolFlowperRatedTotCap));
12770 0 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
12771 0 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
12772 : }
12773 0 : ShowRecurringWarningErrorAtEnd(state,
12774 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
12775 : "at speed {} error continues...",
12776 0 : thisDXCoil.DXCoilType,
12777 0 : thisDXCoil.Name,
12778 : SpeedNumHS),
12779 : thisDXCoil.MSErrIndex(SpeedNumHS),
12780 : VolFlowperRatedTotCap,
12781 : VolFlowperRatedTotCap);
12782 : }
12783 :
12784 : // Adjust high speed coil bypass factor for actual maximum air flow rate.
12785 21 : RatedCBFHS = thisDXCoil.MSRatedCBF(SpeedNumHS);
12786 21 : CBFHS = AdjustCBF(RatedCBFHS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS), MSHPMassFlowRateHigh);
12787 21 : RatedCBFLS = thisDXCoil.MSRatedCBF(SpeedNumLS);
12788 21 : CBFLS = AdjustCBF(RatedCBFLS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS), MSHPMassFlowRateLow);
12789 : // get low speed total capacity and SHR at current conditions
12790 63 : CalcTotCapSHR(state,
12791 : InletAirDryBulbTemp,
12792 : InletAirHumRat,
12793 : InletAirEnthalpy,
12794 : InletAirWetBulbC,
12795 : AirMassFlowRatioLS,
12796 : MSHPMassFlowRateLow,
12797 21 : thisDXCoil.MSRatedTotCap(SpeedNumLS),
12798 : CBFLS,
12799 21 : thisDXCoil.MSCCapFTemp(SpeedNumLS),
12800 21 : thisDXCoil.MSCCapFFlow(SpeedNumLS),
12801 : TotCapLS,
12802 : SHRLS,
12803 : CondInletTemp,
12804 : OutdoorPressure,
12805 21 : thisDXCoil.capModFacTotal);
12806 : // get low speed outlet conditions
12807 21 : hDelta = TotCapLS / MSHPMassFlowRateLow;
12808 : // Calculate new apparatus dew point conditions
12809 21 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBFLS);
12810 21 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineNameHighSpeedAlt);
12811 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12812 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
12813 21 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
12814 21 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
12815 : // get corresponding SHR
12816 21 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
12817 21 : SHRLS = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
12818 : } else {
12819 0 : SHRLS = 1.0;
12820 : }
12821 : // cr8918 SHRLS = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
12822 : // get low speed outlet conditions
12823 21 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
12824 21 : hTinwout = InletAirEnthalpy - (1.0 - SHRLS) * hDelta;
12825 21 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
12826 21 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
12827 21 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineName);
12828 21 : if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
12829 1 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
12830 1 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineName);
12831 : }
12832 :
12833 : // get high speed total capacity and SHR at current conditions
12834 :
12835 63 : CalcTotCapSHR(state,
12836 : InletAirDryBulbTemp,
12837 : InletAirHumRat,
12838 : InletAirEnthalpy,
12839 : InletAirWetBulbC,
12840 : AirMassFlowRatioHS,
12841 : MSHPMassFlowRateHigh,
12842 21 : thisDXCoil.MSRatedTotCap(SpeedNumHS),
12843 : CBFHS,
12844 21 : thisDXCoil.MSCCapFTemp(SpeedNumHS),
12845 21 : thisDXCoil.MSCCapFFlow(SpeedNumHS),
12846 : TotCapHS,
12847 : SHRHS,
12848 : CondInletTemp,
12849 : OutdoorPressure,
12850 21 : thisDXCoil.capModFacTotal);
12851 21 : hDelta = TotCapHS / MSHPMassFlowRateHigh;
12852 : // Calculate new apparatus dew point conditions
12853 21 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBFHS);
12854 21 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
12855 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12856 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
12857 21 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
12858 21 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
12859 : // get corresponding SHR
12860 21 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
12861 21 : SHRHS = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
12862 : } else {
12863 0 : SHRHS = 1.0;
12864 : }
12865 : // cr8918 SHRHS = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
12866 : // get the part load factor that will account for cycling losses
12867 21 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNumHS), SpeedRatio);
12868 21 : if (PLF < 0.7) {
12869 0 : PLF = 0.7;
12870 : }
12871 : // calculate the run time fraction
12872 21 : thisDXCoil.CoolingCoilRuntimeFraction = SpeedRatio / PLF;
12873 21 : thisDXCoil.PartLoadRatio = SpeedRatio;
12874 :
12875 21 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
12876 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
12877 : }
12878 :
12879 : // get high speed outlet conditions
12880 21 : HSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
12881 21 : hTinwout = InletAirEnthalpy - (1.0 - SHRHS) * hDelta;
12882 21 : HSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
12883 21 : HSOutletAirDryBulbTemp = PsyTdbFnHW(HSOutletAirEnthalpy, HSOutletAirHumRat);
12884 21 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, HSOutletAirEnthalpy, OutdoorPressure, RoutineName);
12885 21 : if (HSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
12886 1 : HSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
12887 1 : HSOutletAirHumRat = PsyWFnTdbH(state, HSOutletAirDryBulbTemp, HSOutletAirEnthalpy, RoutineName);
12888 : }
12889 :
12890 : // If constant fan with cycling compressor, call function to determine "effective SHR"
12891 : // which includes the part-load degradation on latent capacity
12892 21 : if (thisDXCoil.LatentImpact && fanOp == HVAC::FanOp::Continuous && SpeedRatio > 0.0) {
12893 0 : QLatRated = thisDXCoil.MSRatedTotCap(SpeedNumHS) * (1.0 - thisDXCoil.MSRatedSHR(SpeedNumHS));
12894 0 : QLatActual = TotCapHS * (1.0 - SHRHS);
12895 0 : SHRUnadjusted = SHRHS;
12896 0 : SHR = CalcEffectiveSHR(state,
12897 : DXCoilNum,
12898 : SHRHS,
12899 : thisDXCoil.CoolingCoilRuntimeFraction,
12900 : QLatRated,
12901 : QLatActual,
12902 : InletAirDryBulbTemp,
12903 : InletAirWetBulbC,
12904 : SpeedNumHS);
12905 : // Calculate full load output conditions
12906 0 : if (SHR > 1.0) SHR = 1.0;
12907 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
12908 0 : if (SHR < 1.0) {
12909 0 : HSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
12910 : } else {
12911 0 : HSOutletAirHumRat = InletAirHumRat;
12912 : }
12913 0 : HSOutletAirDryBulbTemp = PsyTdbFnHW(HSOutletAirEnthalpy, HSOutletAirHumRat);
12914 : }
12915 :
12916 : // get high speed EIR at current conditions
12917 21 : EIRTempModFacHS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), InletAirWetBulbC, CondInletTemp);
12918 21 : EIRFlowModFacHS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumHS), AirMassFlowRatioHS);
12919 21 : EIRHS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumHS) * EIRFlowModFacHS * EIRTempModFacHS;
12920 : // get low speed EIR at current conditions
12921 21 : EIRTempModFacLS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), InletAirWetBulbC, CondInletTemp);
12922 21 : EIRFlowModFacLS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumLS), AirMassFlowRatioLS);
12923 21 : EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumLS) * EIRTempModFacLS * EIRFlowModFacLS;
12924 :
12925 : // get current total capacity, SHR, EIR
12926 21 : if (SpeedRatio >= 1.0) {
12927 15 : SHR = SHRHS;
12928 15 : EIR = EIRHS;
12929 15 : CondAirMassFlow = RhoAir * thisDXCoil.MSEvapCondAirFlow(SpeedNumHS);
12930 15 : EvapCondPumpElecPower = thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumHS);
12931 : } else {
12932 6 : EIR = SpeedRatio * EIRHS + (1.0 - SpeedRatio) * EIRLS;
12933 6 : SHR = SpeedRatio * SHRHS + (1.0 - SpeedRatio) * SHRLS;
12934 6 : CondAirMassFlow =
12935 6 : RhoAir * (SpeedRatio * thisDXCoil.MSEvapCondAirFlow(SpeedNumHS) + (1.0 - SpeedRatio) * thisDXCoil.MSEvapCondAirFlow(SpeedNumLS));
12936 6 : EvapCondPumpElecPower = SpeedRatio * thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumHS) +
12937 6 : (1.0 - SpeedRatio) * thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumLS);
12938 : }
12939 :
12940 : // Outlet calculation
12941 21 : Real64 SensibleOutputLS(0.0); // low speed sensible output rate
12942 21 : Real64 LatentOutputLS(0.0); // low speed latent output rate
12943 21 : Real64 TotalOutputLS(0.0); // low speed total output rate
12944 21 : Real64 SensibleOutputHS(0.0); // high speed sensible output rate
12945 21 : Real64 LatentOutputHS(0.0); // high speed latent output rate
12946 21 : Real64 TotalOutputHS(0.0); // high speed total output rate
12947 21 : CalcComponentSensibleLatentOutput(MSHPMassFlowRateLow,
12948 : InletAirDryBulbTemp,
12949 : InletAirHumRat,
12950 : LSOutletAirDryBulbTemp,
12951 : LSOutletAirHumRat,
12952 : SensibleOutputLS,
12953 : LatentOutputLS,
12954 : TotalOutputLS);
12955 21 : CalcComponentSensibleLatentOutput(MSHPMassFlowRateHigh,
12956 : InletAirDryBulbTemp,
12957 : InletAirHumRat,
12958 : HSOutletAirDryBulbTemp,
12959 : HSOutletAirHumRat,
12960 : SensibleOutputHS,
12961 : LatentOutputHS,
12962 : TotalOutputHS);
12963 21 : thisDXCoil.TotalCoolingEnergyRate = TotalOutputHS * SpeedRatio + TotalOutputLS * (1.0 - SpeedRatio);
12964 21 : thisDXCoil.SensCoolingEnergyRate = SensibleOutputHS * SpeedRatio + SensibleOutputLS * (1.0 - SpeedRatio);
12965 21 : thisDXCoil.LatCoolingEnergyRate = LatentOutputHS * SpeedRatio + LatentOutputLS * (1.0 - SpeedRatio);
12966 : // Average outlet enthalpy
12967 21 : OutletAirEnthalpy = InletAirEnthalpy - thisDXCoil.TotalCoolingEnergyRate / thisDXCoil.InletAirMassFlowRate;
12968 :
12969 21 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
12970 : // Update outlet conditions
12971 21 : if (SpeedRatio == 0.0 && fanOp == HVAC::FanOp::Cycling) {
12972 3 : OutletAirEnthalpy = LSOutletAirEnthalpy;
12973 3 : OutletAirHumRat = LSOutletAirHumRat;
12974 3 : OutletAirDryBulbTemp = LSOutletAirDryBulbTemp;
12975 18 : } else if (SpeedRatio >= 1.0 && fanOp == HVAC::FanOp::Cycling) {
12976 6 : OutletAirEnthalpy = HSOutletAirEnthalpy;
12977 6 : OutletAirHumRat = HSOutletAirHumRat;
12978 6 : OutletAirDryBulbTemp = HSOutletAirDryBulbTemp;
12979 : } else {
12980 12 : OutletAirHumRat =
12981 12 : ((HSOutletAirHumRat * SpeedRatio * MSHPMassFlowRateHigh) + (LSOutletAirHumRat * (1.0 - SpeedRatio) * MSHPMassFlowRateLow)) /
12982 12 : thisDXCoil.InletAirMassFlowRate;
12983 12 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
12984 12 : if (OutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
12985 0 : OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
12986 0 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy, RoutineName);
12987 0 : CalcComponentSensibleLatentOutput(AirMassFlow,
12988 : InletAirDryBulbTemp,
12989 : InletAirHumRat,
12990 : OutletAirDryBulbTemp,
12991 : OutletAirHumRat,
12992 0 : thisDXCoil.SensCoolingEnergyRate,
12993 0 : thisDXCoil.LatCoolingEnergyRate,
12994 0 : thisDXCoil.TotalCoolingEnergyRate);
12995 : }
12996 : }
12997 :
12998 21 : LSElecCoolingPower = TotCapLS * EIRLS;
12999 21 : HSElecCoolingPower = TotCapHS * EIRHS;
13000 :
13001 : // Power calculation
13002 21 : if (!thisDXCoil.PLRImpact) {
13003 21 : thisDXCoil.ElecCoolingPower = SpeedRatio * HSElecCoolingPower + (1.0 - SpeedRatio) * LSElecCoolingPower;
13004 : } else {
13005 0 : thisDXCoil.ElecCoolingPower =
13006 0 : thisDXCoil.CoolingCoilRuntimeFraction * HSElecCoolingPower + (1.0 - thisDXCoil.CoolingCoilRuntimeFraction) * LSElecCoolingPower;
13007 : }
13008 : // Now reset runtime fraction to 1.0 (because LS is running the full timestep)
13009 21 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0;
13010 :
13011 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
13012 21 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
13013 :
13014 : // Waste heat calculation
13015 : // TODO: waste heat not considered even if defined in Cooling:DX:MultiSpeed, N16, \field Speed 1 Rated Waste Heat Fraction of
13016 : // Power Input
13017 21 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13018 8 : if (thisDXCoil.MSWasteHeat(SpeedNumLS) == 0) {
13019 7 : WasteHeatLS = thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13020 : } else {
13021 1 : WasteHeatLS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumLS), OutdoorDryBulb, InletAirDryBulbTemp) *
13022 1 : thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13023 : }
13024 8 : if (thisDXCoil.MSWasteHeat(SpeedNumHS) == 0) {
13025 7 : WasteHeatHS = thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13026 : } else {
13027 1 : WasteHeatHS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumHS), OutdoorDryBulb, InletAirDryBulbTemp) *
13028 1 : thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13029 : }
13030 8 : thisDXCoil.MSFuelWasteHeat = (SpeedRatio * WasteHeatHS + (1.0 - SpeedRatio) * WasteHeatLS) * thisDXCoil.ElecCoolingPower;
13031 8 : if (thisDXCoil.MSHPHeatRecActive) {
13032 1 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
13033 : }
13034 : }
13035 :
13036 : // Energy use for other fuel types
13037 21 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13038 8 : thisDXCoil.FuelUsed = thisDXCoil.ElecCoolingPower;
13039 8 : thisDXCoil.ElecCoolingPower = 0.0;
13040 : }
13041 :
13042 21 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
13043 21 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
13044 21 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
13045 21 : thisDXCoil.CrankcaseHeaterPower = 0.0;
13046 :
13047 99 : } else if (CycRatio > 0.0) {
13048 :
13049 78 : if (fanOp == HVAC::FanOp::Cycling) AirMassFlow /= CycRatio;
13050 78 : if (fanOp == HVAC::FanOp::Continuous) AirMassFlow = MSHPMassFlowRateHigh;
13051 :
13052 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at low speed
13053 78 : AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
13054 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13055 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
13056 78 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNum);
13057 78 : if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13058 99 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
13059 21 : state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
13060 21 : if (thisDXCoil.MSErrIndex(SpeedNum) == 0) {
13061 4 : ShowWarningMessage(
13062 : state,
13063 4 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
13064 2 : thisDXCoil.DXCoilType,
13065 2 : thisDXCoil.Name,
13066 : SpeedNum));
13067 4 : ShowContinueErrorTimeStamp(state, "");
13068 4 : ShowContinueError(state,
13069 4 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13070 2 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13071 2 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13072 : VolFlowperRatedTotCap));
13073 4 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13074 6 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13075 : }
13076 168 : ShowRecurringWarningErrorAtEnd(state,
13077 42 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
13078 : "at speed {} error continues...",
13079 21 : thisDXCoil.DXCoilType,
13080 21 : thisDXCoil.Name,
13081 : SpeedNumHS),
13082 : thisDXCoil.MSErrIndex(SpeedNumHS),
13083 : VolFlowperRatedTotCap,
13084 : VolFlowperRatedTotCap);
13085 : }
13086 :
13087 78 : if (thisDXCoil.CondenserType(SpeedNum) == DataHeatBalance::RefrigCondenserType::Evap) {
13088 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
13089 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.MSEvapCondEffect(SpeedNum));
13090 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure, RoutineName);
13091 : }
13092 :
13093 78 : RatedCBFLS = thisDXCoil.MSRatedCBF(SpeedNum);
13094 78 : CBFLS = AdjustCBF(RatedCBFLS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNum), MSHPMassFlowRateHigh);
13095 :
13096 : // Adjust low speed coil bypass factor for actual flow rate.
13097 : // CBF = AdjustCBF(DXCoil(DXCoilNum)%RatedCBF2,DXCoil(DXCoilNum)%RatedAirMassFlowRate2,AirMassFlow)
13098 : // get low speed total capacity and SHR at current conditions
13099 234 : CalcTotCapSHR(state,
13100 : InletAirDryBulbTemp,
13101 : InletAirHumRat,
13102 : InletAirEnthalpy,
13103 : InletAirWetBulbC,
13104 : AirMassFlowRatioLS,
13105 : MSHPMassFlowRateHigh,
13106 78 : thisDXCoil.MSRatedTotCap(SpeedNum),
13107 : CBFLS,
13108 78 : thisDXCoil.MSCCapFTemp(SpeedNum),
13109 78 : thisDXCoil.MSCCapFFlow(SpeedNum),
13110 : TotCapLS,
13111 : SHRLS,
13112 : CondInletTemp,
13113 : OutdoorPressure,
13114 78 : thisDXCoil.capModFacTotal);
13115 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13116 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)
13117 78 : hDelta = TotCapLS / AirMassFlow;
13118 : // Adjust CBF for off-nominal flow
13119 78 : CBF = AdjustCBF(thisDXCoil.MSRatedCBF(SpeedNum), thisDXCoil.MSRatedAirMassFlowRate(SpeedNum), AirMassFlow);
13120 : // Calculate new apparatus dew point conditions
13121 78 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
13122 78 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
13123 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13124 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
13125 78 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
13126 78 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
13127 : // get corresponding SHR
13128 78 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
13129 78 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
13130 : } else {
13131 0 : SHR = 1.0;
13132 : }
13133 : // cr8918 SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
13134 :
13135 : // get the part load factor that will account for cycling losses
13136 78 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNum), CycRatio);
13137 78 : if (fanOp == HVAC::FanOp::Cycling && CycRatio == 1.0 && PLF != 1.0) {
13138 0 : if (thisDXCoil.PLFErrIndex == 0) {
13139 0 : ShowWarningMessage(state,
13140 0 : format("The PLF curve value for DX cooling coil {} ={:.2R} for part-load ratio = 1", thisDXCoil.Name, PLF));
13141 0 : ShowContinueError(state, "PLF curve value must be = 1.0 and has been reset to 1.0. Simulation is continuing.");
13142 0 : ShowContinueErrorTimeStamp(state, "");
13143 : }
13144 0 : ShowRecurringWarningErrorAtEnd(
13145 0 : state, thisDXCoil.Name + "\": DX cooling coil PLF curve value <> 1.0 warning continues...", thisDXCoil.PLFErrIndex, PLF, PLF);
13146 0 : PLF = 1.0;
13147 : }
13148 :
13149 78 : if (PLF < 0.7) {
13150 0 : PLF = 0.7;
13151 : }
13152 : // calculate the run time fraction
13153 78 : thisDXCoil.CoolingCoilRuntimeFraction = CycRatio / PLF;
13154 78 : thisDXCoil.PartLoadRatio = CycRatio;
13155 :
13156 78 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
13157 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
13158 : }
13159 :
13160 : // get low speed outlet conditions
13161 78 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
13162 78 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
13163 78 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
13164 78 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
13165 78 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineName);
13166 78 : if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
13167 0 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
13168 0 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineName);
13169 : }
13170 :
13171 : // If constant fan with cycling compressor, call function to determine "effective SHR"
13172 : // which includes the part-load degradation on latent capacity
13173 78 : if (fanOp == HVAC::FanOp::Continuous) {
13174 41 : QLatRated = thisDXCoil.MSRatedTotCap(SpeedNum) * (1.0 - thisDXCoil.MSRatedSHR(SpeedNum));
13175 41 : QLatActual = TotCapLS * (1.0 - SHR);
13176 41 : SHRUnadjusted = SHR;
13177 41 : SHR = CalcEffectiveSHR(state,
13178 : DXCoilNum,
13179 : SHR,
13180 : thisDXCoil.CoolingCoilRuntimeFraction,
13181 : QLatRated,
13182 : QLatActual,
13183 : InletAirDryBulbTemp,
13184 : InletAirWetBulbC,
13185 : SpeedNum);
13186 : // Calculate full load output conditions
13187 41 : if (SHR > 1.0) SHR = 1.0;
13188 41 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
13189 41 : if (SHR < 1.0) {
13190 33 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
13191 : } else {
13192 8 : LSOutletAirHumRat = InletAirHumRat;
13193 : }
13194 41 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
13195 : }
13196 :
13197 78 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
13198 78 : if (fanOp == HVAC::FanOp::Continuous) {
13199 : // outlet conditions are average of inlet and low speed weighted by CycRatio
13200 : // Continuous fan, cycling compressor
13201 41 : Real64 CycAirFlowRatio =
13202 41 : CycRatio * AirMassFlow / thisDXCoil.InletAirMassFlowRate; // ratio of compressor on airflow to average timestep airflow
13203 41 : OutletAirEnthalpy = CycAirFlowRatio * LSOutletAirEnthalpy + (1.0 - CycAirFlowRatio) * InletAirEnthalpy;
13204 41 : OutletAirHumRat = CycAirFlowRatio * LSOutletAirHumRat + (1.0 - CycAirFlowRatio) * InletAirHumRat;
13205 41 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
13206 : } else {
13207 37 : OutletAirHumRat = LSOutletAirHumRat;
13208 37 : OutletAirDryBulbTemp = LSOutletAirDryBulbTemp;
13209 37 : OutletAirEnthalpy = LSOutletAirEnthalpy;
13210 : }
13211 :
13212 : // get low speed EIR at current conditions
13213 78 : EIRTempModFacLS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNum), InletAirWetBulbC, CondInletTemp);
13214 78 : EIRFlowModFacLS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNum), AirMassFlowRatioLS);
13215 78 : EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNum) * EIRTempModFacLS * EIRFlowModFacLS;
13216 :
13217 : // get the electrical power consumption
13218 78 : thisDXCoil.ElecCoolingPower = TotCapLS * EIRLS * thisDXCoil.CoolingCoilRuntimeFraction;
13219 : // calculate cooling output power
13220 : // AirMassFlow = DXCoil(DXCoilNum)%InletAirMassFlowRate
13221 78 : CalcComponentSensibleLatentOutput(AirMassFlow,
13222 : InletAirDryBulbTemp,
13223 : InletAirHumRat,
13224 : LSOutletAirDryBulbTemp,
13225 : LSOutletAirHumRat,
13226 78 : thisDXCoil.SensCoolingEnergyRate,
13227 78 : thisDXCoil.LatCoolingEnergyRate,
13228 78 : thisDXCoil.TotalCoolingEnergyRate);
13229 78 : thisDXCoil.TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate * CycRatio;
13230 78 : thisDXCoil.SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate * CycRatio;
13231 78 : thisDXCoil.LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate * CycRatio;
13232 :
13233 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
13234 78 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
13235 78 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
13236 78 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
13237 78 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
13238 78 : CondAirMassFlow = RhoAir * thisDXCoil.MSEvapCondAirFlow(SpeedNum) * thisDXCoil.CoolingCoilRuntimeFraction;
13239 78 : EvapCondPumpElecPower = thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNum) * thisDXCoil.CoolingCoilRuntimeFraction;
13240 :
13241 : // Waste heat
13242 78 : if (thisDXCoil.MSHPHeatRecActive) {
13243 0 : if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
13244 0 : thisDXCoil.MSFuelWasteHeat = thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecCoolingPower;
13245 : } else {
13246 0 : thisDXCoil.MSFuelWasteHeat = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNum), OutdoorDryBulb, InletAirDryBulbTemp) *
13247 0 : thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecCoolingPower;
13248 : }
13249 0 : if (thisDXCoil.MSHPHeatRecActive) {
13250 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
13251 : }
13252 : }
13253 : // Energy use for other fuel types
13254 78 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13255 22 : thisDXCoil.FuelUsed = thisDXCoil.ElecCoolingPower;
13256 22 : thisDXCoil.ElecCoolingPower = 0.0;
13257 : }
13258 :
13259 78 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
13260 78 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
13261 : } else {
13262 0 : thisDXCoil.CrankcaseHeaterPower =
13263 0 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.CoolingCoilRuntimeFraction,
13264 0 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction));
13265 : }
13266 : }
13267 :
13268 99 : if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
13269 : //******************
13270 : // WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
13271 : // H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
13272 : // /RhoWater [kgWater/m3]
13273 : //******************
13274 0 : RhoWater = RhoH2O(OutdoorDryBulb);
13275 0 : thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater;
13276 0 : thisDXCoil.EvapCondPumpElecPower = EvapCondPumpElecPower;
13277 : // set water system demand request (if needed)
13278 0 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
13279 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
13280 0 : thisDXCoil.EvapWaterConsumpRate;
13281 : }
13282 :
13283 : // Calculate basin heater power
13284 0 : CalcBasinHeaterPower(state,
13285 : thisDXCoil.BasinHeaterPowerFTempDiff,
13286 : thisDXCoil.basinHeaterSched,
13287 : thisDXCoil.BasinHeaterSetPointTemp,
13288 0 : thisDXCoil.BasinHeaterPower);
13289 0 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
13290 : }
13291 :
13292 : } else {
13293 :
13294 : // DX coil is off; just pass through conditions
13295 166 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
13296 166 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
13297 166 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
13298 :
13299 166 : thisDXCoil.FuelUsed = 0.0;
13300 166 : thisDXCoil.ElecCoolingPower = 0.0;
13301 166 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
13302 166 : thisDXCoil.SensCoolingEnergyRate = 0.0;
13303 166 : thisDXCoil.LatCoolingEnergyRate = 0.0;
13304 166 : thisDXCoil.EvapCondPumpElecPower = 0.0;
13305 166 : thisDXCoil.EvapWaterConsumpRate = 0.0;
13306 :
13307 166 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
13308 166 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
13309 : } else {
13310 0 : thisDXCoil.CrankcaseHeaterPower =
13311 0 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction);
13312 : }
13313 :
13314 : // Calculate basin heater power
13315 166 : if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
13316 0 : CalcBasinHeaterPower(state,
13317 : thisDXCoil.BasinHeaterPowerFTempDiff,
13318 : thisDXCoil.basinHeaterSched,
13319 : thisDXCoil.BasinHeaterSetPointTemp,
13320 0 : thisDXCoil.BasinHeaterPower);
13321 : }
13322 : }
13323 :
13324 265 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
13325 265 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
13326 265 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
13327 265 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
13328 265 : thisDXCoil.CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure
13329 :
13330 : // set outlet node conditions
13331 265 : int airOutletNode = thisDXCoil.AirOutNode;
13332 265 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
13333 265 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
13334 :
13335 : // calc secondary coil if specified
13336 265 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
13337 0 : CalcSecondaryDXCoils(state, DXCoilNum);
13338 : }
13339 265 : }
13340 :
13341 211 : void CalcMultiSpeedDXCoilHeating(EnergyPlusData &state,
13342 : int const DXCoilNum, // the number of the DX heating coil to be simulated
13343 : Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
13344 : Real64 const CycRatio, // cycling part load ratio
13345 : int const SpeedNum, // Speed number
13346 : HVAC::FanOp const fanOp, // Fan operation mode
13347 : int const SingleMode // Single mode operation Yes/No; 1=Yes, 0=No
13348 : )
13349 : {
13350 :
13351 : // SUBROUTINE INFORMATION:
13352 : // AUTHOR Lixing Gu, FSEC
13353 : // DATE WRITTEN June 2007
13354 : // RE-ENGINEERED Revised based on CalcDXHeatingCoil
13355 :
13356 : // PURPOSE OF THIS SUBROUTINE:
13357 : // Calculates the air-side performance and electrical energy use of a direct-
13358 : // expansion, air-cooled cooling unit with a multispeed compressor.
13359 :
13360 : // METHODOLOGY EMPLOYED:
13361 : // Uses the same methodology as the single speed DX heating unit model (SUBROUTINE CalcDXHeatingCoil).
13362 : // In addition it assumes that the unit performance is obtained by interpolating between
13363 : // the performance at high speed and that at low speed. If the output needed is below
13364 : // that produced at low speed, the compressor cycles between off and low speed.
13365 :
13366 : // Using/Aliasing
13367 : using Curve::CurveValue;
13368 211 : Real64 MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
13369 211 : Real64 MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
13370 211 : auto &MSHPWasteHeat = state.dataHVACGlobal->MSHPWasteHeat;
13371 :
13372 : // SUBROUTINE ARGUMENT DEFINITIONS:
13373 : // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
13374 :
13375 : // SUBROUTINE PARAMETER DEFINITIONS:
13376 : static constexpr std::string_view RoutineName("CalcMultiSpeedDXCoilHeating");
13377 : static constexpr std::string_view RoutineNameAverageLoad("CalcMultiSpeedDXCoilHeating:Averageload");
13378 : static constexpr std::string_view RoutineNameFullLoad("CalcMultiSpeedDXCoilHeating:fullload");
13379 :
13380 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13381 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
13382 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
13383 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
13384 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
13385 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
13386 : Real64 OutletAirEnthalpy; // outlet air enthalpy [J/kg]
13387 : Real64 OutletAirHumRat; // outlet air humidity ratio [kg/kg]
13388 : Real64 TotCapHS; // total capacity at high speed [W]
13389 : Real64 TotCapLS; // total capacity at low speed [W]
13390 : Real64 TotCapHSAdj; // total adjusted capacity at high speed [W]
13391 : Real64 TotCapLSAdj; // total adjusted capacity at low speed [W]
13392 : Real64 EIRHS; // EIR at off rated conditions (high speed)
13393 : Real64 EIRLS; // EIR at off rated conditions (low speed)
13394 : Real64 TotCap; // total capacity at current speed [W]
13395 : Real64 TotCapAdj; // total adjusted capacity at current speed [W]
13396 : Real64 EIR; // EIR at current speed
13397 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in
13398 : // power calculation
13399 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
13400 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
13401 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
13402 : int SpeedNumHS; // High speed number
13403 : int SpeedNumLS; // Low speed number
13404 : Real64 AirMassFlowRatioLS; // airflow ratio at low speed
13405 : Real64 AirMassFlowRatioHS; // airflow ratio at high speed
13406 : Real64 AirFlowRatio; // Airflow ratio
13407 : Real64 PLRHeating; // Part load ratio in heating
13408 : Real64 CrankcaseHeatingPower; // Power due to crank case heater
13409 : Real64 AirVolumeFlowRate; // Air volume flow rate across the heating coil
13410 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total heating capacity
13411 211 : Real64 TotCapTempModFac(0.0); // Total capacity modifier as a function of temperature
13412 : Real64 TotCapFlowModFac; // Total capacity modifier as a function of flow ratio
13413 : Real64 OutdoorCoilT; // Outdoor coil temperature
13414 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temperature of OutdoorCoilT
13415 : Real64 LoadDueToDefrost; // Additional load due to defrost
13416 : Real64 LoadDueToDefrostLS; // Additional load due to defrost at low speed
13417 : Real64 LoadDueToDefrostHS; // Additional load due to defrost at high speed
13418 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
13419 : Real64 FractionalDefrostTime; // Fraction of time step when system is in defrost
13420 : Real64 InputPowerMultiplier; // Multiplier for power when system is in defrost
13421 : Real64 DefrostEIRTempModFac; // EIR modifier for defrost
13422 : Real64 FullLoadOutAirEnth; // Outlet full load enthalpy
13423 : Real64 FullLoadOutAirHumRat; // Outlet humidity ratio at full load
13424 : Real64 FullLoadOutAirTemp; // Outlet temperature at full load
13425 : Real64 FullLoadOutAirRH; // Outlet relative humidity at full load
13426 : Real64 OutletAirTemp; // Supply air temperature
13427 211 : Real64 EIRTempModFac(0.0); // EIR modifier as a function of temperature
13428 : Real64 EIRFlowModFac; // EIR modifier as a function of airflow ratio
13429 : Real64 WasteHeatLS; // Waste heat at low speed
13430 : Real64 WasteHeatHS; // Waste heat at high speed
13431 : Real64 LSFullLoadOutAirEnth; // Outlet full load enthalpy at low speed
13432 : Real64 HSFullLoadOutAirEnth; // Outlet full load enthalpy at high speed
13433 : Real64 LSElecHeatingPower; // Full load power at low speed
13434 : Real64 HSElecHeatingPower; // Full load power at high speed
13435 : Real64 DefrostPowerLS; // Defrost power at low speed [W]
13436 : Real64 DefrostPowerHS; // Defrost power at high speed [W]
13437 :
13438 : // Autodesk:Uninit Initialize variables used uninitialized
13439 211 : FullLoadOutAirEnth = 0.0; // Autodesk:Uninit Force default initialization
13440 :
13441 211 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
13442 :
13443 211 : if (SpeedNum > 1) {
13444 54 : SpeedNumLS = SpeedNum - 1;
13445 54 : SpeedNumHS = SpeedNum;
13446 54 : if (SpeedNum > thisDXCoil.NumOfSpeeds) {
13447 0 : SpeedNumLS = thisDXCoil.NumOfSpeeds - 1;
13448 0 : SpeedNumHS = thisDXCoil.NumOfSpeeds;
13449 : }
13450 : } else {
13451 157 : SpeedNumLS = 1;
13452 157 : SpeedNumHS = 1;
13453 : }
13454 :
13455 211 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
13456 211 : AirMassFlowRatioLS = MSHPMassFlowRateLow / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS);
13457 211 : AirMassFlowRatioHS = MSHPMassFlowRateHigh / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS);
13458 211 : if ((AirMassFlow > 0.0) && (CycRatio > 0.0) && (MSHPMassFlowRateHigh == 0.0)) {
13459 0 : ShowSevereError(
13460 : state,
13461 0 : format("CalcMultiSpeedDXCoilHeating: {} \"{} Developer error - inconsistent airflow rates.", thisDXCoil.DXCoilType, thisDXCoil.Name));
13462 0 : if (MSHPMassFlowRateLow == 0.0 && SpeedNum > 1) {
13463 0 : ShowContinueError(state,
13464 : "When AirMassFlow > 0.0 and CycRatio > 0.0 and SpeedNum > 1, then MSHPMassFlowRateLow and MSHPMassFlowRateHigh "
13465 : "must also be > 0.0");
13466 0 : ShowContinueErrorTimeStamp(state, "");
13467 0 : ShowContinueError(state,
13468 0 : format("AirMassFlow={:.3R},CycRatio={:.3R},SpeedNum={:.0R}, MSHPMassFlowRateLow={:.3R}, MSHPMassFlowRateHigh={:.3R}",
13469 : AirMassFlow,
13470 0 : double(SpeedNum),
13471 : CycRatio,
13472 : MSHPMassFlowRateLow,
13473 : MSHPMassFlowRateHigh));
13474 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
13475 : } else {
13476 0 : ShowContinueError(state, "When AirMassFlow > 0.0 and CycRatio > 0.0, then MSHPMassFlowRateHigh must also be > 0.0");
13477 0 : ShowContinueErrorTimeStamp(state, "");
13478 0 : ShowContinueError(state,
13479 0 : format("AirMassFlow={:.3R},CycRatio={:.3R}, MSHPMassFlowRateHigh={:.3R}", AirMassFlow, CycRatio, MSHPMassFlowRateHigh));
13480 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
13481 : }
13482 211 : } else if (CycRatio > 1.0 || SpeedRatio > 1.0) {
13483 0 : ShowSevereError(
13484 : state,
13485 0 : format("CalcMultiSpeedDXCoilHeating: {} \"{} Developer error - inconsistent speed ratios.", thisDXCoil.DXCoilType, thisDXCoil.Name));
13486 0 : ShowContinueError(state, "CycRatio and SpeedRatio must be between 0.0 and 1.0");
13487 0 : ShowContinueErrorTimeStamp(state, "");
13488 0 : ShowContinueError(state, format("CycRatio={:.1R}, SpeedRatio = {:.1R}", CycRatio, SpeedRatio));
13489 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
13490 : }
13491 :
13492 211 : AirFlowRatio = 1.0;
13493 211 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) MSHPWasteHeat = 0.0;
13494 :
13495 : // Get condenser outdoor node info from DX Heating Coil
13496 211 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
13497 71 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press;
13498 : // If node is not connected to anything, pressure = default, use weather data
13499 71 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
13500 71 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13501 71 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13502 71 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13503 : } else {
13504 0 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp;
13505 0 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat;
13506 : }
13507 71 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
13508 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
13509 0 : OutdoorDryBulb = secZoneHB.ZT;
13510 0 : OutdoorHumRat = secZoneHB.airHumRat;
13511 : // OutdoorWetBulb = DXCoil( DXCoilNum ).EvapInletWetBulb;
13512 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13513 : }
13514 140 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
13515 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
13516 0 : OutdoorDryBulb = secZoneHB.ZT;
13517 0 : OutdoorHumRat = secZoneHB.airHumRat;
13518 : // OutdoorWetBulb = DXCoil( DXCoilNum ).EvapInletWetBulb;
13519 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13520 : } else {
13521 140 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13522 140 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13523 140 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13524 : }
13525 :
13526 211 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
13527 211 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
13528 211 : InletAirHumRat = thisDXCoil.InletAirHumRat;
13529 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13530 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
13531 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
13532 211 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure, RoutineName);
13533 211 : PLRHeating = 0.0;
13534 211 : thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
13535 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
13536 211 : if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
13537 123 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
13538 123 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
13539 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
13540 : }
13541 : } else {
13542 88 : CrankcaseHeatingPower = 0.0;
13543 : }
13544 211 : thisDXCoil.PartLoadRatio = 0.0;
13545 211 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
13546 :
13547 302 : if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && ((CycRatio > 0.0) || (SpeedRatio > 0.0 && SingleMode == 0)) &&
13548 91 : OutdoorDryBulb > thisDXCoil.MinOATCompressor) {
13549 :
13550 91 : if (SpeedNum > 1 && SingleMode == 0) {
13551 :
13552 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton) at low speed
13553 28 : AirVolumeFlowRate = MSHPMassFlowRateLow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
13554 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13555 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
13556 28 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumLS);
13557 56 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13558 28 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
13559 0 : if (thisDXCoil.MSErrIndex(SpeedNumLS) == 0) {
13560 0 : ShowWarningMessage(
13561 : state,
13562 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed {}.",
13563 0 : thisDXCoil.DXCoilType,
13564 0 : thisDXCoil.Name,
13565 : SpeedNumLS));
13566 0 : ShowContinueErrorTimeStamp(state, "");
13567 0 : ShowContinueError(state,
13568 0 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13569 0 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13570 0 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13571 : VolFlowperRatedTotCap));
13572 0 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13573 0 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13574 : }
13575 0 : ShowRecurringWarningErrorAtEnd(state,
13576 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range "
13577 : "at speed {} error continues...",
13578 0 : thisDXCoil.DXCoilType,
13579 0 : thisDXCoil.Name,
13580 : SpeedNumLS),
13581 : thisDXCoil.MSErrIndex(SpeedNumLS),
13582 : VolFlowperRatedTotCap,
13583 : VolFlowperRatedTotCap);
13584 : }
13585 :
13586 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton) at high speed
13587 28 : AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
13588 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13589 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
13590 28 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumHS);
13591 56 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13592 28 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
13593 0 : if (thisDXCoil.MSErrIndex(SpeedNumHS) == 0) {
13594 0 : ShowWarningMessage(
13595 : state,
13596 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed {}.",
13597 0 : thisDXCoil.DXCoilType,
13598 0 : thisDXCoil.Name,
13599 : SpeedNumHS));
13600 0 : ShowContinueErrorTimeStamp(state, "");
13601 0 : ShowContinueError(state,
13602 0 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13603 0 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13604 0 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13605 : VolFlowperRatedTotCap));
13606 0 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13607 0 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13608 : }
13609 0 : ShowRecurringWarningErrorAtEnd(state,
13610 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range "
13611 : "at speed {} error continues...",
13612 0 : thisDXCoil.DXCoilType,
13613 0 : thisDXCoil.Name,
13614 : SpeedNumHS),
13615 : thisDXCoil.MSErrIndex(SpeedNumHS),
13616 : VolFlowperRatedTotCap,
13617 : VolFlowperRatedTotCap);
13618 : }
13619 :
13620 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
13621 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
13622 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
13623 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
13624 : // Low speed
13625 28 : if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNumLS))->numDims == 1) {
13626 1 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumLS), OutdoorDryBulb);
13627 : } else {
13628 27 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumLS), InletAirDryBulbTemp, OutdoorDryBulb);
13629 : }
13630 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
13631 28 : TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNumLS), AirMassFlowRatioLS);
13632 : // Calculate total heating capacity for off-rated conditions
13633 28 : TotCapLS = thisDXCoil.MSRatedTotCap(SpeedNumLS) * TotCapFlowModFac * TotCapTempModFac;
13634 : // High speed
13635 28 : if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNumHS))->numDims == 1) {
13636 1 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumHS), OutdoorDryBulb);
13637 : } else {
13638 27 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumHS), InletAirDryBulbTemp, OutdoorDryBulb);
13639 : }
13640 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
13641 28 : TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNumHS), AirMassFlowRatioHS);
13642 : // Calculate total heating capacity for off-rated conditions
13643 28 : TotCapHS = thisDXCoil.MSRatedTotCap(SpeedNumHS) * TotCapFlowModFac * TotCapTempModFac;
13644 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
13645 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
13646 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
13647 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
13648 : // Low Speed
13649 28 : if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(SpeedNumLS))->numDims == 1) {
13650 1 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), OutdoorDryBulb);
13651 : } else {
13652 27 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), InletAirDryBulbTemp, OutdoorDryBulb);
13653 : }
13654 28 : EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumLS), AirMassFlowRatioLS);
13655 28 : EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumLS) * EIRTempModFac * EIRFlowModFac;
13656 : // High Speed
13657 28 : if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(SpeedNumHS))->numDims == 1) {
13658 1 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), OutdoorDryBulb);
13659 : } else {
13660 27 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), InletAirDryBulbTemp, OutdoorDryBulb);
13661 : }
13662 28 : EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumHS), AirMassFlowRatioHS);
13663 28 : EIRHS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumHS) * EIRTempModFac * EIRFlowModFac;
13664 :
13665 : // Calculating adjustment factors for defrost
13666 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
13667 28 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
13668 28 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure, RoutineName)));
13669 :
13670 : // Initializing defrost adjustment factors
13671 28 : LoadDueToDefrostLS = 0.0;
13672 28 : LoadDueToDefrostHS = 0.0;
13673 28 : HeatingCapacityMultiplier = 1.0;
13674 28 : FractionalDefrostTime = 0.0;
13675 28 : InputPowerMultiplier = 1.0;
13676 28 : DefrostPowerLS = 0.0;
13677 28 : DefrostPowerHS = 0.0;
13678 :
13679 : // Check outdoor temperature to determine if defrost is active
13680 28 : if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost) {
13681 : // Calculate defrost adjustment factors depending on defrost control type
13682 6 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
13683 6 : FractionalDefrostTime = thisDXCoil.DefrostTime;
13684 6 : if (FractionalDefrostTime > 0.0) {
13685 5 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13686 2 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
13687 2 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
13688 : } else {
13689 3 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
13690 3 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
13691 3 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13692 2 : ShowWarningMessage(
13693 : state,
13694 2 : format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
13695 : "actuator must be both provided for DX heating coil {}",
13696 1 : thisDXCoil.Name));
13697 3 : ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
13698 : }
13699 : }
13700 : }
13701 : } else { // else defrost control is on-demand
13702 0 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
13703 0 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13704 0 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
13705 0 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
13706 : } else {
13707 0 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
13708 0 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
13709 0 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13710 0 : ShowWarningMessage(state,
13711 0 : format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
13712 : "actuator must be both provided for DX heating coil {}",
13713 0 : thisDXCoil.Name));
13714 0 : ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
13715 : }
13716 : }
13717 : }
13718 :
13719 6 : if (FractionalDefrostTime > 0.0) {
13720 : // Calculate defrost adjustment factors depending on defrost control strategy
13721 5 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
13722 1 : DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
13723 1 : LoadDueToDefrostLS =
13724 1 : (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(SpeedNumLS) / 1.01667);
13725 1 : DefrostPowerLS = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(SpeedNumLS) / 1.01667) * FractionalDefrostTime;
13726 1 : LoadDueToDefrostHS =
13727 1 : (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(SpeedNumHS) / 1.01667);
13728 1 : DefrostPowerHS = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(SpeedNumHS) / 1.01667) * FractionalDefrostTime;
13729 : } else { // Defrost strategy is resistive
13730 4 : thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
13731 : }
13732 : } else { // Defrost is not active because (OutDryBulbTemp .GT. DXCoil(DXCoilNum)%MaxOATDefrost)
13733 1 : thisDXCoil.DefrostPower = 0.0;
13734 : }
13735 : }
13736 :
13737 28 : TotCapLSAdj = TotCapLS * HeatingCapacityMultiplier;
13738 28 : TotCapHSAdj = TotCapHS * HeatingCapacityMultiplier;
13739 :
13740 : // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
13741 28 : PLRHeating = min(1.0, (SpeedRatio + LoadDueToDefrostHS / TotCapHSAdj));
13742 28 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNumHS), PLRHeating); // Calculate part-load factor
13743 :
13744 28 : if (PLF < 0.7) {
13745 0 : if (thisDXCoil.PLRErrIndex == 0) {
13746 0 : ShowWarningMessage(
13747 : state,
13748 0 : format("The PLF curve value at high speed for DX multispeed heating coil {} ={:.2R} for part-load ratio ={:.2R}",
13749 0 : thisDXCoil.Name,
13750 : PLF,
13751 : PLRHeating));
13752 0 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
13753 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:MultiSpeed].");
13754 0 : ShowContinueErrorTimeStamp(state, "");
13755 : }
13756 0 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
13757 0 : PLF = 0.7;
13758 : }
13759 :
13760 28 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
13761 28 : if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
13762 0 : if (thisDXCoil.ErrIndex4 == 0) {
13763 0 : ShowWarningMessage(state,
13764 0 : format("The runtime fraction at high speed for DX multispeed heating coil {} exceeded 1.0. [{:.4R}].",
13765 0 : thisDXCoil.Name,
13766 0 : thisDXCoil.HeatingCoilRuntimeFraction));
13767 0 : ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
13768 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
13769 0 : ShowContinueErrorTimeStamp(state, "");
13770 : }
13771 0 : ShowRecurringWarningErrorAtEnd(state,
13772 0 : thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
13773 0 : thisDXCoil.ErrIndex4,
13774 0 : thisDXCoil.HeatingCoilRuntimeFraction,
13775 0 : thisDXCoil.HeatingCoilRuntimeFraction);
13776 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
13777 28 : } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
13778 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
13779 : }
13780 :
13781 : // Get full load output and power
13782 28 : LSFullLoadOutAirEnth = InletAirEnthalpy + TotCapLSAdj / MSHPMassFlowRateLow;
13783 28 : HSFullLoadOutAirEnth = InletAirEnthalpy + TotCapHSAdj / MSHPMassFlowRateHigh;
13784 28 : LSElecHeatingPower = TotCapLS * EIRLS * InputPowerMultiplier;
13785 28 : HSElecHeatingPower = TotCapHS * EIRHS * InputPowerMultiplier;
13786 28 : OutletAirHumRat = InletAirHumRat;
13787 :
13788 : // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
13789 28 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
13790 :
13791 : // Power calculation
13792 28 : if (!thisDXCoil.PLRImpact) {
13793 28 : thisDXCoil.ElecHeatingPower = SpeedRatio * HSElecHeatingPower + (1.0 - SpeedRatio) * LSElecHeatingPower;
13794 : } else {
13795 0 : thisDXCoil.ElecHeatingPower =
13796 0 : thisDXCoil.HeatingCoilRuntimeFraction * HSElecHeatingPower + (1.0 - thisDXCoil.HeatingCoilRuntimeFraction) * LSElecHeatingPower;
13797 : }
13798 :
13799 28 : thisDXCoil.TotalHeatingEnergyRate = MSHPMassFlowRateHigh * (HSFullLoadOutAirEnth - InletAirEnthalpy) * SpeedRatio +
13800 28 : MSHPMassFlowRateLow * (LSFullLoadOutAirEnth - InletAirEnthalpy) * (1.0 - SpeedRatio);
13801 28 : OutletAirEnthalpy = InletAirEnthalpy + thisDXCoil.TotalHeatingEnergyRate / thisDXCoil.InletAirMassFlowRate;
13802 28 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
13803 28 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, OutdoorPressure, RoutineNameAverageLoad);
13804 28 : if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
13805 0 : OutletAirTemp = PsyTsatFnHPb(state,
13806 : FullLoadOutAirEnth,
13807 : OutdoorPressure,
13808 : RoutineName); // Autodesk:Uninit FullLoadOutAirEnth was possibly uninitialized
13809 0 : OutletAirHumRat = PsyWFnTdbH(
13810 : state, OutletAirTemp, FullLoadOutAirEnth, RoutineName); // Autodesk:Uninit FullLoadOutAirEnth was possibly uninitialized
13811 : }
13812 :
13813 : // Waste heat calculation
13814 28 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13815 1 : if (thisDXCoil.MSWasteHeat(SpeedNumLS) == 0) {
13816 0 : WasteHeatLS = thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13817 : } else {
13818 1 : WasteHeatLS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumLS), OutdoorDryBulb, InletAirDryBulbTemp) *
13819 1 : thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13820 : }
13821 1 : if (thisDXCoil.MSWasteHeat(SpeedNumHS) == 0) {
13822 0 : WasteHeatHS = thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13823 : } else {
13824 1 : WasteHeatHS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumHS), OutdoorDryBulb, InletAirDryBulbTemp) *
13825 1 : thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13826 : }
13827 1 : thisDXCoil.MSFuelWasteHeat = (SpeedRatio * WasteHeatHS + (1.0 - SpeedRatio) * WasteHeatLS) * thisDXCoil.ElecCoolingPower;
13828 1 : if (thisDXCoil.MSHPHeatRecActive) {
13829 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
13830 : }
13831 : }
13832 28 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13833 :
13834 1 : thisDXCoil.FuelUsed = thisDXCoil.ElecHeatingPower;
13835 1 : thisDXCoil.ElecHeatingPower = 0.0;
13836 : }
13837 :
13838 : // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
13839 : // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
13840 28 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
13841 21 : if (!thisDXCoil.PLRImpact) {
13842 21 : thisDXCoil.DefrostPower = DefrostPowerHS * SpeedRatio + DefrostPowerLS * (1.0 - SpeedRatio);
13843 : } else {
13844 0 : thisDXCoil.DefrostPower =
13845 0 : DefrostPowerHS * thisDXCoil.HeatingCoilRuntimeFraction + DefrostPowerLS * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
13846 : }
13847 : }
13848 28 : thisDXCoil.OutletAirTemp = OutletAirTemp;
13849 28 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
13850 28 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
13851 28 : thisDXCoil.CrankcaseHeaterPower = 0.0;
13852 :
13853 : // Stage 1
13854 63 : } else if (CycRatio > 0.0 || (CycRatio > 0.0 && SingleMode == 1)) {
13855 :
13856 : // for cycling fan, reset mass flow to full on rate
13857 63 : if (fanOp == HVAC::FanOp::Cycling) AirMassFlow /= CycRatio;
13858 63 : if (fanOp == HVAC::FanOp::Continuous) AirMassFlow = MSHPMassFlowRateHigh;
13859 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton)
13860 63 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
13861 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13862 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
13863 63 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNum);
13864 :
13865 126 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13866 63 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
13867 5 : if (thisDXCoil.ErrIndex1 == 0) {
13868 2 : ShowWarningMessage(state,
13869 2 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed 1.",
13870 1 : thisDXCoil.DXCoilType,
13871 1 : thisDXCoil.Name));
13872 2 : ShowContinueErrorTimeStamp(state, "");
13873 2 : ShowContinueError(state,
13874 2 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13875 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13876 1 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13877 : VolFlowperRatedTotCap));
13878 2 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13879 3 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13880 : }
13881 40 : ShowRecurringWarningErrorAtEnd(
13882 : state,
13883 10 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
13884 : "\" - Air volume flow rate per watt of rated total heating capacity is out of range error continues at speed 1...",
13885 5 : thisDXCoil.ErrIndex1,
13886 : VolFlowperRatedTotCap,
13887 : VolFlowperRatedTotCap);
13888 : }
13889 :
13890 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
13891 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
13892 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
13893 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
13894 63 : if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNum))->numDims == 1) {
13895 32 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNum), OutdoorDryBulb);
13896 : } else {
13897 31 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNum), InletAirDryBulbTemp, OutdoorDryBulb);
13898 : }
13899 :
13900 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
13901 : // AirMassFlowRatio = AirMassFlow/DXCoil(DXCoilNum)%MSRatedAirMassFlowRate(SpeedNumLS)
13902 : // TotCapFlowModFac = CurveValue(state, DXCoil(DXCoilNum)%MSCCapFFlow(SpeedNumLS),AirMassFlowRatio)
13903 63 : TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNum), AirMassFlowRatioLS);
13904 : // Calculate total heating capacity for off-rated conditions
13905 63 : TotCap = thisDXCoil.MSRatedTotCap(SpeedNum) * TotCapFlowModFac * TotCapTempModFac;
13906 :
13907 : // Calculating adjustment factors for defrost
13908 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
13909 63 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
13910 63 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure, RoutineName)));
13911 :
13912 : // Initializing defrost adjustment factors
13913 63 : LoadDueToDefrost = 0.0;
13914 63 : HeatingCapacityMultiplier = 1.0;
13915 63 : FractionalDefrostTime = 0.0;
13916 63 : InputPowerMultiplier = 1.0;
13917 :
13918 : // Check outdoor temperature to determine of defrost is active
13919 63 : if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost) {
13920 : // Calculate defrost adjustment factors depending on defrost control type
13921 36 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
13922 36 : FractionalDefrostTime = thisDXCoil.DefrostTime;
13923 36 : if (FractionalDefrostTime > 0.0) {
13924 36 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13925 2 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
13926 2 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
13927 : } else {
13928 34 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
13929 34 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
13930 34 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13931 4 : ShowWarningMessage(
13932 : state,
13933 4 : format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
13934 : "actuator must be both provided for DX heating coil {}",
13935 2 : thisDXCoil.Name));
13936 6 : ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
13937 : }
13938 : }
13939 : }
13940 : } else { // else defrost control is on-demand
13941 0 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
13942 0 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13943 0 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
13944 0 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
13945 : } else {
13946 0 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
13947 0 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
13948 0 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13949 0 : ShowWarningMessage(state,
13950 0 : format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
13951 : "actuator must be both provided for DX heating coil {}",
13952 0 : thisDXCoil.Name));
13953 0 : ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
13954 : }
13955 : }
13956 : }
13957 :
13958 36 : if (FractionalDefrostTime > 0.0) {
13959 : // Calculate defrost adjustment factors depending on defrost control strategy
13960 36 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
13961 32 : LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(1) / 1.01667);
13962 32 : DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
13963 32 : thisDXCoil.DefrostPower = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(1) / 1.01667) * FractionalDefrostTime;
13964 : } else { // Defrost strategy is resistive
13965 4 : thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
13966 : }
13967 : } else { // Defrost is not active because (OutDryBulbTemp .GT. DXCoil(DXCoilNum)%MaxOATDefrost)
13968 0 : thisDXCoil.DefrostPower = 0.0;
13969 : }
13970 : }
13971 :
13972 : // Modify total heating capacity based on defrost heating capacity multiplier
13973 63 : TotCapAdj = TotCap * HeatingCapacityMultiplier;
13974 :
13975 : // Calculate full load outlet conditions
13976 63 : FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
13977 63 : FullLoadOutAirHumRat = InletAirHumRat;
13978 63 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
13979 63 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
13980 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13981 : // FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
13982 63 : if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
13983 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure, RoutineName);
13984 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13985 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
13986 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
13987 : }
13988 :
13989 : // Set outlet conditions from the full load calculation
13990 63 : OutletAirEnthalpy = FullLoadOutAirEnth;
13991 63 : OutletAirHumRat = FullLoadOutAirHumRat;
13992 63 : OutletAirTemp = FullLoadOutAirTemp;
13993 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
13994 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
13995 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
13996 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
13997 63 : if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(1))->numDims == 1) {
13998 32 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(1), OutdoorDryBulb);
13999 : } else {
14000 31 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(1), InletAirDryBulbTemp, OutdoorDryBulb);
14001 : }
14002 63 : EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(1), AirMassFlowRatioLS);
14003 63 : EIR = 1.0 / thisDXCoil.MSRatedCOP(1) * EIRTempModFac * EIRFlowModFac;
14004 : // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
14005 63 : PLRHeating = min(1.0, (CycRatio + LoadDueToDefrost / TotCapAdj));
14006 63 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(1), PLRHeating); // Calculate part-load factor
14007 63 : if (fanOp == HVAC::FanOp::Cycling && CycRatio == 1.0 && PLF != 1.0) {
14008 0 : if (thisDXCoil.PLFErrIndex == 0) {
14009 0 : ShowWarningMessage(state,
14010 0 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio = 1", thisDXCoil.Name, PLF));
14011 0 : ShowContinueError(state, "PLF curve value must be = 1.0 and has been reset to 1.0. Simulation is continuing.");
14012 0 : ShowContinueErrorTimeStamp(state, "");
14013 : }
14014 0 : ShowRecurringWarningErrorAtEnd(
14015 0 : state, thisDXCoil.Name + "\": DX heating coil PLF curve value <> 1.0 warning continues...", thisDXCoil.PLFErrIndex, PLF, PLF);
14016 0 : PLF = 1.0;
14017 : }
14018 :
14019 63 : if (PLF < 0.7) {
14020 0 : if (thisDXCoil.PLRErrIndex == 0) {
14021 0 : ShowWarningMessage(
14022 : state,
14023 0 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
14024 0 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
14025 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
14026 0 : ShowContinueErrorTimeStamp(state, "");
14027 : }
14028 0 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
14029 0 : PLF = 0.7;
14030 : }
14031 :
14032 63 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
14033 63 : if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
14034 0 : if (thisDXCoil.ErrIndex4 == 0) {
14035 0 : ShowWarningMessage(state,
14036 0 : format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
14037 0 : thisDXCoil.Name,
14038 0 : thisDXCoil.HeatingCoilRuntimeFraction));
14039 0 : ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
14040 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
14041 0 : ShowContinueErrorTimeStamp(state, "");
14042 : }
14043 0 : ShowRecurringWarningErrorAtEnd(state,
14044 0 : thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
14045 0 : thisDXCoil.ErrIndex4,
14046 0 : thisDXCoil.HeatingCoilRuntimeFraction,
14047 0 : thisDXCoil.HeatingCoilRuntimeFraction);
14048 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
14049 63 : } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
14050 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
14051 : }
14052 : // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
14053 63 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
14054 63 : thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
14055 :
14056 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
14057 : // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
14058 :
14059 63 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
14060 5 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
14061 : } else {
14062 58 : thisDXCoil.CrankcaseHeaterPower =
14063 58 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
14064 58 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
14065 : }
14066 :
14067 63 : thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (FullLoadOutAirEnth - InletAirEnthalpy) * CycRatio;
14068 63 : if (fanOp == HVAC::FanOp::Continuous) {
14069 31 : OutletAirEnthalpy = InletAirEnthalpy + thisDXCoil.TotalHeatingEnergyRate / thisDXCoil.InletAirMassFlowRate;
14070 31 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
14071 : }
14072 63 : if (thisDXCoil.MSHPHeatRecActive || thisDXCoil.FuelType != Constant::eFuel::Electricity) {
14073 32 : if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
14074 0 : thisDXCoil.MSFuelWasteHeat = thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecHeatingPower;
14075 : } else {
14076 32 : thisDXCoil.MSFuelWasteHeat = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNum), OutdoorDryBulb, InletAirDryBulbTemp) *
14077 32 : thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecHeatingPower;
14078 : }
14079 32 : if (thisDXCoil.MSHPHeatRecActive) {
14080 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
14081 : }
14082 : }
14083 63 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
14084 :
14085 32 : thisDXCoil.FuelUsed = thisDXCoil.ElecHeatingPower;
14086 32 : thisDXCoil.ElecHeatingPower = 0.0;
14087 : }
14088 : // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
14089 : // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
14090 63 : thisDXCoil.DefrostPower *= thisDXCoil.HeatingCoilRuntimeFraction;
14091 :
14092 63 : thisDXCoil.OutletAirTemp = OutletAirTemp;
14093 63 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
14094 63 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
14095 : }
14096 :
14097 : } else {
14098 :
14099 : // DX coil is off; just pass through conditions
14100 120 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
14101 120 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
14102 120 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
14103 :
14104 120 : thisDXCoil.ElecHeatingPower = 0.0;
14105 120 : thisDXCoil.FuelUsed = 0.0;
14106 120 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
14107 120 : thisDXCoil.DefrostPower = 0.0;
14108 :
14109 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
14110 : // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
14111 120 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
14112 10 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
14113 : } else {
14114 110 : thisDXCoil.CrankcaseHeaterPower =
14115 110 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
14116 : }
14117 :
14118 : } // end of on/off if - else
14119 :
14120 211 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
14121 211 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
14122 211 : thisDXCoil.PartLoadRatio = PLRHeating;
14123 211 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
14124 211 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
14125 211 : thisDXCoil.MSSpeedNumLS = SpeedNumLS;
14126 211 : thisDXCoil.MSSpeedNumHS = SpeedNumHS;
14127 211 : thisDXCoil.MSSpeedRatio = SpeedRatio;
14128 211 : thisDXCoil.MSCycRatio = CycRatio;
14129 :
14130 : // set outlet node conditions
14131 211 : int airOutletNode = thisDXCoil.AirOutNode;
14132 211 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
14133 211 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
14134 :
14135 : // calc secondary coil if specified
14136 211 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
14137 0 : CalcSecondaryDXCoils(state, DXCoilNum);
14138 : }
14139 211 : }
14140 :
14141 539062 : void UpdateDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current fan coil unit being simulated
14142 : {
14143 :
14144 : // SUBROUTINE INFORMATION:
14145 : // AUTHOR Fred Buhl
14146 : // DATE WRITTEN May 2000
14147 :
14148 : // PURPOSE OF THIS SUBROUTINE:
14149 : // This subroutine is for passing results to the outlet air node.
14150 :
14151 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14152 : int AirOutletNode; // air outlet node number
14153 : int AirInletNode; // air inlet node number
14154 :
14155 539062 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
14156 :
14157 539062 : AirOutletNode = thisDXCoil.AirOutNode;
14158 539062 : AirInletNode = thisDXCoil.AirInNode;
14159 : // changed outputs
14160 539062 : state.dataLoopNodes->Node(AirOutletNode).Enthalpy = thisDXCoil.OutletAirEnthalpy;
14161 539062 : state.dataLoopNodes->Node(AirOutletNode).Temp = thisDXCoil.OutletAirTemp;
14162 539062 : state.dataLoopNodes->Node(AirOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
14163 539062 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRate = thisDXCoil.InletAirMassFlowRate;
14164 : // pass through outputs
14165 539062 : state.dataLoopNodes->Node(AirOutletNode).Quality = state.dataLoopNodes->Node(AirInletNode).Quality;
14166 539062 : state.dataLoopNodes->Node(AirOutletNode).Press = state.dataLoopNodes->Node(AirInletNode).Press;
14167 539062 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMin = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMin;
14168 539062 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMax = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax;
14169 539062 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMinAvail;
14170 539062 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMaxAvail;
14171 :
14172 539062 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
14173 0 : state.dataLoopNodes->Node(AirOutletNode).CO2 = state.dataLoopNodes->Node(AirInletNode).CO2;
14174 : }
14175 539062 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
14176 0 : state.dataLoopNodes->Node(AirOutletNode).GenContam = state.dataLoopNodes->Node(AirInletNode).GenContam;
14177 : }
14178 539062 : }
14179 :
14180 539064 : void ReportDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current fan coil unit being simulated
14181 : {
14182 :
14183 : // SUBROUTINE INFORMATION:
14184 : // AUTHOR Fred Buhl
14185 : // DATE WRITTEN May 2000
14186 : // MODIFIED Richard Raustad/Don Shirey Oct 2001, Feb 2004
14187 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
14188 : // Always update evap value to support new coil type COIL:DX:MultiMode:CoolingEmpirical:
14189 : // Lixing Gu. Jan. 5, 2007, pass information to the AirflowNetwork model
14190 :
14191 : // PURPOSE OF THIS SUBROUTINE:
14192 : // Fills some of the report variables for the DX coils
14193 :
14194 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14195 :
14196 539064 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
14197 :
14198 539064 : if (thisDXCoil.reportCoilFinalSizes) {
14199 192897 : if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->DoingSizing) {
14200 104 : Real64 ratedSensCap(0.0);
14201 104 : ratedSensCap = thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1);
14202 104 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
14203 104 : state, thisDXCoil.Name, thisDXCoil.DXCoilType, thisDXCoil.RatedTotCap(1), ratedSensCap, thisDXCoil.RatedAirVolFlowRate(1), -999.0);
14204 104 : thisDXCoil.reportCoilFinalSizes = false;
14205 : }
14206 : }
14207 :
14208 539064 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
14209 :
14210 539064 : switch (thisDXCoil.DXCoilType_Num) {
14211 201111 : case HVAC::CoilDX_HeatingEmpirical:
14212 : case HVAC::CoilVRF_Heating:
14213 : case HVAC::CoilVRF_FluidTCtrl_Heating: {
14214 201111 : thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
14215 201111 : thisDXCoil.ElecHeatingConsumption = thisDXCoil.ElecHeatingPower * ReportingConstant;
14216 201111 : thisDXCoil.DefrostConsumption = thisDXCoil.DefrostPower * ReportingConstant;
14217 201111 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14218 201111 : state.dataHVACGlobal->DXElecHeatingPower = thisDXCoil.ElecHeatingPower + thisDXCoil.CrankcaseHeaterPower;
14219 201111 : state.dataHVACGlobal->DefrostElecPower = thisDXCoil.DefrostPower;
14220 201111 : } break;
14221 199 : case HVAC::CoilDX_MultiSpeedHeating: {
14222 199 : thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
14223 199 : if (thisDXCoil.FuelType == Constant::eFuel::Electricity) {
14224 116 : thisDXCoil.ElecHeatingConsumption = thisDXCoil.ElecHeatingPower * ReportingConstant;
14225 : } else {
14226 83 : thisDXCoil.FuelConsumed = thisDXCoil.FuelUsed * ReportingConstant;
14227 : }
14228 199 : thisDXCoil.DefrostConsumption = thisDXCoil.DefrostPower * ReportingConstant;
14229 199 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14230 199 : state.dataHVACGlobal->DXElecHeatingPower = thisDXCoil.ElecHeatingPower + thisDXCoil.CrankcaseHeaterPower;
14231 199 : state.dataHVACGlobal->DefrostElecPower = thisDXCoil.DefrostPower;
14232 199 : } break;
14233 251 : case HVAC::CoilDX_MultiSpeedCooling: {
14234 251 : thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
14235 251 : thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
14236 251 : thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
14237 251 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14238 251 : state.dataHVACGlobal->DXElecCoolingPower = thisDXCoil.ElecCoolingPower;
14239 251 : thisDXCoil.EvapCondPumpElecConsumption = thisDXCoil.EvapCondPumpElecPower * ReportingConstant;
14240 251 : thisDXCoil.EvapWaterConsump = thisDXCoil.EvapWaterConsumpRate * ReportingConstant;
14241 251 : if (thisDXCoil.FuelType == Constant::eFuel::Electricity) {
14242 179 : thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
14243 : } else {
14244 72 : thisDXCoil.FuelConsumed = thisDXCoil.FuelUsed * ReportingConstant;
14245 : }
14246 251 : if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
14247 0 : thisDXCoil.BasinHeaterConsumption = thisDXCoil.BasinHeaterPower * ReportingConstant;
14248 : }
14249 251 : } break;
14250 161 : case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
14251 : case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
14252 : // water heating energy for HP water heater DX Coil condenser
14253 161 : thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
14254 : // water heating power for HP water heater
14255 161 : thisDXCoil.ElecWaterHeatingConsumption = thisDXCoil.ElecWaterHeatingPower * ReportingConstant;
14256 : // other usual DX cooling coil outputs
14257 161 : thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
14258 161 : thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
14259 161 : thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
14260 161 : thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
14261 161 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14262 : // DXElecCoolingPower global is only used for air-to-air cooling and heating coils
14263 161 : state.dataHVACGlobal->DXElecCoolingPower = 0.0;
14264 161 : } break;
14265 337342 : default: {
14266 337342 : thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
14267 337342 : thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
14268 337342 : thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
14269 337342 : thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
14270 337342 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14271 337342 : state.dataHVACGlobal->DXElecCoolingPower = thisDXCoil.ElecCoolingPower;
14272 337342 : thisDXCoil.EvapCondPumpElecConsumption = thisDXCoil.EvapCondPumpElecPower * ReportingConstant;
14273 337342 : thisDXCoil.EvapWaterConsump = thisDXCoil.EvapWaterConsumpRate * ReportingConstant;
14274 337342 : if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
14275 33575 : thisDXCoil.BasinHeaterConsumption = thisDXCoil.BasinHeaterPower * ReportingConstant;
14276 : }
14277 337342 : } break;
14278 : }
14279 :
14280 539064 : if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
14281 : // calculate and report condensation rates (how much water extracted from the air stream)
14282 : // water flow of water in m3/s for water system interactions
14283 : // put here to catch all types of DX coils
14284 2 : Real64 Tavg = (thisDXCoil.InletAirTemp + thisDXCoil.OutletAirTemp) / 2.0;
14285 : // CR9155 Remove specific humidity calculations
14286 : // mdot * del HumRat / rho water
14287 2 : thisDXCoil.CondensateVdot =
14288 2 : max(0.0, (thisDXCoil.InletAirMassFlowRate * (thisDXCoil.InletAirHumRat - thisDXCoil.OutletAirHumRat) / Psychrometrics::RhoH2O(Tavg)));
14289 2 : thisDXCoil.CondensateVol = thisDXCoil.CondensateVdot * ReportingConstant;
14290 :
14291 2 : state.dataWaterData->WaterStorage(thisDXCoil.CondensateTankID).VdotAvailSupply(thisDXCoil.CondensateTankSupplyARRID) =
14292 2 : thisDXCoil.CondensateVdot;
14293 2 : state.dataWaterData->WaterStorage(thisDXCoil.CondensateTankID).TwaterSupply(thisDXCoil.CondensateTankSupplyARRID) = thisDXCoil.OutletAirTemp;
14294 : }
14295 :
14296 539064 : state.dataAirLoop->LoopDXCoilRTF = max(thisDXCoil.CoolingCoilRuntimeFraction, thisDXCoil.HeatingCoilRuntimeFraction);
14297 539064 : if (thisDXCoil.AirLoopNum > 0) {
14298 223282 : state.dataAirLoop->AirLoopAFNInfo(thisDXCoil.AirLoopNum).AFNLoopDXCoilRTF =
14299 223282 : max(thisDXCoil.CoolingCoilRuntimeFraction, thisDXCoil.HeatingCoilRuntimeFraction);
14300 : }
14301 539064 : }
14302 :
14303 6 : void CalcTwoSpeedDXCoilStandardRating(EnergyPlusData &state, int const DXCoilNum)
14304 : {
14305 : // SUBROUTINE INFORMATION:
14306 : // AUTHOR B. Griffith, (Derived from CalcDXCoilStandardRating by Bereket Nigusse & Chandan Sharma)
14307 : // DATE WRITTEN July 2012
14308 :
14309 : // PURPOSE OF THIS SUBROUTINE:
14310 : // Calculate the following
14311 : // (1) Standard Rated (net) Cooling Capacity
14312 : // (2) Energy Efficiency Ratio (EER),
14313 : // (3) Integrated Energy Efficiency Ratio (IEER)
14314 :
14315 : // REFERENCES:
14316 : // ANSI/AHRI Standard 340/360-2007, Performance Rating of Commercial and Industrial Unitary Air-Conditioning and
14317 : // Heat Pump Equipment, Air-Conditioning, Heating, and Refrigeration Institute, Arlington VA.
14318 :
14319 : // Using/Aliasing
14320 : using Curve::CurveValue;
14321 : using namespace OutputReportPredefined;
14322 :
14323 : // SUBROUTINE PARAMETER DEFINITIONS:
14324 : // AHRI Standard 340/360-2007 Performance Rating of Commercial and Industrial Unitary Air-Conditioning and Heat Pump Equipment
14325 6 : Real64 constexpr CoolingCoilInletAirWetBulbTempRated(19.4); // 19.44C (67F)
14326 6 : Real64 constexpr CoolingCoilInletAirDryBulbTempRated(26.7);
14327 6 : Real64 constexpr OutdoorUnitInletAirDryBulbTempRated(35.0); // 35.00C (95F)
14328 6 : static Array1D<Real64> const OutdoorUnitInletAirDryBulbTempPLTestPoint(3, {27.5, 20.0, 18.3});
14329 6 : static Array1D<Real64> const NetCapacityFactorPLTestPoint(3, {0.75, 0.50, 0.25});
14330 6 : Real64 constexpr ConvFromSIToIP(3.412141633); // Conversion from SI to IP [3.412 Btu/hr-W]
14331 :
14332 6 : Real64 constexpr AirMassFlowRatioRated(1.0); // AHRI test is at the design flow rate
14333 : // and hence AirMassFlowRatio is 1.0
14334 :
14335 6 : Real64 constexpr DefaultFanPowerPerEvapAirFlowRate(773.3); // 365 W/1000 scfm or 773.3 W/(m3/s). The AHRI standard
14336 6 : Real64 constexpr DefaultFanPowerPerEvapAirFlowRateSEER2(934.4); // 441 W/1000 scfm or 934.4 W/(m3/s). The AHRI standard
14337 : // specifies a nominal/default fan electric power consumption per rated air
14338 : // volume flow rate to account for indoor fan electric power consumption
14339 : // when the standard tests are conducted on units that do not have an
14340 : // indoor air circulating fan. Used if user doesn't enter a specific value.
14341 :
14342 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14343 : static constexpr std::string_view RoutineName("CalcTwoSpeedDXCoilStandardRating");
14344 :
14345 6 : auto &NetCoolingCapRated = state.dataDXCoils->NetCoolingCapRated;
14346 6 : auto &EER = state.dataDXCoils->EER;
14347 6 : auto &IEER = state.dataDXCoils->IEER;
14348 6 : auto &TotCapTempModFac = state.dataDXCoils->TotCapTempModFac;
14349 6 : auto &TotCapFlowModFac = state.dataDXCoils->TotCapFlowModFac;
14350 6 : auto &EIRTempModFac = state.dataDXCoils->EIRTempModFac;
14351 6 : auto &EIRFlowModFac = state.dataDXCoils->EIRFlowModFac;
14352 6 : auto &TempDryBulb_Leaving_Apoint = state.dataDXCoils->TempDryBulb_Leaving_Apoint;
14353 :
14354 6 : constexpr Real64 AccuracyTolerance(0.2); // tolerance in AHRI 340/360 Table 6 note 1
14355 6 : constexpr int MaximumIterations(1000);
14356 : Real64 EIR;
14357 : Real64 TotalElecPowerRated;
14358 6 : Array1D<Real64> EER_TestPoint_SI(4); // 1 = A, 2 = B, 3= C, 4= D
14359 6 : Array1D<Real64> EER_TestPoint_IP(4); // 1 = A, 2 = B, 3= C, 4= D
14360 6 : Array1D<Real64> NetCapacity_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
14361 6 : Array1D<Real64> NetPower_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
14362 6 : Array1D<Real64> SupAirMdot_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
14363 :
14364 : Real64 HighSpeedNetCoolingCap;
14365 : Real64 LowSpeedNetCoolingCap;
14366 :
14367 : Real64 PartLoadAirMassFlowRate;
14368 : Real64 AirMassFlowRatio;
14369 : int SolverFlag;
14370 : Real64 EIR_HighSpeed;
14371 : Real64 EIR_LowSpeed;
14372 : int FanInletNode;
14373 : int FanOutletNode;
14374 : int Iter;
14375 : Real64 ExternalStatic;
14376 : Real64 FanStaticPressureRise;
14377 : Real64 FanHeatCorrection;
14378 : Real64 FanPowerCorrection;
14379 6 : Real64 FanPowerPerEvapAirFlowRate = 0.0;
14380 : Real64 FanPowerPerEvapAirFlowRateSEER2;
14381 : Real64 SpeedRatio;
14382 : Real64 CycRatio;
14383 : Real64 TargetNetCapacity;
14384 : Real64 SupplyAirHumRat;
14385 : Real64 SupplyAirRho;
14386 : Real64 SupplyAirVolFlowRate;
14387 : Real64 HighSpeedTotCoolingCap;
14388 : Real64 LowSpeedTotCoolingCap;
14389 : Real64 TotCoolingCap;
14390 : Real64 NetCoolingCap;
14391 : Real64 PLF;
14392 : Real64 RunTimeFraction;
14393 : Real64 LowerBoundMassFlowRate;
14394 : int PartLoadTestPoint;
14395 : int countStaticInputs;
14396 : int index;
14397 :
14398 : // Formats
14399 : static constexpr std::string_view Header(
14400 : "! <VAV DX Cooling Coil Standard Rating Information>, DX Coil Type, DX Coil Name, Fan Type, Fan Name, Standard Net Cooling Capacity "
14401 : "{{W}}, Standard Net Cooling Capacity {{Btu/h}}, IEER {{Btu/W-h}}, COP 100% Capacity {{W/W}}, COP 75% Capacity {{W/W}}, COP 50% Capacity "
14402 : "{{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% "
14403 : "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% "
14404 : "{{kg/s}}\n");
14405 :
14406 : static constexpr std::string_view Format_891{
14407 : " VAV DX Cooling Coil Standard Rating Information, "
14408 : "{},{},{},{},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.4R},{:.4R},{:.4R},{:.4R},\n"};
14409 :
14410 6 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
14411 :
14412 : // Get fan index and name if not already available
14413 6 : if (thisDXCoil.SupplyFanIndex == 0)
14414 2 : GetFanIndexForTwoSpeedCoil(state, DXCoilNum, thisDXCoil.SupplyFanIndex, thisDXCoil.SupplyFanName, thisDXCoil.supplyFanType);
14415 6 : if (thisDXCoil.SupplyFanIndex == 0) { // didn't find VAV fan, do not rate this coil
14416 0 : thisDXCoil.RateWithInternalStaticAndFanObject = false;
14417 0 : ShowWarningError(state,
14418 0 : format("CalcTwoSpeedDXCoilStandardRating: Did not find an appropriate fan associated with DX coil named = \"{}\". Standard "
14419 : "Ratings will not be calculated.",
14420 0 : thisDXCoil.Name));
14421 0 : return;
14422 : }
14423 6 : bool saveTurnFansOn = state.dataHVACGlobal->TurnFansOn;
14424 6 : bool saveTurnFansOff = state.dataHVACGlobal->TurnFansOff;
14425 6 : state.dataHVACGlobal->TurnFansOn = true; // enable fans, will override fan availability schedule if needed
14426 6 : state.dataHVACGlobal->TurnFansOff = false;
14427 :
14428 : // Calculate the Indoor fan electric power consumption. The electric power consumption is estimated
14429 : // using either user supplied or AHRI default value for fan power per air volume flow rate
14430 6 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14431 :
14432 3 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatioRated);
14433 3 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
14434 15 : for (Iter = 1; Iter <= 4; ++Iter) { // iterative solution in the event that net capacity is near a threshold for external static
14435 : // Obtain external static pressure from Table 5 in ANSI/AHRI Std. 340/360-2007
14436 12 : if (NetCoolingCapRated <= 21000.0) {
14437 12 : ExternalStatic = 50.0;
14438 0 : } else if (21000.0 < NetCoolingCapRated && NetCoolingCapRated <= 30800.0) {
14439 0 : ExternalStatic = 60.0;
14440 0 : } else if (30800.0 < NetCoolingCapRated && NetCoolingCapRated <= 39300.0) {
14441 0 : ExternalStatic = 70.0;
14442 0 : } else if (39300.0 < NetCoolingCapRated && NetCoolingCapRated <= 61500.0) {
14443 0 : ExternalStatic = 90.0;
14444 0 : } else if (61500.0 < NetCoolingCapRated && NetCoolingCapRated <= 82100.0) {
14445 0 : ExternalStatic = 100.0;
14446 0 : } else if (82100.0 < NetCoolingCapRated && NetCoolingCapRated <= 103000.0) {
14447 0 : ExternalStatic = 110.0;
14448 0 : } else if (103000.0 < NetCoolingCapRated && NetCoolingCapRated <= 117000.0) {
14449 0 : ExternalStatic = 140.0;
14450 0 : } else if (117000.0 < NetCoolingCapRated && NetCoolingCapRated <= 147000.0) {
14451 0 : ExternalStatic = 160.0;
14452 0 : } else if (147000.0 < NetCoolingCapRated) {
14453 0 : ExternalStatic = 190.0;
14454 : }
14455 12 : FanStaticPressureRise = ExternalStatic + thisDXCoil.InternalStaticPressureDrop;
14456 12 : FanInletNode = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->inletNodeNum;
14457 12 : FanOutletNode = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->outletNodeNum;
14458 :
14459 : // set node state variables in preparation for fan model.
14460 12 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
14461 12 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
14462 12 : state.dataLoopNodes->Node(FanInletNode).Temp = CoolingCoilInletAirDryBulbTempRated;
14463 12 : state.dataLoopNodes->Node(FanInletNode).HumRat = PsyWFnTdbTwbPb(
14464 12 : state, CoolingCoilInletAirDryBulbTempRated, CoolingCoilInletAirWetBulbTempRated, state.dataEnvrn->OutBaroPress, RoutineName);
14465 12 : state.dataLoopNodes->Node(FanInletNode).Enthalpy =
14466 12 : PsyHFnTdbW(CoolingCoilInletAirDryBulbTempRated, state.dataLoopNodes->Node(FanInletNode).HumRat);
14467 12 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
14468 12 : FanPowerCorrection = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->totalPower;
14469 :
14470 12 : FanHeatCorrection = state.dataLoopNodes->Node(FanInletNode).MassFlowRate *
14471 12 : (state.dataLoopNodes->Node(FanOutletNode).Enthalpy - state.dataLoopNodes->Node(FanInletNode).Enthalpy);
14472 :
14473 12 : NetCoolingCapRated = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14474 : }
14475 :
14476 : } else {
14477 3 : FanPowerPerEvapAirFlowRate = DefaultFanPowerPerEvapAirFlowRate;
14478 3 : FanPowerPerEvapAirFlowRateSEER2 = DefaultFanPowerPerEvapAirFlowRateSEER2;
14479 3 : FanPowerCorrection = DefaultFanPowerPerEvapAirFlowRate * thisDXCoil.RatedAirVolFlowRate(1);
14480 3 : FanHeatCorrection = DefaultFanPowerPerEvapAirFlowRate * thisDXCoil.RatedAirVolFlowRate(1);
14481 3 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatioRated);
14482 3 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
14483 3 : NetCoolingCapRated = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14484 : }
14485 :
14486 6 : SupAirMdot_TestPoint(1) = thisDXCoil.RatedAirMassFlowRate(1);
14487 :
14488 : // Calculate Energy Efficiency Ratio (EER) at (19.44C WB and 35.0C DB ), ANSI/AHRI Std. 340/360
14489 6 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
14490 6 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatioRated);
14491 6 : if (thisDXCoil.RatedCOP(1) > 0.0) {
14492 : // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
14493 6 : EIR = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP(1);
14494 : } else {
14495 0 : EIR = 0.0;
14496 : }
14497 6 : TotalElecPowerRated = EIR * (thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac) + FanPowerCorrection;
14498 :
14499 6 : if (TotalElecPowerRated > 0.0) {
14500 6 : EER = NetCoolingCapRated / TotalElecPowerRated;
14501 : } else {
14502 0 : EER = 0.0;
14503 : }
14504 :
14505 : // IEER - A point 100 % net capacity
14506 6 : EER_TestPoint_SI(1) = EER;
14507 6 : EER_TestPoint_IP(1) = EER * ConvFromSIToIP;
14508 :
14509 : // find coil leaving drybulb at point A, with full rated air flow rate.
14510 : // init coil
14511 6 : thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
14512 6 : thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(1);
14513 6 : thisDXCoil.InletAirTemp = 26.7;
14514 6 : thisDXCoil.InletAirHumRat = PsyWFnTdbTwbPb(state, 26.7, 19.4, state.dataEnvrn->OutBaroPress, RoutineName);
14515 6 : thisDXCoil.InletAirEnthalpy = PsyHFnTdbW(26.7, thisDXCoil.InletAirHumRat);
14516 :
14517 6 : Real64 const heldOutDryBulb = state.dataEnvrn->OutDryBulbTemp;
14518 6 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
14519 0 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = OutdoorUnitInletAirDryBulbTempRated;
14520 : } else {
14521 6 : state.dataEnvrn->OutDryBulbTemp = OutdoorUnitInletAirDryBulbTempRated;
14522 : }
14523 6 : SpeedRatio = 1.0;
14524 6 : CycRatio = 1.0;
14525 6 : CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio, true);
14526 6 : TempDryBulb_Leaving_Apoint = state.dataDXCoils->DXCoilOutletTemp(DXCoilNum); // store result
14527 :
14528 : // IEER - part load test points ***************************************************
14529 24 : for (PartLoadTestPoint = 1; PartLoadTestPoint <= 3; ++PartLoadTestPoint) {
14530 : // determine minimum unloading capacity fraction at point B conditions.
14531 18 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
14532 0 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
14533 : } else {
14534 18 : state.dataEnvrn->OutDryBulbTemp = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
14535 : }
14536 :
14537 18 : TargetNetCapacity = NetCapacityFactorPLTestPoint(PartLoadTestPoint) * NetCoolingCapRated;
14538 :
14539 : // set up parameters for the solver here
14540 18 : Real64 const par3 = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
14541 18 : Real64 par7 = FanPowerPerEvapAirFlowRate;
14542 18 : int fanInNode = 0;
14543 18 : int fanOutNode = 0;
14544 18 : Real64 externalStatic = 0.0;
14545 18 : int fanIndex = 0;
14546 18 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14547 9 : par7 = 0.0;
14548 9 : fanInNode = FanInletNode;
14549 9 : fanOutNode = FanOutletNode;
14550 9 : externalStatic = ExternalStatic;
14551 9 : fanIndex = thisDXCoil.SupplyFanIndex;
14552 : }
14553 :
14554 18 : LowerBoundMassFlowRate = 0.01 * thisDXCoil.RatedAirMassFlowRate(1);
14555 :
14556 : // OK, so there are two variables here which are const at compile time. The question is whether compile time data needs to be
14557 : // explicitly captured in the lambda capture block.
14558 : // For GCC it currently doesn't mind whether they are captured or not, no warnings.
14559 : // On Clang, if you list them, there is a compiler warning.
14560 : // 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.
14561 : // 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
14562 : // really simple, I'm just going to use two local variables and capture them instead of the original data.
14563 : // 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.
14564 18 : Real64 dbRated = CoolingCoilInletAirDryBulbTempRated;
14565 18 : Real64 wbRated = CoolingCoilInletAirWetBulbTempRated;
14566 : auto f = // (AUTO_OK_LAMBDA)
14567 3318 : [&state, DXCoilNum, TempDryBulb_Leaving_Apoint, TargetNetCapacity, par3, par7, fanInNode, fanOutNode, externalStatic, dbRated, wbRated](
14568 : Real64 SupplyAirMassFlowRate) {
14569 : static constexpr std::string_view RoutineName("CalcTwoSpeedDXCoilIEERResidual");
14570 3300 : auto &coil = state.dataDXCoils->DXCoil(DXCoilNum);
14571 3300 : Real64 AirMassFlowRatio = 0.0;
14572 3300 : if (coil.RatedAirMassFlowRate(1) > 0.0) {
14573 3300 : AirMassFlowRatio = SupplyAirMassFlowRate / coil.RatedAirMassFlowRate(1);
14574 : }
14575 3300 : Real64 SupplyAirHumRat = PsyWFnTdbTwbPb(state, dbRated, wbRated, state.dataEnvrn->OutBaroPress, RoutineName);
14576 3300 : Real64 SupplyAirRho = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, dbRated, SupplyAirHumRat, RoutineName);
14577 3300 : Real64 SupplyAirVolFlowRate = SupplyAirMassFlowRate / SupplyAirRho;
14578 :
14579 : Real64 FanHeatCorrection;
14580 3300 : if (coil.RateWithInternalStaticAndFanObject) {
14581 : // modify external static per AHRI 340/360, Table 6, note 1.
14582 1539 : Real64 FanStaticPressureRise = coil.InternalStaticPressureDrop + (externalStatic * pow_2(AirMassFlowRatio));
14583 1539 : auto &inletNode = state.dataLoopNodes->Node(fanInNode);
14584 1539 : auto &outletNode = state.dataLoopNodes->Node(fanOutNode);
14585 1539 : inletNode.MassFlowRate = SupplyAirMassFlowRate;
14586 1539 : outletNode.MassFlowRate = SupplyAirMassFlowRate;
14587 1539 : inletNode.Temp = dbRated;
14588 1539 : inletNode.HumRat = PsyWFnTdbTwbPb(state, dbRated, wbRated, state.dataEnvrn->OutBaroPress, RoutineName);
14589 1539 : inletNode.Enthalpy = PsyHFnTdbW(dbRated, inletNode.HumRat);
14590 1539 : state.dataFans->fans(coil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
14591 1539 : FanHeatCorrection = SupplyAirMassFlowRate * (outletNode.Enthalpy - inletNode.Enthalpy);
14592 : } else {
14593 1761 : FanHeatCorrection = par7 * SupplyAirVolFlowRate;
14594 : }
14595 :
14596 3300 : Real64 TotCapFlowModFac = Curve::CurveValue(state, coil.CCapFFlow(1), AirMassFlowRatio);
14597 3300 : Real64 TotCapTempModFac = Curve::CurveValue(state, coil.CCapFTemp(1), wbRated, par3);
14598 3300 : Real64 HighSpeedNetCoolingCap = coil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14599 :
14600 : // TotCapFlowModFac = CurveManager::CurveValue(state, coil.CCapFFlow(1), AirMassFlowRatio);
14601 3300 : TotCapTempModFac = Curve::CurveValue(state, coil.CCapFTemp2, wbRated, par3);
14602 3300 : Real64 LowSpeedNetCoolingCap = coil.RatedTotCap2 * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14603 :
14604 : Real64 SpeedRatio;
14605 : Real64 CycRatio;
14606 3300 : if (LowSpeedNetCoolingCap <= TargetNetCapacity) {
14607 1899 : CycRatio = 1.0;
14608 1899 : SpeedRatio = (TargetNetCapacity - LowSpeedNetCoolingCap) / (HighSpeedNetCoolingCap - LowSpeedNetCoolingCap);
14609 : } else { // minimum unloading limit exceeded for no cycling
14610 1401 : SpeedRatio = 0.0;
14611 1401 : CycRatio = TargetNetCapacity / LowSpeedNetCoolingCap;
14612 : }
14613 :
14614 3300 : coil.InletAirMassFlowRate = SupplyAirMassFlowRate;
14615 3300 : CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio, true);
14616 3300 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(DXCoilNum);
14617 3300 : return TempDryBulb_Leaving_Apoint - OutletAirTemp;
14618 18 : };
14619 18 : General::SolveRoot(state,
14620 : AccuracyTolerance,
14621 : MaximumIterations,
14622 : SolverFlag,
14623 : PartLoadAirMassFlowRate,
14624 : f,
14625 : LowerBoundMassFlowRate,
14626 18 : thisDXCoil.RatedAirMassFlowRate(1));
14627 :
14628 18 : if (SolverFlag == -1) {
14629 :
14630 0 : ShowWarningError(state, "CalcTwoSpeedDXCoilStandardRating: air flow rate solver failed. Iteration limit exceeded ");
14631 :
14632 0 : SupAirMdot_TestPoint(1 + PartLoadTestPoint) = -999.0;
14633 0 : EER_TestPoint_SI(1 + PartLoadTestPoint) = -999.0;
14634 0 : EER_TestPoint_IP(1 + PartLoadTestPoint) = -999.0;
14635 0 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = -999.0;
14636 0 : NetPower_TestPoint(1 + PartLoadTestPoint) = -999.0;
14637 :
14638 18 : } else if (SolverFlag == -2) {
14639 0 : ShowWarningError(state, "CalcTwoSpeedDXCoilStandardRating: air flow rate solver failed. root not bounded ");
14640 :
14641 0 : SupAirMdot_TestPoint(1 + PartLoadTestPoint) = -999.0;
14642 0 : EER_TestPoint_SI(1 + PartLoadTestPoint) = -999.0;
14643 0 : EER_TestPoint_IP(1 + PartLoadTestPoint) = -999.0;
14644 0 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = -999.0;
14645 0 : NetPower_TestPoint(1 + PartLoadTestPoint) = -999.0;
14646 : } else {
14647 : // now we have the supply air flow rate
14648 18 : SupAirMdot_TestPoint(1 + PartLoadTestPoint) = PartLoadAirMassFlowRate;
14649 18 : AirMassFlowRatio = PartLoadAirMassFlowRate / thisDXCoil.RatedAirMassFlowRate(1);
14650 18 : SupplyAirHumRat = PsyWFnTdbTwbPb(
14651 18 : state, CoolingCoilInletAirDryBulbTempRated, CoolingCoilInletAirWetBulbTempRated, state.dataEnvrn->OutBaroPress, RoutineName);
14652 18 : SupplyAirRho = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, CoolingCoilInletAirDryBulbTempRated, SupplyAirHumRat, RoutineName);
14653 18 : SupplyAirVolFlowRate = PartLoadAirMassFlowRate / SupplyAirRho;
14654 :
14655 18 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14656 9 : FanStaticPressureRise = thisDXCoil.InternalStaticPressureDrop + (ExternalStatic * pow_2(AirMassFlowRatio));
14657 9 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = PartLoadAirMassFlowRate;
14658 9 : state.dataLoopNodes->Node(FanInletNode).Temp = CoolingCoilInletAirDryBulbTempRated;
14659 9 : state.dataLoopNodes->Node(FanInletNode).HumRat = SupplyAirHumRat;
14660 9 : state.dataLoopNodes->Node(FanInletNode).Enthalpy = PsyHFnTdbW(CoolingCoilInletAirDryBulbTempRated, SupplyAirHumRat);
14661 :
14662 9 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
14663 9 : FanPowerCorrection = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->totalPower;
14664 :
14665 9 : FanHeatCorrection =
14666 9 : PartLoadAirMassFlowRate * (state.dataLoopNodes->Node(FanOutletNode).Enthalpy - state.dataLoopNodes->Node(FanInletNode).Enthalpy);
14667 :
14668 : } else {
14669 9 : FanPowerCorrection = FanPowerPerEvapAirFlowRate * PartLoadAirMassFlowRate;
14670 9 : FanHeatCorrection = FanPowerPerEvapAirFlowRate * PartLoadAirMassFlowRate;
14671 : }
14672 :
14673 18 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatio);
14674 : // Warn user if curve output goes negative
14675 18 : if (TotCapFlowModFac < 0.0) {
14676 0 : if (thisDXCoil.CCapFFlowErrorIndex == 0) {
14677 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
14678 0 : ShowContinueError(
14679 : state,
14680 0 : format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).", TotCapFlowModFac));
14681 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
14682 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
14683 : }
14684 0 : ShowRecurringWarningErrorAtEnd(
14685 : state,
14686 0 : format("{}{}\"{}\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
14687 : RoutineName,
14688 0 : thisDXCoil.DXCoilType,
14689 0 : thisDXCoil.Name),
14690 0 : thisDXCoil.CCapFFlowErrorIndex,
14691 : TotCapFlowModFac,
14692 : TotCapFlowModFac);
14693 0 : TotCapFlowModFac = 0.0;
14694 : }
14695 :
14696 54 : TotCapTempModFac = CurveValue(
14697 18 : state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14698 : // Warn user if curve output goes negative
14699 18 : if (TotCapTempModFac < 0.0) {
14700 0 : if (thisDXCoil.CCapFTempErrorIndex == 0) {
14701 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
14702 0 : ShowContinueError(
14703 : state,
14704 0 : format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
14705 0 : ShowContinueError(state,
14706 0 : format(" Negative value occurs using a coil inlet wet-bulb temperature of {:.1T} and an outdoor unit inlet air "
14707 : "dry-bulb temperature of {:.1T}.",
14708 : CoolingCoilInletAirWetBulbTempRated,
14709 : OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint)));
14710 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
14711 : }
14712 0 : ShowRecurringWarningErrorAtEnd(
14713 : state,
14714 0 : format("{}{} \"{}\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
14715 : RoutineName,
14716 0 : thisDXCoil.DXCoilType,
14717 0 : thisDXCoil.Name),
14718 0 : thisDXCoil.CCapFTempErrorIndex,
14719 : TotCapTempModFac,
14720 : TotCapTempModFac);
14721 0 : TotCapTempModFac = 0.0;
14722 : }
14723 :
14724 18 : HighSpeedTotCoolingCap = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac;
14725 18 : HighSpeedNetCoolingCap = HighSpeedTotCoolingCap - FanHeatCorrection;
14726 :
14727 54 : EIRTempModFac = CurveValue(
14728 18 : state, thisDXCoil.EIRFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14729 18 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatio);
14730 18 : if (thisDXCoil.RatedCOP(1) > 0.0) {
14731 : // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
14732 18 : EIR_HighSpeed = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP(1);
14733 : } else {
14734 0 : EIR = 0.0;
14735 : }
14736 :
14737 : // TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatio);
14738 36 : TotCapTempModFac = CurveValue(
14739 18 : state, thisDXCoil.CCapFTemp2, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14740 : // Warn user if curve output goes negative
14741 18 : if (TotCapTempModFac < 0.0) {
14742 0 : if (thisDXCoil.CCapFTempErrorIndex == 0) {
14743 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
14744 0 : ShowContinueError(
14745 : state,
14746 0 : format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
14747 0 : ShowContinueError(state,
14748 0 : format(" Negative value occurs using a coil inlet wet-bulb temperature of {:.1T} and an outdoor unit inlet air "
14749 : "dry-bulb temperature of {:.1T}.",
14750 : CoolingCoilInletAirWetBulbTempRated,
14751 : OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint)));
14752 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
14753 : }
14754 0 : ShowRecurringWarningErrorAtEnd(
14755 : state,
14756 0 : format("{}{} \"{}\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
14757 : RoutineName,
14758 0 : thisDXCoil.DXCoilType,
14759 0 : thisDXCoil.Name),
14760 0 : thisDXCoil.CCapFTempErrorIndex,
14761 : TotCapTempModFac,
14762 : TotCapTempModFac);
14763 0 : TotCapTempModFac = 0.0;
14764 : }
14765 :
14766 18 : LowSpeedTotCoolingCap = thisDXCoil.RatedTotCap2 * TotCapTempModFac * TotCapFlowModFac;
14767 18 : LowSpeedNetCoolingCap = LowSpeedTotCoolingCap - FanHeatCorrection;
14768 :
14769 36 : EIRTempModFac = CurveValue(
14770 18 : state, thisDXCoil.EIRFTemp2, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14771 18 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatio);
14772 18 : if (thisDXCoil.RatedCOP2 > 0.0) {
14773 : // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
14774 18 : EIR_LowSpeed = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP2;
14775 : } else {
14776 0 : EIR_LowSpeed = 0.0;
14777 : }
14778 :
14779 18 : if (LowSpeedNetCoolingCap <= TargetNetCapacity) {
14780 12 : CycRatio = 1.0;
14781 12 : SpeedRatio = (TargetNetCapacity - LowSpeedNetCoolingCap) / (HighSpeedNetCoolingCap - LowSpeedNetCoolingCap);
14782 12 : TotCoolingCap = HighSpeedTotCoolingCap * SpeedRatio + LowSpeedTotCoolingCap * (1.0 - SpeedRatio);
14783 12 : NetCoolingCap = TotCoolingCap - FanHeatCorrection;
14784 12 : EIR = EIR_HighSpeed * SpeedRatio + EIR_LowSpeed * (1.0 - SpeedRatio);
14785 12 : TotalElecPowerRated = TotCoolingCap * EIR + FanPowerCorrection;
14786 12 : EER_TestPoint_SI(1 + PartLoadTestPoint) = NetCoolingCap / TotalElecPowerRated;
14787 12 : EER_TestPoint_IP(1 + PartLoadTestPoint) = EER_TestPoint_SI(1 + PartLoadTestPoint) * ConvFromSIToIP;
14788 12 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = NetCoolingCap;
14789 12 : NetPower_TestPoint(1 + PartLoadTestPoint) = TotalElecPowerRated;
14790 : } else { // minimum unloading limit exceeded without cycling, so cycle
14791 6 : SpeedRatio = 0.0;
14792 6 : CycRatio = TargetNetCapacity / LowSpeedNetCoolingCap;
14793 6 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(1), CycRatio);
14794 6 : if (PLF < 0.7) {
14795 0 : PLF = 0.7;
14796 : }
14797 6 : RunTimeFraction = CycRatio / PLF;
14798 6 : RunTimeFraction = min(RunTimeFraction, 1.0);
14799 6 : TotCoolingCap = LowSpeedTotCoolingCap * RunTimeFraction;
14800 6 : NetCoolingCap = TotCoolingCap - FanHeatCorrection;
14801 6 : TotalElecPowerRated = LowSpeedTotCoolingCap * EIR_LowSpeed * RunTimeFraction + FanPowerCorrection;
14802 6 : EER_TestPoint_SI(1 + PartLoadTestPoint) = NetCoolingCap / TotalElecPowerRated;
14803 6 : EER_TestPoint_IP(1 + PartLoadTestPoint) = EER_TestPoint_SI(1 + PartLoadTestPoint) * ConvFromSIToIP;
14804 6 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = NetCoolingCap;
14805 6 : NetPower_TestPoint(1 + PartLoadTestPoint) = TotalElecPowerRated;
14806 : }
14807 : }
14808 : } // loop over 3 part load test points
14809 6 : state.dataHVACGlobal->TurnFansOn = saveTurnFansOn;
14810 6 : state.dataHVACGlobal->TurnFansOff = saveTurnFansOff;
14811 :
14812 6 : 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));
14813 : // CalcMultiSpeedDXCoilCooling() //??
14814 : // begin output
14815 6 : if (state.dataDXCoils->CalcTwoSpeedDXCoilStandardRatingOneTimeEIOHeaderWrite) {
14816 4 : print(state.files.eio, Header);
14817 4 : state.dataDXCoils->CalcTwoSpeedDXCoilStandardRatingOneTimeEIOHeaderWrite = false;
14818 8 : state.dataOutRptPredefined->pdstVAVDXCoolCoil =
14819 4 : newPreDefSubTable(state, state.dataOutRptPredefined->pdrEquip, "VAV DX Cooling Standard Rating Details");
14820 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilType =
14821 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "DX Cooling Coil Type");
14822 4 : state.dataOutRptPredefined->pdchVAVDXFanName = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Associated Fan");
14823 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilNetCapSI =
14824 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Net Cooling Capacity [W]");
14825 4 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP [W/W]");
14826 4 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEERIP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER [Btu/W-h]");
14827 4 : state.dataOutRptPredefined->pdchVAVDXCoolCoilIEERIP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "IEER [Btu/W-h]");
14828 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotA =
14829 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 100% [kg/s]");
14830 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_B =
14831 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 75% Capacity [W/W]");
14832 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_B_IP =
14833 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 75% Capacity [Btu/W-h]");
14834 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotB =
14835 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 75% [kg/s]");
14836 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_C =
14837 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 50% Capacity [W/W]");
14838 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_C_IP =
14839 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 50% Capacity [Btu/W-h]");
14840 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotC =
14841 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 50% [kg/s]");
14842 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_D =
14843 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 25% Capacity [W/W]");
14844 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_D_IP =
14845 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 25% Capacity [Btu/W-h]");
14846 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotD =
14847 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 25% [kg/s]");
14848 :
14849 : // determine footnote content
14850 4 : countStaticInputs = 0;
14851 8 : for (index = 1; index <= state.dataDXCoils->NumDXCoils; ++index) {
14852 :
14853 7 : if (state.dataDXCoils->DXCoil(index).RateWithInternalStaticAndFanObject &&
14854 3 : state.dataDXCoils->DXCoil(index).DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
14855 3 : ++countStaticInputs;
14856 : }
14857 : }
14858 :
14859 4 : if (countStaticInputs == state.dataDXCoils->NumDXMulSpeedCoils) {
14860 6 : addFootNoteSubTable(state,
14861 3 : state.dataOutRptPredefined->pdstVAVDXCoolCoil,
14862 : "Packaged VAV unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2");
14863 1 : } else if (countStaticInputs == 0) {
14864 2 : addFootNoteSubTable(state,
14865 1 : state.dataOutRptPredefined->pdstVAVDXCoolCoil,
14866 : "Indoor-coil-only unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2, with "
14867 : "supply fan specific power at 365 {{W/1000cfm}} (773.3 {{W/(m3/s)}})");
14868 : } else { // both
14869 0 : addFootNoteSubTable(state,
14870 0 : state.dataOutRptPredefined->pdstVAVDXCoolCoil,
14871 : "Packaged VAV unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2, "
14872 : "indoor-coil-only units with supply fan specific power at 365 {{W/1000cfm}} (773.3 {{W/(m3/s)}})");
14873 : }
14874 : }
14875 :
14876 0 : const auto &fan_type_name = [&]() -> std::pair<const char *, std::string> {
14877 6 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14878 3 : return {"Fan:VariableVolume", thisDXCoil.SupplyFanName};
14879 : } else {
14880 3 : return {"N/A", "N/A"};
14881 : }
14882 6 : }();
14883 :
14884 6 : print(state.files.eio,
14885 : Format_891,
14886 : "Coil:Cooling:DX:TwoSpeed",
14887 6 : thisDXCoil.Name,
14888 6 : fan_type_name.first,
14889 6 : fan_type_name.second,
14890 : NetCoolingCapRated,
14891 6 : (NetCoolingCapRated * ConvFromSIToIP),
14892 : IEER,
14893 : EER_TestPoint_SI(1),
14894 : EER_TestPoint_SI(2),
14895 : EER_TestPoint_SI(3),
14896 : EER_TestPoint_SI(4),
14897 : EER_TestPoint_IP(1),
14898 : EER_TestPoint_IP(2),
14899 : EER_TestPoint_IP(3),
14900 : EER_TestPoint_IP(4),
14901 : SupAirMdot_TestPoint(1),
14902 : SupAirMdot_TestPoint(2),
14903 : SupAirMdot_TestPoint(3),
14904 : SupAirMdot_TestPoint(4));
14905 :
14906 6 : if (state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag) {
14907 : static constexpr std::string_view Format_994(
14908 : "! <DX Cooling Coil Standard Rating Information>, Component Type, Component Name, Standard Rating (Net) "
14909 : "Cooling Capacity {W}, Standard Rating Net COP {W/W}, EER {Btu/W-h}, SEER User {Btu/W-h}, SEER Standard {Btu/W-h}, "
14910 : "IEER "
14911 : "{Btu/W-h}");
14912 4 : print(state.files.eio, "{}\n", Format_994);
14913 4 : state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag = false;
14914 : }
14915 : static constexpr std::string_view Format_995(" DX Cooling Coil Standard Rating Information, {}, {}, {:.1R}, {}, {}, {}, {}, {}\n");
14916 6 : print(state.files.eio,
14917 : Format_995,
14918 : "Coil:Cooling:DX:TwoSpeed",
14919 6 : thisDXCoil.Name,
14920 : NetCoolingCapRated,
14921 : EER_TestPoint_SI(1),
14922 : EER_TestPoint_IP(1),
14923 : "N/A",
14924 : "N/A",
14925 : IEER);
14926 :
14927 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilType, thisDXCoil.Name, "Coil:Cooling:DX:TwoSpeed");
14928 : // W to tons
14929 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilNetCapSI, thisDXCoil.Name, NetCoolingCapRated, 1);
14930 :
14931 : // TODO: Commercial and industrial unitary air-conditioning condensing units with a capacity greater than 135,000 Btu/h (39564.59445 Watts)
14932 : // as defined in ANSI/AHRI Standard 365(I-P). | Scope 2.2.6 (ANSI/AHRI 340-360 2022)
14933 : //
14934 : // These will convert with a factor of 1 which is ok
14935 : // SEER | Capacity less than 65K Btu/h (19050 W) - calculated as per AHRI Standard 210/240-2023.
14936 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilCOP, thisDXCoil.Name, EER_TestPoint_SI(1), 2);
14937 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilEERIP, thisDXCoil.Name, EER_TestPoint_IP(1), 2);
14938 : // These will convert with a factor of 1 which is ok
14939 : // IEER | Capacity of 65K Btu/h (19050 W) to less than 135K Btu/h (39565 W) - calculated as per AHRI Standard 340/360-2022.
14940 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilIEERIP, thisDXCoil.Name, IEER, 1);
14941 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERUserIP, thisDXCoil.Name, "N/A");
14942 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERStandardIP, thisDXCoil.Name, "N/A");
14943 :
14944 6 : addFootNoteSubTable(state, state.dataOutRptPredefined->pdstDXCoolCoil, StandardRatings::AHRI2017FOOTNOTE);
14945 :
14946 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilType, thisDXCoil.Name, "Coil:Cooling:DX:TwoSpeed");
14947 6 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14948 3 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXFanName, thisDXCoil.Name, thisDXCoil.SupplyFanName);
14949 : } else {
14950 3 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXFanName, thisDXCoil.Name, "None");
14951 : }
14952 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilNetCapSI, thisDXCoil.Name, NetCoolingCapRated, 2);
14953 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP, thisDXCoil.Name, EER_TestPoint_SI(1), 2);
14954 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilIEERIP, thisDXCoil.Name, IEER, 2);
14955 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEERIP, thisDXCoil.Name, EER_TestPoint_IP(1), 2);
14956 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotA, thisDXCoil.Name, SupAirMdot_TestPoint(1), 4);
14957 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_B, thisDXCoil.Name, EER_TestPoint_SI(2), 2);
14958 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_B_IP, thisDXCoil.Name, EER_TestPoint_IP(2), 2);
14959 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotB, thisDXCoil.Name, SupAirMdot_TestPoint(2), 4);
14960 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_C, thisDXCoil.Name, EER_TestPoint_SI(3), 2);
14961 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_C_IP, thisDXCoil.Name, EER_TestPoint_IP(3), 2);
14962 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotC, thisDXCoil.Name, SupAirMdot_TestPoint(3), 4);
14963 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_D, thisDXCoil.Name, EER_TestPoint_SI(4), 2);
14964 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_D_IP, thisDXCoil.Name, EER_TestPoint_IP(4), 2);
14965 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotD, thisDXCoil.Name, SupAirMdot_TestPoint(4), 4);
14966 :
14967 6 : state.dataEnvrn->OutDryBulbTemp = heldOutDryBulb; // reset the outdoor dry bulb when done with it
14968 6 : }
14969 :
14970 2 : void GetFanIndexForTwoSpeedCoil(
14971 : EnergyPlusData &state, int const CoolingCoilIndex, int &SupplyFanIndex, std::string &SupplyFanName, HVAC::FanType &supplyFanType)
14972 : {
14973 :
14974 : // SUBROUTINE INFORMATION:
14975 : // AUTHOR <author>
14976 : // DATE WRITTEN <date_written>
14977 :
14978 : // PURPOSE OF THIS SUBROUTINE:
14979 : // This routine looks up the given TwoSpeed DX coil and returns the companion supply fan index
14980 :
14981 : // Using/Aliasing
14982 2 : int NumPrimaryAirSys = state.dataHVACGlobal->NumPrimaryAirSys;
14983 :
14984 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14985 : int FoundBranch;
14986 : int FoundAirSysNum;
14987 : int AirSysNum;
14988 : int BranchNum;
14989 : int CompNum;
14990 :
14991 2 : FoundBranch = 0;
14992 2 : FoundAirSysNum = 0;
14993 2 : SupplyFanIndex = 0;
14994 2 : SupplyFanName = "n/a";
14995 4 : for (AirSysNum = 1; AirSysNum <= NumPrimaryAirSys; ++AirSysNum) {
14996 :
14997 4 : for (BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).NumBranches; ++BranchNum) {
14998 :
14999 4 : for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).TotalComponents; ++CompNum) {
15000 :
15001 4 : if (state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num ==
15002 : SimAirServingZones::CompType::DXSystem) {
15003 :
15004 2 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name,
15005 2 : state.dataDXCoils->DXCoil(CoolingCoilIndex).CoilSystemName)) {
15006 2 : FoundBranch = BranchNum;
15007 2 : FoundAirSysNum = AirSysNum;
15008 2 : break;
15009 : }
15010 : // these are specified in SimAirServingZones and need to be moved to a Data* file. UnitarySystem=19
15011 2 : } else if (state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num ==
15012 : SimAirServingZones::CompType::UnitarySystemModel) {
15013 :
15014 0 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name,
15015 0 : state.dataDXCoils->DXCoil(CoolingCoilIndex).CoilSystemName)) {
15016 0 : FoundBranch = BranchNum;
15017 0 : FoundAirSysNum = AirSysNum;
15018 0 : break;
15019 : }
15020 : }
15021 : }
15022 :
15023 2 : if (FoundBranch > 0 && FoundAirSysNum > 0) {
15024 9 : for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).TotalComponents;
15025 : ++CompNum) {
15026 8 : if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
15027 : SimAirServingZones::CompType::Fan_Simple_VAV) {
15028 1 : SupplyFanName = state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).Name;
15029 1 : SupplyFanIndex = Fans::GetFanIndex(state, SupplyFanName);
15030 1 : supplyFanType = HVAC::FanType::VAV;
15031 1 : break;
15032 : // these are specified in SimAirServingZones and need to be moved to a Data* file. UnitarySystem=19
15033 7 : } else if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
15034 : SimAirServingZones::CompType::Fan_System_Object) {
15035 1 : SupplyFanName = state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).Name;
15036 1 : SupplyFanIndex = Fans::GetFanIndex(state, SupplyFanName);
15037 1 : supplyFanType = HVAC::FanType::SystemModel;
15038 :
15039 6 : } else if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
15040 : SimAirServingZones::CompType::UnitarySystemModel) {
15041 : // fan may not be specified in a unitary system object, keep looking
15042 : // Unitary System will "set" the fan index to the DX coil if contained within the HVAC system
15043 0 : if (state.dataDXCoils->DXCoil(CoolingCoilIndex).SupplyFanIndex > 0) break;
15044 : }
15045 : }
15046 : }
15047 : }
15048 : }
15049 2 : }
15050 :
15051 165 : void GetDXCoilIndex(EnergyPlusData &state,
15052 : std::string const &DXCoilName,
15053 : int &DXCoilIndex,
15054 : bool &ErrorsFound,
15055 : std::string_view const ThisObjectType,
15056 : bool const SuppressWarning)
15057 : {
15058 :
15059 : // SUBROUTINE INFORMATION:
15060 : // AUTHOR Richard Raustad
15061 : // DATE WRITTEN March 2005
15062 :
15063 : // PURPOSE OF THIS SUBROUTINE:
15064 : // This subroutine sets an index for a given DX Coil -- issues error message if that
15065 : // DX Coil is not a legal DX Coil.
15066 :
15067 165 : if (state.dataDXCoils->GetCoilsInputFlag) {
15068 58 : GetDXCoils(state);
15069 58 : state.dataDXCoils->GetCoilsInputFlag = false;
15070 : }
15071 :
15072 165 : DXCoilIndex = Util::FindItemInList(DXCoilName, state.dataDXCoils->DXCoil);
15073 165 : if (DXCoilIndex == 0) {
15074 0 : if (!SuppressWarning) {
15075 : // No warning printed if only searching for the existence of a DX Coil
15076 0 : if (!ThisObjectType.empty()) {
15077 0 : ShowSevereError(state, fmt::format("{}, GetDXCoilIndex: DX Coil not found={}", ThisObjectType, DXCoilName));
15078 : } else {
15079 0 : ShowSevereError(state, format("GetDXCoilIndex: DX Coil not found={}", DXCoilName));
15080 : }
15081 : }
15082 0 : ErrorsFound = true;
15083 : }
15084 165 : }
15085 :
15086 : std::string
15087 0 : GetDXCoilName(EnergyPlusData &state, int &DXCoilIndex, bool &ErrorsFound, std::string_view const ThisObjectType, bool const SuppressWarning)
15088 : {
15089 :
15090 : // SUBROUTINE INFORMATION:
15091 : // AUTHOR Richard Raustad
15092 : // DATE WRITTEN May 2017
15093 :
15094 : // PURPOSE OF THIS SUBROUTINE:
15095 : // This subroutine gets a name for a given DX Coil -- issues error message if that
15096 : // DX Coil is not a legal DX Coil.
15097 :
15098 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
15099 0 : GetDXCoils(state);
15100 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15101 : }
15102 :
15103 0 : if (DXCoilIndex == 0) {
15104 0 : if (!SuppressWarning) {
15105 : // No warning printed if only searching for the existence of a DX Coil
15106 0 : if (!ThisObjectType.empty()) {
15107 0 : ShowSevereError(state, fmt::format("{}, GetDXCoilIndex: DX Coil not found ", ThisObjectType));
15108 : } else {
15109 0 : ShowSevereError(state, "GetDXCoilIndex: DX Coil not found ");
15110 : }
15111 : }
15112 0 : ErrorsFound = true;
15113 0 : return " "; // This does not seem great
15114 :
15115 : } else {
15116 0 : return state.dataDXCoils->DXCoil(DXCoilIndex).Name;
15117 : }
15118 : }
15119 :
15120 6 : Real64 GetCoilCapacity(EnergyPlusData &state,
15121 : std::string const &CoilType, // must match coil types in this module
15122 : std::string const &CoilName, // must match coil names for the coil type
15123 : bool &ErrorsFound // set to true if problem
15124 : )
15125 : {
15126 :
15127 : // FUNCTION INFORMATION:
15128 : // AUTHOR Linda Lawrie
15129 : // DATE WRITTEN February 2006
15130 :
15131 : // PURPOSE OF THIS FUNCTION:
15132 : // This function looks up the coil capacity for the given coil and returns it. If
15133 : // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
15134 : // as negative.
15135 :
15136 : // Return value
15137 : Real64 CoilCapacity; // returned capacity of matched coil
15138 :
15139 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15140 : int WhichCoil;
15141 :
15142 : // Obtains and Allocates DXCoils
15143 6 : if (state.dataDXCoils->GetCoilsInputFlag) {
15144 0 : GetDXCoils(state);
15145 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15146 : }
15147 :
15148 6 : if (Util::SameString(CoilType, "Coil:Heating:DX:SingleSpeed") || Util::SameString(CoilType, "Coil:Cooling:DX:SingleSpeed")) {
15149 6 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15150 6 : if (WhichCoil != 0) {
15151 6 : CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(1);
15152 : }
15153 0 : } else if (Util::SameString(CoilType, "Coil:Cooling:DX:TwoStageWithHumidityControlMode")) {
15154 0 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15155 0 : if (WhichCoil != 0) {
15156 0 : CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(state.dataDXCoils->DXCoil(WhichCoil).NumCapacityStages);
15157 : }
15158 0 : } else if (Util::SameString(CoilType, "Coil:Cooling:DX:TwoSpeed")) {
15159 0 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15160 0 : if (WhichCoil != 0) {
15161 0 : CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(1);
15162 : }
15163 0 : } else if (Util::SameString(CoilType, "Coil:Cooling:DX:MultiSpeed") || Util::SameString(CoilType, "Coil:Heating:DX:MultiSpeed")) {
15164 0 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15165 0 : if (WhichCoil != 0) {
15166 0 : CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).MSRatedTotCap(state.dataDXCoils->DXCoil(WhichCoil).NumOfSpeeds);
15167 : }
15168 : } else {
15169 0 : WhichCoil = 0;
15170 : }
15171 :
15172 6 : if (WhichCoil == 0) {
15173 0 : ShowSevereError(state, format("GetCoilCapacity: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15174 0 : ShowContinueError(state, "... returning capacity as -1000.");
15175 0 : ErrorsFound = true;
15176 0 : CoilCapacity = -1000.0;
15177 : }
15178 :
15179 6 : return CoilCapacity;
15180 : }
15181 :
15182 39 : Real64 GetCoilCapacityByIndexType(EnergyPlusData &state,
15183 : int const CoilIndex, // must match coil index for the coil type
15184 : int const CoilType_Num, // must match coil types in this module
15185 : bool &ErrorsFound // set to true if problem
15186 : )
15187 : {
15188 :
15189 : // FUNCTION INFORMATION:
15190 : // AUTHOR Richard Raustad
15191 : // DATE WRITTEN October 2010
15192 :
15193 : // PURPOSE OF THIS FUNCTION:
15194 : // This function looks up the coil capacity for the given coil and returns it. If
15195 : // incorrect coil index or type is given, ErrorsFound is returned as true and capacity is returned
15196 : // as negative.
15197 :
15198 : // Return value
15199 : Real64 CoilCapacity; // returned capacity of matched coil
15200 :
15201 : // Obtains and Allocates DXCoils
15202 39 : if (state.dataDXCoils->GetCoilsInputFlag) {
15203 0 : GetDXCoils(state);
15204 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15205 : }
15206 :
15207 39 : if (CoilIndex == 0) {
15208 0 : ShowSevereError(state, "GetCoilCapacityByIndexType: Invalid index passed = 0");
15209 0 : ShowContinueError(state, "... returning capacity as -1000.");
15210 0 : ErrorsFound = true;
15211 0 : CoilCapacity = -1000.0;
15212 0 : return CoilCapacity;
15213 : }
15214 :
15215 39 : if (CoilType_Num != state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
15216 0 : ShowSevereError(state, "GetCoilCapacityByIndexType: Index passed does not match DX Coil type passed.");
15217 0 : ShowContinueError(state, "... returning capacity as -1000.");
15218 0 : ErrorsFound = true;
15219 0 : CoilCapacity = -1000.0;
15220 : } else {
15221 39 : switch (state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
15222 4 : case HVAC::CoilDX_MultiSpeedCooling:
15223 : case HVAC::CoilDX_MultiSpeedHeating: {
15224 4 : CoilCapacity = state.dataDXCoils->DXCoil(CoilIndex).MSRatedTotCap(state.dataDXCoils->DXCoil(CoilIndex).NumOfSpeeds);
15225 4 : } break;
15226 35 : default: {
15227 35 : CoilCapacity = state.dataDXCoils->DXCoil(CoilIndex).RatedTotCap(state.dataDXCoils->DXCoil(CoilIndex).NumCapacityStages);
15228 35 : } break;
15229 : }
15230 : }
15231 :
15232 39 : return CoilCapacity;
15233 : }
15234 :
15235 76 : int GetCoilTypeNum(EnergyPlusData &state,
15236 : std::string const &CoilType, // must match coil types in this module
15237 : std::string const &CoilName, // must match coil names for the coil type
15238 : bool &ErrorsFound, // set to true if problem
15239 : ObjexxFCL::Optional_bool_const PrintWarning // prints warning when true
15240 : )
15241 : {
15242 :
15243 : // FUNCTION INFORMATION:
15244 : // AUTHOR R. Raustad - FSEC
15245 : // DATE WRITTEN August 2008
15246 :
15247 : // PURPOSE OF THIS FUNCTION:
15248 : // This function looks up the integerized coil type for the given coil and returns it. If
15249 : // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
15250 : // as negative.
15251 :
15252 : // Return value
15253 : int TypeNum; // returned integerized type of matched coil
15254 :
15255 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15256 : int WhichCoil;
15257 : bool PrintMessage;
15258 :
15259 : // Obtains and Allocates DXCoils
15260 76 : if (state.dataDXCoils->GetCoilsInputFlag) {
15261 29 : GetDXCoils(state);
15262 29 : state.dataDXCoils->GetCoilsInputFlag = false;
15263 : }
15264 :
15265 76 : if (present(PrintWarning)) {
15266 74 : PrintMessage = PrintWarning;
15267 : } else {
15268 2 : PrintMessage = true;
15269 : }
15270 :
15271 76 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15272 76 : if (WhichCoil != 0) {
15273 76 : TypeNum = state.dataDXCoils->DXCoil(WhichCoil).DXCoilType_Num;
15274 : } else {
15275 0 : if (PrintMessage) {
15276 0 : ShowSevereError(state, format("GetCoilTypeNum: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15277 : }
15278 0 : ErrorsFound = true;
15279 0 : TypeNum = 0;
15280 : }
15281 :
15282 76 : return TypeNum;
15283 : }
15284 :
15285 76 : Real64 GetMinOATCompressor(EnergyPlusData &state,
15286 : int const CoilIndex, // index to cooling coil
15287 : bool &ErrorsFound // set to true if problem
15288 : )
15289 : {
15290 :
15291 : // Obtains and Allocates DXCoils
15292 76 : if (state.dataDXCoils->GetCoilsInputFlag) {
15293 0 : GetDXCoils(state);
15294 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15295 : }
15296 :
15297 76 : if (CoilIndex == 0) {
15298 0 : ShowSevereError(state, "GetMinOATCompressor: Index passed = 0");
15299 0 : ShowContinueError(state, "... returning Min OAT for compressor operation as -1000.");
15300 0 : ErrorsFound = true;
15301 0 : return -1000.0;
15302 : } else {
15303 76 : return state.dataDXCoils->DXCoil(CoilIndex).MinOATCompressor;
15304 : }
15305 : }
15306 :
15307 78 : int GetCoilInletNode(EnergyPlusData &state,
15308 : std::string const &CoilType, // must match coil types in this module
15309 : std::string const &CoilName, // must match coil names for the coil type
15310 : bool &ErrorsFound // set to true if problem
15311 : )
15312 : {
15313 :
15314 : // FUNCTION INFORMATION:
15315 : // AUTHOR Linda Lawrie
15316 : // DATE WRITTEN February 2006
15317 :
15318 : // PURPOSE OF THIS FUNCTION:
15319 : // This function looks up the given coil and returns the inlet node number. If
15320 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
15321 : // as zero.
15322 :
15323 : // Return value
15324 : int NodeNumber; // returned node number of matched coil
15325 :
15326 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15327 : int WhichCoil;
15328 :
15329 : // Obtains and Allocates DXCoils
15330 78 : if (state.dataDXCoils->GetCoilsInputFlag) {
15331 1 : GetDXCoils(state);
15332 1 : state.dataDXCoils->GetCoilsInputFlag = false;
15333 : }
15334 :
15335 78 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15336 78 : if (WhichCoil != 0) {
15337 78 : NodeNumber = state.dataDXCoils->DXCoil(WhichCoil).AirInNode;
15338 : } else {
15339 0 : ShowSevereError(state, format("GetCoilInletNode: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15340 0 : ErrorsFound = true;
15341 0 : NodeNumber = 0;
15342 : }
15343 :
15344 78 : return NodeNumber;
15345 : }
15346 :
15347 0 : int getCoilInNodeIndex(EnergyPlusData &state,
15348 : int const CoilIndex, // coil index
15349 : bool &ErrorsFound // set to true if problem
15350 : )
15351 : {
15352 :
15353 : int NodeNumber; // returned node number of matched coil
15354 :
15355 : // Obtains and Allocates DXCoils
15356 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
15357 0 : GetDXCoils(state);
15358 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15359 : }
15360 :
15361 0 : if (CoilIndex != 0) {
15362 0 : NodeNumber = state.dataDXCoils->DXCoil(CoilIndex).AirInNode;
15363 : } else {
15364 0 : ShowSevereError(state, "GetCoilInletNode: Could not find Coil Type");
15365 0 : ErrorsFound = true;
15366 0 : NodeNumber = 0;
15367 : }
15368 :
15369 0 : return NodeNumber;
15370 : }
15371 :
15372 83 : int GetCoilOutletNode(EnergyPlusData &state,
15373 : std::string const &CoilType, // must match coil types in this module
15374 : std::string const &CoilName, // must match coil names for the coil type
15375 : bool &ErrorsFound // set to true if problem
15376 : )
15377 : {
15378 :
15379 : // FUNCTION INFORMATION:
15380 : // AUTHOR Linda Lawrie
15381 : // DATE WRITTEN February 2006
15382 :
15383 : // PURPOSE OF THIS FUNCTION:
15384 : // This function looks up the given coil and returns the inlet node number. If
15385 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
15386 : // as zero.
15387 :
15388 : // Return value
15389 : int NodeNumber; // returned node number of matched coil
15390 :
15391 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15392 : int WhichCoil;
15393 :
15394 : // Obtains and Allocates DXCoils
15395 83 : if (state.dataDXCoils->GetCoilsInputFlag) {
15396 3 : GetDXCoils(state);
15397 3 : state.dataDXCoils->GetCoilsInputFlag = false;
15398 : }
15399 :
15400 83 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15401 83 : if (WhichCoil != 0) {
15402 83 : NodeNumber = state.dataDXCoils->DXCoil(WhichCoil).AirOutNode;
15403 : } else {
15404 0 : ShowSevereError(
15405 : state,
15406 0 : format("GetCoilOutletNode: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil outlet node number.", CoilType, CoilName));
15407 0 : ErrorsFound = true;
15408 0 : NodeNumber = 0;
15409 : }
15410 :
15411 83 : return NodeNumber;
15412 : }
15413 :
15414 0 : int getCoilOutNodeIndex(EnergyPlusData &state,
15415 : int const CoilIndex, // must match coil types in this module
15416 : bool &ErrorsFound // set to true if problem
15417 : )
15418 : {
15419 :
15420 : int NodeNumber; // returned node number of matched coil
15421 :
15422 : // Obtains and Allocates DXCoils
15423 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
15424 0 : GetDXCoils(state);
15425 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15426 : }
15427 :
15428 0 : if (CoilIndex != 0) {
15429 0 : NodeNumber = state.dataDXCoils->DXCoil(CoilIndex).AirOutNode;
15430 : } else {
15431 0 : ShowSevereError(state, "GetCoilOutletNode: Could not find Coil Type");
15432 0 : ErrorsFound = true;
15433 0 : NodeNumber = 0;
15434 : }
15435 :
15436 0 : return NodeNumber;
15437 : }
15438 :
15439 45 : int GetCoilCondenserInletNode(EnergyPlusData &state,
15440 : std::string const &CoilType, // must match coil types in this module
15441 : std::string const &CoilName, // must match coil names for the coil type
15442 : bool &ErrorsFound // set to true if problem
15443 : )
15444 : {
15445 :
15446 : // FUNCTION INFORMATION:
15447 : // AUTHOR R. Raustad
15448 : // DATE WRITTEN January 2007
15449 :
15450 : // PURPOSE OF THIS FUNCTION:
15451 : // This function looks up the given coil and returns the condenser inlet node. If
15452 : // incorrect coil type or name is given, ErrorsFound is returned as true.
15453 :
15454 : // Return value
15455 : int CondNode; // returned condenser node number of matched coil
15456 :
15457 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15458 : int WhichCoil;
15459 :
15460 : // Obtains and Allocates DXCoils
15461 45 : if (state.dataDXCoils->GetCoilsInputFlag) {
15462 0 : GetDXCoils(state);
15463 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15464 : }
15465 :
15466 45 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15467 45 : if (WhichCoil != 0) {
15468 45 : CondNode = state.dataDXCoils->DXCoil(WhichCoil).CondenserInletNodeNum(1);
15469 : } else {
15470 0 : ShowSevereError(state, format("GetCoilCondenserInletNode: Invalid DX Coil, Type= \"{}\" Name=\"{}\"", CoilType, CoilName));
15471 0 : ErrorsFound = true;
15472 0 : CondNode = 0;
15473 : }
15474 :
15475 45 : return CondNode;
15476 : }
15477 :
15478 2 : Real64 GetDXCoilBypassedFlowFrac(EnergyPlusData &state,
15479 : std::string const &CoilType, // must match coil types in this module
15480 : std::string const &CoilName, // must match coil names for the coil type
15481 : bool &ErrorsFound // set to true if problem
15482 : )
15483 : {
15484 :
15485 : // FUNCTION INFORMATION:
15486 : // AUTHOR R. Raustad
15487 : // DATE WRITTEN June 2007
15488 :
15489 : // PURPOSE OF THIS FUNCTION:
15490 : // This function looks up the given coil and returns the bypassed air flow fraction.
15491 : // Bypassed air flow fraction can only be greater than 0 for multimode DX cooling coils and is typical for 1st stage
15492 : // If incorrect coil type or name is given, ErrorsFound is returned as true.
15493 :
15494 : // Return value
15495 : Real64 BypassFraction; // returned bypass air fraction of matched coil
15496 :
15497 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15498 : int WhichCoil;
15499 :
15500 : // Obtains and Allocates DXCoils
15501 2 : if (state.dataDXCoils->GetCoilsInputFlag) {
15502 0 : GetDXCoils(state);
15503 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15504 : }
15505 :
15506 2 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15507 2 : if (WhichCoil != 0) {
15508 2 : BypassFraction = state.dataDXCoils->DXCoil(WhichCoil).BypassedFlowFrac(1);
15509 : } else {
15510 0 : ShowSevereError(state, format("GetDXCoilBypassedFlowFrac: Invalid DX Coil Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15511 0 : ErrorsFound = true;
15512 0 : BypassFraction = 0.0;
15513 : }
15514 :
15515 2 : return BypassFraction;
15516 : }
15517 :
15518 40 : int GetHPCoolingCoilIndex(EnergyPlusData &state,
15519 : std::string const &HeatingCoilType, // Type of DX heating coil used in HP
15520 : std::string const &HeatingCoilName, // Name of DX heating coil used in HP
15521 : int const HeatingCoilIndex // Index of DX heating coil used in HP
15522 : )
15523 : {
15524 :
15525 : // FUNCTION INFORMATION:
15526 : // AUTHOR R. Raustad
15527 : // DATE WRITTEN February 2007
15528 :
15529 : // PURPOSE OF THIS FUNCTION:
15530 : // This function looks up the given DX heating coil and returns the companion DX cooling coil.
15531 :
15532 : // Return value
15533 : int DXCoolingCoilIndex; // Index of HP DX cooling coil returned from this function
15534 :
15535 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15536 : int WhichComp; // DO loop counter to find correct comp set
15537 : int WhichCompanionComp; // DO loop counter to find companion coil comp set
15538 : int WhichHXAssistedComp; // DO loop counter when DX coil is used in a HX assisted cooling coil
15539 :
15540 40 : DXCoolingCoilIndex = 0;
15541 :
15542 : DataLoopNode::ConnectionObjectType HeatingCoilTypeNum = static_cast<DataLoopNode::ConnectionObjectType>(
15543 40 : getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC, Util::makeUPPER(HeatingCoilType)));
15544 :
15545 : DataLoopNode::ConnectionObjectType CompSetsParentType; // Parent object type which uses DX heating coil pass into this function
15546 40 : std::string CompSetsParentName;
15547 110 : for (WhichComp = 1; WhichComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichComp) {
15548 :
15549 151 : if (HeatingCoilTypeNum != state.dataBranchNodeConnections->CompSets(WhichComp).ComponentObjectType ||
15550 41 : !Util::SameString(HeatingCoilName, state.dataBranchNodeConnections->CompSets(WhichComp).CName))
15551 70 : continue;
15552 40 : CompSetsParentType = state.dataBranchNodeConnections->CompSets(WhichComp).ParentObjectType;
15553 40 : CompSetsParentName = state.dataBranchNodeConnections->CompSets(WhichComp).ParentCName;
15554 40 : if ((CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAir) ||
15555 14 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::ZoneHVACPackagedTerminalHeatPump) ||
15556 12 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed) ||
15557 12 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass) ||
15558 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitarySystem)) {
15559 : // Search for DX cooling coils
15560 104 : for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
15561 154 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, CompSetsParentName) ||
15562 64 : (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
15563 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed))
15564 64 : continue;
15565 : DXCoolingCoilIndex =
15566 26 : Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
15567 26 : break;
15568 : }
15569 152 : for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
15570 207 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, CompSetsParentName) ||
15571 91 : (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
15572 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed))
15573 112 : continue;
15574 : DXCoolingCoilIndex =
15575 4 : Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
15576 4 : break;
15577 : }
15578 : // Search for Heat Exchanger Assisted DX cooling coils
15579 40 : if (DXCoolingCoilIndex == 0) {
15580 93 : for (WhichHXAssistedComp = 1; WhichHXAssistedComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichHXAssistedComp) {
15581 124 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ParentCName, CompSetsParentName) ||
15582 62 : (state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ComponentObjectType !=
15583 : DataLoopNode::ConnectionObjectType::CoilSystemCoolingDXHeatExchangerAssisted))
15584 62 : continue;
15585 : DataLoopNode::ConnectionObjectType HXCompSetsParentType; // Used when DX cooling coil is a child of a HX assisted cooling coil
15586 0 : HXCompSetsParentType = state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ComponentObjectType;
15587 0 : std::string const &HXCompSetsParentName = state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).CName;
15588 0 : for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
15589 0 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, HXCompSetsParentName) ||
15590 0 : (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
15591 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed))
15592 0 : continue;
15593 : DXCoolingCoilIndex =
15594 0 : Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
15595 0 : break;
15596 : }
15597 0 : break;
15598 : }
15599 : }
15600 40 : } else {
15601 : // ErrorFound, Coil:Heating:DX:SingleSpeed is used in wrong type of parent object (should never get here)
15602 0 : ShowSevereError(state,
15603 0 : format("Configuration error in {}\"{}\"",
15604 0 : BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(CompSetsParentType)],
15605 : CompSetsParentName));
15606 0 : ShowContinueError(state, "DX heating coil not allowed in this configuration.");
15607 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
15608 : }
15609 40 : break;
15610 : }
15611 :
15612 : // Check and warn user is crankcase heater power or max OAT for crankcase heater differs in DX cooling and heating coils
15613 40 : if (DXCoolingCoilIndex > 0) {
15614 9 : if (state.dataDXCoils->DXCoil(DXCoolingCoilIndex).CrankcaseHeaterCapacity != 0.0) {
15615 1 : if (state.dataDXCoils->DXCoil(DXCoolingCoilIndex).CrankcaseHeaterCapacity !=
15616 2 : state.dataDXCoils->DXCoil(HeatingCoilIndex).CrankcaseHeaterCapacity ||
15617 1 : state.dataDXCoils->DXCoil(DXCoolingCoilIndex).MaxOATCrankcaseHeater !=
15618 1 : state.dataDXCoils->DXCoil(HeatingCoilIndex).MaxOATCrankcaseHeater) {
15619 0 : ShowWarningError(state, "Crankcase heater capacity or max outdoor temp for crankcase heater operation specified in");
15620 0 : ShowContinueError(state, format("Coil:Cooling:DX:SingleSpeed = {}", state.dataDXCoils->DXCoil(DXCoolingCoilIndex).Name));
15621 0 : ShowContinueError(state, format("is different than that specified in Coil:Heating:DX:SingleSpeed = {}.", HeatingCoilName));
15622 0 : ShowContinueError(state,
15623 0 : format("Both of these DX coils are part of {}={}.",
15624 0 : BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(CompSetsParentType)],
15625 : CompSetsParentName));
15626 0 : ShowContinueError(state, "The value specified in the DX heating coil will be used and the simulation continues...");
15627 : }
15628 : }
15629 : }
15630 :
15631 40 : return DXCoolingCoilIndex;
15632 40 : }
15633 :
15634 6 : int GetDXCoilNumberOfSpeeds(EnergyPlusData &state,
15635 : std::string const &CoilType, // must match coil types in this module
15636 : std::string const &CoilName, // must match coil names for the coil type
15637 : bool &ErrorsFound // set to true if problem
15638 : )
15639 : {
15640 :
15641 : // FUNCTION INFORMATION:
15642 : // AUTHOR L. Gu
15643 : // DATE WRITTEN July 2007
15644 :
15645 : // PURPOSE OF THIS FUNCTION:
15646 : // This function looks up the given coil and returns the number of speeds for multispeed coils.
15647 : // If incorrect coil type or name is given, ErrorsFound is returned as true.
15648 :
15649 : // Return value
15650 : int NumberOfSpeeds; // returned the number of speed of matched coil
15651 :
15652 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15653 : int WhichCoil;
15654 :
15655 : // Obtains and Allocates DXCoils
15656 6 : if (state.dataDXCoils->GetCoilsInputFlag) {
15657 0 : GetDXCoils(state);
15658 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15659 : }
15660 :
15661 6 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15662 6 : if (WhichCoil != 0) {
15663 6 : NumberOfSpeeds = state.dataDXCoils->DXCoil(WhichCoil).NumOfSpeeds;
15664 : } else {
15665 0 : ShowSevereError(state, format("GetDXCoilNumberOfSpeeds: Invalid DX Coil Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15666 0 : ErrorsFound = true;
15667 0 : NumberOfSpeeds = 0;
15668 : }
15669 :
15670 6 : return NumberOfSpeeds;
15671 : }
15672 :
15673 68 : Sched::Schedule *GetDXCoilAvailSched(EnergyPlusData &state,
15674 : std::string const &CoilType, // must match coil types in this module
15675 : std::string const &CoilName, // must match coil names for the coil type
15676 : bool &ErrorsFound, // set to true if problem
15677 : ObjexxFCL::Optional_int_const CoilIndex // Coil index number
15678 : )
15679 : {
15680 :
15681 : // FUNCTION INFORMATION:
15682 : // AUTHOR Richard Raustad
15683 : // DATE WRITTEN January 2013
15684 :
15685 : // PURPOSE OF THIS FUNCTION:
15686 : // This function looks up the given coil and returns the availability schedule index. If
15687 : // incorrect coil type or name is given, ErrorsFound is returned as true and schedule index is returned
15688 : // as -1.
15689 :
15690 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15691 : int WhichCoil;
15692 :
15693 : // Obtains and Allocates DXCoils
15694 68 : if (state.dataDXCoils->GetCoilsInputFlag) {
15695 0 : GetDXCoils(state);
15696 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15697 : }
15698 :
15699 68 : if (present(CoilIndex)) {
15700 2 : if (CoilIndex == 0) {
15701 0 : ShowSevereError(state, "GetDXCoilAvailSchPtr: Invalid index passed = 0");
15702 0 : ShowContinueError(state, "... returning DXCoilAvailSchPtr as -1.");
15703 0 : ErrorsFound = true;
15704 0 : return nullptr;
15705 : } else {
15706 2 : WhichCoil = CoilIndex;
15707 : }
15708 : } else {
15709 66 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15710 : }
15711 68 : if (WhichCoil != 0) {
15712 68 : return state.dataDXCoils->DXCoil(WhichCoil).availSched;
15713 : } else {
15714 0 : if (!present(CoilIndex)) {
15715 0 : ShowSevereError(state,
15716 0 : format("GetDXCoilAvailSch: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil availability schedule index.",
15717 : CoilType,
15718 : CoilName));
15719 : }
15720 0 : ErrorsFound = true;
15721 0 : return nullptr;
15722 : }
15723 : }
15724 :
15725 0 : Real64 GetDXCoilAirFlow(EnergyPlusData &state,
15726 : std::string const &CoilType, // must match coil types in this module
15727 : std::string const &CoilName, // must match coil names for the coil type
15728 : bool &ErrorsFound // set to true if problem
15729 : )
15730 : {
15731 :
15732 : // FUNCTION INFORMATION:
15733 : // AUTHOR Richard Raustad
15734 : // DATE WRITTEN January 2013
15735 :
15736 : // PURPOSE OF THIS FUNCTION:
15737 : // This function looks up the given coil and returns the availability schedule index. If
15738 : // incorrect coil type or name is given, ErrorsFound is returned as true and schedule index is returned
15739 : // as -1.
15740 :
15741 : // Return value
15742 : Real64 AirFlow; // returned coil air flow rate
15743 :
15744 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15745 : int WhichCoil;
15746 :
15747 : // Obtains and Allocates DXCoils
15748 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
15749 0 : GetDXCoils(state);
15750 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15751 : }
15752 :
15753 0 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15754 0 : if (WhichCoil != 0) {
15755 0 : switch (state.dataDXCoils->DXCoil(WhichCoil).DXCoilType_Num) {
15756 0 : case HVAC::CoilDX_CoolingSingleSpeed:
15757 : case HVAC::CoilDX_CoolingTwoSpeed:
15758 : case HVAC::CoilDX_HeatingEmpirical:
15759 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
15760 0 : AirFlow = state.dataDXCoils->DXCoil(WhichCoil).RatedAirVolFlowRate(1);
15761 0 : } break;
15762 0 : case HVAC::CoilDX_MultiSpeedCooling:
15763 : case HVAC::CoilDX_MultiSpeedHeating: {
15764 0 : AirFlow = state.dataDXCoils->DXCoil(WhichCoil).MSRatedAirVolFlowRate(1);
15765 0 : } break;
15766 0 : default: {
15767 0 : ShowSevereError(
15768 : state,
15769 0 : format("GetDXCoilAirFlow: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil air flow rate.", CoilType, CoilName));
15770 0 : ErrorsFound = true;
15771 0 : AirFlow = -1.0;
15772 0 : } break;
15773 : }
15774 : } else {
15775 0 : ShowSevereError(
15776 0 : state, format("GetDXCoilAirFlow: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil air flow rate.", CoilType, CoilName));
15777 0 : ErrorsFound = true;
15778 0 : AirFlow = -1.0;
15779 : }
15780 :
15781 0 : return AirFlow;
15782 : }
15783 :
15784 48 : int GetDXCoilCapFTCurveIndex(EnergyPlusData &state,
15785 : int const CoilIndex, // coil index pointer
15786 : bool &ErrorsFound // set to true if problem
15787 : )
15788 : {
15789 :
15790 : // FUNCTION INFORMATION:
15791 : // AUTHOR Richard Raustad
15792 : // DATE WRITTEN August 2013
15793 :
15794 : // PURPOSE OF THIS FUNCTION:
15795 : // This function looks up the given coil and returns the CapFT schedule index. If
15796 : // incorrect coil index is given, ErrorsFound is returned as true and schedule index is returned
15797 : // as -1.
15798 :
15799 : // Return value
15800 : int CapFTCurveIndex; // returned coil CapFT curve index
15801 :
15802 : // Obtains and Allocates DXCoils
15803 48 : if (state.dataDXCoils->GetCoilsInputFlag) {
15804 0 : GetDXCoils(state);
15805 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15806 : }
15807 :
15808 48 : if (CoilIndex != 0) {
15809 48 : switch (state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
15810 18 : case HVAC::CoilDX_CoolingSingleSpeed:
15811 : case HVAC::CoilDX_CoolingTwoSpeed:
15812 : case HVAC::CoilDX_HeatingEmpirical:
15813 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
15814 18 : CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).CCapFTemp(1);
15815 18 : } break;
15816 8 : case HVAC::CoilDX_MultiSpeedCooling:
15817 : case HVAC::CoilDX_MultiSpeedHeating: {
15818 8 : CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).MSCCapFTemp(state.dataDXCoils->DXCoil(CoilIndex).NumOfSpeeds);
15819 8 : } break;
15820 22 : case HVAC::CoilVRF_Heating: {
15821 22 : CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).CCapFTemp(1);
15822 22 : } break;
15823 0 : default: {
15824 : // CALL ShowSevereError(state, 'GetDXCoilCapFTCurveIndex: Could not find Coil, Type="'// &
15825 : // TRIM(cAllCoilTypes(DXCoil(CoilIndex)%DXCoilType_Num))//'" Name="'//TRIM(DXCoil(CoilIndex)%Name)// &
15826 : // '" when accessing coil capacity as a function of temperature curve.')
15827 0 : ErrorsFound = true;
15828 0 : CapFTCurveIndex = 0;
15829 0 : } break;
15830 : }
15831 : } else {
15832 : // CALL ShowSevereError(state, 'GetDXCoilCapFTCurveIndex: Could not find Coil, Index = 0'// &
15833 : // ' when accessing coil air flow rate.')
15834 0 : ErrorsFound = true;
15835 0 : CapFTCurveIndex = 0;
15836 : }
15837 :
15838 48 : return CapFTCurveIndex;
15839 : }
15840 :
15841 643 : void SetDXCoolingCoilData(
15842 : EnergyPlusData &state,
15843 : int const DXCoilNum, // Number of DX Cooling Coil
15844 : bool &ErrorsFound, // Set to true if certain errors found
15845 : ObjexxFCL::Optional_int HeatingCoilPLFCurvePTR, // Parameter equivalent of heating coil PLR curve index
15846 : ObjexxFCL::Optional<DataHeatBalance::RefrigCondenserType> CondenserType, // Parameter equivalent of condenser type parameter
15847 : ObjexxFCL::Optional_int CondenserInletNodeNum, // Parameter equivalent of condenser inlet node number
15848 : ObjexxFCL::Optional<Real64> MaxOATCrankcaseHeater, // Parameter equivalent of condenser Max OAT for Crank Case Heater temp
15849 : ObjexxFCL::Optional<Real64> MinOATCooling, // Parameter equivalent of condenser Min OAT for compressor cooling operation
15850 : ObjexxFCL::Optional<Real64> MaxOATCooling, // Parameter equivalent of condenser Max OAT for compressor cooling operation
15851 : ObjexxFCL::Optional<Real64> MinOATHeating, // Parameter equivalent of condenser Min OAT for compressor heating operation
15852 : ObjexxFCL::Optional<Real64> MaxOATHeating, // Parameter equivalent of condenser Max OAT for compressor heating operation
15853 : ObjexxFCL::Optional<HVAC::OATType> HeatingPerformanceOATType, // Parameter equivalent to condenser entering air temp type (1-db, 2=wb)
15854 : ObjexxFCL::Optional<StandardRatings::DefrostStrat> DefrostStrategy,
15855 : ObjexxFCL::Optional<StandardRatings::HPdefrostControl> DefrostControl,
15856 : ObjexxFCL::Optional_int DefrostEIRPtr,
15857 : ObjexxFCL::Optional<Real64> DefrostFraction,
15858 : ObjexxFCL::Optional<Real64> DefrostCapacity,
15859 : ObjexxFCL::Optional<Real64> MaxOATDefrost,
15860 : ObjexxFCL::Optional_bool CoolingCoilPresent,
15861 : ObjexxFCL::Optional_bool HeatingCoilPresent,
15862 : ObjexxFCL::Optional<Real64> HeatSizeRatio,
15863 : ObjexxFCL::Optional<Real64> TotCap,
15864 : ObjexxFCL::Optional_int SupplyFanIndex,
15865 : ObjexxFCL::Optional_string SupplyFanName,
15866 : ObjexxFCL::Optional<HVAC::FanType> supplyFanType)
15867 : {
15868 :
15869 : // SUBROUTINE INFORMATION:
15870 : // AUTHOR Richard Raustad, FSEC
15871 : // DATE WRITTEN December 2008
15872 :
15873 : // PURPOSE OF THIS SUBROUTINE:
15874 : // This routine was designed to allow the DX coil to access information from a gas or
15875 : // electric heating coil when these coils are each used in a parent object.
15876 : // Also, this is an illustration of setting Data from an outside source.
15877 :
15878 : // Using/Aliasing
15879 :
15880 : // Obtains and Allocates DXCoils
15881 643 : if (state.dataDXCoils->GetCoilsInputFlag) {
15882 0 : GetDXCoils(state);
15883 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15884 : }
15885 :
15886 643 : if (DXCoilNum <= 0 || DXCoilNum > state.dataDXCoils->NumDXCoils) {
15887 4 : ShowSevereError(state,
15888 4 : format("SetDXCoolingCoilData: called with DX Cooling Coil Number out of range={} should be >0 and <{}",
15889 : DXCoilNum,
15890 2 : state.dataDXCoils->NumDXCoils));
15891 2 : ErrorsFound = true;
15892 2 : return;
15893 : }
15894 :
15895 641 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
15896 641 : if (present(HeatingCoilPLFCurvePTR)) {
15897 0 : thisDXCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurvePTR;
15898 : }
15899 :
15900 641 : if (present(CondenserType)) {
15901 66 : thisDXCoil.CondenserType = CondenserType;
15902 : }
15903 :
15904 641 : if (present(CondenserInletNodeNum)) {
15905 66 : thisDXCoil.CondenserInletNodeNum(1) = CondenserInletNodeNum;
15906 : }
15907 :
15908 641 : if (present(MaxOATCrankcaseHeater)) {
15909 66 : thisDXCoil.MaxOATCrankcaseHeater = MaxOATCrankcaseHeater;
15910 : }
15911 :
15912 641 : if (present(MaxOATCooling)) {
15913 33 : thisDXCoil.MaxOATCompressor = MaxOATCooling;
15914 : }
15915 :
15916 641 : if (present(MaxOATHeating)) {
15917 11 : thisDXCoil.MaxOATCompressor = MaxOATHeating;
15918 : }
15919 :
15920 641 : if (present(MinOATCooling)) {
15921 33 : thisDXCoil.MinOATCompressor = MinOATCooling;
15922 : }
15923 :
15924 641 : if (present(MinOATHeating)) {
15925 33 : thisDXCoil.MinOATCompressor = MinOATHeating;
15926 : }
15927 :
15928 641 : if (present(HeatingPerformanceOATType)) {
15929 33 : thisDXCoil.HeatingPerformanceOATType = HeatingPerformanceOATType;
15930 : }
15931 :
15932 641 : if (present(DefrostStrategy)) {
15933 33 : thisDXCoil.DefrostStrategy = DefrostStrategy;
15934 : }
15935 :
15936 641 : if (present(DefrostControl)) {
15937 33 : thisDXCoil.DefrostControl = DefrostControl;
15938 : }
15939 :
15940 641 : if (present(DefrostEIRPtr)) {
15941 33 : thisDXCoil.DefrostEIRFT = DefrostEIRPtr;
15942 : }
15943 :
15944 641 : if (present(DefrostFraction)) {
15945 33 : thisDXCoil.DefrostTime = DefrostFraction;
15946 : }
15947 :
15948 641 : if (present(DefrostCapacity)) {
15949 33 : thisDXCoil.DefrostCapacity = DefrostCapacity;
15950 : }
15951 :
15952 641 : if (present(MaxOATDefrost)) {
15953 33 : thisDXCoil.MaxOATDefrost = MaxOATDefrost;
15954 : }
15955 :
15956 641 : if (present(CoolingCoilPresent)) {
15957 33 : thisDXCoil.CoolingCoilPresent = CoolingCoilPresent;
15958 : }
15959 :
15960 641 : if (present(HeatingCoilPresent)) {
15961 33 : thisDXCoil.HeatingCoilPresent = HeatingCoilPresent;
15962 : }
15963 :
15964 641 : if (present(HeatSizeRatio)) {
15965 0 : thisDXCoil.HeatSizeRatio = HeatSizeRatio;
15966 : }
15967 :
15968 641 : if (present(TotCap)) {
15969 0 : thisDXCoil.RatedTotCap(1) = TotCap;
15970 : }
15971 :
15972 641 : if (present(SupplyFanIndex)) {
15973 12 : thisDXCoil.SupplyFanIndex = SupplyFanIndex;
15974 : }
15975 :
15976 641 : if (present(SupplyFanName)) {
15977 12 : thisDXCoil.SupplyFanName = SupplyFanName;
15978 : }
15979 :
15980 641 : if (present(supplyFanType)) {
15981 12 : thisDXCoil.supplyFanType = supplyFanType;
15982 12 : if (thisDXCoil.SupplyFanIndex > 0) {
15983 12 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
15984 12 : thisDXCoil.Name,
15985 12 : thisDXCoil.DXCoilType,
15986 12 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->Name,
15987 12 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->type,
15988 : thisDXCoil.SupplyFanIndex);
15989 : }
15990 : }
15991 : }
15992 :
15993 1 : void SetCoilSystemHeatingDXFlag(EnergyPlusData &state,
15994 : std::string const &CoilType, // must match coil types in this module
15995 : std::string const &CoilName // must match coil names for the coil type
15996 : )
15997 : {
15998 :
15999 : // SUBROUTINE INFORMATION:
16000 : // AUTHOR B. Griffith
16001 : // DATE WRITTEN Jan. 2012
16002 :
16003 : // PURPOSE OF THIS SUBROUTINE:
16004 : // inform DX heating coil that is is part of a CoilSystem:Heating:DX
16005 : // and therefore it need not find its companion cooling coil
16006 :
16007 : // METHODOLOGY EMPLOYED:
16008 : // set value of logical flag FindCompanionUpStreamCoil to true
16009 :
16010 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16011 : int WhichCoil;
16012 :
16013 : // Obtains and Allocates DXCoils
16014 1 : if (state.dataDXCoils->GetCoilsInputFlag) {
16015 0 : GetDXCoils(state);
16016 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16017 : }
16018 :
16019 1 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
16020 1 : if (WhichCoil != 0) {
16021 1 : state.dataDXCoils->DXCoil(WhichCoil).FindCompanionUpStreamCoil = false;
16022 : } else {
16023 0 : ShowSevereError(state, format("SetCoilSystemHeatingDXFlag: Could not find Coil, Type=\"{}\"Name=\"{}\"", CoilType, CoilName));
16024 : }
16025 1 : }
16026 :
16027 2 : void SetCoilSystemCoolingData(EnergyPlusData &state,
16028 : std::string const &CoilName, // must match coil names for the coil type
16029 : std::string const &CoilSystemName)
16030 : {
16031 :
16032 : // SUBROUTINE INFORMATION:
16033 : // AUTHOR B. Griffith
16034 : // DATE WRITTEN July 2012
16035 :
16036 : // PURPOSE OF THIS SUBROUTINE:
16037 : // inform the child DX coil what the name of its parent is.
16038 :
16039 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16040 : int WhichCoil;
16041 :
16042 2 : if (state.dataDXCoils->GetCoilsInputFlag) {
16043 0 : GetDXCoils(state);
16044 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16045 : }
16046 :
16047 2 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
16048 2 : if (WhichCoil != 0) {
16049 2 : state.dataDXCoils->DXCoil(WhichCoil).CoilSystemName = CoilSystemName;
16050 : } else {
16051 0 : ShowSevereError(state, format("SetCoilSystemCoolingData: Could not find Coil \"Name=\"{}\"", CoilName));
16052 : }
16053 2 : }
16054 :
16055 3 : Real64 CalcSHRUserDefinedCurves(EnergyPlusData &state,
16056 : Real64 const InletDryBulb, // inlet air dry bulb temperature [C]
16057 : Real64 const InletWetBulb, // inlet air wet bulb temperature [C]
16058 : Real64 const AirMassFlowRatio, // ratio of actual air mass flow to rated air mass flow
16059 : int const SHRFTempCurveIndex, // SHR modifier curve index
16060 : int const SHRFFlowCurveIndex, // SHR modifier curve index
16061 : Real64 const SHRRated // rated sensible heat ratio, user input
16062 : )
16063 : {
16064 :
16065 : // SUBROUTINE INFORMATION:
16066 : // AUTHOR Bereket Nigusse, FSEC
16067 : // DATE WRITTEN December 2012
16068 :
16069 : // PURPOSE OF THIS FUNCTION:
16070 : // Returns the operating sensible heat ratio for a given Rated SHR and coil entering
16071 : // air DBT and WBT, and supply air mass flow fraction.
16072 :
16073 : // METHODOLOGY EMPLOYED:
16074 : // Model uses user specified rated SHR, and SHR modifying curves for temperature and flow
16075 : // fraction. The curves adjust the rated SHR based on biquadratic curve for temperatures
16076 : // and quadratic function for supply air mass flow ratio (actual vs rated).
16077 : // The biquadratic and quadratic curves are normalized curves generated from manufacturer's
16078 : // performance data
16079 :
16080 : // Using/Aliasing
16081 : using Curve::CurveValue;
16082 :
16083 : // Return value
16084 : Real64 SHRopr; // operating SHR, corrected for Temp and Flow Fraction
16085 :
16086 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16087 : Real64 SHRTempModFac; // Sensible Heat Ratio modifier (function of entering wetbulb, entering drybulb)
16088 : Real64 SHRFlowModFac; // Sensible Heat Ratio modifier (function of actual vs rated flow)
16089 :
16090 : // Get SHR modifying factor (function of inlet wetbulb & drybulb) for off-rated conditions
16091 3 : if (SHRFTempCurveIndex == 0) {
16092 3 : SHRTempModFac = 1.0;
16093 : } else {
16094 0 : SHRTempModFac = CurveValue(state, SHRFTempCurveIndex, InletWetBulb, InletDryBulb);
16095 0 : if (SHRTempModFac < 0.0) {
16096 0 : SHRTempModFac = 0.0;
16097 : }
16098 : }
16099 : // Get SHR modifying factor (function of mass flow ratio) for off-rated conditions
16100 3 : if (SHRFFlowCurveIndex == 0) {
16101 3 : SHRFlowModFac = 1.0;
16102 : } else {
16103 0 : SHRFlowModFac = CurveValue(state, SHRFFlowCurveIndex, AirMassFlowRatio);
16104 0 : if (SHRFlowModFac < 0.0) {
16105 0 : SHRFlowModFac = 0.0;
16106 : }
16107 : }
16108 : // Calculate "operating" sensible heat ratio
16109 3 : SHRopr = SHRRated * SHRTempModFac * SHRFlowModFac;
16110 :
16111 3 : if (SHRopr < 0.0) SHRopr = 0.0; // SHR cannot be less than zero
16112 3 : if (SHRopr > 1.0) SHRopr = 1.0; // SHR cannot be greater than 1.0
16113 :
16114 3 : return SHRopr;
16115 : }
16116 :
16117 0 : void SetDXCoilTypeData(EnergyPlusData &state, std::string const &CoilName) // must match coil names for the coil type
16118 : {
16119 :
16120 : // SUBROUTINE INFORMATION:
16121 : // AUTHOR B. Nigusse
16122 : // DATE WRITTEN January 2013
16123 :
16124 : // PURPOSE OF THIS SUBROUTINE:
16125 : // inform the child DX coil if the DX cooling coil is for 100% DOAS application.
16126 :
16127 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16128 : int WhichCoil;
16129 :
16130 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
16131 0 : GetDXCoils(state);
16132 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16133 : }
16134 :
16135 0 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
16136 0 : if (WhichCoil != 0) {
16137 0 : state.dataDXCoils->DXCoil(WhichCoil).ISHundredPercentDOASDXCoil = true;
16138 : } else {
16139 : // DXCoil(WhichCoil)%ISHundredPercentDOASDXCoil = .FALSE. //Autodesk:BoundsViolation DXCoil(0): DXCoil is not allocated with a 0
16140 : // element: Commented out
16141 0 : ShowSevereError(state, format("SetDXCoilTypeData: Could not find Coil \"Name=\"{}\"", CoilName));
16142 : }
16143 0 : }
16144 :
16145 5 : void CalcSecondaryDXCoils(EnergyPlusData &state, int const DXCoilNum)
16146 : {
16147 :
16148 : // SUBROUTINE INFORMATION:
16149 : // AUTHOR B. Nigusse
16150 : // DATE WRITTEN February 2015
16151 :
16152 : // PURPOSE OF THIS SUBROUTINE:
16153 : // Calculates secondary zone heat gain from secondary DX coils placed in a zone.
16154 :
16155 : // METHODOLOGY EMPLOYED:
16156 : // Energy balance:
16157 : // (1) Condenser placed in a zone, the zone total (sensible) heat
16158 : // gain rate is given Qcond = QEvap + WcompPluscondFanPower
16159 : // (2) Evaporator placed in a zone, the zone total heat removal
16160 : // rate is given Qevap = Qcond - WcompPluscondFanPower
16161 : // Furthermore, the evaporator total heat removal is split into
16162 : // latent and sensible components using user specified SHR
16163 :
16164 : // Using/Aliasing
16165 : using Curve::CurveValue;
16166 :
16167 : // SUBROUTINE PARAMETER DEFINITIONS:
16168 : static constexpr std::string_view RoutineName("CalcSecondaryDXCoils");
16169 :
16170 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16171 : Real64 CondInletDryBulb; // condenser entering air dry-bulb temperature (C)
16172 : Real64 EvapAirMassFlow; // Condenser air mass flow rate [kg/s]
16173 : Real64 EvapInletDryBulb; // evaporator inlet air drybulb [C]
16174 : Real64 EvapInletHumRat; // evaporator inlet air humidity ratio [kg/kg]
16175 : Real64 EvapInletWetBulb; // evaporator inlet air wetbulb [C]
16176 : Real64 EvapInletEnthalpy; // evaporator inlet air enthalpy [J/kg]
16177 : Real64 FullLoadOutAirEnth; // evaporator outlet full load enthalpy [J/kg]
16178 : Real64 FullLoadOutAirHumRat; // evaporator outlet humidity ratio at full load
16179 : Real64 FullLoadOutAirTemp; // evaporator outlet air temperature at full load [C]
16180 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
16181 5 : Real64 SHR(0); // sensible heat ratio
16182 : Real64 RhoAir; // secondary coil entering air density [kg/m3]
16183 5 : Real64 PartLoadRatio(0); // primary coil part-load ratio [-]
16184 : Real64 SecCoilRatedSHR; // secondary DX coil nominal or rated sensible heat ratio
16185 : Real64 SecCoilFlowFraction; // secondary coil flow fraction, is 1.0 for single speed machine
16186 : Real64 TotalHeatRemovalRate; // secondary coil total heat removal rate
16187 : Real64 TotalHeatRejectionRate; // secondary coil total heat rejection rate
16188 : int SecCoilSHRFT; // index of the SHR modifier curve for temperature of a secondary DX coil
16189 : int SecCoilSHRFF; // index of the sHR modifier curve for flow fraction of a secondary DX coil
16190 : int MSSpeedNumLS; // current low speed number of multispeed HP
16191 : int MSSpeedNumHS; // current high speed number of multispeed HP
16192 : Real64 MSSpeedRatio; // current speed ratio of multispeed HP
16193 : Real64 MSCycRatio; // current cycling ratio of multispeed HP
16194 : Real64 SHRHighSpeed; // sensible heat ratio at high speed
16195 : Real64 SHRLowSpeed; // sensible heat ratio at low speed
16196 :
16197 5 : EvapAirMassFlow = 0.0;
16198 :
16199 5 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
16200 :
16201 5 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
16202 5 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
16203 : // Select the correct unit type
16204 5 : switch (thisDXCoil.DXCoilType_Num) {
16205 3 : case HVAC::CoilDX_CoolingSingleSpeed:
16206 : case HVAC::CoilDX_CoolingTwoSpeed:
16207 : case HVAC::CoilDX_MultiSpeedCooling: {
16208 : // total sensible heat gain of the secondary zone from the secondary coil (condenser)
16209 3 : if (thisDXCoil.ElecCoolingPower > 0.0) {
16210 3 : TotalHeatRejectionRate = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
16211 : } else {
16212 0 : TotalHeatRejectionRate = 0.0;
16213 0 : return;
16214 : }
16215 3 : thisDXCoil.SecCoilSensibleHeatGainRate = TotalHeatRejectionRate;
16216 3 : } break;
16217 1 : case HVAC::CoilDX_HeatingEmpirical: {
16218 : // evaporator coil in the secondary zone
16219 1 : if (thisDXCoil.ElecHeatingPower > 0.0) {
16220 1 : TotalHeatRemovalRate = max(0.0, thisDXCoil.TotalHeatingEnergyRate - thisDXCoil.ElecHeatingPower);
16221 : } else {
16222 0 : TotalHeatRemovalRate = 0.0;
16223 0 : thisDXCoil.SecCoilSHR = 0.0;
16224 0 : return;
16225 : }
16226 1 : thisDXCoil.SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower;
16227 1 : EvapInletDryBulb = secZoneHB.ZT;
16228 1 : EvapInletHumRat = secZoneHB.airHumRat;
16229 1 : RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat);
16230 1 : EvapAirMassFlow = RhoAir * thisDXCoil.SecCoilAirFlow;
16231 : ;
16232 1 : PartLoadRatio = thisDXCoil.CompressorPartLoadRatio;
16233 1 : SecCoilRatedSHR = thisDXCoil.SecCoilRatedSHR;
16234 1 : if ((EvapAirMassFlow > HVAC::SmallMassFlow) && (PartLoadRatio > 0.0) &&
16235 1 : (EvapInletDryBulb > thisDXCoil.MinOATCompressor)) { // coil is running
16236 1 : SecCoilFlowFraction = 1.0; // for single speed DX coil the secondary coil (condenser) flow fraction is 1.0
16237 1 : CondInletDryBulb = state.dataLoopNodes->Node(thisDXCoil.AirInNode).Temp;
16238 1 : EvapInletWetBulb = PsyTwbFnTdbWPb(state, EvapInletDryBulb, EvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
16239 1 : EvapInletEnthalpy = PsyHFnTdbW(EvapInletDryBulb, EvapInletHumRat);
16240 1 : SecCoilSHRFT = thisDXCoil.SecCoilSHRFT;
16241 1 : SecCoilSHRFF = thisDXCoil.SecCoilSHRFF;
16242 : // determine the current SHR
16243 1 : SHR = CalcSecondaryDXCoilsSHR(state,
16244 : DXCoilNum,
16245 : EvapAirMassFlow,
16246 : TotalHeatRemovalRate,
16247 : PartLoadRatio,
16248 : SecCoilRatedSHR,
16249 : EvapInletDryBulb,
16250 : EvapInletHumRat,
16251 : EvapInletWetBulb,
16252 : EvapInletEnthalpy,
16253 : CondInletDryBulb,
16254 : SecCoilFlowFraction,
16255 : SecCoilSHRFT,
16256 : SecCoilSHRFF);
16257 : // Calculate full load output conditions
16258 1 : FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16259 1 : hTinwout = EvapInletEnthalpy - (1.0 - SHR) * ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
16260 1 : FullLoadOutAirHumRat = PsyWFnTdbH(state, EvapInletDryBulb, hTinwout, RoutineName, true);
16261 1 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
16262 : // when the air outlet temperature falls below the saturation temperature, it is reset to saturation temperature
16263 1 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
16264 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName);
16265 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
16266 : // Adjust SHR for the new outlet condition that balances energy
16267 0 : hTinwout = PsyHFnTdbW(EvapInletDryBulb, FullLoadOutAirHumRat);
16268 0 : SHR = 1.0 - (EvapInletEnthalpy - hTinwout) / ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
16269 0 : SHR = min(SHR, 1.0);
16270 : }
16271 : // calculate the sensible and latent zone heat removal (extraction) rate by the secondary coil
16272 1 : thisDXCoil.SecCoilSensibleHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate * SHR;
16273 1 : thisDXCoil.SecCoilLatentHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate - thisDXCoil.SecCoilSensibleHeatRemovalRate;
16274 : } else {
16275 : // DX coil is off;
16276 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
16277 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
16278 0 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
16279 0 : SHR = 0.0; // SHR is set to zero if the coil is off
16280 : }
16281 1 : thisDXCoil.SecCoilSHR = SHR;
16282 1 : } break;
16283 1 : case HVAC::CoilDX_MultiSpeedHeating: {
16284 1 : EvapInletDryBulb = secZoneHB.ZT;
16285 1 : EvapInletHumRat = secZoneHB.airHumRat;
16286 1 : RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat);
16287 1 : MSSpeedRatio = thisDXCoil.MSSpeedRatio;
16288 1 : MSCycRatio = thisDXCoil.MSCycRatio;
16289 1 : MSSpeedNumHS = thisDXCoil.MSSpeedNumHS;
16290 1 : MSSpeedNumLS = thisDXCoil.MSSpeedNumLS;
16291 1 : if (MSSpeedRatio > 0.0) {
16292 0 : EvapAirMassFlow = RhoAir * (thisDXCoil.MSSecCoilAirFlow(MSSpeedNumHS) * MSSpeedRatio +
16293 0 : thisDXCoil.MSSecCoilAirFlow(MSSpeedNumLS) * (1.0 - MSSpeedRatio));
16294 1 : } else if (MSCycRatio > 0.0) {
16295 1 : EvapAirMassFlow = RhoAir * thisDXCoil.MSSecCoilAirFlow(MSSpeedNumLS);
16296 : }
16297 1 : if (thisDXCoil.ElecHeatingPower > 0.0) {
16298 1 : TotalHeatRemovalRate = max(0.0, thisDXCoil.TotalHeatingEnergyRate - thisDXCoil.ElecHeatingPower);
16299 : } else {
16300 0 : TotalHeatRemovalRate = 0.0;
16301 0 : return;
16302 : }
16303 1 : thisDXCoil.SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower;
16304 1 : if ((EvapAirMassFlow > HVAC::SmallMassFlow) && (MSSpeedRatio > 0.0 || MSCycRatio > 0.0) &&
16305 1 : (EvapInletDryBulb > thisDXCoil.MinOATCompressor)) { // coil is running
16306 1 : SecCoilFlowFraction = 1.0; // for single speed DX coil the secondary coil (condenser) flow fraction is 1.0
16307 1 : CondInletDryBulb = state.dataLoopNodes->Node(thisDXCoil.AirInNode).Temp;
16308 1 : EvapInletWetBulb = PsyTwbFnTdbWPb(state, EvapInletDryBulb, EvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
16309 1 : EvapInletEnthalpy = PsyHFnTdbW(EvapInletDryBulb, EvapInletHumRat);
16310 : // determine the current SHR
16311 1 : if (MSSpeedRatio > 0.0) {
16312 : // calculate SHR for the higher speed
16313 0 : PartLoadRatio = 1.0;
16314 0 : SecCoilFlowFraction = 1.0;
16315 0 : SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumHS);
16316 0 : SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumHS);
16317 0 : SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumHS);
16318 0 : SHRHighSpeed = CalcSecondaryDXCoilsSHR(state,
16319 : DXCoilNum,
16320 : EvapAirMassFlow,
16321 : TotalHeatRemovalRate,
16322 : PartLoadRatio,
16323 : SecCoilRatedSHR,
16324 : EvapInletDryBulb,
16325 : EvapInletHumRat,
16326 : EvapInletWetBulb,
16327 : EvapInletEnthalpy,
16328 : CondInletDryBulb,
16329 : SecCoilFlowFraction,
16330 : SecCoilSHRFT,
16331 : SecCoilSHRFF);
16332 : // calculate SHR for the lower speed
16333 0 : SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumLS);
16334 0 : SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumLS);
16335 0 : SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumLS);
16336 0 : SHRLowSpeed = CalcSecondaryDXCoilsSHR(state,
16337 : DXCoilNum,
16338 : EvapAirMassFlow,
16339 : TotalHeatRemovalRate,
16340 : PartLoadRatio,
16341 : SecCoilRatedSHR,
16342 : EvapInletDryBulb,
16343 : EvapInletHumRat,
16344 : EvapInletWetBulb,
16345 : EvapInletEnthalpy,
16346 : CondInletDryBulb,
16347 : SecCoilFlowFraction,
16348 : SecCoilSHRFT,
16349 : SecCoilSHRFF);
16350 0 : SHR = SHRHighSpeed * MSSpeedRatio + SHRLowSpeed * (1.0 - MSSpeedRatio);
16351 :
16352 1 : } else if (MSCycRatio > 0.0) {
16353 : // calculate SHR for the lower speed
16354 1 : PartLoadRatio = MSCycRatio;
16355 1 : SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumLS);
16356 1 : SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumLS);
16357 1 : SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumLS);
16358 1 : SecCoilFlowFraction = 1.0;
16359 1 : SHRLowSpeed = CalcSecondaryDXCoilsSHR(state,
16360 : DXCoilNum,
16361 : EvapAirMassFlow,
16362 : TotalHeatRemovalRate,
16363 : MSCycRatio,
16364 : SecCoilRatedSHR,
16365 : EvapInletDryBulb,
16366 : EvapInletHumRat,
16367 : EvapInletWetBulb,
16368 : EvapInletEnthalpy,
16369 : CondInletDryBulb,
16370 : SecCoilFlowFraction,
16371 : SecCoilSHRFT,
16372 : SecCoilSHRFF);
16373 1 : SHR = SHRLowSpeed;
16374 : }
16375 : // Calculate full load output conditions
16376 1 : FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16377 1 : hTinwout = EvapInletEnthalpy - (1.0 - SHR) * ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
16378 1 : FullLoadOutAirHumRat = PsyWFnTdbH(state, EvapInletDryBulb, hTinwout, RoutineName, true);
16379 1 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
16380 : // when the air outlet temperature falls below the saturation temperature, it is reset to saturation temperature
16381 1 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
16382 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName);
16383 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
16384 : // Adjust SHR for the new outlet condition that balances energy
16385 0 : hTinwout = PsyHFnTdbW(EvapInletDryBulb, FullLoadOutAirHumRat);
16386 0 : SHR = 1.0 - (EvapInletEnthalpy - hTinwout) / (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16387 0 : SHR = min(SHR, 1.0);
16388 : }
16389 : // calculate the sensible and latent zone heat removal (extraction) rate by the secondary coil
16390 1 : thisDXCoil.SecCoilSensibleHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate * SHR;
16391 1 : thisDXCoil.SecCoilLatentHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate - thisDXCoil.SecCoilSensibleHeatRemovalRate;
16392 : } else {
16393 : // DX coil is off;
16394 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
16395 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
16396 0 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
16397 0 : SHR = 0.0; // SHR is set to rated value if the coil is off
16398 : }
16399 1 : thisDXCoil.SecCoilSHR = SHR;
16400 1 : } break;
16401 0 : default:
16402 0 : break;
16403 : }
16404 :
16405 : } else {
16406 0 : thisDXCoil.SecCoilSensibleHeatGainRate = 0.0;
16407 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
16408 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
16409 0 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
16410 : }
16411 : }
16412 :
16413 3 : Real64 CalcSecondaryDXCoilsSHR(EnergyPlusData &state,
16414 : [[maybe_unused]] int const DXCoilNum,
16415 : Real64 const EvapAirMassFlow,
16416 : Real64 const TotalHeatRemovalRate,
16417 : Real64 const PartLoadRatio,
16418 : Real64 const SecCoilRatedSHR,
16419 : Real64 const EvapInletDryBulb,
16420 : Real64 const EvapInletHumRat,
16421 : Real64 const EvapInletWetBulb,
16422 : Real64 const EvapInletEnthalpy,
16423 : Real64 const CondInletDryBulb,
16424 : Real64 const SecCoilFlowFraction,
16425 : int const SecCoilSHRFT,
16426 : int const SecCoilSHRFF)
16427 : {
16428 :
16429 : // SUBROUTINE INFORMATION:
16430 : // AUTHOR B. Nigusse
16431 : // DATE WRITTEN February 2015
16432 :
16433 : // PURPOSE OF THIS SUBROUTINE:
16434 : // Calculates secondary coil (evaporator) sensible heat ratio.
16435 :
16436 : // METHODOLOGY EMPLOYED:
16437 : // Energy balance:
16438 : // (1) checks if the secondary coil operation is dry and calculates applicable SHR.
16439 : // (2) determines SHR from user specified rated SHR values and SHR modifier curves for
16440 : // temperature and flow fraction.
16441 : // (3) if secondary coil operates dry then the larger of the user SHR value and dry
16442 : // coil operation SHR is selected.
16443 :
16444 : // Using/Aliasing
16445 : using Curve::CurveValue;
16446 :
16447 : // SUBROUTINE PARAMETER DEFINITIONS:
16448 3 : int constexpr MaxIter(30);
16449 3 : Real64 constexpr RelaxationFactor(0.4);
16450 3 : Real64 constexpr Tolerance(0.1);
16451 3 : Real64 constexpr DryCoilTestEvapInletHumRatReset(0.00001);
16452 : static constexpr std::string_view RoutineName("CalcSecondaryDXCoilsSHR");
16453 :
16454 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16455 : Real64 DryCoilTestEvapInletHumRat; // evaporator coil inlet humidity ratio test for dry coil
16456 : Real64 DryCoilTestEvapInletWetBulb; // evaporator coil inlet dry bulb temperature test for dry coil
16457 : Real64 FullLoadOutAirEnth; // evaporator outlet full load enthalpy [J/kg]
16458 : Real64 FullLoadOutAirTemp; // evaporator outlet air temperature at full load [C]
16459 : Real64 hTinwADP; // enthalpy of air at secondary coil entering temperature and Humidity ratio at ADP
16460 : Real64 SHRadp; // Sensible heat ratio
16461 : Real64 hADP; // enthalpy of air at secondary coil at ADP
16462 : Real64 tADP; // dry bulb temperature of air at secondary coil at ADP
16463 : Real64 wADP; // humidity ratio of air at secondary coil at ADP
16464 : Real64 HumRatError; // humidity ratio error
16465 : bool CoilMightBeDry; // TRUE means the secondary DX coil runs dry
16466 : int Counter; // iteration counter
16467 : bool Converged; // convergence flag
16468 : Real64 SHR; // current time step sensible heat ratio of secondary coil
16469 :
16470 3 : CoilMightBeDry = false;
16471 3 : FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16472 3 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, EvapInletHumRat);
16473 3 : if (FullLoadOutAirTemp > PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
16474 3 : CoilMightBeDry = true;
16475 : // find wADP, humidity ratio at apparatus dewpoint and inlet hum rat that would have dry coil
16476 3 : DryCoilTestEvapInletHumRat = EvapInletHumRat;
16477 3 : DryCoilTestEvapInletWetBulb = EvapInletWetBulb;
16478 3 : Counter = 0;
16479 3 : Converged = false;
16480 6 : while (!Converged) {
16481 : // assumes coil bypass factor (CBF) = 0.0
16482 3 : hADP = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16483 3 : tADP = PsyTsatFnHPb(state, hADP, state.dataEnvrn->OutBaroPress, RoutineName);
16484 3 : wADP = min(EvapInletHumRat, PsyWFnTdbH(state, tADP, hADP, RoutineName));
16485 3 : hTinwADP = PsyHFnTdbW(EvapInletDryBulb, wADP);
16486 3 : if ((EvapInletEnthalpy - hADP) > 1.e-10) {
16487 3 : SHRadp = min((hTinwADP - hADP) / (EvapInletEnthalpy - hADP), 1.0);
16488 : } else {
16489 0 : SHRadp = 1.0;
16490 : }
16491 3 : if ((wADP > DryCoilTestEvapInletHumRat) || (Counter >= 1 && Counter < MaxIter)) {
16492 0 : if (DryCoilTestEvapInletHumRat <= 0.0) DryCoilTestEvapInletHumRat = DryCoilTestEvapInletHumRatReset;
16493 0 : HumRatError = (DryCoilTestEvapInletHumRat - wADP) / DryCoilTestEvapInletHumRat;
16494 0 : DryCoilTestEvapInletHumRat = RelaxationFactor * wADP + (1.0 - RelaxationFactor) * DryCoilTestEvapInletHumRat;
16495 : DryCoilTestEvapInletWetBulb =
16496 0 : PsyTwbFnTdbWPb(state, EvapInletDryBulb, DryCoilTestEvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
16497 0 : ++Counter;
16498 0 : if (std::abs(HumRatError) <= Tolerance) {
16499 0 : Converged = true;
16500 : } else {
16501 0 : Converged = false;
16502 : }
16503 : } else {
16504 3 : Converged = true;
16505 : }
16506 : }
16507 : }
16508 : // determine SHR from user specified nominal value and SHR modifier curves
16509 3 : SHR = CalcSHRUserDefinedCurves(state, CondInletDryBulb, EvapInletWetBulb, SecCoilFlowFraction, SecCoilSHRFT, SecCoilSHRFF, SecCoilRatedSHR);
16510 3 : if (CoilMightBeDry) {
16511 3 : if ((EvapInletHumRat < DryCoilTestEvapInletHumRat) && (SHRadp > SHR)) { // coil is dry for sure
16512 0 : SHR = 1.0;
16513 3 : } else if (SHRadp > SHR) {
16514 0 : SHR = SHRadp;
16515 : }
16516 : }
16517 3 : return SHR;
16518 : }
16519 :
16520 23659 : void CalcVRFCoolingCoil_FluidTCtrl(EnergyPlusData &state,
16521 : int const DXCoilNum, // the number of the DX coil to be simulated
16522 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
16523 : bool const FirstHVACIteration, // true if this is the first iteration of HVAC
16524 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
16525 : HVAC::FanOp const fanOp, // Allows parent object to control fan operation
16526 : Real64 const CompCycRatio, // cycling ratio of VRF condenser
16527 : ObjexxFCL::Optional_int_const PerfMode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
16528 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
16529 : Real64 MaxCoolCap // maximum allowed cooling capacity
16530 : )
16531 : {
16532 : // SUBROUTINE INFORMATION:
16533 : // AUTHOR Xiufeng Pang, LBNL
16534 : // DATE WRITTEN Jan 2013
16535 : // MODIFIED Nov 2015, RP Zhang, LBNL
16536 :
16537 : // PURPOSE OF THIS SUBROUTINE:
16538 : // Calculates the air-side performance of a direct-expansion, air-cooled
16539 : // VRF terminal unit cooling coil, for the VRF_FluidTCtrl model.
16540 :
16541 : // METHODOLOGY EMPLOYED:
16542 : // This subroutine is derived from CalcVRFCoolingCoil, and implements the new VRF model for FluidTCtrl.
16543 :
16544 : // Using/Aliasing
16545 : using Curve::CurveValue;
16546 23659 : Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
16547 23659 : Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
16548 : using General::CreateSysTimeIntervalString;
16549 :
16550 : using namespace HVACVariableRefrigerantFlow;
16551 :
16552 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16553 :
16554 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
16555 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
16556 : // (average flow if cycling fan, full flow if constant fan)
16557 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
16558 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
16559 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
16560 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
16561 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
16562 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
16563 : Real64 RatedCBF; // coil bypass factor at rated conditions
16564 : Real64 CBF; // coil bypass factor at off rated conditions
16565 : Real64 A0; // NTU * air mass flow rate, used in CBF calculation
16566 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
16567 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
16568 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
16569 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
16570 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
16571 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
16572 : Real64 RhoAir; // Density of air [kg/m3]
16573 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
16574 23659 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
16575 : Real64 AirFlowRatio; // ratio of compressor on airflow to average timestep airflow
16576 : // used when constant fan mode yields different air flow rates when compressor is ON and OFF
16577 : // (e.g. Packaged Terminal Heat Pump)
16578 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
16579 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
16580 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
16581 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
16582 :
16583 : int Mode; // Performance mode for Multimode DX coil; Always 1 for other coil types
16584 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
16585 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
16586 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
16587 : Real64 ADiff; // Used for exponential
16588 :
16589 : // Followings for VRF FluidTCtrl Only
16590 : Real64 QCoilReq; // Coil load (W)
16591 : Real64 FanSpdRatio; // Fan speed ratio
16592 : Real64 AirMassFlowMin; // Min air mass flow rate due to OA requirement [kg/s]
16593 : Real64 ActualSH; // Super heating degrees (C)
16594 : Real64 ActualSC; // Sub cooling degrees (C)
16595 :
16596 : // If Performance mode not present, then set to 1. Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
16597 23659 : if (present(PerfMode)) {
16598 0 : Mode = PerfMode;
16599 : } else {
16600 23659 : Mode = 1;
16601 : }
16602 :
16603 : // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
16604 : // during cooling and when no cooling is required (constant fan, fan speed changes)
16605 23659 : if (present(OnOffAirFlowRatio)) {
16606 0 : AirFlowRatio = OnOffAirFlowRatio;
16607 : } else {
16608 23659 : AirFlowRatio = 1.0;
16609 : }
16610 :
16611 23659 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
16612 :
16613 : // Initialize coil air side parameters
16614 23659 : CondInletTemp = 0.0;
16615 23659 : CondInletHumRat = 0.0;
16616 23659 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
16617 23659 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
16618 23659 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
16619 23659 : InletAirHumRat = thisDXCoil.InletAirHumRat;
16620 23659 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
16621 23659 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
16622 23659 : thisDXCoil.PartLoadRatio = 0.0;
16623 23659 : thisDXCoil.BasinHeaterPower = 0.0;
16624 23659 : thisDXCoil.EvaporatingTemp = state.dataHVACVarRefFlow->VRF(thisDXCoil.VRFOUPtr).IUEvaporatingTemp;
16625 :
16626 23659 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
16627 0 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
16628 0 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
16629 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
16630 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
16631 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
16632 : } else {
16633 0 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
16634 : // If node is not connected to anything, pressure = default, use weather data
16635 0 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
16636 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
16637 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
16638 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
16639 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
16640 : } else {
16641 0 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
16642 0 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
16643 : }
16644 : }
16645 : } else {
16646 23659 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
16647 23659 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
16648 23659 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
16649 23659 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
16650 : }
16651 :
16652 23659 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
16653 0 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
16654 0 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
16655 : // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
16656 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
16657 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
16658 0 : CompAmbTemp = OutdoorDryBulb;
16659 : } else { // for air or water-cooled, inlet temp is stored in OutdoorDryBulb temp
16660 23659 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp or water inlet temp
16661 23659 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
16662 0 : CompAmbTemp = state.dataEnvrn->OutDryBulbTemp; // for crankcase heater use actual outdoor temp for water-cooled
16663 : } else {
16664 23659 : CompAmbTemp = OutdoorDryBulb;
16665 : }
16666 : }
16667 :
16668 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
16669 : // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
16670 23659 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
16671 32 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
16672 32 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
16673 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
16674 : }
16675 : } else {
16676 23627 : CrankcaseHeatingPower = 0.0;
16677 : }
16678 :
16679 : // calculate end time of current time step to determine if error messages should be printed
16680 23659 : state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
16681 :
16682 : // The following checks are not necessary for VRF-FluidTCtrl model. (1) OAT check is already performed in the VRF OU routines (2)
16683 : // VRF-FluidTCtrl model is physics based, not system curve based, and thus doesn't require special performance curves for operations at
16684 : // low inlet temperatures
16685 : // Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
16686 : // Wait for next time step to print warnings. If simulation iterates, print out
16687 : // the warning for the last iteration only. Must wait for next time step to accomplish this.
16688 : // If a warning occurs and the simulation down shifts, the warning is not valid.
16689 : // if ( DXCoil( DXCoilNum ).PrintLowAmbMessage ) { // .AND. &
16690 : // if ( CurrentEndTime > DXCoil( DXCoilNum ).CurrentEndTimeLast && TimeStepSys >= DXCoil( DXCoilNum ).TimeStepSysLast ) {
16691 : // if ( DXCoil( DXCoilNum ).LowAmbErrIndex == 0 ) {
16692 : // ShowWarningMessage(state, DXCoil( DXCoilNum ).LowAmbBuffer1 );
16693 : // ShowContinueError(state, DXCoil( DXCoilNum ).LowAmbBuffer2 );
16694 : // ShowContinueError(state, "... Operation at low inlet temperatures may require special performance curves." );
16695 : // }
16696 : // ShowRecurringWarningErrorAtEnd(state, DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Low condenser inlet
16697 : // temperature error continues...", DXCoil( DXCoilNum ).LowAmbErrIndex, DXCoil( DXCoilNum ).LowTempLast, DXCoil( DXCoilNum ).LowTempLast,
16698 : // _,
16699 : // "[C]", "[C]" );
16700 : // }
16701 : // }
16702 : //
16703 : // if ( DXCoil( DXCoilNum ).PrintHighAmbMessage ) { // .AND. &
16704 : // if ( CurrentEndTime > DXCoil( DXCoilNum ).CurrentEndTimeLast && TimeStepSys >= DXCoil( DXCoilNum ).TimeStepSysLast ) {
16705 : // if ( DXCoil( DXCoilNum ).HighAmbErrIndex == 0 ) {
16706 : // ShowWarningMessage(state, DXCoil( DXCoilNum ).HighAmbBuffer1 );
16707 : // ShowContinueError(state, DXCoil( DXCoilNum ).HighAmbBuffer2 );
16708 : // ShowContinueError(state, "... Operation at high inlet temperatures may require special performance curves." );
16709 : // }
16710 : // ShowRecurringWarningErrorAtEnd(state, DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - High condenser inlet
16711 : // temperature error continues...", DXCoil( DXCoilNum ).HighAmbErrIndex, DXCoil( DXCoilNum ).HighTempLast, DXCoil( DXCoilNum
16712 : // ).HighTempLast,
16713 : // _, "[C]", "[C]" );
16714 : // }
16715 : // }
16716 :
16717 23659 : if (thisDXCoil.PrintLowOutTempMessage) {
16718 0 : if ((state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime > thisDXCoil.CurrentEndTimeLast) &&
16719 0 : (TimeStepSys >= thisDXCoil.TimeStepSysLast)) {
16720 0 : if (thisDXCoil.LowOutletTempIndex == 0) {
16721 0 : ShowWarningMessage(state, thisDXCoil.LowOutTempBuffer1);
16722 0 : ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
16723 0 : ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
16724 0 : ShowContinueError(state,
16725 0 : format(" 1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
16726 0 : thisDXCoil.FullLoadInletAirTempLast));
16727 0 : ShowContinueError(state, " 2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
16728 0 : ShowContinueError(state,
16729 : " 3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
16730 : }
16731 0 : ShowRecurringWarningErrorAtEnd(state,
16732 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
16733 : "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
16734 : "Outlet air temperature statistics follow:",
16735 0 : thisDXCoil.LowOutletTempIndex,
16736 0 : thisDXCoil.FullLoadOutAirTempLast,
16737 0 : thisDXCoil.FullLoadOutAirTempLast);
16738 : }
16739 : }
16740 :
16741 : // save last system time step and last end time of current time step (used to determine if warning is valid)
16742 23659 : thisDXCoil.TimeStepSysLast = TimeStepSys;
16743 23659 : thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime;
16744 23659 : thisDXCoil.PrintLowAmbMessage = false;
16745 23659 : thisDXCoil.PrintLowOutTempMessage = false;
16746 :
16747 23659 : if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
16748 : (compressorOp == HVAC::CompressorOp::On)) { // for cycling fan, reset mass flow to full on rate
16749 :
16750 10299 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
16751 0 : ShowFatalError(state, format("{} \"{}\" - Rated total cooling capacity is zero or less.", thisDXCoil.DXCoilType, thisDXCoil.Name));
16752 : }
16753 :
16754 10299 : TotCap = min(MaxCoolCap, thisDXCoil.RatedTotCap(Mode));
16755 :
16756 10299 : QCoilReq = -PartLoadRatio * TotCap;
16757 10299 : if (PartLoadRatio == 0.0) {
16758 0 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
16759 : } else {
16760 10299 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
16761 : }
16762 :
16763 : // Call ControlVRFIUCoil to calculate: (1) FanSpdRatio, (2) coil inlet/outlet conditions, and (3) SH/SC
16764 10299 : ControlVRFIUCoil(state,
16765 : DXCoilNum,
16766 : QCoilReq,
16767 : thisDXCoil.InletAirTemp,
16768 : thisDXCoil.InletAirHumRat,
16769 : thisDXCoil.EvaporatingTemp,
16770 : AirMassFlowMin,
16771 : FanSpdRatio,
16772 : OutletAirHumRat,
16773 : OutletAirTemp,
16774 : OutletAirEnthalpy,
16775 : ActualSH,
16776 : ActualSC);
16777 10299 : AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
16778 :
16779 10299 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
16780 10299 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
16781 : // VolFlowperRatedTotCap was checked at the initialization step
16782 : // No need to check VolFlowperRatedTotCap at the simulation
16783 : // New VRF_FluidTCtrl model implements VAV fan which can vary air flow rate during simulation
16784 :
16785 10299 : RatedCBF = thisDXCoil.RatedCBF(Mode);
16786 10299 : if (RatedCBF > 0.0) {
16787 10299 : A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
16788 : } else {
16789 0 : A0 = 0.0;
16790 : }
16791 10299 : ADiff = -A0 / AirMassFlow;
16792 10299 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
16793 7714 : CBF = std::exp(ADiff);
16794 : } else {
16795 2585 : CBF = 0.0;
16796 : }
16797 :
16798 : // The following checks are not necessary for VRF-FluidTCtrl model. (1) OAT check is already performed in the VRF OU routines (2)
16799 : // VRF-FluidTCtrl model is physics based, not system curve based, and thus doesn't require special performance curves for operations
16800 : // at low inlet temperatures
16801 : // // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
16802 : // if ( OutdoorDryBulb < DXCoil( DXCoilNum ).MinOATCompressor && ! WarmupFlag ) {
16803 : // DXCoil( DXCoilNum ).PrintLowAmbMessage = true;
16804 : // DXCoil( DXCoilNum ).LowTempLast = OutdoorDryBulb;
16805 : // if ( DXCoil( DXCoilNum ).LowAmbErrIndex == 0 ) {
16806 : // DXCoil( DXCoilNum ).LowAmbBuffer1 = DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Condenser
16807 : // inlet temperature below " + RoundSigDigits( DXCoil( DXCoilNum ).MinOATCompressor, 2 ) + " C. Condenser inlet temperature = " +
16808 : // RoundSigDigits( OutdoorDryBulb, 2 );
16809 : // DXCoil( DXCoilNum ).LowAmbBuffer2 = " ... Occurrence info = " + EnvironmentName + ", " + CurMnDy + " " +
16810 : // CreateSysTimeIntervalString();
16811 : // }
16812 : // }
16813 : //
16814 : // // check boundary for high ambient temperature and post warnings to individual DX coil buffers to print at end of time step
16815 : // if ( OutdoorDryBulb > DXCoil( DXCoilNum ).MaxOATCompressor && ! WarmupFlag ) {
16816 : // DXCoil( DXCoilNum ).PrintHighAmbMessage = true;
16817 : // DXCoil( DXCoilNum ).HighTempLast = OutdoorDryBulb;
16818 : // if ( DXCoil( DXCoilNum ).HighAmbErrIndex == 0 ) {
16819 : // DXCoil( DXCoilNum ).HighAmbBuffer1 = DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Condenser
16820 : // inlet temperature above " + RoundSigDigits( DXCoil( DXCoilNum ).MaxOATCompressor, 2 ) + " C. Condenser temperature = " +
16821 : // RoundSigDigits( OutdoorDryBulb, 2 ); DXCoil( DXCoilNum ).HighAmbBuffer2 = " ... Occurrence info = " + EnvironmentName + ",
16822 : // "
16823 : // + CurMnDy + " " + CreateSysTimeIntervalString();
16824 : // }
16825 : // }
16826 :
16827 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
16828 : // InletAirHumRat may be modified in this ADP/BF loop, use temporary varible for calculations
16829 :
16830 : // commented, not used issue #6950
16831 : // InletAirHumRatTemp = InletAirHumRat;
16832 :
16833 : //// Calculate apparatus dew point conditions using TotCap and CBF
16834 : // hDelta = TotCap / AirMassFlow;
16835 : //// there is an issue here with using CBF to calculate the ADP enthalpy.
16836 : //// at low loads the bypass factor increases significantly.
16837 : // hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
16838 : // tADP = PsyTsatFnHPb(hADP, OutdoorPressure, RoutineName);
16839 : //// Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
16840 : //// tADP = PsyTsatFnHPb(hADP,InletAirPressure)
16841 : // wADP = min(InletAirHumRat, PsyWFnTdbH(tADP, hADP, RoutineName));
16842 : // hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
16843 : // if ((InletAirEnthalpy - hADP) > 1.e-10) {
16844 : // SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
16845 : //} else {
16846 : // SHR = 1.0;
16847 : //}
16848 : // commented, not used issue #6950 ends here
16849 :
16850 10299 : if (thisDXCoil.PLFFPLR(Mode) > 0 && CompCycRatio < 1.0) {
16851 0 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CompCycRatio); // Calculate part-load factor
16852 : } else {
16853 10299 : PLF = 1.0;
16854 : }
16855 :
16856 10299 : if (PLF < 0.7) {
16857 0 : if (thisDXCoil.ErrIndex2 == 0) {
16858 0 : ShowWarningMessage(
16859 : state,
16860 0 : format(
16861 0 : "The PLF curve value for the DX cooling coil {} ={:.3R} for part-load ratio ={:.3R}", thisDXCoil.Name, PLF, PartLoadRatio));
16862 0 : ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
16863 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
16864 : }
16865 0 : ShowRecurringWarningErrorAtEnd(
16866 0 : state, thisDXCoil.Name + ", DX cooling coil PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
16867 0 : PLF = 0.7;
16868 : }
16869 :
16870 10299 : thisDXCoil.PartLoadRatio = PartLoadRatio;
16871 10299 : thisDXCoil.CoolingCoilRuntimeFraction = CompCycRatio / PLF;
16872 10299 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
16873 0 : if (thisDXCoil.ErrIndex3 == 0) {
16874 0 : ShowWarningMessage(state,
16875 0 : format("The runtime fraction for DX cooling coil {} exceeded 1.0. [{:.4R}].",
16876 0 : thisDXCoil.Name,
16877 0 : thisDXCoil.CoolingCoilRuntimeFraction));
16878 0 : ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
16879 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
16880 0 : ShowContinueErrorTimeStamp(state, "");
16881 : }
16882 0 : ShowRecurringWarningErrorAtEnd(state,
16883 0 : thisDXCoil.Name + ", DX cooling coil runtime fraction > 1.0 warning continues...",
16884 0 : thisDXCoil.ErrIndex3,
16885 0 : thisDXCoil.CoolingCoilRuntimeFraction,
16886 0 : thisDXCoil.CoolingCoilRuntimeFraction);
16887 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
16888 10299 : } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
16889 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
16890 : }
16891 :
16892 : // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
16893 10299 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = thisDXCoil.CoolingCoilRuntimeFraction;
16894 :
16895 : // Check for saturation error and modify temperature at constant enthalpy
16896 10299 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) {
16897 18 : OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
16898 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
16899 : // IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
16900 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
16901 18 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
16902 : }
16903 :
16904 : // Store actual outlet conditions when DX coil is ON for use in heat recovery module
16905 10299 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = OutletAirTemp;
16906 10299 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = OutletAirHumRat;
16907 :
16908 : // Add warning message for cold cooling coil (OutletAirTemp < 2 C)
16909 10299 : if (OutletAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
16910 0 : thisDXCoil.PrintLowOutTempMessage = true;
16911 0 : thisDXCoil.FullLoadOutAirTempLast = OutletAirTemp;
16912 0 : if (thisDXCoil.LowOutletTempIndex == 0) {
16913 0 : thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
16914 0 : thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
16915 : "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
16916 0 : thisDXCoil.DXCoilType,
16917 0 : thisDXCoil.Name,
16918 0 : OutletAirTemp);
16919 0 : thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + " " +
16920 0 : CreateSysTimeIntervalString(state);
16921 : }
16922 : }
16923 :
16924 : // Coil total/sensible/latent cooling rates
16925 10299 : CalcComponentSensibleLatentOutput(AirMassFlow * PartLoadRatio,
16926 : InletAirDryBulbTemp,
16927 : InletAirHumRat,
16928 : OutletAirTemp,
16929 : OutletAirHumRat,
16930 10299 : thisDXCoil.SensCoolingEnergyRate,
16931 10299 : thisDXCoil.LatCoolingEnergyRate,
16932 10299 : thisDXCoil.TotalCoolingEnergyRate);
16933 :
16934 : // Coil outlet conditions
16935 10299 : thisDXCoil.OutletAirTemp = OutletAirTemp;
16936 10299 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
16937 10299 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
16938 :
16939 : // Coil SH/SC
16940 10299 : thisDXCoil.ActualSH = ActualSH;
16941 10299 : thisDXCoil.ActualSC = ActualSC;
16942 :
16943 : } else {
16944 : // DX coil is off; just pass through conditions
16945 :
16946 13360 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
16947 13360 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
16948 13360 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
16949 :
16950 13360 : thisDXCoil.ElecCoolingPower = 0.0;
16951 13360 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
16952 13360 : thisDXCoil.SensCoolingEnergyRate = 0.0;
16953 13360 : thisDXCoil.LatCoolingEnergyRate = 0.0;
16954 13360 : thisDXCoil.EvapCondPumpElecPower = 0.0;
16955 13360 : thisDXCoil.EvapWaterConsumpRate = 0.0;
16956 :
16957 13360 : thisDXCoil.ActualSH = 999.0;
16958 13360 : thisDXCoil.ActualSC = 999.0;
16959 :
16960 : // Reset globals when DX coil is OFF for use in heat recovery module
16961 13360 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
16962 13360 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
16963 :
16964 : } // end of on/off
16965 :
16966 : // set water system demand request (if needed)
16967 23659 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
16968 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
16969 0 : thisDXCoil.EvapWaterConsumpRate;
16970 : }
16971 :
16972 23659 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
16973 23659 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
16974 23659 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
16975 23659 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
16976 23659 : thisDXCoil.CondInletTemp = CondInletTemp;
16977 23659 : state.dataDXCoils->DXCoilTotalCooling(DXCoilNum) = thisDXCoil.TotalCoolingEnergyRate;
16978 23659 : state.dataDXCoils->DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
16979 23659 : }
16980 :
16981 23659 : void CalcVRFHeatingCoil_FluidTCtrl(EnergyPlusData &state,
16982 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
16983 : int const DXCoilNum, // the number of the DX heating coil to be simulated
16984 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
16985 : HVAC::FanOp const fanOp, // Allows parent object to control fan mode
16986 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
16987 : ObjexxFCL::Optional<Real64 const> MaxHeatCap // maximum allowed heating capacity
16988 : )
16989 : {
16990 : // SUBROUTINE INFORMATION:
16991 : // AUTHOR Xiufeng Pang (XP), LBNL
16992 : // DATE WRITTEN Mar 2013
16993 : // MODIFIED Nov 2015, RP Zhang, LBNL
16994 :
16995 : // PURPOSE OF THIS SUBROUTINE:
16996 : // Calculates the air-side performance of a direct-expansion, air-cooled
16997 : // VRF terminal unit heating coil, for the new VRF model.
16998 :
16999 : // METHODOLOGY EMPLOYED:
17000 : // This subroutine is derived from CalcVRFCoolingCoil, and implements the new VRF model for FluidTCtrl.
17001 :
17002 : // Using/Aliasing
17003 : using Curve::CurveValue;
17004 :
17005 : using namespace HVACVariableRefrigerantFlow;
17006 :
17007 : // INTERFACE BLOCK SPECIFICATIONS
17008 : static constexpr std::string_view RoutineNameFullLoad("CalcVRFHeatingCoil_FluidTCtrl:fullload");
17009 :
17010 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
17011 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
17012 : Real64 AirMassFlowRatio; // Ratio of actual air mass flow to rated air mass flow
17013 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s]
17014 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W]
17015 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
17016 : Real64 TotCapAdj; // adjusted total cooling capacity at off-rated conditions [W]
17017 : // on the type of curve
17018 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
17019 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
17020 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
17021 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
17022 : Real64 FullLoadOutAirEnth; // outlet full load enthalpy [J/kg]
17023 : Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
17024 : Real64 FullLoadOutAirTemp; // outlet air temperature at full load [C]
17025 : Real64 FullLoadOutAirRH; // outlet air relative humidity at full load
17026 23659 : Real64 EIRTempModFac(0.0); // EIR modifier (function of entering drybulb, outside drybulb) depending on the
17027 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17028 : // type of curve
17029 : // Real64 DefrostEIRTempModFac; // EIR modifier for defrost (function of entering wetbulb, outside drybulb)
17030 : Real64 EIRFlowModFac; // EIR modifier (function of actual supply air flow vs rated flow)
17031 : Real64 EIR; // EIR at part load and off rated conditions
17032 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup
17033 : Real64 PLRHeating; // PartLoadRatio in heating
17034 : Real64 OutdoorCoilT; // Outdoor coil temperature (C)
17035 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
17036 : Real64 FractionalDefrostTime; // Fraction of time step system is in defrost
17037 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
17038 : Real64 InputPowerMultiplier; // Multiplier for power when system is in defrost
17039 : Real64 LoadDueToDefrost; // Additional load due to defrost
17040 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
17041 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
17042 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
17043 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
17044 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
17045 23659 : constexpr int Mode(1); // Performance mode for MultiMode DX coil. Always 1 for other coil types
17046 : Real64 AirFlowRatio; // Ratio of compressor on airflow to average timestep airflow
17047 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
17048 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
17049 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
17050 :
17051 : // Followings for VRF FluidTCtrl Only
17052 : Real64 QCoilReq; // Coil load (W)
17053 : Real64 FanSpdRatio; // Fan Speed Ratio
17054 : Real64 AirMassFlowMin; // Min air mass flow rate due to OA requirement [kg/s]
17055 : Real64 ActualSH; // Actual Super Heating
17056 : Real64 ActualSC; // Actual Sub Cooling
17057 :
17058 23659 : if (present(OnOffAirFlowRatio)) {
17059 0 : AirFlowRatio = OnOffAirFlowRatio;
17060 : } else {
17061 23659 : AirFlowRatio = 1.0;
17062 : }
17063 :
17064 : // Air cooled condenser
17065 23659 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
17066 23659 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
17067 23659 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
17068 23659 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
17069 :
17070 23659 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
17071 :
17072 23659 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
17073 23659 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
17074 23659 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
17075 23659 : InletAirHumRat = thisDXCoil.InletAirHumRat;
17076 23659 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
17077 23659 : PLRHeating = 0.0;
17078 23659 : thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
17079 23659 : thisDXCoil.CondensingTemp = state.dataHVACVarRefFlow->VRF(thisDXCoil.VRFOUPtr).IUCondensingTemp;
17080 :
17081 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
17082 23659 : if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
17083 32 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
17084 32 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
17085 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
17086 : }
17087 : } else {
17088 23627 : CrankcaseHeatingPower = 0.0;
17089 : }
17090 :
17091 32212 : if ((AirMassFlow > 0.0) && (compressorOp == HVAC::CompressorOp::On) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
17092 8553 : (OutdoorDryBulb > thisDXCoil.MinOATCompressor)) {
17093 :
17094 8553 : TotCap = thisDXCoil.RatedTotCap(Mode);
17095 8553 : HeatingCapacityMultiplier = 1.0;
17096 : // Modify total heating capacity based on defrost heating capacity multiplier
17097 : // MaxHeatCap passed from parent object VRF Condenser and is used to limit capacity of TU's to that available from condenser
17098 8553 : if (present(MaxHeatCap)) {
17099 8547 : TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
17100 8547 : TotCap = min(MaxHeatCap, TotCap);
17101 : } else {
17102 6 : TotCapAdj = TotCap * HeatingCapacityMultiplier;
17103 : }
17104 :
17105 8553 : QCoilReq = PartLoadRatio * TotCap;
17106 8553 : if (PartLoadRatio == 0.0) {
17107 0 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
17108 : } else {
17109 8553 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
17110 : }
17111 :
17112 : // Call ControlVRFIUCoil to calculate: (1) FanSpdRatio, (2) coil inlet/outlet conditions, and (3) SH/SC
17113 8553 : ControlVRFIUCoil(state,
17114 : DXCoilNum,
17115 : QCoilReq,
17116 : thisDXCoil.InletAirTemp,
17117 : thisDXCoil.InletAirHumRat,
17118 : thisDXCoil.CondensingTemp,
17119 : AirMassFlowMin,
17120 : FanSpdRatio,
17121 : OutletAirHumRat,
17122 : OutletAirTemp,
17123 : OutletAirEnthalpy,
17124 : ActualSH,
17125 : ActualSC);
17126 8553 : AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
17127 :
17128 8553 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
17129 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17130 8553 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
17131 : // VolFlowperRatedTotCap was checked at the initialization step
17132 : // No need to check VolFlowperRatedTotCap at the simulation
17133 : // New VRF_FluidTCtrl model implements VAV fan which can vary air flow rate during simulation
17134 :
17135 8553 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
17136 :
17137 : // Calculating adjustment factors for defrost
17138 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
17139 8553 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
17140 8553 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
17141 :
17142 : // Initializing defrost adjustment factors
17143 8553 : LoadDueToDefrost = 0.0;
17144 8553 : FractionalDefrostTime = 0.0;
17145 8553 : InputPowerMultiplier = 1.0;
17146 :
17147 : // Calculate full load outlet conditions
17148 8553 : FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
17149 8553 : FullLoadOutAirHumRat = InletAirHumRat;
17150 8553 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
17151 8553 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
17152 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17153 : // FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
17154 8553 : if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
17155 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
17156 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17157 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
17158 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
17159 : }
17160 :
17161 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
17162 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
17163 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
17164 : // advised to use the bi-quaratic curve if sufficient manufacturer data is available.
17165 8553 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
17166 0 : if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 1) {
17167 0 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), OutdoorDryBulb);
17168 : } else {
17169 0 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
17170 : }
17171 0 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
17172 : } else {
17173 8553 : EIRTempModFac = 1.0;
17174 8553 : EIRFlowModFac = 1.0;
17175 : }
17176 8553 : EIR = thisDXCoil.RatedEIR(Mode) * EIRTempModFac * EIRFlowModFac;
17177 :
17178 : // Calculate PLRHeating: modified PartLoadRatio due to defrost ( reverse-cycle defrost only )
17179 8553 : if (TotCap > 0.0) {
17180 8553 : PLRHeating = min(1.0, (PartLoadRatio + LoadDueToDefrost / TotCap));
17181 : } else {
17182 0 : PLRHeating = min(1.0, PartLoadRatio);
17183 : }
17184 :
17185 8553 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
17186 0 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PLRHeating); // Calculate part-load factor
17187 : } else {
17188 8553 : PLF = 1.0;
17189 : }
17190 :
17191 8553 : if (PLF < 0.7) {
17192 0 : if (thisDXCoil.PLRErrIndex == 0) {
17193 0 : ShowWarningMessage(
17194 : state,
17195 0 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
17196 0 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
17197 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
17198 0 : ShowContinueErrorTimeStamp(state, "");
17199 : }
17200 0 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
17201 0 : PLF = 0.7;
17202 : }
17203 :
17204 8553 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
17205 8553 : if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
17206 0 : if (thisDXCoil.ErrIndex4 == 0) {
17207 0 : ShowWarningMessage(state,
17208 0 : format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
17209 0 : thisDXCoil.Name,
17210 0 : thisDXCoil.HeatingCoilRuntimeFraction));
17211 0 : ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
17212 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
17213 0 : ShowContinueErrorTimeStamp(state, "");
17214 : }
17215 0 : ShowRecurringWarningErrorAtEnd(state,
17216 0 : thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
17217 0 : thisDXCoil.ErrIndex4,
17218 0 : thisDXCoil.HeatingCoilRuntimeFraction,
17219 0 : thisDXCoil.HeatingCoilRuntimeFraction);
17220 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
17221 8553 : } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
17222 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
17223 : }
17224 :
17225 : // if cycling fan, send coil part-load fraction to on / off fan via HVACDataGlobals
17226 8553 : if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
17227 8553 : thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
17228 :
17229 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
17230 : // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
17231 8553 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
17232 8553 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
17233 : } else {
17234 0 : thisDXCoil.CrankcaseHeaterPower =
17235 0 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
17236 0 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
17237 : }
17238 :
17239 8553 : thisDXCoil.OutletAirTemp = OutletAirTemp;
17240 8553 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
17241 8553 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
17242 8553 : thisDXCoil.CompressorPartLoadRatio = PartLoadRatio;
17243 8553 : thisDXCoil.ActualSH = ActualSH;
17244 8553 : thisDXCoil.ActualSC = ActualSC;
17245 8553 : thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy) * PartLoadRatio;
17246 8553 : thisDXCoil.DefrostPower = thisDXCoil.DefrostPower * thisDXCoil.HeatingCoilRuntimeFraction;
17247 :
17248 : } else {
17249 : // DX coil is off; just pass through conditions
17250 :
17251 15106 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
17252 15106 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
17253 15106 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
17254 :
17255 15106 : thisDXCoil.ElecHeatingPower = 0.0;
17256 15106 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
17257 15106 : thisDXCoil.DefrostPower = 0.0;
17258 :
17259 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
17260 : // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
17261 15106 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
17262 15106 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
17263 : } else {
17264 0 : thisDXCoil.CrankcaseHeaterPower =
17265 0 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
17266 : }
17267 15106 : thisDXCoil.CompressorPartLoadRatio = 0.0;
17268 :
17269 15106 : thisDXCoil.ActualSH = 999.0;
17270 15106 : thisDXCoil.ActualSC = 999.0;
17271 : } // end of on/off if - else
17272 :
17273 23659 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
17274 23659 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
17275 23659 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
17276 23659 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
17277 23659 : state.dataDXCoils->DXCoilTotalHeating(DXCoilNum) = thisDXCoil.TotalHeatingEnergyRate;
17278 23659 : state.dataDXCoils->DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
17279 23659 : state.dataDXCoils->DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;
17280 :
17281 : // calc secondary coil if specified
17282 23659 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
17283 0 : CalcSecondaryDXCoils(state, DXCoilNum);
17284 : }
17285 23659 : }
17286 :
17287 90388 : void ControlVRFIUCoil(EnergyPlusData &state,
17288 : int const CoilIndex, // index to VRFTU coil
17289 : Real64 const QCoil, // coil load
17290 : Real64 const Tin, // inlet air temperature
17291 : Real64 const Win, // inlet air humidity ratio
17292 : Real64 const TeTc, // evaporating or condensing temperature
17293 : Real64 const OAMassFlow, // mass flow rate of outdoor air
17294 : Real64 &FanSpdRatio, // fan speed ratio: actual flow rate / rated flow rate
17295 : Real64 &Wout, // outlet air humidity ratio
17296 : Real64 &Tout, // outlet air temperature
17297 : Real64 &Hout, // outlet air enthalpy
17298 : Real64 &SHact, // actual SH
17299 : Real64 &SCact // actual SC
17300 : )
17301 : {
17302 : // SUBROUTINE INFORMATION:
17303 : // AUTHOR Xiufeng Pang, LBNL
17304 : // DATE WRITTEN Feb 2013
17305 : // MODIFIED Nov 2015, RP Zhang, LBNL
17306 : //
17307 : // PURPOSE OF THIS SUBROUTINE:
17308 : // Analyze the VRF Indoor Unit operations given coil loads.
17309 : // Calculated parameters include: (1) Fan Speed Ratio (2) SH/SC, (3) Coil Outlet conditions
17310 : //
17311 : // METHODOLOGY EMPLOYED:
17312 : // A new physics based VRF model applicable for Fluid Temperature Control.
17313 : //
17314 : // USE STATEMENTS:
17315 : using Psychrometrics::PsyHFnTdbW;
17316 :
17317 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
17318 90388 : int MaxIter(500); // Max iteration numbers (-)
17319 : int SolFla; // Solving flag for SolveRoot (-)
17320 90388 : int constexpr FlagCoolMode(0); // Flag for cooling mode
17321 90388 : int constexpr FlagHeatMode(1); // Flag for heating mode
17322 : Real64 BF; // Bypass factor (-)
17323 : Real64 C1Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17324 : Real64 C2Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17325 : Real64 C3Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17326 : Real64 C1Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17327 : Real64 C2Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17328 : Real64 C3Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17329 : Real64 CoilOnOffRatio; // coil on/off ratio: time coil is on divided by total time
17330 : Real64 deltaT; // Difference between evaporating/condensing temperature and coil surface temperature (C)
17331 : Real64 FanSpdRatioMin; // Min fan speed ratio, below which the cycling will be activated (-)
17332 : Real64 FanSpdRatioMax; // Max fan speed ratio (-)
17333 : Real64 Garate; // Nominal air mass flow rate (m3/s)
17334 : Real64 MaxSH; // Max super heating degrees (C)
17335 : Real64 MaxSC; // Max subcooling degrees (C)
17336 : Real64 QinSenMin1; // Coil capacity at minimum fan speed, corresponding to real SH (W)
17337 : Real64 QinSenMin2; // Coil capacity at minimum fan speed, corresponding to corresponds maximum SH (W)
17338 : Real64 QinSenPerFlowRate; // Coil capacity per air mass flow rate(W-s/kg)
17339 : Real64 QCoilSenCoolingLoad; // Coil sensible cooling load (W)
17340 : Real64 QCoilSenHeatingLoad; // Coil sensible heating load (W)
17341 : Real64 Ratio1; // Fan speed ratio (-)
17342 : Real64 RHsat; // Relative humidity of the air at saturated condition(-)
17343 : Real64 SH; // Super heating degrees (C)
17344 : Real64 SC; // Subcooling degrees (C)
17345 : Real64 Ts_1; // Air temperature at the coil surface, corresponding to SH (C)
17346 : Real64 Ts_2; // Air temperature at the coil surface, corresponding to MaxSH (C)
17347 : Real64 To_1; // Air temperature at the coil outlet, corresponding to SH (C)
17348 : Real64 To_2; // Air temperature at the coil outlet, corresponding to MaxSH (C)
17349 : Real64 Ts; // Air temperature at the coil surface (C)
17350 : Real64 Ws; // Air humidity ratio at the coil surface (kg/kg)
17351 :
17352 90388 : RHsat = 0.98; // Saturated RH
17353 90388 : MaxSH = 15;
17354 90388 : MaxSC = 20;
17355 90388 : Garate = state.dataDXCoils->DXCoil(CoilIndex).RatedAirMassFlowRate(1);
17356 90388 : FanSpdRatioMin = min(OAMassFlow / Garate, 1.0); // ensure that coil flow rate is higher than OA flow rate
17357 :
17358 90388 : if (QCoil == 0) {
17359 : // No Heating or Cooling
17360 0 : FanSpdRatio = OAMassFlow / Garate;
17361 0 : CoilOnOffRatio = 0.0;
17362 :
17363 0 : SHact = 999.0;
17364 0 : SCact = 999.0;
17365 0 : Tout = Tin;
17366 0 : Hout = PsyHFnTdbW(Tin, Win);
17367 0 : Wout = Win;
17368 :
17369 90388 : } else if (QCoil < 0) {
17370 : // Cooling Mode
17371 :
17372 : // Obtain coil cooling loads
17373 47821 : QCoilSenCoolingLoad = -QCoil;
17374 :
17375 : // Coefficients describing coil performance
17376 47821 : SH = state.dataDXCoils->DXCoil(CoilIndex).SH;
17377 47821 : C1Tevap = state.dataDXCoils->DXCoil(CoilIndex).C1Te;
17378 47821 : C2Tevap = state.dataDXCoils->DXCoil(CoilIndex).C2Te;
17379 47821 : C3Tevap = state.dataDXCoils->DXCoil(CoilIndex).C3Te;
17380 47821 : BF = state.dataDXCoils->DXCoil(CoilIndex).RateBFVRFIUEvap;
17381 :
17382 : // Coil sensible heat transfer_minimum value
17383 47821 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilIndex, Tin, TeTc, SH, BF, QinSenPerFlowRate, Ts_1);
17384 47821 : To_1 = Tin - QinSenPerFlowRate / 1005;
17385 47821 : QinSenMin1 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds real SH
17386 :
17387 47821 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilIndex, Tin, TeTc, MaxSH, BF, QinSenPerFlowRate, Ts_2);
17388 47821 : To_2 = Tin - QinSenPerFlowRate / 1005;
17389 47821 : QinSenMin2 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds maximum SH
17390 :
17391 47821 : if (QCoilSenCoolingLoad > QinSenMin1) {
17392 : // Increase fan speed to meet room sensible load; SH is not updated
17393 45830 : FanSpdRatioMax = 1.0;
17394 130189 : auto f = [QCoilSenCoolingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
17395 130189 : return FanSpdResidualCool(FanSpdRto, QCoilSenCoolingLoad, Ts_1, Tin, Garate, BF);
17396 45830 : };
17397 45830 : General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, Ratio1, f, FanSpdRatioMin, FanSpdRatioMax);
17398 45830 : if (SolFla < 0) Ratio1 = FanSpdRatioMax; // over capacity
17399 45830 : FanSpdRatio = Ratio1;
17400 45830 : CoilOnOffRatio = 1.0;
17401 :
17402 45830 : Tout = To_1; // Since SH is not updated
17403 45830 : Ws = PsyWFnTdbRhPb(state, Ts_1, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
17404 45830 : if (Ws < Win) {
17405 45829 : Wout = Win - (Win - Ws) * (1 - BF);
17406 : } else {
17407 1 : Wout = Win;
17408 : }
17409 45830 : Hout = PsyHFnTdbW(Tout, Wout);
17410 45830 : SCact = 999.0;
17411 45830 : SHact = SH;
17412 :
17413 : } else {
17414 : // Low load modification algorithm
17415 : // Need to increase SH to further reduce coil capacity
17416 : // May further implement coil cycling control if SC modification is not enough
17417 :
17418 1991 : FanSpdRatio = FanSpdRatioMin;
17419 :
17420 1991 : CoilOnOffRatio = 1.0;
17421 :
17422 1991 : Tout = Tin - QCoilSenCoolingLoad / 1005.0 / FanSpdRatioMin / Garate;
17423 1991 : Ts = Tin - (Tin - Tout) / (1 - BF);
17424 1991 : deltaT = Ts - TeTc;
17425 :
17426 : // Update SH
17427 1991 : if (C3Tevap <= 0.0) {
17428 1991 : if (C2Tevap > 0.0) {
17429 1991 : SHact = (deltaT - C1Tevap) / C2Tevap;
17430 : } else {
17431 0 : SHact = 998.0;
17432 : }
17433 : } else {
17434 0 : SHact = (-C2Tevap + sqrt(pow_2(C2Tevap) - 4 * C3Tevap * (C1Tevap - deltaT))) / 2 / C3Tevap;
17435 : }
17436 :
17437 1991 : Ws = PsyWFnTdbRhPb(state, Ts, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
17438 1991 : if (Ws < Win) {
17439 1776 : Wout = Win - (Win - Ws) * (1 - BF);
17440 : } else {
17441 215 : Wout = Win;
17442 : }
17443 :
17444 1991 : if (SHact > MaxSH) {
17445 : // Further implement On/Off Control
17446 791 : SHact = MaxSH;
17447 791 : CoilOnOffRatio = QCoilSenCoolingLoad / QinSenMin2;
17448 :
17449 791 : Ts = Ts_2;
17450 791 : Ws = PsyWFnTdbRhPb(state, Ts, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
17451 791 : if (Ws < Win) {
17452 791 : Wout = Win - (Win - Ws) * (1 - BF);
17453 : } else {
17454 0 : Wout = Win;
17455 : }
17456 :
17457 : // outlet air temperature and humidity ratio is time-weighted
17458 791 : Tout = CoilOnOffRatio * To_2 + (1 - CoilOnOffRatio) * Tin;
17459 791 : Wout = CoilOnOffRatio * Wout + (1 - CoilOnOffRatio) * Win;
17460 : }
17461 :
17462 1991 : Hout = PsyHFnTdbW(Tout, Wout);
17463 1991 : SCact = 999.0;
17464 : }
17465 :
17466 42567 : } else if (QCoil > 0) {
17467 : // Heating Mode
17468 :
17469 : // Obtain zonal heating loads
17470 42567 : QCoilSenHeatingLoad = QCoil;
17471 :
17472 : // Coefficients describing coil performance
17473 42567 : SC = state.dataDXCoils->DXCoil(CoilIndex).SC;
17474 42567 : C1Tcond = state.dataDXCoils->DXCoil(CoilIndex).C1Tc;
17475 42567 : C2Tcond = state.dataDXCoils->DXCoil(CoilIndex).C2Tc;
17476 42567 : C3Tcond = state.dataDXCoils->DXCoil(CoilIndex).C3Tc;
17477 42567 : BF = state.dataDXCoils->DXCoil(CoilIndex).RateBFVRFIUCond;
17478 :
17479 : // Coil sensible heat transfer_minimum value
17480 42567 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilIndex, Tin, TeTc, SC, BF, QinSenPerFlowRate, Ts_1);
17481 42567 : To_1 = QinSenPerFlowRate / 1005 + Tin;
17482 42567 : QinSenMin1 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds real SH
17483 :
17484 42567 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilIndex, Tin, TeTc, MaxSC, BF, QinSenPerFlowRate, Ts_2);
17485 42567 : To_2 = QinSenPerFlowRate / 1005 + Tin;
17486 42567 : QinSenMin2 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds maximum SH
17487 :
17488 42567 : if (QCoilSenHeatingLoad > QinSenMin1) {
17489 : // Modulate fan speed to meet room sensible load; SC is not updated
17490 42271 : FanSpdRatioMax = 1.0;
17491 126812 : auto f = [QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
17492 126812 : return FanSpdResidualHeat(FanSpdRto, QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF);
17493 42271 : };
17494 42271 : General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, Ratio1, f, FanSpdRatioMin, FanSpdRatioMax);
17495 : // this will likely cause problems eventually, -1 and -2 mean different things
17496 42271 : if (SolFla < 0) Ratio1 = FanSpdRatioMax; // over capacity
17497 42271 : FanSpdRatio = Ratio1;
17498 42271 : CoilOnOffRatio = 1.0;
17499 :
17500 42271 : Tout = Tin + (Ts_1 - Tin) * (1 - BF);
17501 42271 : Wout = Win;
17502 42271 : Hout = PsyHFnTdbW(Tout, Wout);
17503 42271 : SHact = 999.0;
17504 42271 : SCact = SC;
17505 :
17506 : } else {
17507 : // Low load modification algorithm
17508 : // Need to increase SC to further reduce coil heating capacity
17509 : // May further implement coil cycling control if SC modification is not enough
17510 :
17511 296 : FanSpdRatio = FanSpdRatioMin;
17512 296 : CoilOnOffRatio = 1.0;
17513 :
17514 296 : Tout = Tin + QCoilSenHeatingLoad / 1005.0 / FanSpdRatio / Garate;
17515 296 : Ts = Tin + (Tout - Tin) / (1 - BF);
17516 296 : deltaT = TeTc - Ts;
17517 :
17518 : // Update SC
17519 296 : if (C3Tcond <= 0.0) {
17520 0 : if (C2Tcond > 0.0) {
17521 0 : SCact = (deltaT - C1Tcond) / C2Tcond;
17522 : } else {
17523 0 : SCact = 998.0;
17524 : }
17525 : } else {
17526 296 : SCact = (-C2Tcond + sqrt(pow_2(C2Tcond) - 4 * C3Tcond * (C1Tcond - deltaT))) / 2 / C3Tcond;
17527 : }
17528 :
17529 296 : if (SCact > MaxSC) {
17530 : // Implement On/Off Control
17531 77 : SCact = MaxSC;
17532 77 : CoilOnOffRatio = QCoilSenHeatingLoad / QinSenMin2;
17533 : // outlet air temperature is time-weighted
17534 77 : Tout = CoilOnOffRatio * To_2 + (1 - CoilOnOffRatio) * Tin;
17535 : }
17536 296 : Wout = Win;
17537 296 : Hout = PsyHFnTdbW(Tout, Wout);
17538 296 : SHact = 999.0;
17539 : }
17540 : }
17541 90388 : }
17542 :
17543 180788 : void CalcVRFCoilSenCap(EnergyPlusData &state,
17544 : int const OperationMode, // mode 0 for cooling, 1 for heating
17545 : int const CoilNum, // index to VRFTU cooling or heating coil
17546 : Real64 const Tinlet, // dry bulb temperature of air entering the coil
17547 : Real64 const TeTc, // evaporating or condensing temperature
17548 : Real64 const SHSC, // SH at cooling /SC at heating
17549 : Real64 const BF, // Bypass factor
17550 : Real64 &Q_sen, // VRF coil sensible capacity per air mass flow rate
17551 : Real64 &T_coil_surf // Air temperature at coil surface
17552 : )
17553 : {
17554 : // SUBROUTINE INFORMATION:
17555 : // AUTHOR Rongpeng Zhang, LBNL
17556 : // DATE WRITTEN Jul 2015
17557 : //
17558 : // PURPOSE OF THIS SUBROUTINE:
17559 : // Calculate the VRF coil sensible capacity per air mass flow rate, given:
17560 : // (1) refrigerant temperature (Te or Tc), (2) SH or SC, and (3) inlet air temperature.
17561 : //
17562 : // METHODOLOGY EMPLOYED:
17563 : // A new physics based VRF model appliable for Fluid Temperature Control.
17564 : //
17565 :
17566 180788 : int constexpr FlagCoolMode(0); // Flag for cooling mode
17567 180788 : int constexpr FlagHeatMode(1); // Flag for heating mode
17568 : Real64 C1Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17569 : Real64 C2Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17570 : Real64 C3Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17571 : Real64 C1Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17572 : Real64 C2Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17573 : Real64 C3Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17574 : Real64 deltaT; // Difference between Te/Tc and coil surface temperature (C)
17575 : Real64 SH; // Super heating at cooling mode(C)
17576 : Real64 SC; // Subcooling at heating mode (C)
17577 : Real64 T_coil_in; // Air temperature at coil inlet (C)
17578 : Real64 T_coil_out; // Air temperature at coil outlet (C)
17579 :
17580 180788 : if (OperationMode == FlagCoolMode) {
17581 : // Cooling: OperationMode 0
17582 :
17583 95654 : C1Tevap = state.dataDXCoils->DXCoil(CoilNum).C1Te;
17584 95654 : C2Tevap = state.dataDXCoils->DXCoil(CoilNum).C2Te;
17585 95654 : C3Tevap = state.dataDXCoils->DXCoil(CoilNum).C3Te;
17586 95654 : SH = SHSC;
17587 95654 : T_coil_in = Tinlet;
17588 :
17589 : // Coil surface temperature
17590 95654 : deltaT = C3Tevap * SH * SH + C2Tevap * SH + C1Tevap;
17591 95654 : T_coil_surf = TeTc + deltaT;
17592 :
17593 : // Outlet air temperature
17594 95654 : T_coil_out = T_coil_in - (T_coil_in - T_coil_surf) * (1 - BF);
17595 :
17596 : // Coil sensilbe heat transfer per mass flow rate
17597 95654 : Q_sen = max(1005 * (T_coil_in - T_coil_out), 0.0);
17598 :
17599 85134 : } else if (OperationMode == FlagHeatMode) {
17600 : // Heating: OperationMode 1
17601 :
17602 85134 : C1Tcond = state.dataDXCoils->DXCoil(CoilNum).C1Tc;
17603 85134 : C2Tcond = state.dataDXCoils->DXCoil(CoilNum).C2Tc;
17604 85134 : C3Tcond = state.dataDXCoils->DXCoil(CoilNum).C3Tc;
17605 85134 : SC = SHSC;
17606 85134 : T_coil_in = Tinlet;
17607 :
17608 : // Coil surface temperature
17609 85134 : deltaT = C3Tcond * SC * SC + C2Tcond * SC + C1Tcond;
17610 85134 : T_coil_surf = TeTc - deltaT;
17611 :
17612 : // Coil outlet air temperature
17613 85134 : T_coil_out = T_coil_in + (T_coil_surf - T_coil_in) * (1 - BF);
17614 :
17615 : // Coil sensilbe heat transfer_minimum value
17616 85134 : Q_sen = max(1005 * (T_coil_out - T_coil_in), 0.0);
17617 : }
17618 180788 : }
17619 :
17620 6 : void CalcVRFCoilCapModFac(EnergyPlusData &state,
17621 : int const OperationMode, // mode 0 for cooling, 1 for heating
17622 : ObjexxFCL::Optional<int const> CoilIndex, // index to VRFTU cooling or heating coil
17623 : ObjexxFCL::Optional<std::string> CoilName, // name of VRFTU cooling or heating coil
17624 : Real64 const Tinlet, // dry bulb temperature of air entering the coil
17625 : ObjexxFCL::Optional<Real64 const> TeTc, // evaporating or condensing temperature
17626 : ObjexxFCL::Optional<Real64 const> SHSC, // SH at cooling /SC at heating
17627 : ObjexxFCL::Optional<Real64 const> BF, // Bypass factor
17628 : Real64 &CapModFac // Coil capacity modification factor
17629 : )
17630 : {
17631 : // SUBROUTINE INFORMATION:
17632 : // AUTHOR Rongpeng Zhang, LBNL
17633 : // DATE WRITTEN Jul 2015
17634 : //
17635 : // PURPOSE OF THIS SUBROUTINE:
17636 : // Calculate the VRF coil capacity modification factor, which is the ratio of
17637 : // the capacity at real conditions and that at rated conditions.
17638 : // This is used for the coil sizing subroutine.
17639 : //
17640 : // METHODOLOGY EMPLOYED:
17641 : // A new physics based VRF model applicable for Fluid Temperature Control.
17642 : //
17643 :
17644 6 : bool ErrorsFound(false); // Flag for errors
17645 6 : int constexpr FlagCoolMode(0); // Flag for cooling mode
17646 6 : int constexpr FlagHeatMode(1); // Flag for heating mode
17647 6 : Real64 constexpr SH_rate(3); // Super heating at cooling mode, default 3(C)
17648 6 : Real64 constexpr SC_rate(5); // Subcooling at heating mode, default 5 (C)
17649 6 : Real64 constexpr Te_rate(6); // Evaporating temperature at cooling mode, default 6 (C)
17650 6 : Real64 constexpr Tc_rate(44); // Condensing temperature at heating mode, default 44 (C)
17651 : int CoilNum; // index to VRFTU cooling or heating coil
17652 : Real64 BF_real; // Bypass factor (-)
17653 : Real64 BFC_rate; // Bypass factor at cooling mode (-)
17654 : Real64 BFH_rate; // Bypass factor at heating mode (-)
17655 : Real64 SHSC_real; // Super heating or Subcooling (C)
17656 : Real64 TeTc_real; // Evaporating temperature or condensing temperature (C)
17657 : Real64 Ts; // Air temperature at coil surface (C)
17658 : Real64 Q_real; // Coil capacity at given condition (W)
17659 : Real64 Q_rate; // Coil capacity at rated condition (W)
17660 :
17661 6 : if (present(CoilIndex)) {
17662 0 : CoilNum = CoilIndex;
17663 : } else {
17664 6 : GetDXCoilIndex(state, CoilName, CoilNum, ErrorsFound, "", true);
17665 : }
17666 :
17667 6 : BFC_rate = state.dataDXCoils->DXCoil(CoilNum).RateBFVRFIUEvap;
17668 6 : BFH_rate = state.dataDXCoils->DXCoil(CoilNum).RateBFVRFIUCond;
17669 :
17670 6 : if (OperationMode == FlagCoolMode) {
17671 : // Cooling: OperationMode 0
17672 :
17673 6 : if (present(BF)) {
17674 0 : BF_real = BF;
17675 : } else {
17676 6 : BF_real = BFC_rate;
17677 : }
17678 6 : if (present(TeTc)) {
17679 0 : TeTc_real = TeTc;
17680 : } else {
17681 6 : TeTc_real = Te_rate;
17682 : }
17683 6 : if (present(SHSC)) {
17684 0 : SHSC_real = SHSC;
17685 : } else {
17686 6 : SHSC_real = SH_rate;
17687 : }
17688 :
17689 : // Coil capacity at rated conditions
17690 6 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilNum, 26, Te_rate, SH_rate, BFC_rate, Q_rate, Ts);
17691 :
17692 : // Coil capacity at given conditions
17693 6 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilNum, Tinlet, TeTc_real, SHSC_real, BF_real, Q_real, Ts);
17694 :
17695 6 : if (Q_rate > 0) {
17696 6 : CapModFac = Q_real / Q_rate;
17697 : } else {
17698 0 : CapModFac = 1.0;
17699 : }
17700 :
17701 0 : } else if (OperationMode == FlagHeatMode) {
17702 : // Heating: OperationMode 1
17703 :
17704 0 : if (present(BF)) {
17705 0 : BF_real = BF;
17706 : } else {
17707 0 : BF_real = BFH_rate;
17708 : }
17709 0 : if (present(TeTc)) {
17710 0 : TeTc_real = TeTc;
17711 : } else {
17712 0 : TeTc_real = Tc_rate;
17713 : }
17714 0 : if (present(SHSC)) {
17715 0 : SHSC_real = SHSC;
17716 : } else {
17717 0 : SHSC_real = SC_rate;
17718 : }
17719 :
17720 : // Coil capacity at rated conditions
17721 0 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilNum, 20, Tc_rate, SC_rate, BFH_rate, Q_rate, Ts);
17722 :
17723 : // Coil capacity at given conditions
17724 0 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilNum, Tinlet, TeTc_real, SHSC_real, BF_real, Q_real, Ts);
17725 :
17726 0 : if (Q_rate > 0) {
17727 0 : CapModFac = Q_real / Q_rate;
17728 : } else {
17729 0 : CapModFac = 1.0;
17730 : }
17731 : }
17732 6 : }
17733 :
17734 130190 : Real64 FanSpdResidualCool(
17735 : Real64 const FanSpdRto, Real64 const QCoilSenCoolingLoad, Real64 const Ts_1, Real64 const Tin, Real64 const Garate, Real64 const BF)
17736 : {
17737 : // FUNCTION INFORMATION:
17738 : // AUTHOR Xiufeng Pang (XP)
17739 : // DATE WRITTEN Mar 2013
17740 : // MODIFIED Nov 2015, RP Zhang, LBNL
17741 : //
17742 : // PURPOSE OF THIS FUNCTION:
17743 : // Calculates residual function (desired zone cooling load - actual coil cooling capacity)
17744 : // This is used to modify the fan speed to adjust the coil cooling capacity to match
17745 : // the zone cooling load.
17746 : //
17747 130190 : Real64 ZnSenLoad = QCoilSenCoolingLoad;
17748 : // +-100 W minimum zone load?
17749 130190 : if (std::abs(ZnSenLoad) < 100.0) ZnSenLoad = sign(100.0, ZnSenLoad);
17750 130190 : Real64 Tout = Tin - (Tin - Ts_1) * (1 - BF);
17751 130190 : Real64 TotCap = FanSpdRto * Garate * 1005.0 * (Tin - Tout);
17752 130190 : return (TotCap - ZnSenLoad) / ZnSenLoad;
17753 : }
17754 :
17755 126813 : Real64 FanSpdResidualHeat(Real64 FanSpdRto, Real64 QCoilSenHeatingLoad, Real64 Ts_1, Real64 Tin, Real64 Garate, Real64 BF)
17756 : {
17757 :
17758 : // FUNCTION INFORMATION:
17759 : // AUTHOR Xiufeng Pang (XP)
17760 : // DATE WRITTEN Mar 2013
17761 : // MODIFIED Nov 2015, RP Zhang, LBNL
17762 : //
17763 : // PURPOSE OF THIS FUNCTION:
17764 : // Calculates residual function (desired zone heating load - actual heating coil capacity)
17765 : // This is used to modify the fan speed to adjust the coil heating capacity to match
17766 : // the zone heating load.
17767 : //
17768 :
17769 126813 : Real64 ZnSenLoad = QCoilSenHeatingLoad;
17770 : // +-100 W minimum zone load?
17771 126813 : if (std::abs(ZnSenLoad) < 100.0) ZnSenLoad = sign(100.0, ZnSenLoad);
17772 126813 : Real64 Tout = Tin + (Ts_1 - Tin) * (1 - BF);
17773 126813 : Real64 TotCap = FanSpdRto * Garate * 1005.0 * (Tout - Tin);
17774 126813 : return (TotCap - ZnSenLoad) / ZnSenLoad;
17775 : }
17776 :
17777 4 : void SetMSHPDXCoilHeatRecoveryFlag(EnergyPlusData &state, int const DXCoilNum)
17778 : {
17779 :
17780 : // SUBROUTINE INFORMATION:
17781 : // AUTHOR L. Gu
17782 : // DATE WRITTEN Sep. 2015
17783 :
17784 : // PURPOSE OF THIS SUBROUTINE:
17785 : // Set the heat recovery flag true when the parent object requests heat recovery.
17786 :
17787 4 : if (state.dataDXCoils->DXCoil(DXCoilNum).FuelType != Constant::eFuel::Electricity) {
17788 2 : state.dataDXCoils->DXCoil(DXCoilNum).MSHPHeatRecActive = true;
17789 : }
17790 4 : }
17791 :
17792 4 : void SetDXCoilAirLoopNumber(EnergyPlusData &state, std::string const &CoilName, int const AirLoopNum)
17793 : {
17794 : // SUBROUTINE INFORMATION:
17795 : // AUTHOR L. Gu
17796 : // DATE WRITTEN March, 2018
17797 :
17798 : // PURPOSE OF THIS SUBROUTINE:
17799 : // Set AirLoopNum for AFN model with multiple AirLoops
17800 :
17801 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
17802 : int WhichCoil;
17803 :
17804 4 : if (state.dataDXCoils->GetCoilsInputFlag) {
17805 1 : GetDXCoils(state);
17806 1 : state.dataDXCoils->GetCoilsInputFlag = false;
17807 : }
17808 :
17809 4 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
17810 4 : if (WhichCoil != 0) {
17811 2 : state.dataDXCoils->DXCoil(WhichCoil).AirLoopNum = AirLoopNum;
17812 : } else {
17813 2 : ShowSevereError(state, format("SetDXCoilAirLoopNumber: Could not find Coil \"Name=\"{}\"", CoilName));
17814 : }
17815 4 : } // must match coil names for the coil type
17816 :
17817 1 : void DisableLatentDegradation(EnergyPlusData &state, int const DXCoilNum)
17818 : {
17819 : // SUBROUTINE INFORMATION:
17820 : // AUTHOR L. Gu
17821 : // DATE WRITTEN JUne, 2019
17822 :
17823 : // PURPOSE OF THIS SUBROUTINE:
17824 : // Disable latent degradation when direct solution is used.
17825 :
17826 1 : state.dataDXCoils->DXCoil(DXCoilNum).Twet_Rated(1) = 0.0;
17827 1 : }
17828 :
17829 : } // namespace EnergyPlus::DXCoils
|