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 85 : 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 85 : 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 38583 : CompCycRatio = CompCyclingRatio;
198 : } else {
199 482921 : 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 :
343 250 : } break;
344 199 : case HVAC::CoilDX_MultiSpeedHeating: {
345 199 : if (present(SpeedNum)) {
346 199 : CalcMultiSpeedDXCoilHeating(state,
347 : DXCoilNum,
348 : SpeedRatio,
349 : CycRatio,
350 : SpeedNum,
351 : fanOp,
352 : SingleModeOper); // Autodesk:OPTIONAL fanOp used without PRESENT check
353 : }
354 :
355 199 : } break;
356 0 : default: {
357 0 : ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
358 0 : ShowContinueError(state, format("Invalid DX Coil Type={}", state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType));
359 0 : ShowFatalError(state, "Preceding condition causes termination.");
360 0 : } break;
361 : }
362 :
363 : // Update the unit outlet nodes
364 17558 : UpdateDXCoil(state, DXCoilNum);
365 :
366 : // Report the result of the simulation
367 17558 : ReportDXCoil(state, DXCoilNum);
368 17558 : }
369 :
370 0 : void SimDXCoilMultiMode(EnergyPlusData &state,
371 : std::string_view CompName, // name of the fan coil unit
372 : [[maybe_unused]] HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off !unused1208
373 : bool const FirstHVACIteration, // true if first hvac iteration
374 : Real64 const PartLoadRatio, // part load ratio
375 : HVAC::CoilMode const DehumidMode, // dehumidification mode (0=normal, 1=enhanced)
376 : int &CompIndex,
377 : HVAC::FanOp const fanOp // allows parent object to control fan mode
378 : )
379 : {
380 :
381 : // SUBROUTINE INFORMATION:
382 : // AUTHOR M. J. Witte (based on SimDXCoilMultiSpeed by Fred Buhl)
383 : // DATE WRITTEN February 2005
384 : // MODIFIED April 2010, Chandan sharma, added basin heater
385 :
386 : // PURPOSE OF THIS SUBROUTINE:
387 : // Manages the simulation of a DX coil with multiple performance modes, such as
388 : // multiple stages, or sub-cool reheat for humidity control.
389 :
390 : // Using/Aliasing
391 :
392 : // SUBROUTINE PARAMETER DEFINITIONS:
393 : static constexpr std::string_view RoutineName("SimDXCoilMultiMode");
394 :
395 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
396 : int DXCoilNum; // index of coil being simulated
397 : int PerfMode; // Performance mode for MultiMode DX coil; Always 1 for other coil types
398 : // 1-2=normal mode: 1=stage 1 only, 2=stage 1&2
399 : // 3-4=enhanced dehumidification mode: 3=stage 1 only, 4=stage 1&2
400 : Real64 AirMassFlow; // Dry air mass flow rate through coil [kg/s]
401 :
402 : Real64 S1OutletAirTemp; // Stage 1 Outlet air dry bulb temp [C]
403 : Real64 S1OutletAirHumRat; // Stage 1 Outlet air humidity ratio [kgWater/kgDryAir]
404 : Real64 S1OutletAirEnthalpy; // Stage 1 Outlet air enthalpy
405 : Real64 S1PLR; // Stage 1 Ratio of actual sensible cooling load to
406 : // steady-state sensible cooling capacity
407 : Real64 S1TotalCoolingEnergyRate; // Stage 1 Total cooling rate [W]
408 : Real64 S1SensCoolingEnergyRate; // Stage 1 Sensible cooling rate [W]
409 : Real64 S1LatCoolingEnergyRate; // Stage 1 Latent cooling rate [W]
410 : Real64 S1ElecCoolingPower; // Stage 1 Electric power input [W]
411 0 : Real64 S1RuntimeFraction(0.0); // Stage 1 Run time fraction (overlaps with stage1&2 run time)
412 : Real64 S1EvapCondPumpElecPower; // Stage 1 Evaporative condenser pump electric power input [W]
413 : Real64 S1EvapWaterConsumpRate; // Stage 1 Evap condenser water consumption rate [m3/s]
414 : Real64 S1CrankcaseHeaterPower; // Stage 1 Report variable for average crankcase heater power [W]
415 : Real64 S1FFullLoadOutAirTemp; // Stage 1 Full load outlet temperature [C]
416 : Real64 S1FullLoadOutAirHumRat; // Stage 1 Full load outlet humidity ratio [kgWater/kgDryAir]
417 :
418 : Real64 S12OutletAirTemp; // Stage 1&2 Outlet air dry bulb temp [C]
419 : Real64 S12OutletAirHumRat; // Stage 1&2 Outlet air humidity ratio [kgWater/kgDryAir]
420 : Real64 S12OutletAirEnthalpy; // Stage 1&2 Outlet air enthalpy
421 : // ! steady-state sensible cooling capacity
422 : Real64 S12TotalCoolingEnergyRate; // Stage 1&2 Total cooling rate [W]
423 : Real64 S12SensCoolingEnergyRate; // Stage 1&2 Sensible cooling rate [W]
424 : Real64 S12LatCoolingEnergyRate; // Stage 1&2 Latent cooling rate [W]
425 : Real64 S12ElecCoolingPower; // Stage 1&2 Electric power input [W]
426 : Real64 S12ElecCoolFullLoadPower; // Stage 1&2 Electric power input at full load (PLR=1) [W]
427 0 : Real64 S12RuntimeFraction(0.0); // Stage 1&2 Run time fraction (overlaps with stage1 run time)
428 : Real64 S12EvapCondPumpElecPower; // Stage 1&2 Evaporative condenser pump electric power input [W]
429 : Real64 S12EvapWaterConsumpRate; // Stage 1&2 Evap condenser water consumption rate [m3/s]
430 : Real64 S12CrankcaseHeaterPower; // Stage 1&2 Report variable for average crankcase heater power [W]
431 : Real64 S2PLR; // Stage 2 Ratio of actual sensible cooling load to
432 : // steady-state sensible cooling capacity
433 : Real64 TSat; // calculation to avoid calling psych routines twice
434 : Real64 NodePress; // Pressure at condenser inlet node (Pa)
435 :
436 : // First time SimDXCoil is called, get the input for all the DX coils (condensing units)
437 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
438 0 : GetDXCoils(state);
439 0 : state.dataDXCoils->GetCoilsInputFlag = false; // Set GetInputFlag false so you don't get coil inputs again
440 : }
441 :
442 : // find correct DX Coil
443 0 : if (CompIndex == 0) {
444 0 : DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
445 0 : if (DXCoilNum == 0) {
446 0 : ShowFatalError(state, format("DX Coil not found={}", CompName));
447 : }
448 0 : CompIndex = DXCoilNum;
449 : } else {
450 0 : DXCoilNum = CompIndex;
451 0 : if (DXCoilNum > state.dataDXCoils->NumDXCoils || DXCoilNum < 1) {
452 0 : ShowFatalError(state,
453 0 : format("SimDXCoilMultiMode: Invalid CompIndex passed={}, Number of DX Coils={}, Coil name={}",
454 : DXCoilNum,
455 0 : state.dataDXCoils->NumDXCoils,
456 : CompName));
457 : }
458 0 : if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
459 0 : if ((CompName != "") && (CompName != state.dataDXCoils->DXCoil(DXCoilNum).Name)) {
460 0 : ShowFatalError(state,
461 0 : format("SimDXCoilMultiMode: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
462 : DXCoilNum,
463 : CompName,
464 0 : state.dataDXCoils->DXCoil(DXCoilNum).Name));
465 : }
466 0 : state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
467 : }
468 : }
469 :
470 : // Initialize the DX coil unit
471 0 : InitDXCoil(state, DXCoilNum);
472 :
473 0 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
474 : // Select the correct unit type
475 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
476 : // Initialize local variables
477 0 : S1RuntimeFraction = 0.0;
478 0 : S1OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
479 0 : S1OutletAirHumRat = thisDXCoil.InletAirHumRat;
480 0 : S1OutletAirTemp = thisDXCoil.InletAirTemp;
481 0 : S1ElecCoolingPower = 0.0;
482 0 : S1TotalCoolingEnergyRate = 0.0;
483 0 : S1SensCoolingEnergyRate = 0.0;
484 0 : S1LatCoolingEnergyRate = 0.0;
485 0 : S1CrankcaseHeaterPower = 0.0;
486 0 : S1EvapWaterConsumpRate = 0.0;
487 0 : S1EvapCondPumpElecPower = 0.0;
488 :
489 0 : S12RuntimeFraction = 0.0;
490 0 : S12OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
491 0 : S12OutletAirHumRat = thisDXCoil.InletAirHumRat;
492 0 : S12OutletAirTemp = thisDXCoil.InletAirTemp;
493 0 : S12ElecCoolingPower = 0.0;
494 0 : S12TotalCoolingEnergyRate = 0.0;
495 0 : S12SensCoolingEnergyRate = 0.0;
496 0 : S12LatCoolingEnergyRate = 0.0;
497 0 : S12CrankcaseHeaterPower = 0.0;
498 0 : S12EvapWaterConsumpRate = 0.0;
499 0 : S12EvapCondPumpElecPower = 0.0;
500 :
501 0 : thisDXCoil.DehumidificationMode = DehumidMode;
502 0 : if ((int)DehumidMode > thisDXCoil.NumDehumidModes) {
503 0 : ShowFatalError(state,
504 0 : format("{} \"{}\" - Requested enhanced dehumidification mode not available.", thisDXCoil.DXCoilType, thisDXCoil.Name));
505 : }
506 :
507 : // If a single-stage coil OR If part load is zero,
508 : // run stage 1 at zero part load to set leaving conditions
509 0 : if ((thisDXCoil.NumCapacityStages == 1) || (PartLoadRatio <= 0.0)) {
510 : // Run stage 1 at its part load
511 0 : PerfMode = (int)DehumidMode * 2 + 1; // This. This is not good. Don't do math on enums.
512 0 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, PerfMode);
513 0 : S1PLR = PartLoadRatio;
514 0 : S2PLR = 0.0;
515 : } else {
516 : // If a two-stage coil
517 : // Run stage 1 at full load
518 0 : PerfMode = (int)DehumidMode * 2 + 1;
519 0 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, 1.0, fanOp, PerfMode);
520 0 : S1SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
521 0 : if (S1SensCoolingEnergyRate > 0.0) {
522 0 : S1PLR = PartLoadRatio;
523 : } else {
524 0 : S1PLR = 0.0;
525 : }
526 : // Run stage 1+2 at full load
527 0 : if (thisDXCoil.NumCapacityStages >= 2) {
528 0 : PerfMode = (int)DehumidMode * 2 + 2;
529 0 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, 1.0, fanOp, PerfMode);
530 0 : S12SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
531 0 : S12ElecCoolFullLoadPower = thisDXCoil.ElecCoolingPower;
532 : }
533 :
534 : // Determine run-time fractions for each stage based on sensible capacities
535 : // Relationships:
536 : // Stage 1 PLR1= Load/Cap1
537 : // Stage1+2 PLR12= Load/Cap12
538 : // Stage 2 PLR2= (Load-Cap1)/(Cap2)
539 : // PLR = Load/(Cap1+Cap2)
540 : // Load= PLR*(Cap1+Cap2)
541 : // PLR1= MIN(1,(PLR*(Cap1+Cap2)/Cap1))
542 : // PLR2= MIN(1,((PLR*(Cap1+Cap2)-Cap1)/Cap2))
543 :
544 0 : if (S1SensCoolingEnergyRate > 0.0) {
545 0 : S1PLR = PartLoadRatio * S12SensCoolingEnergyRate / S1SensCoolingEnergyRate;
546 : } else {
547 0 : S1PLR = 0.0;
548 : }
549 0 : S1PLR = min(1.0, S1PLR);
550 0 : S1PLR = max(0.0, S1PLR);
551 0 : if ((S12SensCoolingEnergyRate - S1SensCoolingEnergyRate) > 0.0) {
552 0 : S2PLR = (PartLoadRatio * S12SensCoolingEnergyRate - S1SensCoolingEnergyRate) / (S12SensCoolingEnergyRate - S1SensCoolingEnergyRate);
553 : } else {
554 0 : S2PLR = 0.0;
555 : }
556 0 : S2PLR = min(1.0, S2PLR);
557 0 : S2PLR = max(0.0, S2PLR);
558 :
559 : // Run stage 1 at its part load
560 0 : PerfMode = (int)DehumidMode * 2 + 1;
561 0 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, S1PLR, fanOp, PerfMode);
562 : }
563 : // For stage-1 only operation, all outputs are set by CalcDoe2DXCoil.
564 : // No further adjustments are necessary.
565 :
566 : // Run stage 2 if needed and available
567 0 : if ((S2PLR > 0.0) && (thisDXCoil.NumCapacityStages >= 2)) {
568 : // Store stage 1 outputs
569 0 : S1RuntimeFraction = thisDXCoil.CoolingCoilRuntimeFraction;
570 0 : S1OutletAirEnthalpy = thisDXCoil.OutletAirEnthalpy;
571 0 : S1OutletAirHumRat = thisDXCoil.OutletAirHumRat;
572 0 : S1OutletAirTemp = thisDXCoil.OutletAirTemp;
573 0 : S1ElecCoolingPower = thisDXCoil.ElecCoolingPower;
574 0 : S1TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate;
575 0 : S1SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
576 0 : S1LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate;
577 0 : S1CrankcaseHeaterPower = thisDXCoil.CrankcaseHeaterPower;
578 0 : S1EvapWaterConsumpRate = thisDXCoil.EvapWaterConsumpRate;
579 0 : S1EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecPower;
580 :
581 : // Save first stage full load outlet conditions to pass to heat recovery
582 0 : S1FFullLoadOutAirTemp = state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum);
583 0 : S1FullLoadOutAirHumRat = state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum);
584 :
585 : // Run stage 1+2 at its part load
586 0 : PerfMode = (int)DehumidMode * 2 + 2;
587 0 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, S2PLR, fanOp, PerfMode);
588 0 : S12RuntimeFraction = thisDXCoil.CoolingCoilRuntimeFraction;
589 0 : S12OutletAirEnthalpy = thisDXCoil.OutletAirEnthalpy;
590 0 : S12OutletAirHumRat = thisDXCoil.OutletAirHumRat;
591 0 : S12OutletAirTemp = thisDXCoil.OutletAirTemp;
592 0 : S12ElecCoolingPower = thisDXCoil.ElecCoolingPower;
593 0 : S12TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate;
594 0 : S12SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
595 0 : S12LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate;
596 0 : S12CrankcaseHeaterPower = thisDXCoil.CrankcaseHeaterPower;
597 0 : S12EvapWaterConsumpRate = thisDXCoil.EvapWaterConsumpRate;
598 0 : S12EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecPower;
599 :
600 : // Determine combined performance
601 0 : thisDXCoil.OutletAirEnthalpy = (1.0 - S2PLR) * S1OutletAirEnthalpy + S2PLR * S12OutletAirEnthalpy;
602 0 : thisDXCoil.OutletAirHumRat = (1.0 - S2PLR) * S1OutletAirHumRat + S2PLR * S12OutletAirHumRat;
603 0 : thisDXCoil.OutletAirTemp = PsyTdbFnHW(thisDXCoil.OutletAirEnthalpy, thisDXCoil.OutletAirHumRat);
604 : // Check for saturation error and modify temperature at constant enthalpy
605 0 : if (thisDXCoil.CondenserInletNodeNum(PerfMode) != 0) {
606 0 : NodePress = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(PerfMode)).Press;
607 : // If node is not connected to anything, pressure = default, use weather data
608 0 : if (NodePress == state.dataLoopNodes->DefaultNodeValues.Press) {
609 0 : NodePress = state.dataEnvrn->OutBaroPress;
610 : }
611 0 : TSat = PsyTsatFnHPb(state, thisDXCoil.OutletAirEnthalpy, NodePress, RoutineName);
612 0 : if (thisDXCoil.OutletAirTemp < TSat) {
613 0 : thisDXCoil.OutletAirTemp = TSat;
614 : }
615 0 : thisDXCoil.OutletAirHumRat = PsyWFnTdbH(state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirEnthalpy, RoutineName);
616 : } else {
617 0 : TSat = PsyTsatFnHPb(state, thisDXCoil.OutletAirEnthalpy, state.dataEnvrn->OutBaroPress, RoutineName);
618 0 : if (thisDXCoil.OutletAirTemp < TSat) {
619 0 : thisDXCoil.OutletAirTemp = TSat;
620 : }
621 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
622 : // IF(DXCoil(DXCoilNum)%OutletAirTemp .LT. PsyTsatFnHPb(DXCoil(DXCoilNum)%OutletAirEnthalpy, &
623 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)) THEN
624 : // DXCoil(DXCoilNum)%OutletAirTemp = PsyTsatFnHPb(DXCoil(DXCoilNum)%OutletAirEnthalpy, &
625 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)
626 0 : thisDXCoil.OutletAirHumRat = PsyWFnTdbH(state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirEnthalpy, RoutineName);
627 : }
628 :
629 : // DXCoil(DXCoilNum)%ElecCoolingPower = (1-S12RuntimeFraction)*S1ElecCoolingPower &
630 : // +S12RuntimeFraction*S12ElecCoolingPower
631 : // S12ElecCoolingPower overstates S1 portion of power, because it is also adjust by S12PLR
632 : // So, must make an adjustment for S12ElecCoolingPower/S12ElecCoolFullLoadPower
633 : // when subtracting off S1ElecCoolingPower
634 0 : if (S12ElecCoolFullLoadPower > 0.0) {
635 0 : thisDXCoil.ElecCoolingPower =
636 0 : S1RuntimeFraction * S1ElecCoolingPower +
637 0 : S12RuntimeFraction * (S12ElecCoolingPower - S1ElecCoolingPower * S12ElecCoolingPower / S12ElecCoolFullLoadPower);
638 : } else {
639 0 : thisDXCoil.ElecCoolingPower = 0.0;
640 : }
641 :
642 0 : thisDXCoil.CoolingCoilRuntimeFraction = S1RuntimeFraction;
643 :
644 0 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
645 0 : CalcComponentSensibleLatentOutput(AirMassFlow,
646 : thisDXCoil.InletAirTemp,
647 : thisDXCoil.InletAirHumRat,
648 : thisDXCoil.OutletAirTemp,
649 : thisDXCoil.OutletAirHumRat,
650 0 : thisDXCoil.SensCoolingEnergyRate,
651 0 : thisDXCoil.LatCoolingEnergyRate,
652 0 : thisDXCoil.TotalCoolingEnergyRate);
653 :
654 0 : thisDXCoil.EvapWaterConsumpRate = (1.0 - S12RuntimeFraction) * S1EvapWaterConsumpRate + S12RuntimeFraction * S12EvapWaterConsumpRate;
655 0 : thisDXCoil.EvapCondPumpElecPower = (1.0 - S12RuntimeFraction) * S1EvapCondPumpElecPower + S12RuntimeFraction * S12EvapCondPumpElecPower;
656 :
657 : // Stage 1 runtime sets the crankcase heater power
658 0 : thisDXCoil.CrankcaseHeaterPower = S1CrankcaseHeaterPower;
659 :
660 0 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
661 0 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
662 :
663 : // calculate average full load outlet conditions for second stage operation
664 0 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) =
665 0 : (1.0 - S2PLR) * S1FFullLoadOutAirTemp + S2PLR * state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum);
666 0 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) =
667 0 : (1.0 - S2PLR) * S1FullLoadOutAirHumRat + S2PLR * state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum);
668 :
669 : } // End if stage 2 is operating
670 :
671 : // set the part load ratio and heat reclaim capacity for use by desuperheater heating coils
672 0 : thisDXCoil.PartLoadRatio = S1PLR;
673 0 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = S1PLR;
674 :
675 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
676 0 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
677 :
678 0 : thisDXCoil.CoolingCoilStg2RuntimeFrac = S12RuntimeFraction;
679 :
680 : // Calculate basin heater power
681 0 : CalcBasinHeaterPowerForMultiModeDXCoil(state, DXCoilNum, DehumidMode);
682 : } else {
683 0 : ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
684 0 : ShowContinueError(state, format("Invalid DX Coil Type={}", thisDXCoil.DXCoilType));
685 0 : ShowFatalError(state, "Preceding condition causes termination.");
686 : }
687 :
688 : // Update the unit outlet nodes
689 0 : UpdateDXCoil(state, DXCoilNum);
690 :
691 : // Report the result of the simulation
692 0 : ReportDXCoil(state, DXCoilNum);
693 0 : }
694 :
695 135 : void GetDXCoils(EnergyPlusData &state)
696 : {
697 :
698 : // SUBROUTINE INFORMATION:
699 : // AUTHOR Fred Buhl
700 : // DATE WRITTEN May 2000
701 : // MODIFIED Aug 2000, Don Shirey, Sept 2000, Feb/Oct 2001, Sept 2003, Jan/July 2004
702 : // Feb 2005, M. J. Witte, GARD Analytics, Inc., Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
703 : // May 2005, Rich Raustad, FSEC, Added COIL:DX:HeatPumpWaterHeater
704 : // Jun 2007, L. Gu, FSEC, Added new coil type COIL:DX:MULTISPEED:COOLING and COIL:DX:MULTISPEED:HEATING
705 : // Apr 2010, Chandan Sharma, FSEC, added basin heater inputs
706 : // Jul 2015, RP Zhang, XF Pang, LBNL, Added new coil type for VRF-FluidTemperatureControl Model
707 :
708 : // PURPOSE OF THIS SUBROUTINE:
709 : // Obtains input data for DX coils and stores it in DX coil data structure
710 :
711 : // METHODOLOGY EMPLOYED:
712 : // Uses "Get" routines to read in data.
713 :
714 : // Using/Aliasing
715 : using BranchNodeConnections::TestCompSet;
716 : using Curve::checkCurveIsNormalizedToOne;
717 : using Curve::CurveValue;
718 : using Curve::GetCurveIndex;
719 : using DataSizing::AutoSize;
720 : using EMSManager::ManageEMS;
721 :
722 : using GlobalNames::VerifyUniqueCoilName;
723 : using NodeInputManager::GetOnlySingleNode;
724 : using OutAirNodeManager::CheckOutAirNodeNumber;
725 : using WaterManager::SetupTankDemandComponent;
726 : using WaterManager::SetupTankSupplyComponent;
727 :
728 : // SUBROUTINE PARAMETER DEFINITIONS:
729 : static constexpr std::string_view RoutineName("GetDXCoils: "); // include trailing blank space
730 : static constexpr std::string_view routineName = "GetDXCoils"; // include trailing blank space
731 :
732 135 : constexpr Real64 minOATCompDXCooling = -25.0; // min OAT for compressor operation for DX cooling coils
733 :
734 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
735 : int DXCoilIndex; // loop index
736 : int DXCoilNum; // current DX coil number
737 : int NumAlphas; // Number of alphas in input
738 : int NumNumbers; // Number of numeric items in input
739 135 : Array1D_string Alphas2; // Alpha input items for object
740 135 : Array1D<Real64> Numbers2; // Numeric input items for object
741 135 : Array1D_string cAlphaFields2; // Alpha field names
742 135 : Array1D_string cNumericFields2; // Numeric field names
743 135 : Array1D_bool lAlphaBlanks2; // Logical array, alpha field input BLANK = .TRUE.
744 135 : Array1D_bool lNumericBlanks2; // Logical array, numeric field input BLANK = .TRUE.
745 : int NumAlphas2; // Number of alphas in input for performance object
746 : int NumNumbers2; // Number of numeric items in input for performance object
747 : int IOStatus; // Input status returned from GetObjectItem
748 135 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
749 : int DXHPWaterHeaterCoilNum; // Loop index for 1,NumDXHeatPumpWaterHeaterCoils
750 : int CapacityStageNum; // Loop index for 1,Number of capacity stages
751 : int DehumidModeNum; // Loop index for 1,Number of enhanced dehumidification modes
752 : int PerfModeNum; // Performance mode index
753 : int PerfObjectNum; // Item number for performance object
754 : int AlphaIndex; // Index for current alpha field
755 135 : std::string CurrentModuleObject; // Object type for getting and error messages
756 135 : std::string PerfObjectType; // Performance object type for getting and error messages
757 135 : std::string PerfObjectName; // Performance object name for getting and error messages
758 : Real64 InletAirTemp; // Used to pass proper inlet air temp to HPWH DX coil performance curves
759 : Real64 InletWaterTemp; // Used to pass proper inlet water temp to HPWH DX coil performance curves
760 : int I; // Index of speeds
761 : Real64 CurveVal; // Used to verify modifier curves equal 1 at rated conditions
762 135 : Array1D_string Alphas; // Alpha input items for object
763 135 : Array1D_string cAlphaFields; // Alpha field names
764 135 : Array1D_string cNumericFields; // Numeric field names
765 135 : Array1D<Real64> Numbers; // Numeric input items for object
766 135 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
767 135 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
768 135 : int MaxNumbers(0); // Maximum number of numeric input fields
769 135 : int MaxAlphas(0); // Maximum number of alpha input fields
770 135 : int TotalArgs(0); // Total number of alpha and numeric arguments (max) for a
771 : // certain object in the input file
772 : Real64 MinCurveVal; // used for testing PLF curve output
773 : Real64 MinCurvePLR; // used for testing PLF curve output
774 : Real64 MaxCurveVal; // used for testing PLF curve output
775 : Real64 MaxCurvePLR; // used for testing PLF curve output
776 : Real64 CurveInput; // index used for testing PLF curve output
777 :
778 : // find number of each type of DX coil and calculate the total number
779 135 : state.dataDXCoils->NumDoe2DXCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:SingleSpeed");
780 135 : state.dataDXCoils->NumDXHeatingCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:DX:SingleSpeed");
781 135 : state.dataDXCoils->NumDXMulSpeedCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:TwoSpeed");
782 270 : state.dataDXCoils->NumDXMulModeCoils =
783 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:TwoStageWithHumidityControlMode");
784 270 : state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils =
785 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped));
786 270 : state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils =
787 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped));
788 135 : state.dataDXCoils->NumDXMulSpeedCoolCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:MultiSpeed");
789 135 : state.dataDXCoils->NumDXMulSpeedHeatCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:DX:MultiSpeed");
790 270 : state.dataDXCoils->NumVRFCoolingCoils =
791 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling));
792 270 : state.dataDXCoils->NumVRFHeatingCoils =
793 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating));
794 270 : state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils =
795 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling));
796 270 : state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils =
797 135 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating));
798 :
799 135 : state.dataDXCoils->NumDXCoils = state.dataDXCoils->NumDoe2DXCoils + state.dataDXCoils->NumDXHeatingCoils + state.dataDXCoils->NumDXMulSpeedCoils +
800 135 : state.dataDXCoils->NumDXMulModeCoils + state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils +
801 135 : state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils + state.dataDXCoils->NumDXMulSpeedCoolCoils +
802 135 : state.dataDXCoils->NumDXMulSpeedHeatCoils + state.dataDXCoils->NumVRFCoolingCoils +
803 135 : state.dataDXCoils->NumVRFHeatingCoils + state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils +
804 135 : state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils;
805 :
806 : // Determine max number of alpha and numeric arguments for all objects being read, in order to allocate local arrays
807 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:SingleSpeed", TotalArgs, NumAlphas, NumNumbers);
808 135 : MaxNumbers = NumNumbers;
809 135 : MaxAlphas = NumAlphas;
810 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:DX:SingleSpeed", TotalArgs, NumAlphas, NumNumbers);
811 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
812 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
813 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:TwoSpeed", TotalArgs, NumAlphas, NumNumbers);
814 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
815 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
816 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
817 : state, "Coil:Cooling:DX:TwoStageWithHumidityControlMode", 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_HeatPumpWaterHeaterPumped), TotalArgs, NumAlphas, NumNumbers);
822 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
823 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
824 270 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
825 135 : state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped), TotalArgs, NumAlphas, NumNumbers);
826 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
827 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
828 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:MultiSpeed", TotalArgs, NumAlphas, NumNumbers);
829 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
830 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
831 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:DX:MultiSpeed", 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_Cooling), 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_Heating), 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_Cooling), TotalArgs, NumAlphas, NumNumbers);
844 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
845 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
846 270 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
847 135 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating), TotalArgs, NumAlphas, NumNumbers);
848 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
849 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
850 135 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "CoilPerformance:DX:Cooling", TotalArgs, NumAlphas, NumNumbers);
851 135 : MaxNumbers = max(MaxNumbers, NumNumbers);
852 135 : MaxAlphas = max(MaxAlphas, NumAlphas);
853 :
854 135 : Alphas.allocate(MaxAlphas);
855 135 : cAlphaFields.allocate(MaxAlphas);
856 135 : cNumericFields.allocate(MaxNumbers);
857 135 : Numbers.dimension(MaxNumbers, 0.0);
858 135 : lAlphaBlanks.dimension(MaxAlphas, true);
859 135 : lNumericBlanks.dimension(MaxNumbers, true);
860 :
861 135 : Alphas2.allocate(MaxAlphas);
862 135 : cAlphaFields2.allocate(MaxAlphas);
863 135 : cNumericFields2.allocate(MaxNumbers);
864 135 : Numbers2.dimension(MaxNumbers, 0.0);
865 135 : lAlphaBlanks2.dimension(MaxAlphas, true);
866 135 : lNumericBlanks2.dimension(MaxNumbers, true);
867 :
868 : // allocate the data structure
869 :
870 : // Derived types
871 135 : state.dataDXCoils->DXCoil.allocate(state.dataDXCoils->NumDXCoils);
872 135 : state.dataDXCoils->DXCoilNumericFields.allocate(state.dataDXCoils->NumDXCoils);
873 135 : state.dataHeatBal->HeatReclaimDXCoil.allocate(state.dataDXCoils->NumDXCoils);
874 135 : state.dataDXCoils->CheckEquipName.dimension(state.dataDXCoils->NumDXCoils, true);
875 :
876 : // Module level variable arrays
877 135 : state.dataDXCoils->DXCoilOutletTemp.allocate(state.dataDXCoils->NumDXCoils);
878 135 : state.dataDXCoils->DXCoilOutletHumRat.allocate(state.dataDXCoils->NumDXCoils);
879 135 : state.dataDXCoils->DXCoilPartLoadRatio.allocate(state.dataDXCoils->NumDXCoils);
880 135 : state.dataDXCoils->DXCoilFanOp.allocate(state.dataDXCoils->NumDXCoils);
881 135 : state.dataDXCoils->DXCoilFullLoadOutAirTemp.allocate(state.dataDXCoils->NumDXCoils);
882 135 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat.allocate(state.dataDXCoils->NumDXCoils);
883 135 : state.dataDXCoils->DXCoilTotalCooling.allocate(state.dataDXCoils->NumDXCoils);
884 135 : state.dataDXCoils->DXCoilTotalHeating.allocate(state.dataDXCoils->NumDXCoils);
885 135 : state.dataDXCoils->DXCoilCoolInletAirWBTemp.allocate(state.dataDXCoils->NumDXCoils);
886 135 : state.dataDXCoils->DXCoilHeatInletAirDBTemp.allocate(state.dataDXCoils->NumDXCoils);
887 135 : state.dataDXCoils->DXCoilHeatInletAirWBTemp.allocate(state.dataDXCoils->NumDXCoils);
888 :
889 : // initialize the module level arrays
890 135 : state.dataDXCoils->DXCoilOutletTemp = 0.0;
891 135 : state.dataDXCoils->DXCoilOutletHumRat = 0.0;
892 135 : state.dataDXCoils->DXCoilPartLoadRatio = 0.0;
893 135 : state.dataDXCoils->DXCoilFanOp = HVAC::FanOp::Invalid;
894 135 : state.dataDXCoils->DXCoilFullLoadOutAirTemp = 0.0;
895 135 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat = 0.0;
896 :
897 : // initialize the coil counter
898 135 : DXCoilNum = 0;
899 :
900 : // Loop over the Doe2 DX Coils and get & load the data
901 135 : CurrentModuleObject = "Coil:Cooling:DX:SingleSpeed";
902 197 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDoe2DXCoils; ++DXCoilIndex) {
903 :
904 62 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
905 : CurrentModuleObject,
906 : DXCoilIndex,
907 : Alphas,
908 : NumAlphas,
909 : Numbers,
910 : NumNumbers,
911 : IOStatus,
912 : lNumericBlanks,
913 : lAlphaBlanks,
914 : cAlphaFields,
915 : cNumericFields);
916 :
917 62 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
918 :
919 62 : ++DXCoilNum;
920 : // allocate single performance mode for numeric field strings used for sizing routine
921 62 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
922 62 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
923 62 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
924 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
925 62 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
926 :
927 62 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
928 62 : thisDXCoil.Name = Alphas(1);
929 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
930 62 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
931 62 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
932 62 : thisDXCoil.DXCoilType = CurrentModuleObject;
933 62 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingSingleSpeed;
934 62 : if (lAlphaBlanks(2)) {
935 10 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
936 52 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
937 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
938 0 : ErrorsFound = true;
939 : }
940 62 : thisDXCoil.RatedTotCap(1) = Numbers(1);
941 62 : thisDXCoil.RatedSHR(1) = Numbers(2);
942 62 : thisDXCoil.RatedCOP(1) = Numbers(3);
943 62 : if (thisDXCoil.RatedCOP(1) <= 0.0) {
944 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
945 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(3), Numbers(3)));
946 0 : ErrorsFound = true;
947 : }
948 :
949 62 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(4);
950 62 : thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(5);
951 62 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(6);
952 :
953 62 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
954 62 : Alphas(3),
955 : ErrorsFound,
956 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
957 62 : Alphas(1),
958 : DataLoopNode::NodeFluidType::Air,
959 : DataLoopNode::ConnectionType::Inlet,
960 : NodeInputManager::CompFluidStream::Primary,
961 : ObjectIsNotParent);
962 :
963 124 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
964 62 : Alphas(4),
965 : ErrorsFound,
966 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
967 62 : Alphas(1),
968 : DataLoopNode::NodeFluidType::Air,
969 : DataLoopNode::ConnectionType::Outlet,
970 : NodeInputManager::CompFluidStream::Primary,
971 : ObjectIsNotParent);
972 :
973 62 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
974 :
975 62 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
976 62 : if (thisDXCoil.CCapFTemp(1) == 0) {
977 0 : if (lAlphaBlanks(5)) {
978 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
979 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
980 : } else {
981 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
982 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
983 : }
984 0 : ErrorsFound = true;
985 : } else {
986 : // Verify Curve Object, only legal type is BiQuadratic
987 186 : ErrorsFound |= Curve::CheckCurveDims(state,
988 62 : thisDXCoil.CCapFTemp(1), // Curve index
989 : {2}, // Valid dimensions
990 : RoutineName, // Routine name
991 : CurrentModuleObject, // Object Type
992 : thisDXCoil.Name, // Object Name
993 62 : cAlphaFields(5)); // Field Name
994 :
995 62 : if (!ErrorsFound) {
996 62 : checkCurveIsNormalizedToOne(state,
997 186 : std::string{RoutineName} + CurrentModuleObject,
998 62 : thisDXCoil.Name,
999 62 : thisDXCoil.CCapFTemp(1),
1000 62 : cAlphaFields(5),
1001 62 : Alphas(5),
1002 : RatedInletWetBulbTemp,
1003 : RatedOutdoorAirTemp);
1004 : }
1005 : }
1006 :
1007 62 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
1008 62 : if (thisDXCoil.CCapFFlow(1) == 0) {
1009 0 : if (lAlphaBlanks(6)) {
1010 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1011 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
1012 : } else {
1013 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1014 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
1015 : }
1016 0 : ErrorsFound = true;
1017 : } else {
1018 : // Verify Curve Object, only legal type is Quadratic
1019 186 : ErrorsFound |= Curve::CheckCurveDims(state,
1020 62 : thisDXCoil.CCapFFlow(1), // Curve index
1021 : {1}, // Valid dimensions
1022 : RoutineName, // Routine name
1023 : CurrentModuleObject, // Object Type
1024 : thisDXCoil.Name, // Object Name
1025 62 : cAlphaFields(6)); // Field Name
1026 :
1027 62 : if (!ErrorsFound) {
1028 62 : checkCurveIsNormalizedToOne(
1029 248 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
1030 : }
1031 : }
1032 :
1033 62 : thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
1034 62 : if (thisDXCoil.EIRFTemp(1) == 0) {
1035 0 : if (lAlphaBlanks(7)) {
1036 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1037 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
1038 : } else {
1039 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1040 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
1041 : }
1042 0 : ErrorsFound = true;
1043 : } else {
1044 : // Verify Curve Object, only legal type is BiQuadratic
1045 186 : ErrorsFound |= Curve::CheckCurveDims(state,
1046 62 : thisDXCoil.EIRFTemp(1), // Curve index
1047 : {2}, // Valid dimensions
1048 : RoutineName, // Routine name
1049 : CurrentModuleObject, // Object Type
1050 : thisDXCoil.Name, // Object Name
1051 62 : cAlphaFields(7)); // Field Name
1052 :
1053 62 : if (!ErrorsFound) {
1054 62 : checkCurveIsNormalizedToOne(state,
1055 186 : std::string{RoutineName} + CurrentModuleObject,
1056 62 : thisDXCoil.Name,
1057 62 : thisDXCoil.EIRFTemp(1),
1058 62 : cAlphaFields(7),
1059 62 : Alphas(7),
1060 : RatedInletWetBulbTemp,
1061 : RatedOutdoorAirTemp);
1062 : }
1063 : }
1064 :
1065 62 : thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
1066 62 : if (thisDXCoil.EIRFFlow(1) == 0) {
1067 0 : if (lAlphaBlanks(8)) {
1068 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1069 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
1070 : } else {
1071 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1072 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
1073 : }
1074 0 : ErrorsFound = true;
1075 : } else {
1076 : // Verify Curve Object, only legal type is Quadratic
1077 186 : ErrorsFound |= Curve::CheckCurveDims(state,
1078 62 : thisDXCoil.EIRFFlow(1), // Curve index
1079 : {1}, // Valid dimensions
1080 : RoutineName, // Routine name
1081 : CurrentModuleObject, // Object Type
1082 : thisDXCoil.Name, // Object Name
1083 62 : cAlphaFields(8)); // Field Name
1084 :
1085 62 : if (!ErrorsFound) {
1086 62 : checkCurveIsNormalizedToOne(
1087 248 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
1088 : }
1089 : }
1090 :
1091 62 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
1092 62 : if (thisDXCoil.PLFFPLR(1) == 0) {
1093 0 : if (lAlphaBlanks(9)) {
1094 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1095 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
1096 : } else {
1097 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1098 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
1099 : }
1100 0 : ErrorsFound = true;
1101 : } else {
1102 : // Verify Curve Object, only legal types are Quadratic or Cubic
1103 186 : ErrorsFound |= Curve::CheckCurveDims(state,
1104 62 : thisDXCoil.PLFFPLR(1), // Curve index
1105 : {1}, // Valid dimensions
1106 : RoutineName, // Routine name
1107 : CurrentModuleObject, // Object Type
1108 : thisDXCoil.Name, // Object Name
1109 62 : cAlphaFields(9)); // Field Name
1110 :
1111 62 : if (!ErrorsFound) {
1112 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
1113 62 : MinCurveVal = 999.0;
1114 62 : MaxCurveVal = -999.0;
1115 62 : CurveInput = 0.0;
1116 6262 : while (CurveInput <= 1.0) {
1117 6200 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
1118 6200 : if (CurveVal < MinCurveVal) {
1119 62 : MinCurveVal = CurveVal;
1120 62 : MinCurvePLR = CurveInput;
1121 : }
1122 6200 : if (CurveVal > MaxCurveVal) {
1123 4568 : MaxCurveVal = CurveVal;
1124 4568 : MaxCurvePLR = CurveInput;
1125 : }
1126 6200 : CurveInput += 0.01;
1127 : }
1128 62 : if (MinCurveVal < 0.7) {
1129 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1130 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFields(9), Alphas(9)));
1131 0 : ShowContinueError(state,
1132 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
1133 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
1134 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
1135 : }
1136 :
1137 62 : if (MaxCurveVal > 1.0) {
1138 2 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1139 2 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
1140 4 : ShowContinueError(state,
1141 4 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
1142 4 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
1143 2 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
1144 : }
1145 : }
1146 : }
1147 :
1148 : // Set minimum OAT for compressor operation
1149 62 : thisDXCoil.MinOATCompressor = Numbers(7);
1150 62 : if (NumNumbers < 6) {
1151 0 : thisDXCoil.MinOATCompressor = minOATCompDXCooling; // input field is after min fields and won't default if field not included
1152 : }
1153 :
1154 62 : thisDXCoil.Twet_Rated(1) = Numbers(8);
1155 62 : thisDXCoil.Gamma_Rated(1) = Numbers(9);
1156 62 : thisDXCoil.MaxONOFFCyclesperHour(1) = Numbers(10);
1157 62 : thisDXCoil.LatentCapacityTimeConstant(1) = Numbers(11);
1158 :
1159 : // Numbers (7) through (11) must all be greater than zero to use the latent capacity degradation model
1160 76 : if ((Numbers(8) > 0.0 || Numbers(9) > 0.0 || Numbers(10) > 0.0 || Numbers(11) > 0.0) &&
1161 14 : (Numbers(8) <= 0.0 || Numbers(9) <= 0.0 || Numbers(10) <= 0.0 || Numbers(11) <= 0.0)) {
1162 0 : ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1163 0 : ShowContinueError(state, "...At least one of the four input parameters for the latent capacity degradation model");
1164 0 : ShowContinueError(state, "...is set to zero. Therefore, the latent degradation model will not be used for this simulation.");
1165 : }
1166 :
1167 : // outdoor condenser node
1168 62 : if (lAlphaBlanks(10)) {
1169 48 : thisDXCoil.CondenserInletNodeNum(1) = 0;
1170 : } else {
1171 28 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
1172 14 : Alphas(10),
1173 : ErrorsFound,
1174 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
1175 14 : thisDXCoil.Name,
1176 : DataLoopNode::NodeFluidType::Air,
1177 : DataLoopNode::ConnectionType::OutsideAirReference,
1178 : NodeInputManager::CompFluidStream::Primary,
1179 : ObjectIsNotParent);
1180 :
1181 14 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
1182 4 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1183 8 : ShowContinueError(
1184 : state,
1185 8 : format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(10), Alphas(10)));
1186 12 : ShowContinueError(
1187 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
1188 : }
1189 : }
1190 :
1191 62 : if ((Util::SameString(Alphas(11), "AirCooled")) || lAlphaBlanks(11)) {
1192 48 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
1193 14 : } else if (Util::SameString(Alphas(11), "EvaporativelyCooled")) {
1194 14 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
1195 14 : thisDXCoil.ReportEvapCondVars = true;
1196 : } else {
1197 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1198 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(11), Alphas(11)));
1199 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
1200 0 : ErrorsFound = true;
1201 : }
1202 :
1203 62 : thisDXCoil.EvapCondEffect(1) = Numbers(12);
1204 62 : if (thisDXCoil.EvapCondEffect(1) < 0.0 || thisDXCoil.EvapCondEffect(1) > 1.0) {
1205 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1206 0 : ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields(11)));
1207 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(12)));
1208 0 : ErrorsFound = true;
1209 : }
1210 :
1211 62 : thisDXCoil.EvapCondAirFlow(1) = Numbers(13);
1212 62 : if (thisDXCoil.EvapCondAirFlow(1) < 0.0 && thisDXCoil.EvapCondAirFlow(1) != AutoSize) {
1213 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1214 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(12)));
1215 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(13)));
1216 0 : ErrorsFound = true;
1217 : }
1218 :
1219 62 : thisDXCoil.EvapCondPumpElecNomPower(1) = Numbers(14);
1220 62 : if (thisDXCoil.EvapCondPumpElecNomPower(1) < 0.0 && thisDXCoil.EvapCondPumpElecNomPower(1) != AutoSize) {
1221 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1222 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(13)));
1223 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(14)));
1224 0 : ErrorsFound = true;
1225 : }
1226 :
1227 : // Set crankcase heater capacity
1228 62 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(15);
1229 62 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
1230 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1231 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(14)));
1232 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(15)));
1233 0 : ErrorsFound = true;
1234 : }
1235 :
1236 : // Set crankcase heater cutout temperature
1237 62 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(16);
1238 :
1239 62 : if (thisDXCoil.RatedCOP(1) > 0.0) {
1240 62 : thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
1241 : }
1242 :
1243 : // A12, \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
1244 62 : if (!lAlphaBlanks(12)) {
1245 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(12));
1246 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
1247 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(12), Alphas(12)));
1248 0 : ErrorsFound = true;
1249 : } else {
1250 6 : ErrorsFound |= Curve::CheckCurveDims(state,
1251 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
1252 : {1}, // Valid dimensions
1253 : RoutineName, // Routine name
1254 : CurrentModuleObject, // Object Type
1255 : thisDXCoil.Name, // Object Name
1256 2 : cAlphaFields(12)); // Field Name
1257 : }
1258 : }
1259 :
1260 : // Get Water System tank connections
1261 : // A13, \field Name of Water Storage Tank for Supply
1262 62 : thisDXCoil.EvapWaterSupplyName = Alphas(13);
1263 62 : if (lAlphaBlanks(13)) {
1264 62 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
1265 : } else {
1266 0 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
1267 0 : SetupTankDemandComponent(state,
1268 : thisDXCoil.Name,
1269 : CurrentModuleObject,
1270 : thisDXCoil.EvapWaterSupplyName,
1271 : ErrorsFound,
1272 0 : thisDXCoil.EvapWaterSupTankID,
1273 0 : thisDXCoil.EvapWaterTankDemandARRID);
1274 : }
1275 :
1276 : // A14; \field Name of Water Storage Tank for Condensate Collection
1277 62 : thisDXCoil.CondensateCollectName = Alphas(14);
1278 62 : if (lAlphaBlanks(14)) {
1279 62 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
1280 : } else {
1281 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
1282 0 : SetupTankSupplyComponent(state,
1283 : thisDXCoil.Name,
1284 : CurrentModuleObject,
1285 : thisDXCoil.CondensateCollectName,
1286 : ErrorsFound,
1287 0 : thisDXCoil.CondensateTankID,
1288 0 : thisDXCoil.CondensateTankSupplyARRID);
1289 : }
1290 :
1291 : // Basin heater power as a function of temperature must be greater than or equal to 0
1292 62 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(17);
1293 62 : if (Numbers(17) < 0.0) {
1294 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1295 0 : ShowContinueError(state, format("...{} must be >= 0.0.", cNumericFields(16)));
1296 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(17)));
1297 0 : ErrorsFound = true;
1298 : }
1299 :
1300 62 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(18);
1301 62 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
1302 3 : if (NumNumbers < 18) {
1303 1 : thisDXCoil.BasinHeaterSetPointTemp = 2.0;
1304 : }
1305 3 : if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
1306 0 : ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1307 0 : ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(17)));
1308 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(18)));
1309 : }
1310 : }
1311 :
1312 62 : if (!lAlphaBlanks(15)) {
1313 0 : if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(15))) == nullptr) {
1314 0 : ShowWarningItemNotFound(
1315 0 : state, eoh, cAlphaFields(15), Alphas(15), "Basin heater will be available to operate throughout the simulation.");
1316 : }
1317 : }
1318 :
1319 62 : if (!lAlphaBlanks(16) && NumAlphas > 15) {
1320 0 : thisDXCoil.SHRFTemp(1) = GetCurveIndex(state, Alphas(16)); // convert curve name to number
1321 0 : if (thisDXCoil.SHRFTemp(1) == 0) {
1322 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1323 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
1324 : } else {
1325 : // Verify Curve Object, only legal type is BiQuadratic
1326 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1327 0 : thisDXCoil.SHRFTemp(1), // Curve index
1328 : {2}, // Valid dimensions
1329 : RoutineName, // Routine name
1330 : CurrentModuleObject, // Object Type
1331 : thisDXCoil.Name, // Object Name
1332 0 : cAlphaFields(16)); // Field Name
1333 : }
1334 : }
1335 :
1336 62 : if (!lAlphaBlanks(17) && NumAlphas > 16) {
1337 2 : thisDXCoil.SHRFFlow(1) = GetCurveIndex(state, Alphas(17)); // convert curve name to number
1338 2 : if (thisDXCoil.SHRFTemp(1) == 0) {
1339 2 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1340 2 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
1341 : } else {
1342 : // Verify Curve Object, only legal type is Quadratic and Cubic
1343 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1344 0 : thisDXCoil.SHRFFlow(1), // Curve index
1345 : {1}, // Valid dimensions
1346 : RoutineName, // Routine name
1347 : CurrentModuleObject, // Object Type
1348 : thisDXCoil.Name, // Object Name
1349 0 : cAlphaFields(17)); // Field Name
1350 : }
1351 : }
1352 :
1353 62 : if (thisDXCoil.SHRFTemp(1) > 0 && thisDXCoil.SHRFFlow(1) > 0) {
1354 0 : thisDXCoil.UserSHRCurveExists = true;
1355 : }
1356 : // get User Input flag for ASHRAE Standard 127 Standard Ratings Reporting
1357 62 : if (lAlphaBlanks(18)) {
1358 62 : thisDXCoil.ASHRAE127StdRprt = false;
1359 : } else {
1360 0 : if (Alphas(18) == "YES" || Alphas(18) == "Yes") {
1361 0 : thisDXCoil.ASHRAE127StdRprt = true;
1362 : } else {
1363 0 : thisDXCoil.ASHRAE127StdRprt = false;
1364 : }
1365 : }
1366 : // A19; \field Zone Name for Condenser Placement
1367 62 : if (!lAlphaBlanks(19) && NumAlphas > 18) {
1368 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(19), state.dataHeatBal->Zone);
1369 :
1370 0 : if (thisDXCoil.SecZonePtr > 0) {
1371 0 : SetupZoneInternalGain(state,
1372 : thisDXCoil.SecZonePtr,
1373 : thisDXCoil.Name,
1374 : DataHeatBalance::IntGainType::SecCoolingDXCoilSingleSpeed,
1375 : &thisDXCoil.SecCoilSensibleHeatGainRate);
1376 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
1377 : } else {
1378 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1379 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(19), Alphas(19)));
1380 : }
1381 : }
1382 :
1383 : } // end of the Doe2 DX coil loop
1384 :
1385 135 : if (ErrorsFound) {
1386 0 : ShowFatalError(state,
1387 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
1388 : }
1389 :
1390 : // Loop over the Multimode DX Coils and get & load the data
1391 135 : CurrentModuleObject = "Coil:Cooling:DX:TwoStageWithHumidityControlMode";
1392 137 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulModeCoils; ++DXCoilIndex) {
1393 :
1394 2 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1395 : CurrentModuleObject,
1396 : DXCoilIndex,
1397 : Alphas,
1398 : NumAlphas,
1399 : Numbers,
1400 : NumNumbers,
1401 : IOStatus,
1402 : lNumericBlanks,
1403 : lAlphaBlanks,
1404 : cAlphaFields,
1405 : cNumericFields);
1406 :
1407 2 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
1408 2 : ++DXCoilNum;
1409 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
1410 2 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
1411 :
1412 2 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
1413 2 : thisDXCoil.Name = Alphas(1);
1414 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
1415 2 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
1416 2 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
1417 2 : thisDXCoil.DXCoilType = CurrentModuleObject;
1418 2 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingTwoStageWHumControl;
1419 2 : if (lAlphaBlanks(2)) {
1420 2 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
1421 0 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
1422 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
1423 0 : ErrorsFound = true;
1424 : }
1425 :
1426 2 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
1427 2 : Alphas(3),
1428 : ErrorsFound,
1429 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoStageWithHumidityControlMode,
1430 2 : Alphas(1),
1431 : DataLoopNode::NodeFluidType::Air,
1432 : DataLoopNode::ConnectionType::Inlet,
1433 : NodeInputManager::CompFluidStream::Primary,
1434 : ObjectIsNotParent);
1435 :
1436 4 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
1437 2 : Alphas(4),
1438 : ErrorsFound,
1439 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoStageWithHumidityControlMode,
1440 2 : Alphas(1),
1441 : DataLoopNode::NodeFluidType::Air,
1442 : DataLoopNode::ConnectionType::Outlet,
1443 : NodeInputManager::CompFluidStream::Primary,
1444 : ObjectIsNotParent);
1445 :
1446 2 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
1447 :
1448 : // A5; \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
1449 2 : if (!lAlphaBlanks(5)) {
1450 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
1451 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
1452 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(5), Alphas(5)));
1453 0 : ErrorsFound = true;
1454 : } else {
1455 6 : ErrorsFound |= Curve::CheckCurveDims(state,
1456 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
1457 : {1}, // Valid dimensions
1458 : RoutineName, // Routine name
1459 : CurrentModuleObject, // Object Type
1460 : thisDXCoil.Name, // Object Name
1461 2 : cAlphaFields(5)); // Field Name
1462 : }
1463 : }
1464 :
1465 : // Set crankcase heater capacity
1466 2 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(1);
1467 2 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
1468 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1469 0 : ShowContinueError(state, format("...{} must be >= 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
1470 0 : ErrorsFound = true;
1471 : }
1472 :
1473 : // Set crankcase heater cutout temperature
1474 2 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(2);
1475 :
1476 : // Number of capacity stages
1477 2 : thisDXCoil.NumCapacityStages = Numbers(3);
1478 : // Check if requested number of capacity stages exceeds limits
1479 2 : if ((thisDXCoil.NumCapacityStages > MaxCapacityStages) || (thisDXCoil.NumCapacityStages < 1)) {
1480 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1481 0 : ShowContinueError(state, format("...illegal {} = {}", cNumericFields(3), thisDXCoil.NumCapacityStages));
1482 0 : ShowContinueError(state, format("...Valid range is 1 to {}", MaxCapacityStages));
1483 0 : ErrorsFound = true;
1484 : }
1485 :
1486 : // Number of enhanced dehumidification modes
1487 2 : thisDXCoil.NumDehumidModes = Numbers(4);
1488 : // Check if requested number of enhanced dehumidification modes exceeds limits
1489 2 : if ((thisDXCoil.NumDehumidModes > MaxDehumidModes) || (thisDXCoil.NumDehumidModes < 0)) {
1490 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1491 0 : ShowContinueError(state, format("...illegal {} = {}", cNumericFields(4), thisDXCoil.NumDehumidModes));
1492 0 : ShowContinueError(state, format("...Valid range is 0 to {}", MaxDehumidModes));
1493 0 : ErrorsFound = true;
1494 : }
1495 :
1496 : // Set starting alpha index for coil performance inputs
1497 2 : AlphaIndex = 6;
1498 : // allocate performance modes for numeric field strings used for sizing routine
1499 4 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(
1500 2 : thisDXCoil.NumDehumidModes * 2 + thisDXCoil.NumCapacityStages * 2); // not sure this math is correct, ask MW
1501 :
1502 : // Loop through capacity stages and dehumidification modes
1503 6 : for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
1504 12 : for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
1505 : // Check if sufficient number of fields entered
1506 8 : if ((AlphaIndex + 1) > NumAlphas) {
1507 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1508 0 : ShowContinueError(state, "...not enough remaining fields for specified Number of Operating Modes.");
1509 0 : ShowContinueError(state, "...Need additional Coil Performance Object Type and Coil Performance Object Name fields.");
1510 0 : ErrorsFound = true;
1511 : } else {
1512 8 : PerfObjectType = Alphas(AlphaIndex);
1513 8 : PerfObjectName = Alphas(AlphaIndex + 1);
1514 8 : PerfModeNum = DehumidModeNum * 2 + CapacityStageNum;
1515 8 : thisDXCoil.CoilPerformanceType(PerfModeNum) = PerfObjectType;
1516 8 : if (Util::SameString(PerfObjectType, "CoilPerformance:DX:Cooling")) {
1517 8 : thisDXCoil.CoilPerformanceType_Num(PerfModeNum) = HVAC::CoilPerfDX_CoolBypassEmpirical;
1518 : } else {
1519 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1520 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(AlphaIndex), PerfObjectType));
1521 0 : ShowContinueError(state, "Must be \"CoilPerformance:DX:Cooling\".");
1522 0 : ErrorsFound = true;
1523 : }
1524 8 : thisDXCoil.CoilPerformanceName(PerfModeNum) = PerfObjectName;
1525 : // Get for CoilPerformance object
1526 8 : PerfObjectNum = state.dataInputProcessing->inputProcessor->getObjectItemNum(state, PerfObjectType, PerfObjectName);
1527 8 : if (PerfObjectNum > 0) {
1528 :
1529 8 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1530 : PerfObjectType,
1531 : PerfObjectNum,
1532 : Alphas2,
1533 : NumAlphas2,
1534 : Numbers2,
1535 : NumNumbers2,
1536 : IOStatus,
1537 : lNumericBlanks2,
1538 : lAlphaBlanks2,
1539 : cAlphaFields2,
1540 : cNumericFields2);
1541 :
1542 : // allocate performance mode numeric field strings used for sizing routine
1543 8 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum)
1544 8 : .PerfMode(PerfModeNum)
1545 8 : .FieldNames.allocate(NumNumbers2); // use MaxNumbers here??
1546 8 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(PerfModeNum).FieldNames = cNumericFields2;
1547 :
1548 8 : thisDXCoil.RatedTotCap(PerfModeNum) = Numbers2(1);
1549 8 : thisDXCoil.RatedSHR(PerfModeNum) = Numbers2(2);
1550 8 : thisDXCoil.RatedCOP(PerfModeNum) = Numbers2(3);
1551 : // Rated flow is immediately adjusted for bypass fraction if not autosized
1552 8 : thisDXCoil.BypassedFlowFrac(PerfModeNum) = Numbers2(5);
1553 8 : thisDXCoil.RatedAirVolFlowRate(PerfModeNum) = Numbers2(4);
1554 8 : if (thisDXCoil.RatedAirVolFlowRate(PerfModeNum) != AutoSize) {
1555 0 : thisDXCoil.RatedAirVolFlowRate(PerfModeNum) *= (1.0 - thisDXCoil.BypassedFlowFrac(PerfModeNum));
1556 : }
1557 :
1558 8 : thisDXCoil.CCapFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(2)); // convert curve name to number
1559 8 : if (thisDXCoil.CCapFTemp(PerfModeNum) == 0) {
1560 0 : if (lAlphaBlanks2(2)) {
1561 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1562 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(2)));
1563 : } else {
1564 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1565 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(2), Alphas2(2)));
1566 : }
1567 0 : ErrorsFound = true;
1568 : } else {
1569 : // Verify Curve Object, only legal type is BiQuadratic
1570 24 : ErrorsFound |= Curve::CheckCurveDims(state,
1571 8 : thisDXCoil.CCapFTemp(PerfModeNum), // Curve index
1572 : {2}, // Valid dimensions
1573 : RoutineName, // Routine name
1574 : CurrentModuleObject, // Object Type
1575 : thisDXCoil.Name, // Object Name
1576 8 : cAlphaFields2(2)); // Field Name
1577 :
1578 8 : if (!ErrorsFound) {
1579 8 : checkCurveIsNormalizedToOne(state,
1580 24 : std::string{RoutineName} + CurrentModuleObject,
1581 8 : thisDXCoil.Name,
1582 8 : thisDXCoil.CCapFTemp(PerfModeNum),
1583 8 : cAlphaFields2(2),
1584 8 : Alphas2(2),
1585 : RatedInletWetBulbTemp,
1586 : RatedOutdoorAirTemp);
1587 : }
1588 : }
1589 :
1590 8 : thisDXCoil.CCapFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(3)); // convert curve name to number
1591 8 : if (thisDXCoil.CCapFFlow(PerfModeNum) == 0) {
1592 0 : if (lAlphaBlanks2(3)) {
1593 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1594 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(3)));
1595 : } else {
1596 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1597 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(3), Alphas2(3)));
1598 : }
1599 0 : ErrorsFound = true;
1600 : } else {
1601 : // Verify Curve Object, only legal type is Quadratic
1602 24 : ErrorsFound |= Curve::CheckCurveDims(state,
1603 8 : thisDXCoil.CCapFFlow(PerfModeNum), // Curve index
1604 : {1}, // Valid dimensions
1605 : RoutineName, // Routine name
1606 : CurrentModuleObject, // Object Type
1607 : thisDXCoil.Name, // Object Name
1608 8 : cAlphaFields2(3)); // Field Name
1609 :
1610 8 : if (!ErrorsFound) {
1611 8 : checkCurveIsNormalizedToOne(state,
1612 24 : std::string{RoutineName} + CurrentModuleObject,
1613 8 : thisDXCoil.Name,
1614 8 : thisDXCoil.CCapFFlow(PerfModeNum),
1615 8 : cAlphaFields2(3),
1616 8 : Alphas2(3),
1617 : 1.0);
1618 : }
1619 : }
1620 :
1621 8 : thisDXCoil.EIRFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(4)); // convert curve name to number
1622 8 : if (thisDXCoil.EIRFTemp(PerfModeNum) == 0) {
1623 0 : if (lAlphaBlanks2(4)) {
1624 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1625 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(4)));
1626 : } else {
1627 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1628 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(4), Alphas2(4)));
1629 : }
1630 0 : ErrorsFound = true;
1631 : } else {
1632 : // Verify Curve Object, only legal type is BiQuadratic
1633 24 : ErrorsFound |= Curve::CheckCurveDims(state,
1634 8 : thisDXCoil.EIRFTemp(PerfModeNum), // Curve index
1635 : {2}, // Valid dimensions
1636 : RoutineName, // Routine name
1637 : CurrentModuleObject, // Object Type
1638 : thisDXCoil.Name, // Object Name
1639 8 : cAlphaFields2(4)); // Field Name
1640 :
1641 8 : if (!ErrorsFound) {
1642 8 : checkCurveIsNormalizedToOne(state,
1643 24 : std::string{RoutineName} + CurrentModuleObject,
1644 8 : thisDXCoil.Name,
1645 8 : thisDXCoil.EIRFTemp(PerfModeNum),
1646 8 : cAlphaFields2(4),
1647 8 : Alphas2(4),
1648 : RatedInletWetBulbTemp,
1649 : RatedOutdoorAirTemp);
1650 : }
1651 : }
1652 :
1653 8 : thisDXCoil.EIRFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(5)); // convert curve name to number
1654 8 : if (thisDXCoil.EIRFFlow(PerfModeNum) == 0) {
1655 0 : if (lAlphaBlanks2(5)) {
1656 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1657 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(5)));
1658 : } else {
1659 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1660 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(5), Alphas2(5)));
1661 : }
1662 0 : ErrorsFound = true;
1663 : } else {
1664 : // Verify Curve Object, only legal type is Quadratic
1665 24 : ErrorsFound |= Curve::CheckCurveDims(state,
1666 8 : thisDXCoil.EIRFFlow(PerfModeNum), // Curve index
1667 : {1}, // Valid dimensions
1668 : RoutineName, // Routine name
1669 : CurrentModuleObject, // Object Type
1670 : thisDXCoil.Name, // Object Name
1671 8 : cAlphaFields2(5)); // Field Name
1672 :
1673 8 : if (!ErrorsFound) {
1674 8 : checkCurveIsNormalizedToOne(state,
1675 24 : std::string{RoutineName} + CurrentModuleObject,
1676 8 : thisDXCoil.Name,
1677 8 : thisDXCoil.EIRFFlow(PerfModeNum),
1678 8 : cAlphaFields2(5),
1679 8 : Alphas2(5),
1680 : 1.0);
1681 : }
1682 : }
1683 :
1684 8 : thisDXCoil.PLFFPLR(PerfModeNum) = GetCurveIndex(state, Alphas2(6)); // convert curve name to number
1685 8 : if (thisDXCoil.PLFFPLR(PerfModeNum) == 0) {
1686 0 : if (lAlphaBlanks2(6)) {
1687 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1688 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(6)));
1689 : } else {
1690 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1691 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(6), Alphas2(6)));
1692 : }
1693 0 : ErrorsFound = true;
1694 : } else {
1695 : // Verify Curve Object, only legal types are Quadratic or Cubic
1696 24 : ErrorsFound |= Curve::CheckCurveDims(state,
1697 8 : thisDXCoil.PLFFPLR(PerfModeNum), // Curve index
1698 : {1}, // Valid dimensions
1699 : RoutineName, // Routine name
1700 : CurrentModuleObject, // Object Type
1701 : thisDXCoil.Name, // Object Name
1702 8 : cAlphaFields2(6)); // Field Name
1703 :
1704 8 : if (!ErrorsFound) {
1705 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
1706 8 : MinCurveVal = 999.0;
1707 8 : MaxCurveVal = -999.0;
1708 8 : CurveInput = 0.0;
1709 808 : while (CurveInput <= 1.0) {
1710 800 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(PerfModeNum), CurveInput);
1711 800 : if (CurveVal < MinCurveVal) {
1712 8 : MinCurveVal = CurveVal;
1713 8 : MinCurvePLR = CurveInput;
1714 : }
1715 800 : if (CurveVal > MaxCurveVal) {
1716 8 : MaxCurveVal = CurveVal;
1717 8 : MaxCurvePLR = CurveInput;
1718 : }
1719 800 : CurveInput += 0.01;
1720 : }
1721 8 : if (MinCurveVal < 0.7) {
1722 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1723 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields2(6), Alphas2(6)));
1724 0 : ShowContinueError(
1725 : state,
1726 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
1727 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
1728 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 0.7);
1729 : }
1730 :
1731 8 : if (MaxCurveVal > 1.0) {
1732 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1733 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields2(6), Alphas2(6)));
1734 0 : ShowContinueError(
1735 : state,
1736 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
1737 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
1738 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 1.0);
1739 : }
1740 : }
1741 : }
1742 :
1743 8 : thisDXCoil.Twet_Rated(PerfModeNum) = Numbers2(6);
1744 8 : thisDXCoil.Gamma_Rated(PerfModeNum) = Numbers2(7);
1745 8 : thisDXCoil.MaxONOFFCyclesperHour(PerfModeNum) = Numbers2(8);
1746 8 : thisDXCoil.LatentCapacityTimeConstant(PerfModeNum) = Numbers2(9);
1747 : // Numbers2 (6) through (9) must all be greater than zero to use the latent capacity degradation model
1748 8 : if ((Numbers2(6) > 0.0 || Numbers2(7) > 0.0 || Numbers2(8) > 0.0 || Numbers2(9) > 0.0) &&
1749 0 : (Numbers2(6) <= 0.0 || Numbers2(7) <= 0.0 || Numbers2(8) <= 0.0 || Numbers2(9) <= 0.0)) {
1750 0 : ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, PerfObjectType, PerfObjectName));
1751 0 : ShowContinueError(state, "...At least one of the four input parameters for the latent capacity degradation model");
1752 0 : ShowContinueError(state,
1753 : "...is set to zero. Therefore, the latent degradation model will not be used for this simulation.");
1754 : }
1755 :
1756 : // outdoor condenser node
1757 8 : if (lAlphaBlanks2(7)) {
1758 8 : thisDXCoil.CondenserInletNodeNum(PerfModeNum) = 0;
1759 : } else {
1760 0 : thisDXCoil.CondenserInletNodeNum(PerfModeNum) =
1761 0 : GetOnlySingleNode(state,
1762 0 : Alphas2(7),
1763 : ErrorsFound,
1764 0 : (DataLoopNode::ConnectionObjectType)getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC,
1765 0 : Util::makeUPPER(PerfObjectType)),
1766 : PerfObjectName,
1767 : DataLoopNode::NodeFluidType::Air,
1768 : DataLoopNode::ConnectionType::OutsideAirReference,
1769 : NodeInputManager::CompFluidStream::Primary,
1770 : ObjectIsNotParent);
1771 0 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(PerfModeNum))) {
1772 0 : ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, PerfObjectType, PerfObjectName));
1773 0 : ShowContinueError(state, format("may not be valid {}=\"{}\".", cAlphaFields2(7), Alphas2(7)));
1774 0 : ShowContinueError(state, "node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
1775 0 : ShowContinueError(state,
1776 : "This node needs to be included in an air system or the coil model will not be valid, and the "
1777 : "simulation continues");
1778 : }
1779 : }
1780 8 : if ((Util::SameString(Alphas2(8), "AirCooled")) || lAlphaBlanks2(8)) {
1781 8 : thisDXCoil.CondenserType(PerfModeNum) = DataHeatBalance::RefrigCondenserType::Air;
1782 0 : } else if (Util::SameString(Alphas2(8), "EvaporativelyCooled")) {
1783 0 : thisDXCoil.CondenserType(PerfModeNum) = DataHeatBalance::RefrigCondenserType::Evap;
1784 0 : thisDXCoil.ReportEvapCondVars = true;
1785 : } else {
1786 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1787 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields2(8), Alphas2(8)));
1788 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
1789 0 : ErrorsFound = true;
1790 : }
1791 :
1792 8 : thisDXCoil.EvapCondEffect(PerfModeNum) = Numbers2(10);
1793 8 : if (thisDXCoil.EvapCondEffect(PerfModeNum) < 0.0 || thisDXCoil.EvapCondEffect(PerfModeNum) > 1.0) {
1794 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1795 0 : ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields2(10)));
1796 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(10)));
1797 0 : ErrorsFound = true;
1798 : }
1799 :
1800 8 : thisDXCoil.EvapCondAirFlow(PerfModeNum) = Numbers2(11);
1801 8 : if (thisDXCoil.EvapCondAirFlow(PerfModeNum) < 0.0 && thisDXCoil.EvapCondAirFlow(PerfModeNum) != AutoSize) {
1802 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1803 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields2(11)));
1804 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(11)));
1805 0 : ErrorsFound = true;
1806 : }
1807 :
1808 8 : thisDXCoil.EvapCondPumpElecNomPower(PerfModeNum) = Numbers2(12);
1809 8 : if (thisDXCoil.EvapCondPumpElecNomPower(PerfModeNum) < 0.0 && thisDXCoil.EvapCondAirFlow(PerfModeNum) != AutoSize) {
1810 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
1811 0 : ShowContinueError(state, format("...{} cannot be less than zero.", cNumericFields2(12)));
1812 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(12)));
1813 0 : ErrorsFound = true;
1814 : }
1815 :
1816 8 : thisDXCoil.RatedEIR(PerfModeNum) = 1.0 / thisDXCoil.RatedCOP(PerfModeNum);
1817 :
1818 : // read in user specified SHR modifier curves
1819 8 : if (!lAlphaBlanks2(9) && NumAlphas2 > 8) {
1820 0 : thisDXCoil.SHRFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(9)); // convert curve name to number
1821 0 : if (thisDXCoil.SHRFTemp(PerfModeNum) == 0) {
1822 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1823 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(9), Alphas2(9)));
1824 : } else {
1825 : // Verify Curve Object, only legal type is BiQuadratic
1826 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1827 0 : thisDXCoil.SHRFTemp(PerfModeNum), // Curve index
1828 : {2}, // Valid dimensions
1829 : RoutineName, // Routine name
1830 : CurrentModuleObject, // Object Type
1831 : thisDXCoil.Name, // Object Name
1832 0 : cAlphaFields2(9)); // Field Name
1833 : }
1834 : }
1835 :
1836 8 : if (!lAlphaBlanks2(10) && NumAlphas2 > 9) {
1837 0 : thisDXCoil.SHRFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(10)); // convert curve name to number
1838 0 : if (thisDXCoil.SHRFTemp(PerfModeNum) == 0) {
1839 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1840 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(10), Alphas2(10)));
1841 : } else {
1842 : // Verify Curve Object, only legal type is BiQuadratic
1843 0 : ErrorsFound |= Curve::CheckCurveDims(state,
1844 0 : thisDXCoil.SHRFFlow(PerfModeNum), // Curve index
1845 : {1}, // Valid dimensions
1846 : RoutineName, // Routine name
1847 : CurrentModuleObject, // Object Type
1848 : thisDXCoil.Name, // Object Name
1849 0 : cAlphaFields2(10)); // Field Name
1850 : }
1851 : }
1852 8 : if (thisDXCoil.SHRFTemp(PerfModeNum) > 0 && thisDXCoil.SHRFFlow(PerfModeNum) > 0) {
1853 0 : thisDXCoil.UserSHRCurveExists = true;
1854 : } else {
1855 8 : thisDXCoil.UserSHRCurveExists = false;
1856 : }
1857 :
1858 : } else { // invalid performance object
1859 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1860 0 : ShowContinueError(state, format("... not found {}=\"{}\".", PerfObjectType, PerfObjectName));
1861 0 : ErrorsFound = true;
1862 : } // end of valid performance object check
1863 8 : AlphaIndex += 2;
1864 : } // end of sufficient number of fields entered check
1865 : } // End of multimode DX capacity stages loop
1866 : // Warn if inputs entered for unused capacity stages
1867 4 : for (CapacityStageNum = (thisDXCoil.NumCapacityStages + 1); CapacityStageNum <= MaxCapacityStages; ++CapacityStageNum) {
1868 0 : if ((AlphaIndex <= NumAlphas) && ((!Alphas(AlphaIndex).empty()) || (!Alphas(AlphaIndex + 1).empty()))) {
1869 0 : ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1870 0 : ShowContinueError(state, format("...Capacity Stage {} not active. Therefore,{}", CapacityStageNum, cAlphaFields(AlphaIndex)));
1871 0 : ShowContinueError(state, format("... and {} fields will be ignored.", cAlphaFields(AlphaIndex + 1)));
1872 : }
1873 0 : AlphaIndex += 2;
1874 : } // End of unused capacity stages loop
1875 : } // End of multimode DX dehumidification modes loo
1876 :
1877 : // Get Water System tank connections
1878 : // A14, \field Name of Water Storage Tank for Supply
1879 2 : thisDXCoil.EvapWaterSupplyName = Alphas(14);
1880 2 : if (lAlphaBlanks(14)) {
1881 2 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
1882 : } else {
1883 0 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
1884 0 : SetupTankDemandComponent(state,
1885 : thisDXCoil.Name,
1886 : CurrentModuleObject,
1887 : thisDXCoil.EvapWaterSupplyName,
1888 : ErrorsFound,
1889 0 : thisDXCoil.EvapWaterSupTankID,
1890 0 : thisDXCoil.EvapWaterTankDemandARRID);
1891 : }
1892 :
1893 : // A15; \field Name of Water Storage Tank for Condensate Collection
1894 2 : thisDXCoil.CondensateCollectName = Alphas(15);
1895 2 : if (lAlphaBlanks(15)) {
1896 2 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
1897 : } else {
1898 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
1899 0 : SetupTankSupplyComponent(state,
1900 : thisDXCoil.Name,
1901 : CurrentModuleObject,
1902 : thisDXCoil.CondensateCollectName,
1903 : ErrorsFound,
1904 0 : thisDXCoil.CondensateTankID,
1905 0 : thisDXCoil.CondensateTankSupplyARRID);
1906 : }
1907 :
1908 : // Set minimum OAT for compressor operation
1909 2 : thisDXCoil.MinOATCompressor = Numbers(5);
1910 2 : if (NumNumbers < 5) {
1911 0 : thisDXCoil.MinOATCompressor = minOATCompDXCooling; // input field is after min fields and won't default if field not included
1912 : }
1913 :
1914 : // Basin heater power as a function of temperature must be greater than or equal to 0
1915 2 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(6);
1916 2 : if (Numbers(6) < 0.0) {
1917 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1918 0 : ShowContinueError(state, format("...{} must be >= 0.", cNumericFields(6)));
1919 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(6)));
1920 0 : ErrorsFound = true;
1921 : }
1922 :
1923 2 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(7);
1924 2 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
1925 0 : if (NumNumbers < 7) {
1926 0 : thisDXCoil.BasinHeaterSetPointTemp = 2.0;
1927 : }
1928 0 : if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
1929 0 : ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1930 0 : ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(7)));
1931 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(7)));
1932 : }
1933 : }
1934 :
1935 2 : if (!lAlphaBlanks(16)) {
1936 0 : if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(16))) == nullptr) {
1937 0 : ShowWarningItemNotFound(
1938 0 : state, eoh, cAlphaFields(16), Alphas(16), "Basin heater will be available to operate throughout the simulation.");
1939 : }
1940 : }
1941 :
1942 : } // end of the Multimode DX coil loop
1943 :
1944 135 : if (ErrorsFound) {
1945 0 : ShowFatalError(state,
1946 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
1947 : }
1948 :
1949 : //************* Read Heat Pump (DX Heating Coil) Input **********
1950 135 : CurrentModuleObject = "Coil:Heating:DX:SingleSpeed";
1951 147 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXHeatingCoils; ++DXCoilIndex) {
1952 :
1953 12 : ++DXCoilNum;
1954 :
1955 12 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1956 : CurrentModuleObject,
1957 : DXCoilIndex,
1958 : Alphas,
1959 : NumAlphas,
1960 : Numbers,
1961 : NumNumbers,
1962 : IOStatus,
1963 : lNumericBlanks,
1964 : lAlphaBlanks,
1965 : cAlphaFields,
1966 : cNumericFields);
1967 :
1968 12 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
1969 : // allocate single performance mode for numeric field strings used for sizing routine
1970 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
1971 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
1972 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
1973 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
1974 12 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
1975 :
1976 12 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
1977 12 : thisDXCoil.Name = Alphas(1);
1978 12 : thisDXCoil.DXCoilType = CurrentModuleObject;
1979 12 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatingEmpirical;
1980 12 : if (lAlphaBlanks(2)) {
1981 3 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
1982 9 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
1983 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
1984 0 : ErrorsFound = true;
1985 : }
1986 :
1987 12 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
1988 12 : Alphas(3),
1989 : ErrorsFound,
1990 : DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
1991 12 : Alphas(1),
1992 : DataLoopNode::NodeFluidType::Air,
1993 : DataLoopNode::ConnectionType::Inlet,
1994 : NodeInputManager::CompFluidStream::Primary,
1995 : ObjectIsNotParent);
1996 :
1997 24 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
1998 12 : Alphas(4),
1999 : ErrorsFound,
2000 : DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
2001 12 : Alphas(1),
2002 : DataLoopNode::NodeFluidType::Air,
2003 : DataLoopNode::ConnectionType::Outlet,
2004 : NodeInputManager::CompFluidStream::Primary,
2005 : ObjectIsNotParent);
2006 :
2007 12 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
2008 :
2009 12 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
2010 12 : if (thisDXCoil.CCapFTemp(1) == 0) {
2011 0 : if (lAlphaBlanks(5)) {
2012 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2013 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
2014 : } else {
2015 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2016 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
2017 : }
2018 0 : ErrorsFound = true;
2019 : } else {
2020 : // only legal types are Quadratic, BiQuadratic and Cubic
2021 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2022 12 : thisDXCoil.CCapFTemp(1), // Curve index
2023 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2024 : RoutineName, // Routine name
2025 : CurrentModuleObject, // Object Type
2026 : thisDXCoil.Name, // Object Name
2027 12 : cAlphaFields(5)); // Field Name
2028 :
2029 12 : if (!ErrorsFound) {
2030 12 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
2031 7 : checkCurveIsNormalizedToOne(state,
2032 21 : std::string{RoutineName} + CurrentModuleObject,
2033 7 : thisDXCoil.Name,
2034 7 : thisDXCoil.CCapFTemp(1),
2035 7 : cAlphaFields(5),
2036 7 : Alphas(5),
2037 : RatedOutdoorAirTempHeat);
2038 : } else {
2039 5 : checkCurveIsNormalizedToOne(state,
2040 15 : std::string{RoutineName} + CurrentModuleObject,
2041 5 : thisDXCoil.Name,
2042 5 : thisDXCoil.CCapFTemp(1),
2043 5 : cAlphaFields(5),
2044 5 : Alphas(5),
2045 : RatedInletAirTempHeat,
2046 : RatedOutdoorAirTempHeat);
2047 : }
2048 : }
2049 : }
2050 :
2051 12 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
2052 12 : if (thisDXCoil.CCapFFlow(1) == 0) {
2053 0 : if (lAlphaBlanks(6)) {
2054 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2055 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
2056 : } else {
2057 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2058 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
2059 : }
2060 0 : ErrorsFound = true;
2061 : } else {
2062 : // Verify Curve Object, only legal type is Quadratic
2063 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2064 12 : thisDXCoil.CCapFFlow(1), // Curve index
2065 : {1}, // Valid dimensions
2066 : RoutineName, // Routine name
2067 : CurrentModuleObject, // Object Type
2068 : thisDXCoil.Name, // Object Name
2069 12 : cAlphaFields(6)); // Field Name
2070 :
2071 12 : if (!ErrorsFound) {
2072 12 : checkCurveIsNormalizedToOne(
2073 48 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
2074 : }
2075 : }
2076 :
2077 12 : thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
2078 12 : if (thisDXCoil.EIRFTemp(1) == 0) {
2079 0 : if (lAlphaBlanks(7)) {
2080 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2081 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
2082 : } else {
2083 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2084 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
2085 : }
2086 0 : ErrorsFound = true;
2087 : } else {
2088 : // only legal types are Quadratic, BiQuadratic and Cubic
2089 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2090 12 : thisDXCoil.EIRFTemp(1), // Curve index
2091 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
2092 : RoutineName, // Routine name
2093 : CurrentModuleObject, // Object Type
2094 : thisDXCoil.Name, // Object Name
2095 12 : cAlphaFields(7)); // Field Name
2096 :
2097 12 : if (!ErrorsFound) {
2098 12 : if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(1))->numDims == 1) {
2099 7 : checkCurveIsNormalizedToOne(state,
2100 21 : std::string{RoutineName} + CurrentModuleObject,
2101 7 : thisDXCoil.Name,
2102 7 : thisDXCoil.EIRFTemp(1),
2103 7 : cAlphaFields(7),
2104 7 : Alphas(7),
2105 : RatedOutdoorAirTempHeat);
2106 : } else {
2107 5 : checkCurveIsNormalizedToOne(state,
2108 15 : std::string{RoutineName} + CurrentModuleObject,
2109 5 : thisDXCoil.Name,
2110 5 : thisDXCoil.EIRFTemp(1),
2111 5 : cAlphaFields(7),
2112 5 : Alphas(7),
2113 : RatedInletAirTempHeat,
2114 : RatedOutdoorAirTempHeat);
2115 : }
2116 : }
2117 : }
2118 :
2119 12 : thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
2120 12 : if (thisDXCoil.EIRFFlow(1) == 0) {
2121 0 : if (lAlphaBlanks(8)) {
2122 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2123 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
2124 : } else {
2125 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2126 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
2127 : }
2128 0 : ErrorsFound = true;
2129 : } else {
2130 : // Verify Curve Object, only legal type is Quadratic or Cubic
2131 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2132 12 : thisDXCoil.EIRFFlow(1), // Curve index
2133 : {1}, // Valid dimensions
2134 : RoutineName, // Routine name
2135 : CurrentModuleObject, // Object Type
2136 : thisDXCoil.Name, // Object Name
2137 12 : cAlphaFields(8)); // Field Name
2138 :
2139 12 : if (!ErrorsFound) {
2140 12 : checkCurveIsNormalizedToOne(
2141 48 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
2142 : }
2143 : }
2144 :
2145 12 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
2146 12 : if (thisDXCoil.PLFFPLR(1) == 0) {
2147 0 : if (lAlphaBlanks(9)) {
2148 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2149 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
2150 : } else {
2151 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2152 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
2153 : }
2154 0 : ErrorsFound = true;
2155 : } else {
2156 : // Verify Curve Object, only legal types are Quadratic or Cubic
2157 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2158 12 : thisDXCoil.PLFFPLR(1), // Curve index
2159 : {1}, // Valid dimensions
2160 : RoutineName, // Routine name
2161 : CurrentModuleObject, // Object Type
2162 : thisDXCoil.Name, // Object Name
2163 12 : cAlphaFields(9)); // Field Name
2164 :
2165 12 : if (!ErrorsFound) {
2166 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
2167 12 : MinCurveVal = 999.0;
2168 12 : MaxCurveVal = -999.0;
2169 12 : CurveInput = 0.0;
2170 1212 : while (CurveInput <= 1.0) {
2171 1200 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
2172 1200 : if (CurveVal < MinCurveVal) {
2173 12 : MinCurveVal = CurveVal;
2174 12 : MinCurvePLR = CurveInput;
2175 : }
2176 1200 : if (CurveVal > MaxCurveVal) {
2177 854 : MaxCurveVal = CurveVal;
2178 854 : MaxCurvePLR = CurveInput;
2179 : }
2180 1200 : CurveInput += 0.01;
2181 : }
2182 12 : if (MinCurveVal < 0.7) {
2183 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2184 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
2185 0 : ShowContinueError(state,
2186 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
2187 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
2188 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
2189 : }
2190 :
2191 12 : if (MaxCurveVal > 1.0) {
2192 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2193 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
2194 0 : ShowContinueError(state,
2195 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
2196 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
2197 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
2198 : }
2199 : }
2200 : }
2201 :
2202 : // Only required for reverse cycle heat pumps
2203 12 : thisDXCoil.DefrostEIRFT = GetCurveIndex(state, Alphas(10)); // convert curve name to number
2204 : // A11; \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
2205 12 : if (!lAlphaBlanks(11)) {
2206 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(11));
2207 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
2208 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(11), Alphas(11)));
2209 0 : ErrorsFound = true;
2210 : } else {
2211 6 : ErrorsFound |= Curve::CheckCurveDims(state,
2212 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
2213 : {1}, // Valid dimensions
2214 : RoutineName, // Routine name
2215 : CurrentModuleObject, // Object Type
2216 : thisDXCoil.Name, // Object Name
2217 2 : cAlphaFields(11)); // Field Name
2218 : }
2219 : }
2220 :
2221 12 : if (Util::SameString(Alphas(12), "ReverseCycle")) {
2222 :
2223 3 : if (thisDXCoil.DefrostEIRFT == 0) {
2224 0 : if (lAlphaBlanks(10)) {
2225 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2226 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(10)));
2227 0 : ShowContinueError(state, format("...field is required because {} is \"ReverseCycle\".", cAlphaFields(12)));
2228 : } else {
2229 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2230 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
2231 : }
2232 0 : ErrorsFound = true;
2233 : } else {
2234 : // Verify Curve Object, only legal type is BiQuadratic
2235 6 : ErrorsFound |= Curve::CheckCurveDims(state,
2236 : thisDXCoil.DefrostEIRFT, // Curve index
2237 : {2}, // Valid dimensions
2238 : RoutineName, // Routine name
2239 : CurrentModuleObject, // Object Type
2240 : thisDXCoil.Name, // Object Name
2241 3 : cAlphaFields(10)); // Field Name
2242 :
2243 3 : if (!ErrorsFound) {
2244 3 : checkCurveIsNormalizedToOne(state,
2245 9 : std::string{RoutineName} + CurrentModuleObject,
2246 3 : thisDXCoil.Name,
2247 : thisDXCoil.DefrostEIRFT,
2248 3 : cAlphaFields(10),
2249 3 : Alphas(10),
2250 : RatedInletAirTempHeat,
2251 : RatedOutdoorAirTempHeat);
2252 : }
2253 : }
2254 : }
2255 :
2256 12 : if (Util::SameString(Alphas(12), "ReverseCycle")) {
2257 3 : thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
2258 : }
2259 12 : if (Util::SameString(Alphas(12), "Resistive")) {
2260 9 : thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
2261 : }
2262 :
2263 12 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
2264 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2265 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(12), Alphas(12)));
2266 0 : ShowContinueError(state, "...valid values for this field are ReverseCycle or Resistive.");
2267 0 : ErrorsFound = true;
2268 : }
2269 :
2270 12 : if (Util::SameString(Alphas(13), "Timed")) {
2271 11 : thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::Timed;
2272 : }
2273 12 : if (Util::SameString(Alphas(13), "OnDemand")) {
2274 1 : thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
2275 : }
2276 12 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
2277 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2278 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(13), Alphas(13)));
2279 0 : ShowContinueError(state, "...valid values for this field are Timed or OnDemand.");
2280 0 : ErrorsFound = true;
2281 : }
2282 :
2283 12 : thisDXCoil.RatedSHR(1) = 1.0;
2284 12 : thisDXCoil.RatedTotCap(1) = Numbers(1);
2285 12 : thisDXCoil.RatedCOP(1) = Numbers(2);
2286 12 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(3);
2287 12 : thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(4);
2288 12 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(5);
2289 :
2290 : // Set minimum OAT for heat pump compressor operation
2291 12 : thisDXCoil.MinOATCompressor = Numbers(6);
2292 :
2293 12 : thisDXCoil.OATempCompressorOn = Numbers(7);
2294 :
2295 12 : if (lNumericBlanks(7) || lNumericBlanks(6)) { //??TBD:BPS 6 or 5 | 7 or 6
2296 12 : thisDXCoil.OATempCompressorOnOffBlank = true;
2297 : } else {
2298 0 : thisDXCoil.OATempCompressorOnOffBlank = false;
2299 : }
2300 :
2301 12 : if (thisDXCoil.OATempCompressorOn < thisDXCoil.MinOATCompressor) {
2302 3 : thisDXCoil.OATempCompressorOn = thisDXCoil.MinOATCompressor;
2303 : }
2304 :
2305 : // Set maximum outdoor temp for defrost to occur
2306 12 : thisDXCoil.MaxOATDefrost = Numbers(8);
2307 :
2308 : // Set crankcase heater capacity
2309 12 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(9);
2310 12 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
2311 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2312 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(8)));
2313 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(9)));
2314 0 : ErrorsFound = true;
2315 : }
2316 :
2317 : // Set crankcase heater cutout temperature
2318 12 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(10);
2319 :
2320 : // Set defrost time period
2321 12 : thisDXCoil.DefrostTime = Numbers(11);
2322 12 : if (thisDXCoil.DefrostTime == 0.0 && thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
2323 0 : ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2324 0 : ShowContinueError(state, format("...{} = 0.0 for defrost control = TIMED.", cNumericFields(11)));
2325 : }
2326 :
2327 : // Set defrost capacity (for resistive defrost)
2328 12 : thisDXCoil.DefrostCapacity = Numbers(12);
2329 12 : if (thisDXCoil.DefrostCapacity == 0.0 && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
2330 0 : ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2331 0 : ShowContinueError(state, format("...{} = 0.0 for defrost strategy = RESISTIVE.", cNumericFields(12)));
2332 : }
2333 :
2334 : // Set Region number for calculating HSPF
2335 12 : thisDXCoil.RegionNum = Numbers(13);
2336 :
2337 12 : if (lNumericBlanks(13)) {
2338 11 : thisDXCoil.RegionNum = 4;
2339 : }
2340 :
2341 12 : thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
2342 :
2343 : // A14 is optional evaporator node name
2344 12 : if (lAlphaBlanks(14)) {
2345 12 : thisDXCoil.CondenserInletNodeNum(1) = 0;
2346 : } else {
2347 0 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
2348 0 : Alphas(14),
2349 : ErrorsFound,
2350 : DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
2351 0 : thisDXCoil.Name,
2352 : DataLoopNode::NodeFluidType::Air,
2353 : DataLoopNode::ConnectionType::OutsideAirReference,
2354 : NodeInputManager::CompFluidStream::Primary,
2355 : ObjectIsNotParent);
2356 : // warn if not an outdoor node, but allow
2357 0 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
2358 0 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2359 0 : ShowContinueError(
2360 : state,
2361 0 : format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(14), Alphas(14)));
2362 0 : ShowContinueError(
2363 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
2364 : }
2365 : }
2366 :
2367 : // A14, \field Zone Name for Evaporator Placement
2368 12 : if (!lAlphaBlanks(15) && NumAlphas > 14) {
2369 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(15), state.dataHeatBal->Zone);
2370 0 : if (thisDXCoil.SecZonePtr > 0) {
2371 0 : SetupZoneInternalGain(state,
2372 : thisDXCoil.SecZonePtr,
2373 : thisDXCoil.Name,
2374 : DataHeatBalance::IntGainType::SecHeatingDXCoilSingleSpeed,
2375 : &thisDXCoil.SecCoilSensibleHeatRemovalRate,
2376 : nullptr,
2377 : nullptr,
2378 : &thisDXCoil.SecCoilLatentHeatRemovalRate);
2379 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
2380 : } else {
2381 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2382 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15), Alphas(15)));
2383 : }
2384 : }
2385 12 : if (thisDXCoil.SecZonePtr > 0) {
2386 : // N14, \field Secondary Coil Air Flow Rate
2387 0 : if (!lNumericBlanks(13)) {
2388 0 : thisDXCoil.SecCoilAirFlow = Numbers(14);
2389 : }
2390 : // N15, \field Secondary Coil Fan Flow Scaling Factor
2391 0 : if (!lNumericBlanks(15)) {
2392 0 : thisDXCoil.SecCoilAirFlowScalingFactor = Numbers(15);
2393 : }
2394 : // N16, \field Nominal Sensible Heat Ratio of Secondary Coil
2395 0 : if (!lNumericBlanks(16)) {
2396 0 : thisDXCoil.SecCoilRatedSHR = Numbers(16);
2397 : } else {
2398 0 : thisDXCoil.SecCoilRatedSHR = 1.0;
2399 : }
2400 : // A16, \field Sensible Heat Ratio Modifier Function of Temperature Curve Name
2401 0 : if (!lAlphaBlanks(16)) {
2402 0 : thisDXCoil.SecCoilSHRFT = GetCurveIndex(state, Alphas(16));
2403 0 : if (thisDXCoil.SecCoilSHRFT == 0) {
2404 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2405 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
2406 : }
2407 : }
2408 : // A17; \field Sensible Heat Ratio Function of Flow Fraction Curve Name
2409 0 : if (!lAlphaBlanks(17)) {
2410 0 : thisDXCoil.SecCoilSHRFF = GetCurveIndex(state, Alphas(17));
2411 0 : if (thisDXCoil.SecCoilSHRFF == 0) {
2412 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2413 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
2414 : }
2415 : }
2416 : }
2417 :
2418 : } // end of the DX heating coil loop
2419 :
2420 135 : if (ErrorsFound) {
2421 0 : ShowFatalError(state,
2422 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
2423 : }
2424 :
2425 135 : CurrentModuleObject = "Coil:Cooling:DX:TwoSpeed";
2426 147 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedCoils; ++DXCoilIndex) {
2427 :
2428 12 : ++DXCoilNum;
2429 :
2430 12 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2431 : CurrentModuleObject,
2432 : DXCoilIndex,
2433 : Alphas,
2434 : NumAlphas,
2435 : Numbers,
2436 : NumNumbers,
2437 : IOStatus,
2438 : lNumericBlanks,
2439 : lAlphaBlanks,
2440 : cAlphaFields,
2441 : cNumericFields);
2442 :
2443 12 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
2444 :
2445 : // allocate single performance mode for numeric field strings used for sizing routine
2446 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
2447 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
2448 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
2449 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
2450 12 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
2451 :
2452 12 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
2453 12 : thisDXCoil.Name = Alphas(1);
2454 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
2455 12 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
2456 12 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
2457 12 : thisDXCoil.DXCoilType = CurrentModuleObject;
2458 12 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingTwoSpeed;
2459 12 : if (lAlphaBlanks(2)) {
2460 2 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
2461 10 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
2462 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
2463 0 : ErrorsFound = true;
2464 : }
2465 12 : thisDXCoil.RatedTotCap(1) = Numbers(1);
2466 12 : thisDXCoil.RatedSHR(1) = Numbers(2);
2467 12 : thisDXCoil.RatedCOP(1) = Numbers(3);
2468 12 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(4);
2469 :
2470 12 : thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(5);
2471 12 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(6);
2472 :
2473 12 : if (!lNumericBlanks(7)) {
2474 5 : thisDXCoil.InternalStaticPressureDrop = Numbers(7);
2475 5 : thisDXCoil.RateWithInternalStaticAndFanObject = true;
2476 : } else {
2477 7 : thisDXCoil.InternalStaticPressureDrop = -999.0;
2478 7 : thisDXCoil.RateWithInternalStaticAndFanObject = false;
2479 : }
2480 :
2481 12 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
2482 12 : Alphas(3),
2483 : ErrorsFound,
2484 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
2485 12 : Alphas(1),
2486 : DataLoopNode::NodeFluidType::Air,
2487 : DataLoopNode::ConnectionType::Inlet,
2488 : NodeInputManager::CompFluidStream::Primary,
2489 : ObjectIsNotParent);
2490 :
2491 24 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
2492 12 : Alphas(4),
2493 : ErrorsFound,
2494 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
2495 12 : Alphas(1),
2496 : DataLoopNode::NodeFluidType::Air,
2497 : DataLoopNode::ConnectionType::Outlet,
2498 : NodeInputManager::CompFluidStream::Primary,
2499 : ObjectIsNotParent);
2500 :
2501 12 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
2502 :
2503 12 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
2504 12 : if (thisDXCoil.CCapFTemp(1) == 0) {
2505 0 : if (lAlphaBlanks(5)) {
2506 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2507 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
2508 : } else {
2509 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2510 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
2511 : }
2512 0 : ErrorsFound = true;
2513 : } else {
2514 : // Verify Curve Object, only legal type is BiQuadratic
2515 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2516 12 : thisDXCoil.CCapFTemp(1), // Curve index
2517 : {2}, // Valid dimensions
2518 : RoutineName, // Routine name
2519 : CurrentModuleObject, // Object Type
2520 : thisDXCoil.Name, // Object Name
2521 12 : cAlphaFields(5)); // Field Name
2522 :
2523 12 : if (!ErrorsFound) {
2524 12 : checkCurveIsNormalizedToOne(state,
2525 36 : std::string{RoutineName} + CurrentModuleObject,
2526 12 : thisDXCoil.Name,
2527 12 : thisDXCoil.CCapFTemp(1),
2528 12 : cAlphaFields(5),
2529 12 : Alphas(5),
2530 : RatedInletWetBulbTemp,
2531 : RatedOutdoorAirTemp);
2532 : }
2533 : }
2534 :
2535 12 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
2536 12 : if (thisDXCoil.CCapFFlow(1) == 0) {
2537 0 : if (lAlphaBlanks(6)) {
2538 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2539 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
2540 : } else {
2541 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2542 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
2543 : }
2544 0 : ErrorsFound = true;
2545 : } else {
2546 : // Verify Curve Object, only legal type is Quadratic
2547 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2548 12 : thisDXCoil.CCapFFlow(1), // Curve index
2549 : {1}, // Valid dimensions
2550 : RoutineName, // Routine name
2551 : CurrentModuleObject, // Object Type
2552 : thisDXCoil.Name, // Object Name
2553 12 : cAlphaFields(6)); // Field Name
2554 :
2555 12 : if (!ErrorsFound) {
2556 12 : checkCurveIsNormalizedToOne(
2557 48 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
2558 : }
2559 : }
2560 :
2561 12 : thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
2562 12 : if (thisDXCoil.EIRFTemp(1) == 0) {
2563 0 : if (lAlphaBlanks(7)) {
2564 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2565 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
2566 : } else {
2567 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2568 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
2569 : }
2570 0 : ErrorsFound = true;
2571 : } else {
2572 : // Verify Curve Object, only legal type is BiQuadratic
2573 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2574 12 : thisDXCoil.EIRFTemp(1), // Curve index
2575 : {2}, // Valid dimensions
2576 : RoutineName, // Routine name
2577 : CurrentModuleObject, // Object Type
2578 : thisDXCoil.Name, // Object Name
2579 12 : cAlphaFields(7)); // Field Name
2580 :
2581 12 : if (!ErrorsFound) {
2582 12 : checkCurveIsNormalizedToOne(state,
2583 36 : std::string{RoutineName} + CurrentModuleObject,
2584 12 : thisDXCoil.Name,
2585 12 : thisDXCoil.EIRFTemp(1),
2586 12 : cAlphaFields(7),
2587 12 : Alphas(7),
2588 : RatedInletWetBulbTemp,
2589 : RatedOutdoorAirTemp);
2590 : }
2591 : }
2592 :
2593 12 : thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
2594 12 : if (thisDXCoil.EIRFFlow(1) == 0) {
2595 0 : if (lAlphaBlanks(8)) {
2596 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2597 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
2598 : } else {
2599 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2600 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
2601 : }
2602 0 : ErrorsFound = true;
2603 : } else {
2604 : // Verify Curve Object, only legal type is Quadratic
2605 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2606 12 : thisDXCoil.EIRFFlow(1), // Curve index
2607 : {1}, // Valid dimensions
2608 : RoutineName, // Routine name
2609 : CurrentModuleObject, // Object Type
2610 : thisDXCoil.Name, // Object Name
2611 12 : cAlphaFields(8)); // Field Name
2612 :
2613 12 : if (!ErrorsFound) {
2614 12 : checkCurveIsNormalizedToOne(
2615 48 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
2616 : }
2617 : }
2618 :
2619 12 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
2620 12 : if (thisDXCoil.PLFFPLR(1) == 0) {
2621 0 : if (lAlphaBlanks(9)) {
2622 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2623 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
2624 : } else {
2625 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2626 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
2627 : }
2628 0 : ErrorsFound = true;
2629 : } else {
2630 : // Verify Curve Object, only legal types are Quadratic or Cubic
2631 36 : ErrorsFound |= Curve::CheckCurveDims(state,
2632 12 : thisDXCoil.PLFFPLR(1), // Curve index
2633 : {1}, // Valid dimensions
2634 : RoutineName, // Routine name
2635 : CurrentModuleObject, // Object Type
2636 : thisDXCoil.Name, // Object Name
2637 12 : cAlphaFields(9)); // Field Name
2638 :
2639 12 : if (!ErrorsFound) {
2640 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
2641 12 : MinCurveVal = 999.0;
2642 12 : MaxCurveVal = -999.0;
2643 12 : CurveInput = 0.0;
2644 1212 : while (CurveInput <= 1.0) {
2645 1200 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
2646 1200 : if (CurveVal < MinCurveVal) {
2647 12 : MinCurveVal = CurveVal;
2648 12 : MinCurvePLR = CurveInput;
2649 : }
2650 1200 : if (CurveVal > MaxCurveVal) {
2651 1052 : MaxCurveVal = CurveVal;
2652 1052 : MaxCurvePLR = CurveInput;
2653 : }
2654 1200 : CurveInput += 0.01;
2655 : }
2656 12 : if (MinCurveVal < 0.7) {
2657 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2658 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
2659 0 : ShowContinueError(state,
2660 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
2661 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
2662 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
2663 : }
2664 :
2665 12 : if (MaxCurveVal > 1.0) {
2666 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2667 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
2668 0 : ShowContinueError(state,
2669 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
2670 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
2671 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
2672 : }
2673 : }
2674 : }
2675 :
2676 12 : thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
2677 :
2678 12 : thisDXCoil.RatedTotCap2 = Numbers(8);
2679 12 : thisDXCoil.RatedSHR2 = Numbers(9);
2680 12 : thisDXCoil.RatedCOP2 = Numbers(10);
2681 12 : thisDXCoil.RatedAirVolFlowRate2 = Numbers(11);
2682 :
2683 12 : thisDXCoil.FanPowerPerEvapAirFlowRate_LowSpeed(1) = Numbers(12);
2684 12 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023_LowSpeed(1) = Numbers(13);
2685 :
2686 12 : if (lNumericBlanks(14)) {
2687 11 : thisDXCoil.MinOATCompressor = -25.0;
2688 : } else {
2689 1 : thisDXCoil.MinOATCompressor = Numbers(14);
2690 : }
2691 :
2692 12 : thisDXCoil.CCapFTemp2 = GetCurveIndex(state, Alphas(10)); // convert curve name to number
2693 12 : if (thisDXCoil.CCapFTemp2 == 0) {
2694 0 : if (lAlphaBlanks(10)) {
2695 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2696 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(10)));
2697 : } else {
2698 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2699 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
2700 : }
2701 0 : ErrorsFound = true;
2702 : } else {
2703 : // Verify Curve Object, only legal type is BiQuadratic
2704 24 : ErrorsFound |= Curve::CheckCurveDims(state,
2705 : thisDXCoil.CCapFTemp2, // Curve index
2706 : {2}, // Valid dimensions
2707 : RoutineName, // Routine name
2708 : CurrentModuleObject, // Object Type
2709 : thisDXCoil.Name, // Object Name
2710 12 : cAlphaFields(10)); // Field Name
2711 :
2712 12 : if (!ErrorsFound) {
2713 12 : checkCurveIsNormalizedToOne(state,
2714 36 : std::string{RoutineName} + CurrentModuleObject,
2715 12 : thisDXCoil.Name,
2716 : thisDXCoil.CCapFTemp2,
2717 12 : cAlphaFields(10),
2718 12 : Alphas(10),
2719 : RatedInletWetBulbTemp,
2720 : RatedOutdoorAirTemp);
2721 : }
2722 : }
2723 :
2724 12 : thisDXCoil.EIRFTemp2 = GetCurveIndex(state, Alphas(11)); // convert curve name to number
2725 12 : if (thisDXCoil.EIRFTemp2 == 0) {
2726 0 : if (lAlphaBlanks(11)) {
2727 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2728 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(11)));
2729 : } else {
2730 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2731 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
2732 : }
2733 0 : ErrorsFound = true;
2734 : } else {
2735 : // Verify Curve Object, only legal type is BiQuadratic
2736 24 : ErrorsFound |= Curve::CheckCurveDims(state,
2737 : thisDXCoil.EIRFTemp2, // Curve index
2738 : {2}, // Valid dimensions
2739 : RoutineName, // Routine name
2740 : CurrentModuleObject, // Object Type
2741 : thisDXCoil.Name, // Object Name
2742 12 : cAlphaFields(11)); // Field Name
2743 :
2744 12 : if (!ErrorsFound) {
2745 12 : checkCurveIsNormalizedToOne(state,
2746 36 : std::string{RoutineName} + CurrentModuleObject,
2747 12 : thisDXCoil.Name,
2748 : thisDXCoil.EIRFTemp2,
2749 12 : cAlphaFields(11),
2750 12 : Alphas(11),
2751 : RatedInletWetBulbTemp,
2752 : RatedOutdoorAirTemp);
2753 : }
2754 : }
2755 :
2756 : // outdoor condenser node
2757 12 : if (lAlphaBlanks(12)) {
2758 6 : thisDXCoil.CondenserInletNodeNum(1) = 0;
2759 : } else {
2760 12 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
2761 6 : Alphas(12),
2762 : ErrorsFound,
2763 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
2764 6 : thisDXCoil.Name,
2765 : DataLoopNode::NodeFluidType::Air,
2766 : DataLoopNode::ConnectionType::OutsideAirReference,
2767 : NodeInputManager::CompFluidStream::Primary,
2768 : ObjectIsNotParent);
2769 6 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
2770 4 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2771 8 : ShowContinueError(
2772 : state,
2773 8 : format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(12), Alphas(12)));
2774 12 : ShowContinueError(
2775 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
2776 : }
2777 : }
2778 :
2779 12 : if ((Util::SameString(Alphas(13), "AirCooled")) || lAlphaBlanks(13)) {
2780 10 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
2781 2 : } else if (Util::SameString(Alphas(13), "EvaporativelyCooled")) {
2782 2 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
2783 2 : thisDXCoil.ReportEvapCondVars = true;
2784 : } else {
2785 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2786 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(13), Alphas(13)));
2787 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
2788 0 : ErrorsFound = true;
2789 : }
2790 :
2791 12 : thisDXCoil.EvapCondEffect(1) = Numbers(15);
2792 12 : if (thisDXCoil.EvapCondEffect(1) < 0.0 || thisDXCoil.EvapCondEffect(1) > 1.0) {
2793 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2794 0 : ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields(15)));
2795 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(15)));
2796 0 : ErrorsFound = true;
2797 : }
2798 :
2799 12 : thisDXCoil.EvapCondAirFlow(1) = Numbers(16);
2800 12 : if (thisDXCoil.EvapCondAirFlow(1) < 0.0 && thisDXCoil.EvapCondAirFlow(1) != AutoSize) {
2801 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2802 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(16)));
2803 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(16)));
2804 0 : ErrorsFound = true;
2805 : }
2806 :
2807 12 : thisDXCoil.EvapCondPumpElecNomPower(1) = Numbers(17);
2808 12 : if (thisDXCoil.EvapCondPumpElecNomPower(1) < 0.0 && thisDXCoil.EvapCondPumpElecNomPower(1) != AutoSize) {
2809 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2810 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(17)));
2811 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(17)));
2812 0 : ErrorsFound = true;
2813 : }
2814 :
2815 12 : thisDXCoil.EvapCondEffect2 = Numbers(18);
2816 12 : if (thisDXCoil.EvapCondEffect2 < 0.0 || thisDXCoil.EvapCondEffect2 > 1.0) {
2817 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2818 0 : ShowContinueError(state, format("...{} cannot be cannot be < 0.0 or > 1.0.", cNumericFields(18)));
2819 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(18)));
2820 0 : ErrorsFound = true;
2821 : }
2822 :
2823 12 : thisDXCoil.EvapCondAirFlow2 = Numbers(19);
2824 12 : if (thisDXCoil.EvapCondAirFlow2 < 0.0 && thisDXCoil.EvapCondAirFlow2 != AutoSize) {
2825 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2826 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(19)));
2827 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(19)));
2828 0 : ErrorsFound = true;
2829 : }
2830 :
2831 12 : thisDXCoil.EvapCondPumpElecNomPower2 = Numbers(20);
2832 12 : if (thisDXCoil.EvapCondPumpElecNomPower2 < 0.0 && thisDXCoil.EvapCondPumpElecNomPower2 != AutoSize) {
2833 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2834 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(20)));
2835 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(20)));
2836 0 : ErrorsFound = true;
2837 : }
2838 :
2839 12 : thisDXCoil.RatedEIR2 = 1.0 / thisDXCoil.RatedCOP2;
2840 :
2841 : // Get Water System tank connections
2842 : // A14, \field Name of Water Storage Tank for Supply
2843 12 : thisDXCoil.EvapWaterSupplyName = Alphas(14);
2844 12 : if (lAlphaBlanks(14)) {
2845 12 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
2846 : } else {
2847 0 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
2848 0 : SetupTankDemandComponent(state,
2849 : thisDXCoil.Name,
2850 : CurrentModuleObject,
2851 : thisDXCoil.EvapWaterSupplyName,
2852 : ErrorsFound,
2853 0 : thisDXCoil.EvapWaterSupTankID,
2854 0 : thisDXCoil.EvapWaterTankDemandARRID);
2855 : }
2856 :
2857 : // A15; \field Name of Water Storage Tank for Condensate Collection
2858 12 : thisDXCoil.CondensateCollectName = Alphas(15);
2859 12 : if (lAlphaBlanks(15)) {
2860 12 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
2861 : } else {
2862 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
2863 0 : SetupTankSupplyComponent(state,
2864 : thisDXCoil.Name,
2865 : CurrentModuleObject,
2866 : thisDXCoil.CondensateCollectName,
2867 : ErrorsFound,
2868 0 : thisDXCoil.CondensateTankID,
2869 0 : thisDXCoil.CondensateTankSupplyARRID);
2870 : }
2871 :
2872 : // Basin heater power as a function of temperature must be greater than or equal to 0
2873 12 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(21);
2874 12 : if (Numbers(21) < 0.0) {
2875 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2876 0 : ShowContinueError(state, format("...{} must be >= 0.0.", cNumericFields(21)));
2877 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(21)));
2878 0 : ErrorsFound = true;
2879 : }
2880 :
2881 12 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(22);
2882 12 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
2883 4 : if (NumNumbers < 22) {
2884 0 : thisDXCoil.BasinHeaterSetPointTemp = 2.0;
2885 : }
2886 4 : if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
2887 0 : ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2888 0 : ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(22)));
2889 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(22)));
2890 : }
2891 : }
2892 :
2893 12 : if (!lAlphaBlanks(16)) {
2894 1 : if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(16))) == nullptr) {
2895 2 : ShowWarningItemNotFound(
2896 1 : state, eoh, cAlphaFields(16), Alphas(16), "Basin heater will be available to operate throughout the simulation.");
2897 : }
2898 : }
2899 :
2900 12 : if (!lAlphaBlanks(17) && NumAlphas > 16) {
2901 0 : thisDXCoil.SHRFTemp(1) = GetCurveIndex(state, Alphas(17)); // convert curve name to number
2902 : // DXCoil(DXCoilNum)%SHRFTemp2 = DXCoil(DXCoilNum)%SHRFTemp(1)
2903 0 : if (thisDXCoil.SHRFTemp(1) == 0) {
2904 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2905 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
2906 : } else {
2907 : // Verify Curve Object, only legal type is BiQuadratic
2908 0 : ErrorsFound |= Curve::CheckCurveDims(state,
2909 0 : thisDXCoil.SHRFTemp(1), // Curve index
2910 : {2}, // Valid dimensions
2911 : RoutineName, // Routine name
2912 : CurrentModuleObject, // Object Type
2913 : thisDXCoil.Name, // Object Name
2914 0 : cAlphaFields(17)); // Field Name
2915 : }
2916 : }
2917 :
2918 12 : if (!lAlphaBlanks(18) && NumAlphas > 17) {
2919 0 : thisDXCoil.SHRFFlow(1) = GetCurveIndex(state, Alphas(18)); // convert curve name to number
2920 : // DXCoil(DXCoilNum)%SHRFFlow2 = DXCoil(DXCoilNum)%SHRFFlow(1)
2921 0 : if (thisDXCoil.SHRFFlow(1) == 0) {
2922 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2923 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(18), Alphas(18)));
2924 : } else {
2925 : // Verify Curve Object, only legal type is BiQuadratic
2926 0 : ErrorsFound |= Curve::CheckCurveDims(state,
2927 0 : thisDXCoil.SHRFFlow(1), // Curve index
2928 : {1}, // Valid dimensions
2929 : RoutineName, // Routine name
2930 : CurrentModuleObject, // Object Type
2931 : thisDXCoil.Name, // Object Name
2932 0 : cAlphaFields(18)); // Field Name
2933 : }
2934 : }
2935 :
2936 12 : if (!lAlphaBlanks(19) && NumAlphas > 18) {
2937 0 : thisDXCoil.SHRFTemp2 = GetCurveIndex(state, Alphas(19)); // convert curve name to number
2938 0 : if (thisDXCoil.SHRFTemp2 == 0) {
2939 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2940 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(19), Alphas(19)));
2941 : } else {
2942 : // Verify Curve Object, only legal type is BiQuadratic
2943 0 : ErrorsFound |= Curve::CheckCurveDims(state,
2944 : thisDXCoil.SHRFTemp2, // Curve index
2945 : {2}, // Valid dimensions
2946 : RoutineName, // Routine name
2947 : CurrentModuleObject, // Object Type
2948 : thisDXCoil.Name, // Object Name
2949 0 : cAlphaFields(19)); // Field Name
2950 : }
2951 : }
2952 :
2953 12 : if (!lAlphaBlanks(20) && NumAlphas > 19) {
2954 0 : thisDXCoil.SHRFFlow2 = GetCurveIndex(state, Alphas(20)); // convert curve name to number
2955 0 : if (thisDXCoil.SHRFTemp2 == 0) {
2956 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2957 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(20), Alphas(20)));
2958 : } else {
2959 : // Verify Curve Object, only legal type is BiQuadratic
2960 0 : ErrorsFound |= Curve::CheckCurveDims(state,
2961 : thisDXCoil.SHRFFlow2, // Curve index
2962 : {1}, // Valid dimensions
2963 : RoutineName, // Routine name
2964 : CurrentModuleObject, // Object Type
2965 : thisDXCoil.Name, // Object Name
2966 0 : cAlphaFields(20)); // Field Name
2967 : }
2968 : }
2969 12 : if (thisDXCoil.SHRFTemp(1) > 0 && thisDXCoil.SHRFFlow(1) > 0 && thisDXCoil.SHRFTemp2 > 0 && thisDXCoil.SHRFFlow2 > 0) {
2970 0 : thisDXCoil.UserSHRCurveExists = true;
2971 : } else {
2972 12 : thisDXCoil.UserSHRCurveExists = false;
2973 : }
2974 : // A21; \field Zone Name for Condenser Placement
2975 12 : if (!lAlphaBlanks(21) && NumAlphas > 20) {
2976 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(21), state.dataHeatBal->Zone);
2977 0 : if (thisDXCoil.SecZonePtr > 0) {
2978 0 : SetupZoneInternalGain(state,
2979 : thisDXCoil.SecZonePtr,
2980 : thisDXCoil.Name,
2981 : DataHeatBalance::IntGainType::SecCoolingDXCoilTwoSpeed,
2982 : &thisDXCoil.SecCoilSensibleHeatGainRate);
2983 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
2984 : } else {
2985 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2986 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(21), Alphas(21)));
2987 : }
2988 : }
2989 : }
2990 :
2991 135 : if (ErrorsFound) {
2992 0 : ShowFatalError(state,
2993 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
2994 : }
2995 :
2996 : // Loop over the Pumped DX Water Heater Coils and get & load the data
2997 135 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped);
2998 144 : for (DXHPWaterHeaterCoilNum = 1; DXHPWaterHeaterCoilNum <= state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils; ++DXHPWaterHeaterCoilNum) {
2999 :
3000 9 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3001 : CurrentModuleObject,
3002 : DXHPWaterHeaterCoilNum,
3003 : Alphas,
3004 : NumAlphas,
3005 : Numbers,
3006 : NumNumbers,
3007 : IOStatus,
3008 : lNumericBlanks,
3009 : lAlphaBlanks,
3010 : cAlphaFields,
3011 : cNumericFields);
3012 :
3013 9 : ++DXCoilNum;
3014 :
3015 : // allocate single performance mode for numeric field strings used for sizing routine
3016 9 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
3017 9 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
3018 9 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
3019 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
3020 9 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
3021 :
3022 9 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
3023 9 : thisDXCoil.Name = Alphas(1);
3024 9 : thisDXCoil.DXCoilType = CurrentModuleObject;
3025 9 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatPumpWaterHeaterPumped;
3026 9 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOff(state); // heat pump water heater DX coil has no schedule
3027 :
3028 : // Store the HPWH DX coil heating capacity in RatedTotCap2. After backing off pump and fan heat,
3029 : // move to RatedTotCap() for use by DX coil
3030 9 : thisDXCoil.RatedTotCap2 = Numbers(1);
3031 9 : if (thisDXCoil.RatedTotCap2 <= 0.0) {
3032 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3033 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
3034 0 : ErrorsFound = true;
3035 : }
3036 :
3037 9 : thisDXCoil.RatedCOP(1) = Numbers(2);
3038 9 : if (thisDXCoil.RatedCOP(1) <= 0.0) {
3039 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3040 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(2), Numbers(2)));
3041 0 : ErrorsFound = true;
3042 : }
3043 :
3044 9 : thisDXCoil.RatedSHR(1) = Numbers(3);
3045 9 : if (thisDXCoil.RatedSHR(1) <= 0.0 || thisDXCoil.RatedSHR(1) > 1.0) {
3046 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3047 0 : ShowContinueError(state, format("...{} must be > 0 and <= 1. entered value=[{:.3T}].", cNumericFields(3), Numbers(3)));
3048 :
3049 0 : ErrorsFound = true;
3050 : }
3051 :
3052 9 : thisDXCoil.RatedInletDBTemp = Numbers(4);
3053 9 : if (thisDXCoil.RatedInletDBTemp <= 5.0) {
3054 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3055 0 : ShowContinueError(state, format("...{} must be > 5 {{C}}. entered value=[{:.1T}].", cNumericFields(4), Numbers(4)));
3056 0 : ErrorsFound = true;
3057 : }
3058 :
3059 9 : thisDXCoil.RatedInletWBTemp = Numbers(5);
3060 9 : if (thisDXCoil.RatedInletWBTemp <= 5.0) {
3061 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3062 0 : ShowContinueError(state, format("...{} must be > 5 {{C}}. entered value=[{:.1T}].", cNumericFields(5), Numbers(5)));
3063 0 : ErrorsFound = true;
3064 : }
3065 :
3066 9 : thisDXCoil.RatedInletWaterTemp = Numbers(6);
3067 9 : if (thisDXCoil.RatedInletWaterTemp <= 25.0) {
3068 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3069 0 : ShowContinueError(state, format("...{} must be > 25 {{C}}. entered value=[{:.1T}].", cNumericFields(6), Numbers(6)));
3070 0 : ErrorsFound = true;
3071 : }
3072 :
3073 9 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(7);
3074 9 : if (thisDXCoil.RatedAirVolFlowRate(1) != Constant::AutoCalculate) {
3075 0 : if (thisDXCoil.RatedAirVolFlowRate(1) <= 0.0) {
3076 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3077 0 : ShowContinueError(state, format("...{} must be > 0.0. entered value=[{:.3T}].", cNumericFields(7), Numbers(7)));
3078 0 : ErrorsFound = true;
3079 : }
3080 : }
3081 :
3082 9 : thisDXCoil.RatedHPWHCondWaterFlow = Numbers(8);
3083 : // move to init
3084 9 : if (thisDXCoil.RatedHPWHCondWaterFlow != Constant::AutoCalculate) {
3085 0 : if (thisDXCoil.RatedHPWHCondWaterFlow <= 0.0) {
3086 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3087 0 : ShowContinueError(state, format("...{} must be > 0.0 entered value=[{:.3T}].", cNumericFields(8), Numbers(8)));
3088 0 : ErrorsFound = true;
3089 : }
3090 : // check the range of flow rate to be >= 1 gpm/ton and <= 5 gpm/ton
3091 0 : if (thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2 < 1.79405e-8 ||
3092 0 : thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2 > 8.97024e-8) {
3093 0 : ShowWarningError(state, format("{}{}=\"{}\", outside range", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3094 0 : ShowContinueError(state,
3095 0 : format("...{} per watt of {} is outside the recommended range of >= 1.79405E-8 m3/s/W (0.083 gpm/MBH) and <= "
3096 : "8.97024E-8 m3/s/W (0.417 gpm/MBH).",
3097 : cNumericFields(8),
3098 : cNumericFields(1)));
3099 0 : ShowContinueError(
3100 0 : state, format("...Entered Flow rate per watt = [{:.10T}].", (thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2)));
3101 : }
3102 : }
3103 :
3104 9 : if (Util::SameString(Alphas(2), "Yes") || Util::SameString(Alphas(2), "No")) {
3105 : // initialized to TRUE on allocate
3106 9 : if (Util::SameString(Alphas(2), "No")) {
3107 9 : thisDXCoil.FanPowerIncludedInCOP = false;
3108 : }
3109 : } else {
3110 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3111 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(2), Alphas(2)));
3112 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3113 0 : ErrorsFound = true;
3114 : }
3115 :
3116 9 : if (Util::SameString(Alphas(3), "Yes") || Util::SameString(Alphas(3), "No")) {
3117 : // initialized to FALSE on allocate
3118 9 : if (Util::SameString(Alphas(3), "Yes")) {
3119 0 : thisDXCoil.CondPumpPowerInCOP = true;
3120 : }
3121 : } else {
3122 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3123 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(3), Alphas(3)));
3124 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3125 0 : ErrorsFound = true;
3126 : }
3127 :
3128 9 : if (Util::SameString(Alphas(4), "Yes") || Util::SameString(Alphas(4), "No")) {
3129 : // initialized to FALSE on allocate
3130 9 : if (Util::SameString(Alphas(4), "Yes")) {
3131 0 : thisDXCoil.CondPumpHeatInCapacity = true;
3132 : }
3133 : } else {
3134 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3135 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(4), Alphas(4)));
3136 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3137 0 : ErrorsFound = true;
3138 : }
3139 :
3140 9 : thisDXCoil.HPWHCondPumpElecNomPower = Numbers(9);
3141 9 : if (thisDXCoil.HPWHCondPumpElecNomPower < 0.0) {
3142 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3143 0 : ShowContinueError(state, format("...{} must be >= 0.0 entered value=[{:.3T}].", cNumericFields(9), Numbers(9)));
3144 0 : ErrorsFound = true;
3145 : }
3146 :
3147 9 : thisDXCoil.HPWHCondPumpFracToWater = Numbers(10);
3148 9 : if (thisDXCoil.HPWHCondPumpFracToWater <= 0.0 || thisDXCoil.HPWHCondPumpFracToWater > 1.0) {
3149 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3150 0 : ShowContinueError(state, format("...{} must be >= 0 and <= 1. entered value=[{:.3T}].", cNumericFields(10), Numbers(10)));
3151 0 : ErrorsFound = true;
3152 : }
3153 :
3154 : // Air nodes
3155 9 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
3156 9 : Alphas(5),
3157 : ErrorsFound,
3158 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3159 9 : Alphas(1),
3160 : DataLoopNode::NodeFluidType::Air,
3161 : DataLoopNode::ConnectionType::Inlet,
3162 : NodeInputManager::CompFluidStream::Primary,
3163 : ObjectIsNotParent);
3164 :
3165 18 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
3166 9 : Alphas(6),
3167 : ErrorsFound,
3168 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3169 9 : Alphas(1),
3170 : DataLoopNode::NodeFluidType::Air,
3171 : DataLoopNode::ConnectionType::Outlet,
3172 : NodeInputManager::CompFluidStream::Primary,
3173 : ObjectIsNotParent);
3174 :
3175 9 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(5), Alphas(6), "Air Nodes");
3176 :
3177 : // Check if the air inlet node is OA node, to justify whether the coil is placed in zone or not
3178 9 : thisDXCoil.IsDXCoilInZone = !CheckOutAirNodeNumber(state, thisDXCoil.AirInNode);
3179 :
3180 : // Water nodes
3181 9 : thisDXCoil.WaterInNode = GetOnlySingleNode(state,
3182 9 : Alphas(7),
3183 : ErrorsFound,
3184 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3185 9 : Alphas(1),
3186 : DataLoopNode::NodeFluidType::Water,
3187 : DataLoopNode::ConnectionType::Inlet,
3188 : NodeInputManager::CompFluidStream::Secondary,
3189 : ObjectIsNotParent);
3190 :
3191 18 : thisDXCoil.WaterOutNode = GetOnlySingleNode(state,
3192 9 : Alphas(8),
3193 : ErrorsFound,
3194 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3195 9 : Alphas(1),
3196 : DataLoopNode::NodeFluidType::Water,
3197 : DataLoopNode::ConnectionType::Outlet,
3198 : NodeInputManager::CompFluidStream::Secondary,
3199 : ObjectIsNotParent);
3200 :
3201 9 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(7), Alphas(8), "Water Nodes");
3202 :
3203 9 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(11);
3204 9 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
3205 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3206 0 : ShowContinueError(state, format("...{} must be >= 0.0 entered value=[{:.1T}].", cNumericFields(11), Numbers(11)));
3207 0 : ErrorsFound = true;
3208 : }
3209 :
3210 9 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(12);
3211 9 : if (thisDXCoil.MaxOATCrankcaseHeater < 0.0) {
3212 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3213 0 : ShowContinueError(state, format("...{} must be >= 0 {{C}}. entered value=[{:.1T}].", cNumericFields(12), Numbers(12)));
3214 0 : ErrorsFound = true;
3215 : }
3216 :
3217 9 : if (!lAlphaBlanks(9)) {
3218 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(9));
3219 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
3220 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(9), Alphas(9)));
3221 0 : ErrorsFound = true;
3222 : } else {
3223 6 : ErrorsFound |= Curve::CheckCurveDims(state,
3224 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
3225 : {1}, // Valid dimensions
3226 : RoutineName, // Routine name
3227 : CurrentModuleObject, // Object Type
3228 : thisDXCoil.Name, // Object Name
3229 2 : cAlphaFields(9)); // Field Name
3230 : }
3231 : }
3232 :
3233 9 : thisDXCoil.InletAirTemperatureType = static_cast<HVAC::OATType>(getEnumValue(HVAC::oatTypeNamesUC, Alphas(10)));
3234 :
3235 : // set rated inlet air temperature for curve object verification
3236 9 : if (thisDXCoil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
3237 9 : InletAirTemp = thisDXCoil.RatedInletWBTemp;
3238 : } else {
3239 0 : InletAirTemp = thisDXCoil.RatedInletDBTemp;
3240 : }
3241 : // set rated water temperature for curve object verification
3242 9 : InletWaterTemp = thisDXCoil.RatedInletWaterTemp;
3243 :
3244 9 : if (!lAlphaBlanks(11)) {
3245 9 : thisDXCoil.HCapFTemp = GetCurveIndex(state, Alphas(11));
3246 9 : if (thisDXCoil.HCapFTemp == 0) {
3247 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3248 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
3249 0 : ErrorsFound = true;
3250 : } else {
3251 : // Verify Curve Object, only legal types are BiQuadratic or Cubic
3252 18 : ErrorsFound |= Curve::CheckCurveDims(state,
3253 : thisDXCoil.HCapFTemp, // Curve index
3254 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
3255 : RoutineName, // Routine name
3256 : CurrentModuleObject, // Object Type
3257 : thisDXCoil.Name, // Object Name
3258 9 : cAlphaFields(11)); // Field Name
3259 :
3260 9 : if (!ErrorsFound) {
3261 9 : if (state.dataCurveManager->curves(thisDXCoil.HCapFTemp)->numDims == 1) {
3262 2 : checkCurveIsNormalizedToOne(state,
3263 6 : std::string{RoutineName} + CurrentModuleObject,
3264 2 : thisDXCoil.Name,
3265 : thisDXCoil.HCapFTemp,
3266 2 : cAlphaFields(11),
3267 2 : Alphas(11),
3268 : InletAirTemp);
3269 : } else {
3270 7 : checkCurveIsNormalizedToOne(state,
3271 21 : std::string{RoutineName} + CurrentModuleObject,
3272 7 : thisDXCoil.Name,
3273 : thisDXCoil.HCapFTemp,
3274 7 : cAlphaFields(11),
3275 7 : Alphas(11),
3276 : InletAirTemp,
3277 : InletWaterTemp);
3278 : }
3279 : }
3280 : }
3281 : }
3282 :
3283 9 : if (!lAlphaBlanks(12)) {
3284 2 : thisDXCoil.HCapFAirFlow = GetCurveIndex(state, Alphas(12));
3285 2 : if (thisDXCoil.HCapFAirFlow == 0) {
3286 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3287 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(12), Alphas(12)));
3288 0 : ErrorsFound = true;
3289 : } else {
3290 : // Verify Curve Object, only legal types are Cubic or Quadratic
3291 4 : ErrorsFound |= Curve::CheckCurveDims(state,
3292 : thisDXCoil.HCapFAirFlow, // Curve index
3293 : {1}, // Valid dimensions
3294 : RoutineName, // Routine name
3295 : CurrentModuleObject, // Object Type
3296 : thisDXCoil.Name, // Object Name
3297 2 : cAlphaFields(12)); // Field Name
3298 :
3299 2 : if (!ErrorsFound) {
3300 2 : checkCurveIsNormalizedToOne(state,
3301 6 : std::string{RoutineName} + CurrentModuleObject,
3302 2 : thisDXCoil.Name,
3303 : thisDXCoil.HCapFAirFlow,
3304 2 : cAlphaFields(12),
3305 2 : Alphas(12),
3306 : 1.0);
3307 : }
3308 : }
3309 : }
3310 :
3311 9 : if (!lAlphaBlanks(13)) {
3312 2 : thisDXCoil.HCapFWaterFlow = GetCurveIndex(state, Alphas(13));
3313 2 : if (thisDXCoil.HCapFWaterFlow == 0) {
3314 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3315 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(13), Alphas(13)));
3316 0 : ErrorsFound = true;
3317 : } else {
3318 : // Verify Curve Object, only legal types are Cubic or Quadratic
3319 4 : ErrorsFound |= Curve::CheckCurveDims(state,
3320 : thisDXCoil.HCapFWaterFlow, // Curve index
3321 : {1}, // Valid dimensions
3322 : RoutineName, // Routine name
3323 : CurrentModuleObject, // Object Type
3324 : thisDXCoil.Name, // Object Name
3325 2 : cAlphaFields(13)); // Field Name
3326 :
3327 2 : if (!ErrorsFound) {
3328 2 : checkCurveIsNormalizedToOne(state,
3329 6 : std::string{RoutineName} + CurrentModuleObject,
3330 2 : thisDXCoil.Name,
3331 : thisDXCoil.HCapFWaterFlow,
3332 2 : cAlphaFields(13),
3333 2 : Alphas(13),
3334 : 1.0);
3335 : }
3336 : }
3337 : }
3338 :
3339 9 : if (!lAlphaBlanks(14)) {
3340 9 : thisDXCoil.HCOPFTemp = GetCurveIndex(state, Alphas(14));
3341 9 : if (thisDXCoil.HCOPFTemp == 0) {
3342 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3343 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14), Alphas(14)));
3344 0 : ErrorsFound = true;
3345 : } else {
3346 : // Verify Curve Object, only legal types are BiQuadratic or Cubic
3347 18 : ErrorsFound |= Curve::CheckCurveDims(state,
3348 : thisDXCoil.HCOPFTemp, // Curve index
3349 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
3350 : RoutineName, // Routine name
3351 : CurrentModuleObject, // Object Type
3352 : thisDXCoil.Name, // Object Name
3353 9 : cAlphaFields(14)); // Field Name
3354 :
3355 9 : if (!ErrorsFound) {
3356 9 : if (state.dataCurveManager->curves(thisDXCoil.HCOPFTemp)->numDims == 1) {
3357 0 : checkCurveIsNormalizedToOne(state,
3358 0 : std::string{RoutineName} + CurrentModuleObject,
3359 0 : thisDXCoil.Name,
3360 : thisDXCoil.HCOPFTemp,
3361 0 : cAlphaFields(14),
3362 0 : Alphas(14),
3363 : InletAirTemp);
3364 : } else {
3365 9 : checkCurveIsNormalizedToOne(state,
3366 27 : std::string{RoutineName} + CurrentModuleObject,
3367 9 : thisDXCoil.Name,
3368 : thisDXCoil.HCOPFTemp,
3369 9 : cAlphaFields(14),
3370 9 : Alphas(14),
3371 : InletAirTemp,
3372 : InletWaterTemp);
3373 : }
3374 : }
3375 : }
3376 : }
3377 :
3378 9 : if (!lAlphaBlanks(15)) {
3379 2 : thisDXCoil.HCOPFAirFlow = GetCurveIndex(state, Alphas(15));
3380 2 : if (thisDXCoil.HCOPFAirFlow == 0) {
3381 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3382 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15), Alphas(15)));
3383 0 : ErrorsFound = true;
3384 : } else {
3385 : // Verify Curve Object, only legal types are Cubic or Quadratic
3386 4 : ErrorsFound |= Curve::CheckCurveDims(state,
3387 : thisDXCoil.HCOPFAirFlow, // Curve index
3388 : {1}, // Valid dimensions
3389 : RoutineName, // Routine name
3390 : CurrentModuleObject, // Object Type
3391 : thisDXCoil.Name, // Object Name
3392 2 : cAlphaFields(15)); // Field Name
3393 :
3394 2 : if (!ErrorsFound) {
3395 2 : checkCurveIsNormalizedToOne(state,
3396 6 : std::string{RoutineName} + CurrentModuleObject,
3397 2 : thisDXCoil.Name,
3398 : thisDXCoil.HCOPFAirFlow,
3399 2 : cAlphaFields(15),
3400 2 : Alphas(15),
3401 : 1.0);
3402 : }
3403 : }
3404 : }
3405 :
3406 9 : if (!lAlphaBlanks(16)) {
3407 2 : thisDXCoil.HCOPFWaterFlow = GetCurveIndex(state, Alphas(16));
3408 2 : if (thisDXCoil.HCOPFWaterFlow == 0) {
3409 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3410 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
3411 0 : ErrorsFound = true;
3412 : } else {
3413 : // Verify Curve Object, only legal types are Cubic or Quadratic
3414 4 : ErrorsFound |= Curve::CheckCurveDims(state,
3415 : thisDXCoil.HCOPFWaterFlow, // Curve index
3416 : {1}, // Valid dimensions
3417 : RoutineName, // Routine name
3418 : CurrentModuleObject, // Object Type
3419 : thisDXCoil.Name, // Object Name
3420 2 : cAlphaFields(16)); // Field Name
3421 :
3422 2 : if (!ErrorsFound) {
3423 2 : checkCurveIsNormalizedToOne(state,
3424 6 : std::string{RoutineName} + CurrentModuleObject,
3425 2 : thisDXCoil.Name,
3426 : thisDXCoil.HCOPFWaterFlow,
3427 2 : cAlphaFields(16),
3428 2 : Alphas(16),
3429 : 1.0);
3430 : }
3431 : }
3432 : }
3433 :
3434 9 : if (!lAlphaBlanks(17)) {
3435 9 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(17));
3436 9 : if (thisDXCoil.PLFFPLR(1) == 0) {
3437 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3438 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
3439 0 : ErrorsFound = true;
3440 : } else {
3441 : // Verify Curve Object, only legal types are Cubic or Quadratic
3442 27 : ErrorsFound |= Curve::CheckCurveDims(state,
3443 9 : thisDXCoil.PLFFPLR(1), // Curve index
3444 : {1}, // Valid dimensions
3445 : RoutineName, // Routine name
3446 : CurrentModuleObject, // Object Type
3447 : thisDXCoil.Name, // Object Name
3448 9 : cAlphaFields(17)); // Field Name
3449 :
3450 9 : if (!ErrorsFound) {
3451 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
3452 9 : MinCurveVal = 999.0;
3453 9 : MaxCurveVal = -999.0;
3454 9 : CurveInput = 0.0;
3455 909 : while (CurveInput <= 1.0) {
3456 900 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
3457 900 : if (CurveVal < MinCurveVal) {
3458 9 : MinCurveVal = CurveVal;
3459 9 : MinCurvePLR = CurveInput;
3460 : }
3461 900 : if (CurveVal > MaxCurveVal) {
3462 702 : MaxCurveVal = CurveVal;
3463 702 : MaxCurvePLR = CurveInput;
3464 : }
3465 900 : CurveInput += 0.01;
3466 : }
3467 9 : if (MinCurveVal < 0.7) {
3468 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3469 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(17), Alphas(17)));
3470 0 : ShowContinueError(state,
3471 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
3472 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
3473 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
3474 : }
3475 :
3476 9 : if (MaxCurveVal > 1.0) {
3477 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3478 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(17), Alphas(17)));
3479 0 : ShowContinueError(state,
3480 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
3481 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
3482 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
3483 : }
3484 : }
3485 : }
3486 : }
3487 :
3488 : // assume compressor resides at the inlet to the DX Coil
3489 9 : thisDXCoil.CondenserInletNodeNum(1) = thisDXCoil.AirInNode;
3490 :
3491 : // set condenser type as HPWH
3492 9 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::WaterHeater;
3493 :
3494 : } // end of the DX water heater coil loop
3495 :
3496 135 : if (ErrorsFound) {
3497 0 : ShowFatalError(state,
3498 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
3499 : }
3500 : // Loop over the Wrapped DX Water Heater Coils and get & load the data
3501 135 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped);
3502 142 : for (DXHPWaterHeaterCoilNum = 1; DXHPWaterHeaterCoilNum <= state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils; ++DXHPWaterHeaterCoilNum) {
3503 :
3504 7 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3505 : CurrentModuleObject,
3506 : DXHPWaterHeaterCoilNum,
3507 : Alphas,
3508 : NumAlphas,
3509 : Numbers,
3510 : NumNumbers,
3511 : IOStatus,
3512 : lNumericBlanks,
3513 : lAlphaBlanks,
3514 : cAlphaFields,
3515 : cNumericFields);
3516 :
3517 7 : ++DXCoilNum;
3518 :
3519 : // allocate single performance mode for numeric field strings used for sizing routine
3520 7 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
3521 7 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
3522 7 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
3523 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
3524 7 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
3525 :
3526 7 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
3527 7 : thisDXCoil.Name = Alphas(1);
3528 7 : thisDXCoil.DXCoilType = CurrentModuleObject;
3529 7 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatPumpWaterHeaterWrapped;
3530 7 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOff(state); // heat pump water heater DX coil has no schedule
3531 :
3532 : // Store the HPWH DX coil heating capacity in RatedTotCap2. After backing off pump and fan heat,
3533 : // move to RatedTotCap() for use by DX coil
3534 7 : thisDXCoil.RatedTotCap2 = Numbers(1);
3535 7 : if (thisDXCoil.RatedTotCap2 <= 0.0) {
3536 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3537 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
3538 0 : ErrorsFound = true;
3539 : }
3540 :
3541 7 : thisDXCoil.RatedCOP(1) = Numbers(2);
3542 7 : if (thisDXCoil.RatedCOP(1) <= 0.0) {
3543 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3544 0 : ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(2), Numbers(2)));
3545 0 : ErrorsFound = true;
3546 : }
3547 :
3548 7 : thisDXCoil.RatedSHR(1) = Numbers(3);
3549 7 : if (thisDXCoil.RatedSHR(1) <= 0.0 || thisDXCoil.RatedSHR(1) > 1.0) {
3550 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3551 0 : ShowContinueError(state, format("...{} must be > 0 and <= 1. entered value=[{:.3T}].", cNumericFields(3), Numbers(3)));
3552 :
3553 0 : ErrorsFound = true;
3554 : }
3555 :
3556 7 : thisDXCoil.RatedInletDBTemp = Numbers(4);
3557 7 : if (thisDXCoil.RatedInletDBTemp <= 5.0) {
3558 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3559 0 : ShowContinueError(state, format("...{} must be > 5 {{C}}. entered value=[{:.1T}].", cNumericFields(4), Numbers(4)));
3560 0 : ErrorsFound = true;
3561 : }
3562 :
3563 7 : thisDXCoil.RatedInletWBTemp = Numbers(5);
3564 7 : if (thisDXCoil.RatedInletWBTemp <= 5.0) {
3565 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3566 0 : ShowContinueError(state, format("...{} must be > 5 {{C}}. entered value=[{:.1T}].", cNumericFields(5), Numbers(5)));
3567 0 : ErrorsFound = true;
3568 : }
3569 :
3570 7 : thisDXCoil.RatedInletWaterTemp = Numbers(6);
3571 7 : if (thisDXCoil.RatedInletWaterTemp <= 25.0) {
3572 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3573 0 : ShowContinueError(state, format("...{} must be > 25 {{C}}. entered value=[{:.1T}].", cNumericFields(6), Numbers(6)));
3574 0 : ErrorsFound = true;
3575 : }
3576 :
3577 7 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(7);
3578 7 : if (thisDXCoil.RatedAirVolFlowRate(1) != Constant::AutoCalculate) {
3579 7 : if (thisDXCoil.RatedAirVolFlowRate(1) <= 0.0) {
3580 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3581 0 : ShowContinueError(state, format("...{} must be > 0.0. entered value=[{:.3T}].", cNumericFields(7), Numbers(7)));
3582 0 : ErrorsFound = true;
3583 : }
3584 : }
3585 :
3586 7 : if (Util::SameString(Alphas(2), "Yes") || Util::SameString(Alphas(2), "No")) {
3587 : // initialized to TRUE on allocate
3588 7 : if (Util::SameString(Alphas(2), "No")) {
3589 0 : thisDXCoil.FanPowerIncludedInCOP = false;
3590 : }
3591 : } else {
3592 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3593 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(2), Alphas(2)));
3594 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3595 0 : ErrorsFound = true;
3596 : }
3597 :
3598 : // Air nodes
3599 7 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
3600 7 : Alphas(3),
3601 : ErrorsFound,
3602 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3603 7 : Alphas(1),
3604 : DataLoopNode::NodeFluidType::Air,
3605 : DataLoopNode::ConnectionType::Inlet,
3606 : NodeInputManager::CompFluidStream::Primary,
3607 : ObjectIsNotParent);
3608 :
3609 14 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
3610 7 : Alphas(4),
3611 : ErrorsFound,
3612 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3613 7 : Alphas(1),
3614 : DataLoopNode::NodeFluidType::Air,
3615 : DataLoopNode::ConnectionType::Outlet,
3616 : NodeInputManager::CompFluidStream::Primary,
3617 : ObjectIsNotParent);
3618 :
3619 7 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
3620 :
3621 : // Check if the air inlet node is OA node, to justify whether the coil is placed in zone or not
3622 7 : thisDXCoil.IsDXCoilInZone = !CheckOutAirNodeNumber(state, thisDXCoil.AirInNode);
3623 :
3624 7 : std::string const DummyCondenserInletName("DUMMY CONDENSER INLET " + thisDXCoil.Name);
3625 7 : std::string const DummyCondenserOutletName("DUMMY CONDENSER OUTLET " + thisDXCoil.Name);
3626 7 : thisDXCoil.WaterInNode = GetOnlySingleNode(state,
3627 : DummyCondenserInletName,
3628 : ErrorsFound,
3629 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3630 7 : Alphas(1),
3631 : DataLoopNode::NodeFluidType::Water,
3632 : DataLoopNode::ConnectionType::Inlet,
3633 : NodeInputManager::CompFluidStream::Secondary,
3634 : ObjectIsNotParent);
3635 :
3636 14 : thisDXCoil.WaterOutNode = GetOnlySingleNode(state,
3637 : DummyCondenserOutletName,
3638 : ErrorsFound,
3639 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3640 7 : Alphas(1),
3641 : DataLoopNode::NodeFluidType::Water,
3642 : DataLoopNode::ConnectionType::Outlet,
3643 : NodeInputManager::CompFluidStream::Secondary,
3644 : ObjectIsNotParent);
3645 :
3646 7 : TestCompSet(state, CurrentModuleObject, Alphas(1), DummyCondenserInletName, DummyCondenserOutletName, "Water Nodes");
3647 :
3648 7 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(8);
3649 7 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
3650 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3651 0 : ShowContinueError(state, format("...{} must be >= 0.0 entered value=[{:.1T}].", cNumericFields(8), Numbers(8)));
3652 0 : ErrorsFound = true;
3653 : }
3654 :
3655 7 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(9);
3656 7 : if (thisDXCoil.MaxOATCrankcaseHeater < 0.0) {
3657 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3658 0 : ShowContinueError(state, format("...{} must be >= 0 {{C}}. entered value=[{:.1T}].", cNumericFields(9), Numbers(9)));
3659 0 : ErrorsFound = true;
3660 : }
3661 :
3662 : // Coil:WaterHeating:AirToWaterHeatPump:Wrapped
3663 7 : if (!lAlphaBlanks(5)) {
3664 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
3665 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
3666 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(5), Alphas(5)));
3667 0 : ErrorsFound = true;
3668 : } else {
3669 6 : ErrorsFound |= Curve::CheckCurveDims(state,
3670 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
3671 : {1}, // Valid dimensions
3672 : RoutineName, // Routine name
3673 : CurrentModuleObject, // Object Type
3674 : thisDXCoil.Name, // Object Name
3675 2 : cAlphaFields(5)); // Field Name
3676 : }
3677 : }
3678 :
3679 7 : if (Util::SameString(Alphas(6), "DryBulbTemperature")) {
3680 0 : thisDXCoil.InletAirTemperatureType = HVAC::OATType::DryBulb;
3681 7 : } else if (Util::SameString(Alphas(6), "WetBulbTemperature")) {
3682 7 : thisDXCoil.InletAirTemperatureType = HVAC::OATType::WetBulb;
3683 : } else {
3684 : // wrong temperature type selection
3685 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3686 0 : ShowContinueError(state, format("...{} must be DryBulbTemperature or WetBulbTemperature.", cAlphaFields(6)));
3687 0 : ShowContinueError(state, format("...entered value=\"{}\".", Alphas(6)));
3688 0 : ErrorsFound = true;
3689 : }
3690 :
3691 : // set rated inlet air temperature for curve object verification
3692 7 : if (thisDXCoil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
3693 7 : InletAirTemp = thisDXCoil.RatedInletWBTemp;
3694 : } else {
3695 0 : InletAirTemp = thisDXCoil.RatedInletDBTemp;
3696 : }
3697 : // set rated water temperature for curve object verification
3698 7 : InletWaterTemp = thisDXCoil.RatedInletWaterTemp;
3699 :
3700 7 : if (!lAlphaBlanks(7)) {
3701 7 : thisDXCoil.HCapFTemp = GetCurveIndex(state, Alphas(7));
3702 7 : if (thisDXCoil.HCapFTemp == 0) {
3703 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3704 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
3705 0 : ErrorsFound = true;
3706 : } else {
3707 : // Verify Curve Object, only legal types are BiQuadratic or Cubic
3708 14 : ErrorsFound |= Curve::CheckCurveDims(state,
3709 : thisDXCoil.HCapFTemp, // Curve index
3710 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
3711 : RoutineName, // Routine name
3712 : CurrentModuleObject, // Object Type
3713 : thisDXCoil.Name, // Object Name
3714 7 : cAlphaFields(7)); // Field Name
3715 :
3716 7 : if (!ErrorsFound) {
3717 7 : if (state.dataCurveManager->curves(thisDXCoil.HCapFTemp)->numDims == 1) {
3718 0 : checkCurveIsNormalizedToOne(state,
3719 0 : std::string{RoutineName} + CurrentModuleObject,
3720 0 : thisDXCoil.Name,
3721 : thisDXCoil.HCapFTemp,
3722 0 : cAlphaFields(7),
3723 0 : Alphas(7),
3724 : InletAirTemp);
3725 : } else {
3726 7 : checkCurveIsNormalizedToOne(state,
3727 21 : std::string{RoutineName} + CurrentModuleObject,
3728 7 : thisDXCoil.Name,
3729 : thisDXCoil.HCapFTemp,
3730 7 : cAlphaFields(7),
3731 7 : Alphas(7),
3732 : InletAirTemp,
3733 : InletWaterTemp);
3734 : }
3735 : }
3736 : }
3737 : }
3738 :
3739 7 : if (!lAlphaBlanks(8)) {
3740 2 : thisDXCoil.HCapFAirFlow = GetCurveIndex(state, Alphas(8));
3741 2 : if (thisDXCoil.HCapFAirFlow == 0) {
3742 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3743 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
3744 0 : ErrorsFound = true;
3745 : } else {
3746 : // Verify Curve Object, only legal types are Cubic or Quadratic
3747 4 : ErrorsFound |= Curve::CheckCurveDims(state,
3748 : thisDXCoil.HCapFAirFlow, // Curve index
3749 : {1}, // Valid dimensions
3750 : RoutineName, // Routine name
3751 : CurrentModuleObject, // Object Type
3752 : thisDXCoil.Name, // Object Name
3753 2 : cAlphaFields(8)); // Field Name
3754 :
3755 2 : if (!ErrorsFound) {
3756 2 : checkCurveIsNormalizedToOne(state,
3757 6 : std::string{RoutineName} + CurrentModuleObject,
3758 2 : thisDXCoil.Name,
3759 : thisDXCoil.HCapFAirFlow,
3760 2 : cAlphaFields(8),
3761 2 : Alphas(8),
3762 : 1.0);
3763 : }
3764 : }
3765 : }
3766 :
3767 7 : if (!lAlphaBlanks(9)) {
3768 7 : thisDXCoil.HCOPFTemp = GetCurveIndex(state, Alphas(9));
3769 7 : if (thisDXCoil.HCOPFTemp == 0) {
3770 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3771 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
3772 0 : ErrorsFound = true;
3773 : } else {
3774 : // Verify Curve Object, only legal types are BiQuadratic or Cubic
3775 14 : ErrorsFound |= Curve::CheckCurveDims(state,
3776 : thisDXCoil.HCOPFTemp, // Curve index
3777 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
3778 : RoutineName, // Routine name
3779 : CurrentModuleObject, // Object Type
3780 : thisDXCoil.Name, // Object Name
3781 7 : cAlphaFields(9)); // Field Name
3782 :
3783 7 : if (!ErrorsFound) {
3784 7 : if (state.dataCurveManager->curves(thisDXCoil.HCOPFTemp)->numDims == 1) {
3785 0 : checkCurveIsNormalizedToOne(state,
3786 0 : std::string{RoutineName} + CurrentModuleObject,
3787 0 : thisDXCoil.Name,
3788 : thisDXCoil.HCOPFTemp,
3789 0 : cAlphaFields(9),
3790 0 : Alphas(9),
3791 : InletAirTemp);
3792 : } else {
3793 7 : checkCurveIsNormalizedToOne(state,
3794 21 : std::string{RoutineName} + CurrentModuleObject,
3795 7 : thisDXCoil.Name,
3796 : thisDXCoil.HCOPFTemp,
3797 7 : cAlphaFields(9),
3798 7 : Alphas(9),
3799 : InletAirTemp,
3800 : InletWaterTemp);
3801 : }
3802 : }
3803 : }
3804 : }
3805 :
3806 7 : if (!lAlphaBlanks(10)) {
3807 2 : thisDXCoil.HCOPFAirFlow = GetCurveIndex(state, Alphas(10));
3808 2 : if (thisDXCoil.HCOPFAirFlow == 0) {
3809 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3810 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
3811 0 : ErrorsFound = true;
3812 : } else {
3813 : // Verify Curve Object, only legal types are Cubic or Quadratic
3814 4 : ErrorsFound |= Curve::CheckCurveDims(state,
3815 : thisDXCoil.HCOPFAirFlow, // Curve index
3816 : {1}, // Valid dimensions
3817 : RoutineName, // Routine name
3818 : CurrentModuleObject, // Object Type
3819 : thisDXCoil.Name, // Object Name
3820 2 : cAlphaFields(10)); // Field Name
3821 :
3822 2 : if (!ErrorsFound) {
3823 2 : checkCurveIsNormalizedToOne(state,
3824 6 : std::string{RoutineName} + CurrentModuleObject,
3825 2 : thisDXCoil.Name,
3826 : thisDXCoil.HCOPFAirFlow,
3827 2 : cAlphaFields(10),
3828 2 : Alphas(10),
3829 : 1.0);
3830 : }
3831 : }
3832 : }
3833 :
3834 7 : if (!lAlphaBlanks(11)) {
3835 4 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(11));
3836 4 : if (thisDXCoil.PLFFPLR(1) == 0) {
3837 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3838 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
3839 0 : ErrorsFound = true;
3840 : } else {
3841 : // Verify Curve Object, only legal types are Cubic or Quadratic
3842 12 : ErrorsFound |= Curve::CheckCurveDims(state,
3843 4 : thisDXCoil.PLFFPLR(1), // Curve index
3844 : {1}, // Valid dimensions
3845 : RoutineName, // Routine name
3846 : CurrentModuleObject, // Object Type
3847 : thisDXCoil.Name, // Object Name
3848 4 : cAlphaFields(11)); // Field Name
3849 :
3850 4 : if (!ErrorsFound) {
3851 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
3852 4 : MinCurveVal = 999.0;
3853 4 : MaxCurveVal = -999.0;
3854 4 : CurveInput = 0.0;
3855 404 : while (CurveInput <= 1.0) {
3856 400 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
3857 400 : if (CurveVal < MinCurveVal) {
3858 4 : MinCurveVal = CurveVal;
3859 4 : MinCurvePLR = CurveInput;
3860 : }
3861 400 : if (CurveVal > MaxCurveVal) {
3862 4 : MaxCurveVal = CurveVal;
3863 4 : MaxCurvePLR = CurveInput;
3864 : }
3865 400 : CurveInput += 0.01;
3866 : }
3867 4 : if (MinCurveVal < 0.7) {
3868 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3869 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(11), Alphas(11)));
3870 0 : ShowContinueError(state,
3871 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
3872 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
3873 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
3874 : }
3875 :
3876 4 : if (MaxCurveVal > 1.0) {
3877 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3878 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(11), Alphas(11)));
3879 0 : ShowContinueError(state,
3880 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
3881 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
3882 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
3883 : }
3884 : }
3885 : }
3886 : }
3887 :
3888 : // assume compressor resides at the inlet to the DX Coil
3889 7 : thisDXCoil.CondenserInletNodeNum(1) = thisDXCoil.AirInNode;
3890 :
3891 : // set condenser type as HPWH
3892 7 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::WaterHeater;
3893 :
3894 7 : } // end of the DX water heater wrapped coil loop
3895 :
3896 135 : if (ErrorsFound) {
3897 0 : ShowFatalError(state,
3898 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
3899 : }
3900 :
3901 : // DX Multispeed cooling coil
3902 135 : CurrentModuleObject = "Coil:Cooling:DX:MultiSpeed";
3903 163 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedCoolCoils; ++DXCoilIndex) {
3904 :
3905 28 : ++DXCoilNum;
3906 :
3907 28 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3908 : CurrentModuleObject,
3909 : DXCoilIndex,
3910 : Alphas,
3911 : NumAlphas,
3912 : Numbers,
3913 : NumNumbers,
3914 : IOStatus,
3915 : lNumericBlanks,
3916 : lAlphaBlanks,
3917 : cAlphaFields,
3918 : cNumericFields);
3919 :
3920 28 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
3921 : // allocate single performance mode for numeric field strings used for sizing routine (all fields are in this object)
3922 28 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
3923 28 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
3924 28 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
3925 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
3926 28 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
3927 :
3928 28 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
3929 28 : thisDXCoil.Name = Alphas(1);
3930 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
3931 28 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
3932 28 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
3933 28 : thisDXCoil.DXCoilType = CurrentModuleObject;
3934 28 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_MultiSpeedCooling;
3935 28 : if (lAlphaBlanks(2)) {
3936 18 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
3937 10 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
3938 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
3939 0 : ErrorsFound = true;
3940 : }
3941 :
3942 28 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
3943 28 : Alphas(3),
3944 : ErrorsFound,
3945 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
3946 28 : Alphas(1),
3947 : DataLoopNode::NodeFluidType::Air,
3948 : DataLoopNode::ConnectionType::Inlet,
3949 : NodeInputManager::CompFluidStream::Primary,
3950 : ObjectIsNotParent);
3951 :
3952 56 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
3953 28 : Alphas(4),
3954 : ErrorsFound,
3955 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
3956 28 : Alphas(1),
3957 : DataLoopNode::NodeFluidType::Air,
3958 : DataLoopNode::ConnectionType::Outlet,
3959 : NodeInputManager::CompFluidStream::Primary,
3960 : ObjectIsNotParent);
3961 :
3962 28 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
3963 :
3964 : // outdoor condenser node
3965 28 : if (lAlphaBlanks(5)) {
3966 15 : thisDXCoil.CondenserInletNodeNum(1) = 0;
3967 : } else {
3968 26 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
3969 13 : Alphas(5),
3970 : ErrorsFound,
3971 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
3972 13 : thisDXCoil.Name,
3973 : DataLoopNode::NodeFluidType::Air,
3974 : DataLoopNode::ConnectionType::OutsideAirReference,
3975 : NodeInputManager::CompFluidStream::Primary,
3976 : ObjectIsNotParent);
3977 13 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
3978 4 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3979 8 : ShowContinueError(
3980 8 : state, format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(5), Alphas(5)));
3981 12 : ShowContinueError(
3982 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
3983 : }
3984 : }
3985 :
3986 28 : if ((Util::SameString(Alphas(6), "AirCooled")) || lAlphaBlanks(6)) {
3987 28 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
3988 0 : } else if (Util::SameString(Alphas(6), "EvaporativelyCooled")) {
3989 0 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
3990 0 : thisDXCoil.ReportEvapCondVars = true;
3991 : } else {
3992 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3993 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(6), Alphas(6)));
3994 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
3995 0 : ErrorsFound = true;
3996 : }
3997 :
3998 : // Get Water System tank connections
3999 : // A8, \field Name of Water Storage Tank for Supply
4000 28 : thisDXCoil.EvapWaterSupplyName = Alphas(7);
4001 28 : if (lAlphaBlanks(7)) {
4002 28 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
4003 : } else {
4004 0 : thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
4005 0 : SetupTankDemandComponent(state,
4006 : thisDXCoil.Name,
4007 : CurrentModuleObject,
4008 : thisDXCoil.EvapWaterSupplyName,
4009 : ErrorsFound,
4010 0 : thisDXCoil.EvapWaterSupTankID,
4011 0 : thisDXCoil.EvapWaterTankDemandARRID);
4012 : }
4013 :
4014 : // A9; \field Name of Water Storage Tank for Condensate Collection
4015 28 : thisDXCoil.CondensateCollectName = Alphas(8);
4016 28 : if (lAlphaBlanks(8)) {
4017 28 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
4018 : } else {
4019 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
4020 0 : SetupTankSupplyComponent(state,
4021 : thisDXCoil.Name,
4022 : CurrentModuleObject,
4023 : thisDXCoil.CondensateCollectName,
4024 : ErrorsFound,
4025 0 : thisDXCoil.CondensateTankID,
4026 0 : thisDXCoil.CondensateTankSupplyARRID);
4027 : }
4028 :
4029 : // Set minimum OAT for compressor operation
4030 28 : thisDXCoil.MinOATCompressor = Numbers(1);
4031 :
4032 : // Set crankcase heater capacity
4033 28 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(2);
4034 28 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
4035 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4036 0 : ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(2)));
4037 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(2)));
4038 0 : ErrorsFound = true;
4039 : }
4040 :
4041 : // Set crankcase heater cutout temperature
4042 28 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(3);
4043 :
4044 28 : if (Util::SameString(Alphas(9), "Yes")) {
4045 0 : thisDXCoil.PLRImpact = true;
4046 28 : } else if (Util::SameString(Alphas(9), "No")) {
4047 28 : thisDXCoil.PLRImpact = false;
4048 : } else {
4049 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4050 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(9), Alphas(9)));
4051 0 : ShowContinueError(state, "The allowed choices are Yes or No.");
4052 0 : ErrorsFound = true;
4053 : }
4054 :
4055 28 : if (Util::SameString(Alphas(10), "Yes")) {
4056 0 : thisDXCoil.LatentImpact = true;
4057 28 : } else if (Util::SameString(Alphas(10), "No")) {
4058 28 : thisDXCoil.LatentImpact = false;
4059 : } else {
4060 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4061 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(10), Alphas(10)));
4062 0 : ShowContinueError(state, "The allowed choices are Yes or No.");
4063 0 : ErrorsFound = true;
4064 : }
4065 :
4066 : // Basin heater power as a function of temperature must be greater than or equal to 0
4067 28 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(4);
4068 28 : if (Numbers(4) < 0.0) {
4069 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4070 0 : ShowContinueError(state, format("...{} must be >= 0.0, entered value=[{:.3T}].", cNumericFields(4), Numbers(4)));
4071 0 : ErrorsFound = true;
4072 : }
4073 :
4074 28 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(5);
4075 28 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
4076 0 : if (NumNumbers < 5) {
4077 0 : thisDXCoil.BasinHeaterSetPointTemp = 2.0;
4078 : }
4079 0 : if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
4080 0 : ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4081 0 : ShowContinueError(state, format("...{} is less than 2 {{C}}. Freezing could occur.", cNumericFields(5)));
4082 0 : ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(5)));
4083 : }
4084 : }
4085 :
4086 28 : if (!lAlphaBlanks(11)) {
4087 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(11));
4088 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
4089 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(11), Alphas(11)));
4090 0 : ErrorsFound = true;
4091 : } else {
4092 6 : ErrorsFound |= Curve::CheckCurveDims(state,
4093 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
4094 : {1}, // Valid dimensions
4095 : RoutineName, // Routine name
4096 : CurrentModuleObject, // Object Type
4097 : thisDXCoil.Name, // Object Name
4098 2 : cAlphaFields(11)); // Field Name
4099 : }
4100 : }
4101 :
4102 28 : if (!lAlphaBlanks(12)) {
4103 0 : if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(12))) == nullptr) {
4104 0 : ShowWarningItemNotFound(
4105 0 : state, eoh, cAlphaFields(12), Alphas(12), "Basin heater will be available to operate throughout the simulation.");
4106 : }
4107 : }
4108 :
4109 : // A13; \field Fuel type, Validate fuel type input
4110 28 : thisDXCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(13)));
4111 :
4112 28 : thisDXCoil.NumOfSpeeds = Numbers(6); // Number of speeds
4113 28 : if (thisDXCoil.NumOfSpeeds < 2) {
4114 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4115 0 : ShowContinueError(state, format("...{} must be >= 2. entered number is {:.0T}", cNumericFields(6), Numbers(6)));
4116 0 : ErrorsFound = true;
4117 : }
4118 :
4119 : // Allocate arrays based on the number of speeds
4120 28 : thisDXCoil.MSErrIndex.allocate(thisDXCoil.NumOfSpeeds);
4121 28 : thisDXCoil.MSErrIndex = 0;
4122 28 : thisDXCoil.MSRatedTotCap.allocate(thisDXCoil.NumOfSpeeds);
4123 28 : thisDXCoil.MSRatedTotCapDes.allocate(thisDXCoil.NumOfSpeeds);
4124 28 : thisDXCoil.MSRatedSHR.allocate(thisDXCoil.NumOfSpeeds);
4125 28 : thisDXCoil.MSRatedCOP.allocate(thisDXCoil.NumOfSpeeds);
4126 28 : thisDXCoil.MSRatedAirVolFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4127 28 : thisDXCoil.MSRatedAirMassFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4128 28 : thisDXCoil.MSRatedAirMassFlowRate = 1.0; // avoid divide by 0, will get overwritten in InitDXCoil
4129 28 : thisDXCoil.MSCCapFTemp.allocate(thisDXCoil.NumOfSpeeds);
4130 28 : thisDXCoil.MSCCapFFlow.allocate(thisDXCoil.NumOfSpeeds);
4131 28 : thisDXCoil.MSEIRFTemp.allocate(thisDXCoil.NumOfSpeeds);
4132 28 : thisDXCoil.MSEIRFFlow.allocate(thisDXCoil.NumOfSpeeds);
4133 28 : thisDXCoil.MSWasteHeat.allocate(thisDXCoil.NumOfSpeeds);
4134 28 : thisDXCoil.MSEvapCondEffect.allocate(thisDXCoil.NumOfSpeeds);
4135 28 : thisDXCoil.MSEvapCondAirFlow.allocate(thisDXCoil.NumOfSpeeds);
4136 28 : thisDXCoil.MSEvapCondPumpElecNomPower.allocate(thisDXCoil.NumOfSpeeds);
4137 28 : thisDXCoil.MSRatedCBF.allocate(thisDXCoil.NumOfSpeeds);
4138 28 : thisDXCoil.MSWasteHeatFrac.allocate(thisDXCoil.NumOfSpeeds);
4139 28 : thisDXCoil.MSPLFFPLR.allocate(thisDXCoil.NumOfSpeeds);
4140 28 : thisDXCoil.MSTwet_Rated.allocate(thisDXCoil.NumOfSpeeds);
4141 28 : thisDXCoil.MSGamma_Rated.allocate(thisDXCoil.NumOfSpeeds);
4142 28 : thisDXCoil.MSMaxONOFFCyclesperHour.allocate(thisDXCoil.NumOfSpeeds);
4143 28 : thisDXCoil.MSLatentCapacityTimeConstant.allocate(thisDXCoil.NumOfSpeeds);
4144 28 : thisDXCoil.MSFanPowerPerEvapAirFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4145 28 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023.allocate(thisDXCoil.NumOfSpeeds);
4146 :
4147 107 : for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
4148 79 : thisDXCoil.MSRatedTotCap(I) = Numbers(7 + (I - 1) * 14);
4149 79 : thisDXCoil.MSRatedSHR(I) = Numbers(8 + (I - 1) * 14);
4150 79 : thisDXCoil.MSRatedCOP(I) = Numbers(9 + (I - 1) * 14);
4151 79 : thisDXCoil.MSRatedAirVolFlowRate(I) = Numbers(10 + (I - 1) * 14);
4152 79 : thisDXCoil.MSFanPowerPerEvapAirFlowRate(I) = Numbers(11 + (I - 1) * 14);
4153 79 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023(I) = Numbers(12 + (I - 1) * 14);
4154 :
4155 79 : thisDXCoil.MSCCapFTemp(I) = GetCurveIndex(state, Alphas(14 + (I - 1) * 6)); // convert curve name to number
4156 79 : if (thisDXCoil.MSCCapFTemp(I) == 0) {
4157 0 : if (lAlphaBlanks(14 + (I - 1) * 6)) {
4158 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4159 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(14 + (I - 1) * 6)));
4160 : } else {
4161 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4162 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14 + (I - 1) * 6), Alphas(14 + (I - 1) * 6)));
4163 : }
4164 0 : ErrorsFound = true;
4165 : } else {
4166 : // Verify Curve Object, only legal type is BiQuadratic
4167 237 : ErrorsFound |= Curve::CheckCurveDims(state,
4168 79 : thisDXCoil.MSCCapFTemp(I), // Curve index
4169 : {2}, // Valid dimensions
4170 : RoutineName, // Routine name
4171 : CurrentModuleObject, // Object Type
4172 : thisDXCoil.Name, // Object Name
4173 79 : cAlphaFields(14 + (I - 1) * 6)); // Field Name
4174 :
4175 79 : if (!ErrorsFound) {
4176 76 : checkCurveIsNormalizedToOne(state,
4177 228 : std::string{RoutineName} + CurrentModuleObject,
4178 76 : thisDXCoil.Name,
4179 76 : thisDXCoil.MSCCapFTemp(I),
4180 76 : cAlphaFields(14 + (I - 1) * 6),
4181 76 : Alphas(14 + (I - 1) * 6),
4182 : RatedInletWetBulbTemp,
4183 : RatedOutdoorAirTemp);
4184 : }
4185 : }
4186 :
4187 79 : thisDXCoil.MSCCapFFlow(I) = GetCurveIndex(state, Alphas(15 + (I - 1) * 6)); // convert curve name to number
4188 79 : if (thisDXCoil.MSCCapFFlow(I) == 0) {
4189 0 : if (lAlphaBlanks(15 + (I - 1) * 6)) {
4190 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4191 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(15 + (I - 1) * 6)));
4192 : } else {
4193 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4194 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
4195 : }
4196 0 : ErrorsFound = true;
4197 : } else {
4198 : // Verify Curve Object, only legal type is Quadratic
4199 237 : ErrorsFound |= Curve::CheckCurveDims(state,
4200 79 : thisDXCoil.MSCCapFFlow(I), // Curve index
4201 : {1}, // Valid dimensions
4202 : RoutineName, // Routine name
4203 : CurrentModuleObject, // Object Type
4204 : thisDXCoil.Name, // Object Name
4205 79 : cAlphaFields(15 + (I - 1) * 6)); // Field Name
4206 :
4207 79 : if (!ErrorsFound) {
4208 76 : checkCurveIsNormalizedToOne(state,
4209 228 : std::string{RoutineName} + CurrentModuleObject,
4210 76 : thisDXCoil.Name,
4211 76 : thisDXCoil.MSCCapFFlow(I),
4212 76 : cAlphaFields(15 + (I - 1) * 6),
4213 76 : Alphas(15 + (I - 1) * 6),
4214 : 1.0);
4215 : }
4216 : }
4217 :
4218 79 : thisDXCoil.MSEIRFTemp(I) = GetCurveIndex(state, Alphas(16 + (I - 1) * 6)); // convert curve name to number
4219 79 : if (thisDXCoil.MSEIRFTemp(I) == 0) {
4220 0 : if (lAlphaBlanks(16 + (I - 1) * 6)) {
4221 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4222 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(16 + (I - 1) * 6)));
4223 : } else {
4224 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4225 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16 + (I - 1) * 6), Alphas(16 + (I - 1) * 6)));
4226 : }
4227 0 : ErrorsFound = true;
4228 : } else {
4229 : // Verify Curve Object, only legal type is BiQuadratic
4230 237 : ErrorsFound |= Curve::CheckCurveDims(state,
4231 79 : thisDXCoil.MSEIRFTemp(I), // Curve index
4232 : {2}, // Valid dimensions
4233 : RoutineName, // Routine name
4234 : CurrentModuleObject, // Object Type
4235 : thisDXCoil.Name, // Object Name
4236 79 : cAlphaFields(16 + (I - 1) * 6)); // Field Name
4237 :
4238 79 : if (!ErrorsFound) {
4239 76 : checkCurveIsNormalizedToOne(state,
4240 228 : std::string{RoutineName} + CurrentModuleObject,
4241 76 : thisDXCoil.Name,
4242 76 : thisDXCoil.MSEIRFTemp(I),
4243 76 : cAlphaFields(16 + (I - 1) * 6),
4244 76 : Alphas(16 + (I - 1) * 6),
4245 : RatedInletWetBulbTemp,
4246 : RatedOutdoorAirTemp);
4247 : }
4248 : }
4249 :
4250 79 : thisDXCoil.MSEIRFFlow(I) = GetCurveIndex(state, Alphas(17 + (I - 1) * 6)); // convert curve name to number
4251 79 : if (thisDXCoil.MSEIRFFlow(I) == 0) {
4252 0 : if (lAlphaBlanks(17 + (I - 1) * 6)) {
4253 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4254 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(17 + (I - 1) * 6)));
4255 : } else {
4256 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4257 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17 + (I - 1) * 6), Alphas(17 + (I - 1) * 6)));
4258 : }
4259 0 : ErrorsFound = true;
4260 : } else {
4261 : // Verify Curve Object, only legal type is Quadratic
4262 237 : ErrorsFound |= Curve::CheckCurveDims(state,
4263 79 : thisDXCoil.MSEIRFFlow(I), // Curve index
4264 : {1}, // Valid dimensions
4265 : RoutineName, // Routine name
4266 : CurrentModuleObject, // Object Type
4267 : thisDXCoil.Name, // Object Name
4268 79 : cAlphaFields(17 + (I - 1) * 6)); // Field Name
4269 :
4270 79 : if (!ErrorsFound) {
4271 76 : checkCurveIsNormalizedToOne(state,
4272 228 : std::string{RoutineName} + CurrentModuleObject,
4273 76 : thisDXCoil.Name,
4274 76 : thisDXCoil.MSEIRFFlow(I),
4275 76 : cAlphaFields(17 + (I - 1) * 6),
4276 76 : Alphas(17 + (I - 1) * 6),
4277 : 1.0);
4278 : }
4279 : }
4280 :
4281 79 : thisDXCoil.MSPLFFPLR(I) = GetCurveIndex(state, Alphas(18 + (I - 1) * 6)); // convert curve name to number
4282 79 : if (thisDXCoil.MSPLFFPLR(I) == 0) {
4283 4 : if (lAlphaBlanks(18 + (I - 1) * 6)) {
4284 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4285 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(18 + (I - 1) * 6)));
4286 : } else {
4287 4 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4288 4 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(18 + (I - 1) * 6), Alphas(18 + (I - 1) * 6)));
4289 : }
4290 4 : ErrorsFound = true;
4291 : } else {
4292 : // Verify Curve Object, only legal types are Quadratic or Cubic
4293 225 : ErrorsFound |= Curve::CheckCurveDims(state,
4294 75 : thisDXCoil.MSPLFFPLR(I), // Curve index
4295 : {1}, // Valid dimensions
4296 : RoutineName, // Routine name
4297 : CurrentModuleObject, // Object Type
4298 : thisDXCoil.Name, // Object Name
4299 75 : cAlphaFields(18 + (I - 1) * 6)); // Field Name
4300 :
4301 75 : if (!ErrorsFound) {
4302 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
4303 75 : MinCurveVal = 999.0;
4304 75 : MaxCurveVal = -999.0;
4305 75 : CurveInput = 0.0;
4306 7575 : while (CurveInput <= 1.0) {
4307 7500 : CurveVal = CurveValue(state, thisDXCoil.MSPLFFPLR(I), CurveInput);
4308 7500 : if (CurveVal < MinCurveVal) {
4309 75 : MinCurveVal = CurveVal;
4310 75 : MinCurvePLR = CurveInput;
4311 : }
4312 7500 : if (CurveVal > MaxCurveVal) {
4313 6256 : MaxCurveVal = CurveVal;
4314 6256 : MaxCurvePLR = CurveInput;
4315 : }
4316 7500 : CurveInput += 0.01;
4317 : }
4318 75 : if (MinCurveVal < 0.7) {
4319 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4320 0 : ShowContinueError(state,
4321 0 : format("...{} = {} has out of range value.", cAlphaFields2(18 + (I - 1) * 6), Alphas2(18 + (I - 1) * 6)));
4322 0 : ShowContinueError(state,
4323 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
4324 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
4325 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 0.7);
4326 : }
4327 :
4328 75 : if (MaxCurveVal > 1.0) {
4329 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4330 0 : ShowContinueError(state,
4331 0 : format("...{} = {} has out of range value.", cAlphaFields2(18 + (I - 1) * 6), Alphas2(18 + (I - 1) * 6)));
4332 0 : ShowContinueError(state,
4333 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
4334 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
4335 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 1.0);
4336 : }
4337 : }
4338 : }
4339 :
4340 : // read data for latent degradation
4341 79 : thisDXCoil.MSTwet_Rated(I) = Numbers(13 + (I - 1) * 14);
4342 79 : if (thisDXCoil.MSTwet_Rated(I) < 0.0) {
4343 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4344 0 : ShowContinueError(
4345 0 : state, format("...{} cannot be < 0.0, entered value=[{:.4T}].", cNumericFields(13 + (I - 1) * 14), thisDXCoil.MSTwet_Rated(I)));
4346 0 : ErrorsFound = true;
4347 : }
4348 79 : thisDXCoil.MSGamma_Rated(I) = Numbers(14 + (I - 1) * 14);
4349 79 : if (thisDXCoil.MSGamma_Rated(I) < 0.0) {
4350 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4351 0 : ShowContinueError(
4352 0 : state, format("...{} cannot be < 0.0, entered value=[{:.4T}].", cNumericFields(14 + (I - 1) * 14), thisDXCoil.MSGamma_Rated(I)));
4353 0 : ErrorsFound = true;
4354 : }
4355 79 : thisDXCoil.MSMaxONOFFCyclesperHour(I) = Numbers(15 + (I - 1) * 14);
4356 79 : if (thisDXCoil.Gamma_Rated(I) < 0.0) {
4357 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4358 0 : ShowContinueError(state,
4359 0 : format("...{} cannot be < 0.0, entered value=[{:.2T}].",
4360 0 : cNumericFields(15 + (I - 1) * 14),
4361 : thisDXCoil.MSMaxONOFFCyclesperHour(I)));
4362 0 : ErrorsFound = true;
4363 : }
4364 79 : thisDXCoil.MSLatentCapacityTimeConstant(I) = Numbers(16 + (I - 1) * 14);
4365 79 : if (thisDXCoil.Gamma_Rated(I) < 0.0) {
4366 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4367 0 : ShowContinueError(state,
4368 0 : format("...{} cannot be < 0.0, entered value=[{:.2T}].",
4369 0 : cNumericFields(16 + (I - 1) * 14),
4370 : thisDXCoil.MSLatentCapacityTimeConstant(I)));
4371 0 : ErrorsFound = true;
4372 : }
4373 :
4374 79 : thisDXCoil.MSWasteHeatFrac(I) = Numbers(17 + (I - 1) * 14);
4375 :
4376 : // Read waste heat modifier curve name
4377 79 : thisDXCoil.MSWasteHeat(I) = GetCurveIndex(state, Alphas(19 + (I - 1) * 6)); // convert curve name to number
4378 79 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
4379 16 : if (thisDXCoil.MSWasteHeat(I) > 0) {
4380 : // Verify Curve Object, only legal types are BiQuadratic
4381 48 : ErrorsFound |= Curve::CheckCurveDims(state,
4382 16 : thisDXCoil.MSWasteHeat(I), // Curve index
4383 : {2}, // Valid dimensions
4384 : RoutineName, // Routine name
4385 : CurrentModuleObject, // Object Type
4386 : thisDXCoil.Name, // Object Name
4387 16 : cAlphaFields(19 + (I - 1) * 6)); // Field Name
4388 :
4389 16 : if (!ErrorsFound) {
4390 16 : CurveVal = CurveValue(state, thisDXCoil.MSWasteHeat(I), RatedOutdoorAirTemp, RatedInletAirTemp);
4391 16 : if (CurveVal > 1.10 || CurveVal < 0.90) {
4392 0 : ShowWarningError(state, format("{}{}=\"{}\", curve values", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4393 0 : ShowContinueError(state, format("{} = {}", cAlphaFields(19 + (I - 1) * 6), Alphas(19 + (I - 1) * 6)));
4394 0 : ShowContinueError(
4395 0 : state, format("...{} output is not equal to 1.0 (+ or - 10%) at rated conditions.", cAlphaFields(19 + (I - 1) * 6)));
4396 0 : ShowContinueError(state, format("...Curve output at rated conditions = {:.3T}", CurveVal));
4397 : }
4398 : }
4399 : }
4400 : }
4401 :
4402 79 : thisDXCoil.MSEvapCondEffect(I) = Numbers(18 + (I - 1) * 14);
4403 79 : if (thisDXCoil.MSEvapCondEffect(I) < 0.0 || thisDXCoil.MSEvapCondEffect(I) > 1.0) {
4404 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4405 0 : ShowContinueError(
4406 : state,
4407 0 : format("...{} cannot be < 0.0 or > 1.0, entered value=[{:.3T}].", cNumericFields(18 + (I - 1) * 14), Numbers(18 + (I - 1) * 14)));
4408 0 : ErrorsFound = true;
4409 : }
4410 :
4411 79 : thisDXCoil.MSEvapCondAirFlow(I) = Numbers(19 + (I - 1) * 14);
4412 79 : if (thisDXCoil.MSEvapCondAirFlow(I) < 0.0 && thisDXCoil.MSEvapCondAirFlow(I) != AutoSize) {
4413 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4414 0 : ShowContinueError(
4415 0 : state, format("...{} cannot be < 0.0, entered value=[{:.3T}].", cNumericFields(19 + (I - 1) * 14), Numbers(19 + (I - 1) * 14)));
4416 0 : ErrorsFound = true;
4417 : }
4418 :
4419 79 : thisDXCoil.MSEvapCondPumpElecNomPower(I) = Numbers(20 + (I - 1) * 14);
4420 79 : if (thisDXCoil.MSEvapCondPumpElecNomPower(I) < 0.0 && thisDXCoil.MSEvapCondPumpElecNomPower(I) != AutoSize) {
4421 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4422 0 : ShowContinueError(
4423 0 : state, format("...{} cannot be < 0.0, entered value=[{:.3T}].", cNumericFields(20 + (I - 1) * 14), Numbers(20 + (I - 1) * 14)));
4424 0 : ErrorsFound = true;
4425 : }
4426 : }
4427 : // A38; \field Zone Name for Condenser Placement
4428 28 : if (!lAlphaBlanks(38) && NumAlphas > 37) {
4429 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(38), state.dataHeatBal->Zone);
4430 0 : if (thisDXCoil.SecZonePtr > 0) {
4431 0 : SetupZoneInternalGain(state,
4432 : thisDXCoil.SecZonePtr,
4433 : thisDXCoil.Name,
4434 : DataHeatBalance::IntGainType::SecCoolingDXCoilMultiSpeed,
4435 : &thisDXCoil.SecCoilSensibleHeatGainRate);
4436 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
4437 : } else {
4438 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4439 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(38), Alphas(38)));
4440 : }
4441 : }
4442 : }
4443 :
4444 135 : if (ErrorsFound) {
4445 3 : ShowFatalError(state,
4446 3 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
4447 : }
4448 :
4449 : // DX multispeed heating coil
4450 134 : CurrentModuleObject = "Coil:Heating:DX:MultiSpeed";
4451 148 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedHeatCoils; ++DXCoilIndex) {
4452 :
4453 14 : ++DXCoilNum;
4454 :
4455 14 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4456 : CurrentModuleObject,
4457 : DXCoilIndex,
4458 : Alphas,
4459 : NumAlphas,
4460 : Numbers,
4461 : NumNumbers,
4462 : IOStatus,
4463 : lNumericBlanks,
4464 : lAlphaBlanks,
4465 : cAlphaFields,
4466 : cNumericFields);
4467 :
4468 14 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
4469 :
4470 : // *** will have to circle back to this one to fix since the multispeed coil has all fields in this coil object ***
4471 : // allocate single performance mode for numeric field strings used for sizing routine
4472 14 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
4473 14 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
4474 14 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
4475 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
4476 14 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
4477 :
4478 14 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
4479 14 : thisDXCoil.Name = Alphas(1);
4480 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
4481 14 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
4482 14 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
4483 14 : thisDXCoil.DXCoilType = CurrentModuleObject;
4484 14 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_MultiSpeedHeating;
4485 14 : if (lAlphaBlanks(2)) {
4486 8 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
4487 6 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
4488 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
4489 0 : ErrorsFound = true;
4490 : }
4491 :
4492 14 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
4493 14 : Alphas(3),
4494 : ErrorsFound,
4495 : DataLoopNode::ConnectionObjectType::CoilHeatingDXMultiSpeed,
4496 14 : Alphas(1),
4497 : DataLoopNode::NodeFluidType::Air,
4498 : DataLoopNode::ConnectionType::Inlet,
4499 : NodeInputManager::CompFluidStream::Primary,
4500 : ObjectIsNotParent);
4501 :
4502 28 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
4503 14 : Alphas(4),
4504 : ErrorsFound,
4505 : DataLoopNode::ConnectionObjectType::CoilHeatingDXMultiSpeed,
4506 14 : Alphas(1),
4507 : DataLoopNode::NodeFluidType::Air,
4508 : DataLoopNode::ConnectionType::Outlet,
4509 : NodeInputManager::CompFluidStream::Primary,
4510 : ObjectIsNotParent);
4511 :
4512 14 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
4513 :
4514 : // Set minimum OAT for heat pump compressor operation
4515 14 : thisDXCoil.MinOATCompressor = Numbers(1);
4516 :
4517 : // set Minimum Outdoor Dry-Bulb Temperature for Compressor Operation
4518 14 : thisDXCoil.OATempCompressorOn = Numbers(2);
4519 : // Set crankcase heater capacity
4520 14 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(3);
4521 14 : if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
4522 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4523 0 : ShowContinueError(state, format("...{} cannot be < 0.0, entered value=[{:.2T}].", cNumericFields(3), Numbers(3)));
4524 0 : ErrorsFound = true;
4525 : }
4526 :
4527 : // Set crankcase heater cutout temperature
4528 14 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(4);
4529 :
4530 14 : if (!lAlphaBlanks(5)) {
4531 2 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
4532 2 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
4533 0 : ShowSevereError(state, format("{} = {}: {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(5), Alphas(5)));
4534 0 : ErrorsFound = true;
4535 : } else {
4536 6 : ErrorsFound |= Curve::CheckCurveDims(state,
4537 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
4538 : {1}, // Valid dimensions
4539 : RoutineName, // Routine name
4540 : CurrentModuleObject, // Object Type
4541 : thisDXCoil.Name, // Object Name
4542 2 : cAlphaFields(5)); // Field Name
4543 : }
4544 : }
4545 :
4546 : // Only required for reverse cycle heat pumps
4547 14 : thisDXCoil.DefrostEIRFT = GetCurveIndex(state, Alphas(6)); // convert curve name to number
4548 14 : if (Util::SameString(Alphas(7), "ReverseCycle")) {
4549 13 : if (thisDXCoil.DefrostEIRFT == 0) {
4550 0 : if (lAlphaBlanks(6)) {
4551 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4552 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
4553 : } else {
4554 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4555 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
4556 : }
4557 0 : ErrorsFound = true;
4558 : } else {
4559 : // Verify Curve Object, only legal type is BiQuadratic
4560 26 : ErrorsFound |= Curve::CheckCurveDims(state,
4561 : thisDXCoil.DefrostEIRFT, // Curve index
4562 : {2}, // Valid dimensions
4563 : RoutineName, // Routine name
4564 : CurrentModuleObject, // Object Type
4565 : thisDXCoil.Name, // Object Name
4566 13 : cAlphaFields(6)); // Field Name
4567 :
4568 13 : if (!ErrorsFound) {
4569 13 : checkCurveIsNormalizedToOne(state,
4570 39 : std::string{RoutineName} + CurrentModuleObject,
4571 13 : thisDXCoil.Name,
4572 : thisDXCoil.DefrostEIRFT,
4573 13 : cAlphaFields(6),
4574 13 : Alphas(6),
4575 : RatedInletWetBulbTempHeat,
4576 : RatedOutdoorAirTempHeat);
4577 : }
4578 : }
4579 : }
4580 :
4581 14 : if (Util::SameString(Alphas(7), "ReverseCycle")) {
4582 13 : thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
4583 : }
4584 14 : if (Util::SameString(Alphas(7), "Resistive")) {
4585 1 : thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
4586 : }
4587 14 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
4588 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4589 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(7), Alphas(7)));
4590 0 : ShowContinueError(state, "...valid values for this field are ReverseCycle or Resistive.");
4591 0 : ErrorsFound = true;
4592 : }
4593 :
4594 14 : if (Util::SameString(Alphas(8), "Timed")) {
4595 3 : thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::Timed;
4596 : }
4597 14 : if (Util::SameString(Alphas(8), "OnDemand")) {
4598 11 : thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
4599 : }
4600 14 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
4601 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4602 0 : ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(8), Alphas(8)));
4603 0 : ShowContinueError(state, "...valid values for this field are Timed or OnDemand.");
4604 0 : ErrorsFound = true;
4605 : }
4606 :
4607 : // Set maximum outdoor temp for defrost to occur
4608 14 : thisDXCoil.MaxOATDefrost = Numbers(5);
4609 :
4610 : // Set defrost time period
4611 14 : thisDXCoil.DefrostTime = Numbers(6);
4612 14 : if (thisDXCoil.DefrostTime == 0.0 && thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
4613 0 : ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4614 0 : ShowContinueError(state, format("...{} = 0.0 for defrost control = TIMED.", cNumericFields(5)));
4615 : }
4616 :
4617 : // Set defrost capacity (for resistive defrost)
4618 14 : thisDXCoil.DefrostCapacity = Numbers(7);
4619 14 : if (thisDXCoil.DefrostCapacity == 0.0 && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
4620 0 : ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4621 0 : ShowContinueError(state, format("...{} = 0.0 for defrost strategy = RESISTIVE.", cNumericFields(7)));
4622 : }
4623 :
4624 14 : if (Util::SameString(Alphas(9), "Yes")) {
4625 0 : thisDXCoil.PLRImpact = true;
4626 14 : } else if (Util::SameString(Alphas(9), "No")) {
4627 14 : thisDXCoil.PLRImpact = false;
4628 : } else {
4629 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4630 0 : ShowContinueError(state, format(",,,invalid choice for {}. Entered choice = {}", cAlphaFields(9), Alphas(9)));
4631 0 : ShowContinueError(state, "The allowed choices are Yes or No.");
4632 0 : ErrorsFound = true;
4633 : }
4634 :
4635 : // A10; \field Fuel type, Validate fuel type input
4636 14 : thisDXCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(10)));
4637 :
4638 14 : thisDXCoil.RegionNum = Numbers(8); // Region Number for HSPF Calc
4639 14 : thisDXCoil.NumOfSpeeds = Numbers(9); // Number of speeds
4640 14 : if (thisDXCoil.NumOfSpeeds < 2) {
4641 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4642 0 : ShowContinueError(state, format("...{} must be >= 2. entered number is {:.0T}", cNumericFields(9), Numbers(9)));
4643 0 : ErrorsFound = true;
4644 : }
4645 :
4646 : // Allocate arrays based on the number of speeds
4647 14 : thisDXCoil.MSErrIndex.allocate(thisDXCoil.NumOfSpeeds);
4648 14 : thisDXCoil.MSErrIndex = 0;
4649 14 : thisDXCoil.MSRatedTotCap.allocate(thisDXCoil.NumOfSpeeds);
4650 14 : thisDXCoil.MSRatedCOP.allocate(thisDXCoil.NumOfSpeeds);
4651 14 : thisDXCoil.MSRatedAirVolFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4652 14 : thisDXCoil.MSRatedAirMassFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4653 14 : thisDXCoil.MSRatedAirMassFlowRate = 1.0; // avoid divide by 0, will get overwritten in InitDXCoil
4654 14 : thisDXCoil.MSCCapFTemp.allocate(thisDXCoil.NumOfSpeeds);
4655 14 : thisDXCoil.MSCCapFFlow.allocate(thisDXCoil.NumOfSpeeds);
4656 14 : thisDXCoil.MSEIRFTemp.allocate(thisDXCoil.NumOfSpeeds);
4657 14 : thisDXCoil.MSEIRFFlow.allocate(thisDXCoil.NumOfSpeeds);
4658 14 : thisDXCoil.MSWasteHeat.allocate(thisDXCoil.NumOfSpeeds);
4659 14 : thisDXCoil.MSPLFFPLR.allocate(thisDXCoil.NumOfSpeeds);
4660 14 : thisDXCoil.MSRatedCBF.allocate(thisDXCoil.NumOfSpeeds);
4661 14 : thisDXCoil.MSWasteHeatFrac.allocate(thisDXCoil.NumOfSpeeds);
4662 14 : thisDXCoil.MSFanPowerPerEvapAirFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4663 14 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023.allocate(thisDXCoil.NumOfSpeeds);
4664 14 : thisDXCoil.MSSecCoilSHRFT.allocate(thisDXCoil.NumOfSpeeds);
4665 14 : thisDXCoil.MSSecCoilSHRFF.allocate(thisDXCoil.NumOfSpeeds);
4666 14 : thisDXCoil.MSSecCoilAirFlow.allocate(thisDXCoil.NumOfSpeeds);
4667 14 : thisDXCoil.MSSecCoilAirFlowScalingFactor.allocate(thisDXCoil.NumOfSpeeds);
4668 14 : thisDXCoil.MSSecCoilRatedSHR.allocate(thisDXCoil.NumOfSpeeds);
4669 :
4670 14 : thisDXCoil.RatedSHR(1) = 1.0;
4671 :
4672 48 : for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
4673 34 : thisDXCoil.MSRatedTotCap(I) = Numbers(10 + (I - 1) * 6);
4674 34 : thisDXCoil.MSRatedCOP(I) = Numbers(11 + (I - 1) * 6);
4675 34 : thisDXCoil.MSRatedAirVolFlowRate(I) = Numbers(12 + (I - 1) * 6);
4676 34 : thisDXCoil.MSFanPowerPerEvapAirFlowRate(I) = Numbers(13 + (I - 1) * 6);
4677 34 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023(I) = Numbers(14 + (I - 1) * 6);
4678 34 : thisDXCoil.MSWasteHeatFrac(I) = Numbers(15 + (I - 1) * 6);
4679 :
4680 34 : thisDXCoil.MSCCapFTemp(I) = GetCurveIndex(state, Alphas(11 + (I - 1) * 6)); // convert curve name to number
4681 34 : if (thisDXCoil.MSCCapFTemp(I) == 0) {
4682 0 : ShowSevereError(state,
4683 0 : format("{}, \"{}\" {} not found:{}",
4684 : CurrentModuleObject,
4685 0 : thisDXCoil.Name,
4686 0 : cAlphaFields(11 + (I - 1) * 6),
4687 0 : Alphas(11 + (I - 1) * 6)));
4688 0 : ErrorsFound = true;
4689 : } else {
4690 : // only legal types are Quadratic, BiQuadratic and Cubic
4691 102 : ErrorsFound |= Curve::CheckCurveDims(state,
4692 34 : thisDXCoil.MSCCapFTemp(I), // Curve index
4693 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
4694 : RoutineName, // Routine name
4695 : CurrentModuleObject, // Object Type
4696 : thisDXCoil.Name, // Object Name
4697 34 : cAlphaFields(11 + (I - 1) * 6)); // Field Name
4698 :
4699 34 : if (!ErrorsFound) {
4700 34 : if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(I))->numDims == 1) {
4701 8 : checkCurveIsNormalizedToOne(state,
4702 24 : std::string{RoutineName} + CurrentModuleObject,
4703 8 : thisDXCoil.Name,
4704 8 : thisDXCoil.MSCCapFTemp(I),
4705 8 : cAlphaFields(11 + (I - 1) * 6),
4706 8 : Alphas(11 + (I - 1) * 6),
4707 : RatedOutdoorAirTempHeat);
4708 : } else {
4709 26 : checkCurveIsNormalizedToOne(state,
4710 78 : std::string{RoutineName} + CurrentModuleObject,
4711 26 : thisDXCoil.Name,
4712 26 : thisDXCoil.MSCCapFTemp(I),
4713 26 : cAlphaFields(11 + (I - 1) * 6),
4714 26 : Alphas(11 + (I - 1) * 6),
4715 : RatedInletAirTempHeat,
4716 : RatedOutdoorAirTempHeat);
4717 : }
4718 : }
4719 : }
4720 :
4721 34 : thisDXCoil.MSCCapFFlow(I) = GetCurveIndex(state, Alphas(12 + (I - 1) * 6)); // convert curve name to number
4722 34 : if (thisDXCoil.MSCCapFFlow(I) == 0) {
4723 0 : if (lAlphaBlanks(12 + (I - 1) * 6)) {
4724 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4725 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(12 + (I - 1) * 6)));
4726 : } else {
4727 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4728 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(12 + (I - 1) * 6), Alphas(12 + (I - 1) * 6)));
4729 : }
4730 0 : ErrorsFound = true;
4731 : } else {
4732 : // Verify Curve Object, only legal type is Quadratic
4733 102 : ErrorsFound |= Curve::CheckCurveDims(state,
4734 34 : thisDXCoil.MSCCapFFlow(I), // Curve index
4735 : {1}, // Valid dimensions
4736 : RoutineName, // Routine name
4737 : CurrentModuleObject, // Object Type
4738 : thisDXCoil.Name, // Object Name
4739 34 : cAlphaFields(12 + (I - 1) * 6)); // Field Name
4740 :
4741 34 : if (!ErrorsFound) {
4742 34 : checkCurveIsNormalizedToOne(state,
4743 102 : std::string{RoutineName} + CurrentModuleObject,
4744 34 : thisDXCoil.Name,
4745 34 : thisDXCoil.MSCCapFFlow(I),
4746 34 : cAlphaFields(12 + (I - 1) * 6),
4747 34 : Alphas(12 + (I - 1) * 6),
4748 : 1.0);
4749 : }
4750 : }
4751 :
4752 34 : thisDXCoil.MSEIRFTemp(I) = GetCurveIndex(state, Alphas(13 + (I - 1) * 6)); // convert curve name to number
4753 34 : if (thisDXCoil.MSEIRFTemp(I) == 0) {
4754 0 : if (lAlphaBlanks(13 + (I - 1) * 6)) {
4755 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4756 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(13 + (I - 1) * 6)));
4757 : } else {
4758 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4759 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(13 + (I - 1) * 6), Alphas(13 + (I - 1) * 6)));
4760 : }
4761 0 : ErrorsFound = true;
4762 : } else {
4763 : // only legal types are Quadratic, BiQuadratic and Cubic
4764 102 : ErrorsFound |= Curve::CheckCurveDims(state,
4765 34 : thisDXCoil.MSEIRFTemp(I), // Curve index
4766 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
4767 : RoutineName, // Routine name
4768 : CurrentModuleObject, // Object Type
4769 : thisDXCoil.Name, // Object Name
4770 34 : cAlphaFields(13 + (I - 1) * 6)); // Field Name
4771 :
4772 34 : if (!ErrorsFound) {
4773 34 : if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(I))->numDims == 1) {
4774 8 : checkCurveIsNormalizedToOne(state,
4775 24 : std::string{RoutineName} + CurrentModuleObject,
4776 8 : thisDXCoil.Name,
4777 8 : thisDXCoil.MSEIRFTemp(I),
4778 8 : cAlphaFields(13 + (I - 1) * 6),
4779 8 : Alphas(13 + (I - 1) * 6),
4780 : RatedOutdoorAirTempHeat);
4781 : } else {
4782 26 : checkCurveIsNormalizedToOne(state,
4783 78 : std::string{RoutineName} + CurrentModuleObject,
4784 26 : thisDXCoil.Name,
4785 26 : thisDXCoil.MSEIRFTemp(I),
4786 26 : cAlphaFields(13 + (I - 1) * 6),
4787 26 : Alphas(13 + (I - 1) * 6),
4788 : RatedInletAirTempHeat,
4789 : RatedOutdoorAirTempHeat);
4790 : }
4791 : }
4792 : }
4793 :
4794 34 : thisDXCoil.MSEIRFFlow(I) = GetCurveIndex(state, Alphas(14 + (I - 1) * 6)); // convert curve name to number
4795 34 : if (thisDXCoil.MSEIRFFlow(I) == 0) {
4796 0 : if (lAlphaBlanks(14 + (I - 1) * 6)) {
4797 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4798 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(14 + (I - 1) * 6)));
4799 : } else {
4800 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4801 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14 + (I - 1) * 6), Alphas(14 + (I - 1) * 6)));
4802 : }
4803 0 : ErrorsFound = true;
4804 : } else {
4805 : // Verify Curve Object, only legal type is Quadratic
4806 102 : ErrorsFound |= Curve::CheckCurveDims(state,
4807 34 : thisDXCoil.MSEIRFFlow(I), // Curve index
4808 : {1}, // Valid dimensions
4809 : RoutineName, // Routine name
4810 : CurrentModuleObject, // Object Type
4811 : thisDXCoil.Name, // Object Name
4812 34 : cAlphaFields(14 + (I - 1) * 6)); // Field Name
4813 :
4814 34 : if (!ErrorsFound) {
4815 34 : checkCurveIsNormalizedToOne(state,
4816 102 : std::string{RoutineName} + CurrentModuleObject,
4817 34 : thisDXCoil.Name,
4818 34 : thisDXCoil.MSEIRFFlow(I),
4819 34 : cAlphaFields(14 + (I - 1) * 6),
4820 34 : Alphas(14 + (I - 1) * 6),
4821 : 1.0);
4822 : }
4823 : }
4824 :
4825 34 : thisDXCoil.MSPLFFPLR(I) = GetCurveIndex(state, Alphas(15 + (I - 1) * 6)); // convert curve name to number
4826 34 : if (thisDXCoil.MSPLFFPLR(I) == 0) {
4827 0 : if (lAlphaBlanks(15 + (I - 1) * 6)) {
4828 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4829 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(15 + (I - 1) * 6)));
4830 : } else {
4831 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4832 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
4833 : }
4834 0 : ErrorsFound = true;
4835 : } else {
4836 : // Verify Curve Object, only legal types are Quadratic or Cubic
4837 102 : ErrorsFound |= Curve::CheckCurveDims(state,
4838 34 : thisDXCoil.MSPLFFPLR(I), // Curve index
4839 : {1}, // Valid dimensions
4840 : RoutineName, // Routine name
4841 : CurrentModuleObject, // Object Type
4842 : thisDXCoil.Name, // Object Name
4843 34 : cAlphaFields(15 + (I - 1) * 6)); // Field Name
4844 :
4845 34 : if (!ErrorsFound) {
4846 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
4847 34 : MinCurveVal = 999.0;
4848 34 : MaxCurveVal = -999.0;
4849 34 : CurveInput = 0.0;
4850 3434 : while (CurveInput <= 1.0) {
4851 3400 : CurveVal = CurveValue(state, thisDXCoil.MSPLFFPLR(I), CurveInput);
4852 3400 : if (CurveVal < MinCurveVal) {
4853 34 : MinCurveVal = CurveVal;
4854 34 : MinCurvePLR = CurveInput;
4855 : }
4856 3400 : if (CurveVal > MaxCurveVal) {
4857 2944 : MaxCurveVal = CurveVal;
4858 2944 : MaxCurvePLR = CurveInput;
4859 : }
4860 3400 : CurveInput += 0.01;
4861 : }
4862 34 : if (MinCurveVal < 0.7) {
4863 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4864 0 : ShowContinueError(state,
4865 0 : format("...{} = {} has out of range value.", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
4866 0 : ShowContinueError(state,
4867 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
4868 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
4869 0 : Curve::SetCurveOutputMinValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 0.7);
4870 : }
4871 :
4872 34 : if (MaxCurveVal > 1.0) {
4873 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4874 0 : ShowContinueError(state,
4875 0 : format("...{} = {} has out of range value.", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
4876 0 : ShowContinueError(state,
4877 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
4878 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
4879 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 1.0);
4880 : }
4881 : }
4882 : }
4883 :
4884 : // Read waste heat modifier curve name
4885 34 : thisDXCoil.MSWasteHeat(I) = GetCurveIndex(state, Alphas(16 + (I - 1) * 6)); // convert curve name to number
4886 34 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
4887 12 : if (thisDXCoil.MSWasteHeat(I) > 0) {
4888 : // Verify Curve Object, only legal types are BiQuadratic
4889 24 : ErrorsFound |= Curve::CheckCurveDims(state,
4890 8 : thisDXCoil.MSWasteHeat(I), // Curve index
4891 : {2}, // Valid dimensions
4892 : RoutineName, // Routine name
4893 : CurrentModuleObject, // Object Type
4894 : thisDXCoil.Name, // Object Name
4895 8 : cAlphaFields(16 + (I - 1) * 6)); // Field Name
4896 :
4897 8 : if (!ErrorsFound) {
4898 8 : checkCurveIsNormalizedToOne(state,
4899 24 : std::string{RoutineName} + CurrentModuleObject,
4900 8 : thisDXCoil.Name,
4901 8 : thisDXCoil.MSWasteHeat(I),
4902 8 : cAlphaFields(16 + (I - 1) * 6),
4903 8 : Alphas(16 + (I - 1) * 6),
4904 : RatedOutdoorAirTempHeat,
4905 : RatedInletAirTempHeat);
4906 : }
4907 : }
4908 : }
4909 : }
4910 : // A35; \field Zone Name for Condenser Placement
4911 14 : if (!lAlphaBlanks(35) && NumAlphas > 34) {
4912 0 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(35), state.dataHeatBal->Zone);
4913 0 : if (thisDXCoil.SecZonePtr > 0) {
4914 0 : SetupZoneInternalGain(state,
4915 : thisDXCoil.SecZonePtr,
4916 : thisDXCoil.Name,
4917 : DataHeatBalance::IntGainType::SecHeatingDXCoilMultiSpeed,
4918 : &thisDXCoil.SecCoilSensibleHeatRemovalRate,
4919 : nullptr,
4920 : nullptr,
4921 : &thisDXCoil.SecCoilLatentHeatRemovalRate);
4922 0 : thisDXCoil.IsSecondaryDXCoilInZone = true;
4923 : } else {
4924 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4925 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(35), Alphas(35)));
4926 : }
4927 : }
4928 14 : if (thisDXCoil.SecZonePtr > 0) {
4929 0 : for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
4930 0 : thisDXCoil.MSSecCoilAirFlow(I) = Numbers(34 + (I - 1) * 3);
4931 0 : thisDXCoil.MSSecCoilAirFlowScalingFactor(I) = Numbers(35 + (I - 1) * 3);
4932 0 : thisDXCoil.MSSecCoilRatedSHR(I) = Numbers(36 + (I - 1) * 3);
4933 : // Read SHR modifier curve function of temperature
4934 0 : if (!lAlphaBlanks(36 + (I - 1) * 2)) {
4935 0 : thisDXCoil.MSSecCoilSHRFT(I) = GetCurveIndex(state, Alphas(36 + (I - 1) * 2)); // convert curve name to number
4936 0 : if (thisDXCoil.MSSecCoilSHRFT(I) == 0) {
4937 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4938 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(36 + (I - 1) * 2), Alphas(36 + (I - 1) * 2)));
4939 : }
4940 : }
4941 : // Read SHR modifier curve function of flow fraction
4942 0 : if (!lAlphaBlanks(36 + (I - 1) * 2)) {
4943 0 : thisDXCoil.MSSecCoilSHRFF(I) = GetCurveIndex(state, Alphas(36 + (I - 1) * 2)); // convert curve name to number
4944 0 : if (thisDXCoil.MSSecCoilSHRFF(I) == 0) {
4945 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4946 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(36 + (I - 1) * 2), Alphas(36 + (I - 1) * 2)));
4947 : }
4948 : }
4949 : }
4950 : }
4951 : }
4952 :
4953 : // Loop over the VRF Cooling Coils and get & load the data
4954 134 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling);
4955 158 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFCoolingCoils; ++DXCoilIndex) {
4956 :
4957 24 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4958 : CurrentModuleObject,
4959 : DXCoilIndex,
4960 : Alphas,
4961 : NumAlphas,
4962 : Numbers,
4963 : NumNumbers,
4964 : IOStatus,
4965 : lNumericBlanks,
4966 : lAlphaBlanks,
4967 : cAlphaFields,
4968 : cNumericFields);
4969 :
4970 24 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
4971 :
4972 24 : ++DXCoilNum;
4973 :
4974 : // allocate single performance mode for numeric field strings used for sizing routine
4975 24 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
4976 24 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
4977 24 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
4978 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
4979 24 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
4980 :
4981 24 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
4982 24 : thisDXCoil.Name = Alphas(1);
4983 24 : thisDXCoil.DXCoilType = CurrentModuleObject;
4984 24 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_Cooling;
4985 :
4986 24 : if (lAlphaBlanks(2)) {
4987 2 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
4988 22 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
4989 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
4990 0 : ErrorsFound = true;
4991 : }
4992 24 : thisDXCoil.RatedTotCap(1) = Numbers(1);
4993 24 : thisDXCoil.RatedSHR(1) = Numbers(2);
4994 24 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(3);
4995 :
4996 24 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(3));
4997 : // Verify Curve Object, only legal type is Linear, Quadratic, Cubic, or BiQuadratic
4998 72 : ErrorsFound |= Curve::CheckCurveDims(state,
4999 24 : thisDXCoil.CCapFTemp(1), // Curve index
5000 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
5001 : RoutineName, // Routine name
5002 : CurrentModuleObject, // Object Type
5003 : thisDXCoil.Name, // Object Name
5004 24 : cAlphaFields(3)); // Field Name
5005 :
5006 24 : if (!ErrorsFound) {
5007 24 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
5008 23 : checkCurveIsNormalizedToOne(state,
5009 69 : std::string{RoutineName} + CurrentModuleObject,
5010 23 : thisDXCoil.Name,
5011 23 : thisDXCoil.CCapFTemp(1),
5012 23 : cAlphaFields(3),
5013 23 : Alphas(3),
5014 : RatedInletWetBulbTemp);
5015 : } else {
5016 1 : checkCurveIsNormalizedToOne(state,
5017 3 : std::string{RoutineName} + CurrentModuleObject,
5018 1 : thisDXCoil.Name,
5019 1 : thisDXCoil.CCapFTemp(1),
5020 1 : cAlphaFields(3),
5021 1 : Alphas(3),
5022 : RatedInletWetBulbTemp,
5023 : RatedOutdoorAirTemp);
5024 : }
5025 : }
5026 :
5027 24 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(4)); // convert curve name to number
5028 24 : if (thisDXCoil.CCapFFlow(1) == 0) {
5029 0 : if (lAlphaBlanks(4)) {
5030 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5031 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(4)));
5032 : } else {
5033 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5034 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(4), Alphas(4)));
5035 : }
5036 0 : ErrorsFound = true;
5037 : } else {
5038 : // Verify Curve Object, only legal type is Linear, Quadratic or Cubic
5039 72 : ErrorsFound |= Curve::CheckCurveDims(state,
5040 24 : thisDXCoil.CCapFFlow(1), // Curve index
5041 : {1}, // Valid dimensions
5042 : RoutineName, // Routine name
5043 : CurrentModuleObject, // Object Type
5044 : thisDXCoil.Name, // Object Name
5045 24 : cAlphaFields(4)); // Field Name
5046 :
5047 24 : if (!ErrorsFound) {
5048 24 : checkCurveIsNormalizedToOne(
5049 96 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(4), Alphas(4), 1.0);
5050 : }
5051 : }
5052 :
5053 24 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5054 24 : Alphas(5),
5055 : ErrorsFound,
5056 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlow,
5057 24 : Alphas(1),
5058 : DataLoopNode::NodeFluidType::Air,
5059 : DataLoopNode::ConnectionType::Inlet,
5060 : NodeInputManager::CompFluidStream::Primary,
5061 : ObjectIsNotParent);
5062 :
5063 48 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5064 24 : Alphas(6),
5065 : ErrorsFound,
5066 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlow,
5067 24 : Alphas(1),
5068 : DataLoopNode::NodeFluidType::Air,
5069 : DataLoopNode::ConnectionType::Outlet,
5070 : NodeInputManager::CompFluidStream::Primary,
5071 : ObjectIsNotParent);
5072 :
5073 24 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(5), Alphas(6), "Air Nodes");
5074 :
5075 24 : thisDXCoil.CondensateCollectName = Alphas(7);
5076 24 : if (lAlphaBlanks(7)) {
5077 24 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
5078 : } else {
5079 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
5080 0 : SetupTankSupplyComponent(state,
5081 : thisDXCoil.Name,
5082 : CurrentModuleObject,
5083 : thisDXCoil.CondensateCollectName,
5084 : ErrorsFound,
5085 0 : thisDXCoil.CondensateTankID,
5086 0 : thisDXCoil.CondensateTankSupplyARRID);
5087 : }
5088 : }
5089 :
5090 134 : if (ErrorsFound) {
5091 0 : ShowFatalError(state,
5092 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5093 : }
5094 :
5095 : // Loop over the VRF Heating Coils and get & load the data
5096 134 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating);
5097 157 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFHeatingCoils; ++DXCoilIndex) {
5098 :
5099 23 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5100 : CurrentModuleObject,
5101 : DXCoilIndex,
5102 : Alphas,
5103 : NumAlphas,
5104 : Numbers,
5105 : NumNumbers,
5106 : IOStatus,
5107 : lNumericBlanks,
5108 : lAlphaBlanks,
5109 : cAlphaFields,
5110 : cNumericFields);
5111 :
5112 23 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
5113 23 : ++DXCoilNum;
5114 :
5115 : // allocate single performance mode for numeric field strings used for sizing routine
5116 23 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
5117 23 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
5118 23 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
5119 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
5120 23 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
5121 :
5122 23 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5123 23 : thisDXCoil.Name = Alphas(1);
5124 23 : thisDXCoil.DXCoilType = CurrentModuleObject;
5125 23 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_Heating;
5126 23 : if (lAlphaBlanks(2)) {
5127 2 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
5128 21 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
5129 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
5130 0 : ErrorsFound = true;
5131 : }
5132 23 : thisDXCoil.RatedTotCap(1) = Numbers(1);
5133 23 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(2);
5134 :
5135 23 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5136 23 : Alphas(3),
5137 : ErrorsFound,
5138 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlow,
5139 23 : Alphas(1),
5140 : DataLoopNode::NodeFluidType::Air,
5141 : DataLoopNode::ConnectionType::Inlet,
5142 : NodeInputManager::CompFluidStream::Primary,
5143 : ObjectIsNotParent);
5144 :
5145 46 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5146 23 : Alphas(4),
5147 : ErrorsFound,
5148 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlow,
5149 23 : Alphas(1),
5150 : DataLoopNode::NodeFluidType::Air,
5151 : DataLoopNode::ConnectionType::Outlet,
5152 : NodeInputManager::CompFluidStream::Primary,
5153 : ObjectIsNotParent);
5154 :
5155 23 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
5156 :
5157 23 : thisDXCoil.CCapFTemp = GetCurveIndex(state, Alphas(5));
5158 23 : if (thisDXCoil.CCapFTemp(1) == 0) {
5159 0 : if (lAlphaBlanks(5)) {
5160 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5161 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
5162 : } else {
5163 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5164 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
5165 : }
5166 0 : ErrorsFound = true;
5167 : } else {
5168 69 : ErrorsFound |= Curve::CheckCurveDims(state,
5169 23 : thisDXCoil.CCapFTemp(1), // Curve index
5170 : {1, 2}, // Valid dimensions // MULTIPLECURVEDIMS
5171 : RoutineName, // Routine name
5172 : CurrentModuleObject, // Object Type
5173 : thisDXCoil.Name, // Object Name
5174 23 : cAlphaFields(5)); // Field Name
5175 :
5176 23 : if (!ErrorsFound) {
5177 23 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
5178 23 : checkCurveIsNormalizedToOne(state,
5179 69 : std::string{RoutineName} + CurrentModuleObject,
5180 23 : thisDXCoil.Name,
5181 23 : thisDXCoil.CCapFTemp(1),
5182 23 : cAlphaFields(5),
5183 23 : Alphas(5),
5184 : RatedInletAirTempHeat);
5185 : } else {
5186 : // 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
5187 : // GetInput.
5188 : }
5189 : }
5190 : }
5191 :
5192 23 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
5193 23 : if (thisDXCoil.CCapFFlow(1) == 0) {
5194 0 : if (lAlphaBlanks(6)) {
5195 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5196 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
5197 : } else {
5198 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5199 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
5200 : }
5201 0 : ErrorsFound = true;
5202 : } else {
5203 : // Verify Curve Object, only legal type is Quadratic
5204 69 : ErrorsFound |= Curve::CheckCurveDims(state,
5205 23 : thisDXCoil.CCapFFlow(1), // Curve index
5206 : {1}, // Valid dimensions
5207 : RoutineName, // Routine name
5208 : CurrentModuleObject, // Object Type
5209 : thisDXCoil.Name, // Object Name
5210 23 : cAlphaFields(6)); // Field Name
5211 :
5212 23 : if (!ErrorsFound) {
5213 23 : checkCurveIsNormalizedToOne(
5214 92 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
5215 : }
5216 : }
5217 : }
5218 :
5219 134 : if (ErrorsFound) {
5220 0 : ShowFatalError(state,
5221 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5222 : }
5223 :
5224 : // Loop over the VRF Cooling Coils for VRF FluidTCtrl Model_zrp 2015
5225 134 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling);
5226 146 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils; ++DXCoilIndex) {
5227 :
5228 12 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5229 : CurrentModuleObject,
5230 : DXCoilIndex,
5231 : Alphas,
5232 : NumAlphas,
5233 : Numbers,
5234 : NumNumbers,
5235 : IOStatus,
5236 : lNumericBlanks,
5237 : lAlphaBlanks,
5238 : cAlphaFields,
5239 : cNumericFields);
5240 :
5241 12 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
5242 12 : ++DXCoilNum;
5243 :
5244 : // allocate single performance mode for numeric field strings used for sizing routine
5245 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
5246 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
5247 12 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
5248 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
5249 12 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
5250 :
5251 12 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5252 12 : thisDXCoil.Name = Alphas(1);
5253 12 : thisDXCoil.DXCoilType = CurrentModuleObject;
5254 12 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_FluidTCtrl_Cooling;
5255 12 : if (lAlphaBlanks(2)) {
5256 3 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
5257 9 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
5258 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
5259 0 : ErrorsFound = true;
5260 : }
5261 :
5262 12 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5263 12 : Alphas(3),
5264 : ErrorsFound,
5265 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl,
5266 12 : Alphas(1),
5267 : DataLoopNode::NodeFluidType::Air,
5268 : DataLoopNode::ConnectionType::Inlet,
5269 : NodeInputManager::CompFluidStream::Primary,
5270 : ObjectIsNotParent);
5271 24 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5272 12 : Alphas(4),
5273 : ErrorsFound,
5274 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl,
5275 12 : Alphas(1),
5276 : DataLoopNode::NodeFluidType::Air,
5277 : DataLoopNode::ConnectionType::Outlet,
5278 : NodeInputManager::CompFluidStream::Primary,
5279 : ObjectIsNotParent);
5280 12 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
5281 :
5282 12 : thisDXCoil.RatedTotCap(1) = Numbers(1);
5283 12 : thisDXCoil.RatedSHR(1) = Numbers(2);
5284 12 : thisDXCoil.SH = Numbers(3);
5285 : // @@ DXCoil( DXCoilNum ).RateBFVRFIUEvap = 0.0592; there will be a new field for this, which will be handled in a separate issue to
5286 : // update VRF-HP idd. It is not handled here to avoid transition issues for VRF-HP.
5287 :
5288 12 : int indexSHCurve = GetCurveIndex(state, Alphas(5)); // convert curve name to index number
5289 : // Verify curve name and type
5290 12 : if (indexSHCurve == 0) {
5291 0 : if (lAlphaBlanks(5)) {
5292 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5293 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
5294 : } else {
5295 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5296 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
5297 : }
5298 0 : ErrorsFound = true;
5299 : } else {
5300 : {
5301 12 : if (state.dataCurveManager->curves(indexSHCurve)->curveType == Curve::CurveType::Quadratic) {
5302 12 : thisDXCoil.C1Te = state.dataCurveManager->curves(indexSHCurve)->coeff[0];
5303 12 : thisDXCoil.C2Te = state.dataCurveManager->curves(indexSHCurve)->coeff[1];
5304 12 : thisDXCoil.C3Te = state.dataCurveManager->curves(indexSHCurve)->coeff[2];
5305 :
5306 : } else {
5307 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5308 0 : ShowContinueError(state,
5309 0 : format("...illegal {} type for this object = {}",
5310 : cAlphaFields(5),
5311 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexSHCurve)->curveType)]));
5312 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
5313 0 : ErrorsFound = true;
5314 : }
5315 : }
5316 : }
5317 :
5318 12 : thisDXCoil.CondensateCollectName = Alphas(6);
5319 12 : if (lAlphaBlanks(6)) {
5320 12 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
5321 : } else {
5322 0 : thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
5323 0 : SetupTankSupplyComponent(state,
5324 : thisDXCoil.Name,
5325 : CurrentModuleObject,
5326 : thisDXCoil.CondensateCollectName,
5327 : ErrorsFound,
5328 0 : thisDXCoil.CondensateTankID,
5329 0 : thisDXCoil.CondensateTankSupplyARRID);
5330 : }
5331 : }
5332 :
5333 134 : if (ErrorsFound) {
5334 0 : ShowFatalError(state,
5335 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5336 : }
5337 :
5338 : // Loop over the VRF Heating Coils for VRF FluidTCtrl Model_zrp 2015
5339 134 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating);
5340 145 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils; ++DXCoilIndex) {
5341 :
5342 11 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5343 : CurrentModuleObject,
5344 : DXCoilIndex,
5345 : Alphas,
5346 : NumAlphas,
5347 : Numbers,
5348 : NumNumbers,
5349 : IOStatus,
5350 : lNumericBlanks,
5351 : lAlphaBlanks,
5352 : cAlphaFields,
5353 : cNumericFields);
5354 :
5355 11 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
5356 11 : ++DXCoilNum;
5357 :
5358 : // allocate single performance mode for numeric field strings used for sizing routine
5359 11 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
5360 11 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
5361 11 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
5362 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
5363 11 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
5364 :
5365 11 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5366 11 : thisDXCoil.Name = Alphas(1);
5367 11 : thisDXCoil.DXCoilType = CurrentModuleObject;
5368 11 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_FluidTCtrl_Heating;
5369 11 : if (lAlphaBlanks(2)) {
5370 2 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
5371 9 : } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
5372 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
5373 0 : ErrorsFound = true;
5374 : }
5375 :
5376 11 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5377 11 : Alphas(3),
5378 : ErrorsFound,
5379 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl,
5380 11 : Alphas(1),
5381 : DataLoopNode::NodeFluidType::Air,
5382 : DataLoopNode::ConnectionType::Inlet,
5383 : NodeInputManager::CompFluidStream::Primary,
5384 : ObjectIsNotParent);
5385 22 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5386 11 : Alphas(4),
5387 : ErrorsFound,
5388 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl,
5389 11 : Alphas(1),
5390 : DataLoopNode::NodeFluidType::Air,
5391 : DataLoopNode::ConnectionType::Outlet,
5392 : NodeInputManager::CompFluidStream::Primary,
5393 : ObjectIsNotParent);
5394 11 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
5395 :
5396 11 : thisDXCoil.RatedTotCap(1) = Numbers(1);
5397 11 : thisDXCoil.SC = Numbers(2);
5398 : //@@ DXCoil( DXCoilNum ).RateBFVRFIUCond = 0.136;
5399 :
5400 11 : int indexSCCurve = GetCurveIndex(state, Alphas(5)); // convert curve name to index number
5401 : // Verify curve name and type
5402 11 : if (indexSCCurve == 0) {
5403 0 : if (lAlphaBlanks(5)) {
5404 0 : ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5405 0 : ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
5406 : } else {
5407 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5408 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
5409 : }
5410 0 : ErrorsFound = true;
5411 : } else {
5412 : {
5413 11 : if (state.dataCurveManager->curves(indexSCCurve)->curveType == Curve::CurveType::Quadratic) {
5414 11 : thisDXCoil.C1Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[0];
5415 11 : thisDXCoil.C2Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[1];
5416 11 : thisDXCoil.C3Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[2];
5417 :
5418 : } else {
5419 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
5420 0 : ShowContinueError(state,
5421 0 : format("...illegal {} type for this object = {}",
5422 : cAlphaFields(5),
5423 0 : Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexSCCurve)->curveType)]));
5424 0 : ShowContinueError(state, "... Curve type must be Quadratic.");
5425 0 : ErrorsFound = true;
5426 : }
5427 : }
5428 : }
5429 : }
5430 :
5431 134 : if (ErrorsFound) {
5432 0 : ShowFatalError(state,
5433 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5434 : }
5435 :
5436 349 : for (DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDXCoils; ++DXCoilNum) {
5437 :
5438 215 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5439 :
5440 215 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
5441 : // Setup Report Variables for Cooling Equipment
5442 : // CurrentModuleObject='Coil:Cooling:DX:SingleSpeed/Coil:Cooling:DX:TwoStageWithHumidityControlMode'
5443 128 : SetupOutputVariable(state,
5444 : "Cooling Coil Total Cooling Rate",
5445 : Constant::Units::W,
5446 64 : thisDXCoil.TotalCoolingEnergyRate,
5447 : OutputProcessor::TimeStepType::System,
5448 : OutputProcessor::StoreType::Average,
5449 64 : thisDXCoil.Name);
5450 128 : SetupOutputVariable(state,
5451 : "Cooling Coil Total Cooling Energy",
5452 : Constant::Units::J,
5453 64 : thisDXCoil.TotalCoolingEnergy,
5454 : OutputProcessor::TimeStepType::System,
5455 : OutputProcessor::StoreType::Sum,
5456 64 : thisDXCoil.Name,
5457 : Constant::eResource::EnergyTransfer,
5458 : OutputProcessor::Group::HVAC,
5459 : OutputProcessor::EndUseCat::CoolingCoils);
5460 128 : SetupOutputVariable(state,
5461 : "Cooling Coil Sensible Cooling Rate",
5462 : Constant::Units::W,
5463 64 : thisDXCoil.SensCoolingEnergyRate,
5464 : OutputProcessor::TimeStepType::System,
5465 : OutputProcessor::StoreType::Average,
5466 64 : thisDXCoil.Name);
5467 128 : SetupOutputVariable(state,
5468 : "Cooling Coil Sensible Cooling Energy",
5469 : Constant::Units::J,
5470 64 : thisDXCoil.SensCoolingEnergy,
5471 : OutputProcessor::TimeStepType::System,
5472 : OutputProcessor::StoreType::Sum,
5473 64 : thisDXCoil.Name);
5474 128 : SetupOutputVariable(state,
5475 : "Cooling Coil Latent Cooling Rate",
5476 : Constant::Units::W,
5477 64 : thisDXCoil.LatCoolingEnergyRate,
5478 : OutputProcessor::TimeStepType::System,
5479 : OutputProcessor::StoreType::Average,
5480 64 : thisDXCoil.Name);
5481 128 : SetupOutputVariable(state,
5482 : "Cooling Coil Latent Cooling Energy",
5483 : Constant::Units::J,
5484 64 : thisDXCoil.LatCoolingEnergy,
5485 : OutputProcessor::TimeStepType::System,
5486 : OutputProcessor::StoreType::Sum,
5487 64 : thisDXCoil.Name);
5488 128 : SetupOutputVariable(state,
5489 : "Cooling Coil Electricity Rate",
5490 : Constant::Units::W,
5491 64 : thisDXCoil.ElecCoolingPower,
5492 : OutputProcessor::TimeStepType::System,
5493 : OutputProcessor::StoreType::Average,
5494 64 : thisDXCoil.Name);
5495 128 : SetupOutputVariable(state,
5496 : "Cooling Coil Electricity Energy",
5497 : Constant::Units::J,
5498 64 : thisDXCoil.ElecCoolingConsumption,
5499 : OutputProcessor::TimeStepType::System,
5500 : OutputProcessor::StoreType::Sum,
5501 64 : thisDXCoil.Name,
5502 : Constant::eResource::Electricity,
5503 : OutputProcessor::Group::HVAC,
5504 : OutputProcessor::EndUseCat::Cooling);
5505 128 : SetupOutputVariable(state,
5506 : "Cooling Coil Runtime Fraction",
5507 : Constant::Units::None,
5508 64 : thisDXCoil.CoolingCoilRuntimeFraction,
5509 : OutputProcessor::TimeStepType::System,
5510 : OutputProcessor::StoreType::Average,
5511 64 : thisDXCoil.Name);
5512 64 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
5513 0 : SetupOutputVariable(state,
5514 : "Secondary Coil Heat Rejection Rate",
5515 : Constant::Units::W,
5516 0 : thisDXCoil.SecCoilSensibleHeatGainRate,
5517 : OutputProcessor::TimeStepType::System,
5518 : OutputProcessor::StoreType::Average,
5519 0 : thisDXCoil.Name);
5520 : }
5521 :
5522 : // do we report these even if no storage tank?
5523 64 : if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
5524 0 : SetupOutputVariable(state,
5525 : "Cooling Coil Condensate Volume Flow Rate",
5526 : Constant::Units::m3_s,
5527 0 : thisDXCoil.CondensateVdot,
5528 : OutputProcessor::TimeStepType::System,
5529 : OutputProcessor::StoreType::Average,
5530 0 : thisDXCoil.Name);
5531 0 : SetupOutputVariable(state,
5532 : "Cooling Coil Condensate Volume",
5533 : Constant::Units::m3,
5534 0 : thisDXCoil.CondensateVol,
5535 : OutputProcessor::TimeStepType::System,
5536 : OutputProcessor::StoreType::Sum,
5537 0 : thisDXCoil.Name,
5538 : Constant::eResource::OnSiteWater,
5539 : OutputProcessor::Group::HVAC,
5540 : OutputProcessor::EndUseCat::Condensate);
5541 : }
5542 :
5543 64 : if (thisDXCoil.ReportEvapCondVars) {
5544 28 : SetupOutputVariable(state,
5545 : "Cooling Coil Condenser Inlet Temperature",
5546 : Constant::Units::C,
5547 14 : thisDXCoil.CondInletTemp,
5548 : OutputProcessor::TimeStepType::System,
5549 : OutputProcessor::StoreType::Average,
5550 14 : thisDXCoil.Name);
5551 28 : SetupOutputVariable(state,
5552 : "Cooling Coil Evaporative Condenser Water Volume",
5553 : Constant::Units::m3,
5554 14 : thisDXCoil.EvapWaterConsump,
5555 : OutputProcessor::TimeStepType::System,
5556 : OutputProcessor::StoreType::Sum,
5557 14 : thisDXCoil.Name,
5558 : Constant::eResource::Water,
5559 : OutputProcessor::Group::HVAC,
5560 : OutputProcessor::EndUseCat::Cooling);
5561 28 : SetupOutputVariable(state,
5562 : "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
5563 : Constant::Units::m3,
5564 14 : thisDXCoil.EvapWaterConsump,
5565 : OutputProcessor::TimeStepType::System,
5566 : OutputProcessor::StoreType::Sum,
5567 14 : thisDXCoil.Name,
5568 : Constant::eResource::MainsWater,
5569 : OutputProcessor::Group::HVAC,
5570 : OutputProcessor::EndUseCat::Cooling);
5571 28 : SetupOutputVariable(state,
5572 : "Cooling Coil Evaporative Condenser Pump Electricity Rate",
5573 : Constant::Units::W,
5574 14 : thisDXCoil.EvapCondPumpElecPower,
5575 : OutputProcessor::TimeStepType::System,
5576 : OutputProcessor::StoreType::Average,
5577 14 : thisDXCoil.Name);
5578 28 : SetupOutputVariable(state,
5579 : "Cooling Coil Evaporative Condenser Pump Electricity Energy",
5580 : Constant::Units::J,
5581 14 : thisDXCoil.EvapCondPumpElecConsumption,
5582 : OutputProcessor::TimeStepType::System,
5583 : OutputProcessor::StoreType::Sum,
5584 14 : thisDXCoil.Name,
5585 : Constant::eResource::Electricity,
5586 : OutputProcessor::Group::HVAC,
5587 : OutputProcessor::EndUseCat::Cooling);
5588 14 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
5589 6 : SetupOutputVariable(state,
5590 : "Cooling Coil Basin Heater Electricity Rate",
5591 : Constant::Units::W,
5592 3 : thisDXCoil.BasinHeaterPower,
5593 : OutputProcessor::TimeStepType::System,
5594 : OutputProcessor::StoreType::Average,
5595 3 : thisDXCoil.Name);
5596 6 : SetupOutputVariable(state,
5597 : "Cooling Coil Basin Heater Electricity Energy",
5598 : Constant::Units::J,
5599 3 : thisDXCoil.BasinHeaterConsumption,
5600 : OutputProcessor::TimeStepType::System,
5601 : OutputProcessor::StoreType::Sum,
5602 3 : thisDXCoil.Name,
5603 : Constant::eResource::Electricity,
5604 : OutputProcessor::Group::HVAC,
5605 : OutputProcessor::EndUseCat::Cooling);
5606 : }
5607 : }
5608 :
5609 64 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
5610 : // Setup Report Variables for Cooling Equipment
5611 : // CurrentModuleObject='Cooling:DX:TwoStageWithHumidityControlMode'
5612 4 : SetupOutputVariable(state,
5613 : "Cooling Coil Stage 2 Runtime Fraction",
5614 : Constant::Units::None,
5615 2 : thisDXCoil.CoolingCoilStg2RuntimeFrac,
5616 : OutputProcessor::TimeStepType::System,
5617 : OutputProcessor::StoreType::Average,
5618 2 : thisDXCoil.Name);
5619 2 : SetupOutputVariable(state,
5620 : "Cooling Coil Dehumidification Mode",
5621 : Constant::Units::None,
5622 2 : (int &)thisDXCoil.DehumidificationMode,
5623 : OutputProcessor::TimeStepType::System,
5624 : OutputProcessor::StoreType::Average,
5625 2 : thisDXCoil.Name);
5626 : }
5627 :
5628 : }
5629 :
5630 151 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5631 : // Setup Report Variables for Heating Equipment
5632 : // CurrentModuleObject='Coil:Heating:DX:SingleSpeed'
5633 24 : SetupOutputVariable(state,
5634 : "Heating Coil Heating Rate",
5635 : Constant::Units::W,
5636 12 : thisDXCoil.TotalHeatingEnergyRate,
5637 : OutputProcessor::TimeStepType::System,
5638 : OutputProcessor::StoreType::Average,
5639 12 : thisDXCoil.Name);
5640 24 : SetupOutputVariable(state,
5641 : "Heating Coil Heating Energy",
5642 : Constant::Units::J,
5643 12 : thisDXCoil.TotalHeatingEnergy,
5644 : OutputProcessor::TimeStepType::System,
5645 : OutputProcessor::StoreType::Sum,
5646 12 : thisDXCoil.Name,
5647 : Constant::eResource::EnergyTransfer,
5648 : OutputProcessor::Group::HVAC,
5649 : OutputProcessor::EndUseCat::HeatingCoils);
5650 24 : SetupOutputVariable(state,
5651 : "Heating Coil Electricity Rate",
5652 : Constant::Units::W,
5653 12 : thisDXCoil.ElecHeatingPower,
5654 : OutputProcessor::TimeStepType::System,
5655 : OutputProcessor::StoreType::Average,
5656 12 : thisDXCoil.Name);
5657 24 : SetupOutputVariable(state,
5658 : "Heating Coil Electricity Energy",
5659 : Constant::Units::J,
5660 12 : thisDXCoil.ElecHeatingConsumption,
5661 : OutputProcessor::TimeStepType::System,
5662 : OutputProcessor::StoreType::Sum,
5663 12 : thisDXCoil.Name,
5664 : Constant::eResource::Electricity,
5665 : OutputProcessor::Group::HVAC,
5666 : OutputProcessor::EndUseCat::Heating);
5667 24 : SetupOutputVariable(state,
5668 : "Heating Coil Defrost Electricity Rate",
5669 : Constant::Units::W,
5670 12 : thisDXCoil.DefrostPower,
5671 : OutputProcessor::TimeStepType::System,
5672 : OutputProcessor::StoreType::Average,
5673 12 : thisDXCoil.Name);
5674 24 : SetupOutputVariable(state,
5675 : "Heating Coil Defrost Electricity Energy",
5676 : Constant::Units::J,
5677 12 : thisDXCoil.DefrostConsumption,
5678 : OutputProcessor::TimeStepType::System,
5679 : OutputProcessor::StoreType::Sum,
5680 12 : thisDXCoil.Name,
5681 : Constant::eResource::Electricity,
5682 : OutputProcessor::Group::HVAC,
5683 : OutputProcessor::EndUseCat::Heating);
5684 24 : SetupOutputVariable(state,
5685 : "Heating Coil Crankcase Heater Electricity Rate",
5686 : Constant::Units::W,
5687 12 : thisDXCoil.CrankcaseHeaterPower,
5688 : OutputProcessor::TimeStepType::System,
5689 : OutputProcessor::StoreType::Average,
5690 12 : thisDXCoil.Name);
5691 24 : SetupOutputVariable(state,
5692 : "Heating Coil Crankcase Heater Electricity Energy",
5693 : Constant::Units::J,
5694 12 : thisDXCoil.CrankcaseHeaterConsumption,
5695 : OutputProcessor::TimeStepType::System,
5696 : OutputProcessor::StoreType::Sum,
5697 12 : thisDXCoil.Name,
5698 : Constant::eResource::Electricity,
5699 : OutputProcessor::Group::HVAC,
5700 : OutputProcessor::EndUseCat::Heating);
5701 24 : SetupOutputVariable(state,
5702 : "Heating Coil Runtime Fraction",
5703 : Constant::Units::None,
5704 12 : thisDXCoil.HeatingCoilRuntimeFraction,
5705 : OutputProcessor::TimeStepType::System,
5706 : OutputProcessor::StoreType::Average,
5707 12 : thisDXCoil.Name);
5708 12 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
5709 0 : SetupOutputVariable(state,
5710 : "Secondary Coil Total Heat Removal Rate",
5711 : Constant::Units::W,
5712 0 : thisDXCoil.SecCoilTotalHeatRemovalRate,
5713 : OutputProcessor::TimeStepType::System,
5714 : OutputProcessor::StoreType::Average,
5715 0 : thisDXCoil.Name);
5716 0 : SetupOutputVariable(state,
5717 : "Secondary Coil Sensible Heat Removal Rate",
5718 : Constant::Units::W,
5719 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate,
5720 : OutputProcessor::TimeStepType::System,
5721 : OutputProcessor::StoreType::Average,
5722 0 : thisDXCoil.Name);
5723 0 : SetupOutputVariable(state,
5724 : "Secondary Coil Latent Heat Removal Rate",
5725 : Constant::Units::W,
5726 0 : thisDXCoil.SecCoilLatentHeatRemovalRate,
5727 : OutputProcessor::TimeStepType::System,
5728 : OutputProcessor::StoreType::Average,
5729 0 : thisDXCoil.Name);
5730 0 : SetupOutputVariable(state,
5731 : "Secondary Coil Sensible Heat Ratio",
5732 : Constant::Units::None,
5733 0 : thisDXCoil.SecCoilSHR,
5734 : OutputProcessor::TimeStepType::System,
5735 : OutputProcessor::StoreType::Average,
5736 0 : thisDXCoil.Name);
5737 0 : SetupOutputVariable(state,
5738 : "Secondary Coil Compressor Part Load Ratio",
5739 : Constant::Units::None,
5740 0 : thisDXCoil.CompressorPartLoadRatio,
5741 : OutputProcessor::TimeStepType::System,
5742 : OutputProcessor::StoreType::Average,
5743 0 : thisDXCoil.Name);
5744 : }
5745 12 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
5746 0 : SetupEMSActuator(state,
5747 : thisDXCoil.DXCoilType,
5748 : thisDXCoil.Name,
5749 : "Frost Heating Capacity Multiplier",
5750 : "[]",
5751 0 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
5752 0 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
5753 :
5754 0 : SetupEMSActuator(state,
5755 : thisDXCoil.DXCoilType,
5756 : thisDXCoil.Name,
5757 : "Frost Heating Input Power Multiplier",
5758 : "[]",
5759 0 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
5760 0 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
5761 : }
5762 : }
5763 :
5764 139 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
5765 : // Setup Report Variables for Cooling Equipment
5766 : // CurrentModuleObject='Coil:Cooling:DX:TwoSpeed'
5767 24 : SetupOutputVariable(state,
5768 : "Cooling Coil Total Cooling Rate",
5769 : Constant::Units::W,
5770 12 : thisDXCoil.TotalCoolingEnergyRate,
5771 : OutputProcessor::TimeStepType::System,
5772 : OutputProcessor::StoreType::Average,
5773 12 : thisDXCoil.Name);
5774 24 : SetupOutputVariable(state,
5775 : "Cooling Coil Total Cooling Energy",
5776 : Constant::Units::J,
5777 12 : thisDXCoil.TotalCoolingEnergy,
5778 : OutputProcessor::TimeStepType::System,
5779 : OutputProcessor::StoreType::Sum,
5780 12 : thisDXCoil.Name,
5781 : Constant::eResource::EnergyTransfer,
5782 : OutputProcessor::Group::HVAC,
5783 : OutputProcessor::EndUseCat::CoolingCoils);
5784 24 : SetupOutputVariable(state,
5785 : "Cooling Coil Sensible Cooling Rate",
5786 : Constant::Units::W,
5787 12 : thisDXCoil.SensCoolingEnergyRate,
5788 : OutputProcessor::TimeStepType::System,
5789 : OutputProcessor::StoreType::Average,
5790 12 : thisDXCoil.Name);
5791 24 : SetupOutputVariable(state,
5792 : "Cooling Coil Sensible Cooling Energy",
5793 : Constant::Units::J,
5794 12 : thisDXCoil.SensCoolingEnergy,
5795 : OutputProcessor::TimeStepType::System,
5796 : OutputProcessor::StoreType::Sum,
5797 12 : thisDXCoil.Name);
5798 24 : SetupOutputVariable(state,
5799 : "Cooling Coil Latent Cooling Rate",
5800 : Constant::Units::W,
5801 12 : thisDXCoil.LatCoolingEnergyRate,
5802 : OutputProcessor::TimeStepType::System,
5803 : OutputProcessor::StoreType::Average,
5804 12 : thisDXCoil.Name);
5805 24 : SetupOutputVariable(state,
5806 : "Cooling Coil Latent Cooling Energy",
5807 : Constant::Units::J,
5808 12 : thisDXCoil.LatCoolingEnergy,
5809 : OutputProcessor::TimeStepType::System,
5810 : OutputProcessor::StoreType::Sum,
5811 12 : thisDXCoil.Name);
5812 24 : SetupOutputVariable(state,
5813 : "Cooling Coil Electricity Rate",
5814 : Constant::Units::W,
5815 12 : thisDXCoil.ElecCoolingPower,
5816 : OutputProcessor::TimeStepType::System,
5817 : OutputProcessor::StoreType::Average,
5818 12 : thisDXCoil.Name);
5819 24 : SetupOutputVariable(state,
5820 : "Cooling Coil Electricity Energy",
5821 : Constant::Units::J,
5822 12 : thisDXCoil.ElecCoolingConsumption,
5823 : OutputProcessor::TimeStepType::System,
5824 : OutputProcessor::StoreType::Sum,
5825 12 : thisDXCoil.Name,
5826 : Constant::eResource::Electricity,
5827 : OutputProcessor::Group::HVAC,
5828 : OutputProcessor::EndUseCat::Cooling);
5829 24 : SetupOutputVariable(state,
5830 : "Cooling Coil Runtime Fraction",
5831 : Constant::Units::None,
5832 12 : thisDXCoil.CoolingCoilRuntimeFraction,
5833 : OutputProcessor::TimeStepType::System,
5834 : OutputProcessor::StoreType::Average,
5835 12 : thisDXCoil.Name);
5836 12 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
5837 0 : SetupOutputVariable(state,
5838 : "Secondary Coil Heat Rejection Rate",
5839 : Constant::Units::W,
5840 0 : thisDXCoil.SecCoilSensibleHeatGainRate,
5841 : OutputProcessor::TimeStepType::System,
5842 : OutputProcessor::StoreType::Average,
5843 0 : thisDXCoil.Name);
5844 : }
5845 :
5846 12 : if (thisDXCoil.ReportEvapCondVars) {
5847 4 : SetupOutputVariable(state,
5848 : "Cooling Coil Condenser Inlet Temperature",
5849 : Constant::Units::C,
5850 2 : thisDXCoil.CondInletTemp,
5851 : OutputProcessor::TimeStepType::System,
5852 : OutputProcessor::StoreType::Average,
5853 2 : thisDXCoil.Name);
5854 4 : SetupOutputVariable(state,
5855 : "Cooling Coil Evaporative Condenser Water Volume",
5856 : Constant::Units::m3,
5857 2 : thisDXCoil.EvapWaterConsump,
5858 : OutputProcessor::TimeStepType::System,
5859 : OutputProcessor::StoreType::Sum,
5860 2 : thisDXCoil.Name,
5861 : Constant::eResource::Water,
5862 : OutputProcessor::Group::HVAC,
5863 : OutputProcessor::EndUseCat::Cooling);
5864 4 : SetupOutputVariable(state,
5865 : "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
5866 : Constant::Units::m3,
5867 2 : thisDXCoil.EvapWaterConsump,
5868 : OutputProcessor::TimeStepType::System,
5869 : OutputProcessor::StoreType::Sum,
5870 2 : thisDXCoil.Name,
5871 : Constant::eResource::MainsWater,
5872 : OutputProcessor::Group::HVAC,
5873 : OutputProcessor::EndUseCat::Cooling);
5874 4 : SetupOutputVariable(state,
5875 : "Cooling Coil Evaporative Condenser Pump Electricity Rate",
5876 : Constant::Units::W,
5877 2 : thisDXCoil.EvapCondPumpElecPower,
5878 : OutputProcessor::TimeStepType::System,
5879 : OutputProcessor::StoreType::Average,
5880 2 : thisDXCoil.Name);
5881 4 : SetupOutputVariable(state,
5882 : "Cooling Coil Evaporative Condenser Pump Electricity Energy",
5883 : Constant::Units::J,
5884 2 : thisDXCoil.EvapCondPumpElecConsumption,
5885 : OutputProcessor::TimeStepType::System,
5886 : OutputProcessor::StoreType::Sum,
5887 2 : thisDXCoil.Name,
5888 : Constant::eResource::Electricity,
5889 : OutputProcessor::Group::HVAC,
5890 : OutputProcessor::EndUseCat::Cooling);
5891 2 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
5892 2 : SetupOutputVariable(state,
5893 : "Cooling Coil Basin Heater Electricity Rate",
5894 : Constant::Units::W,
5895 1 : thisDXCoil.BasinHeaterPower,
5896 : OutputProcessor::TimeStepType::System,
5897 : OutputProcessor::StoreType::Average,
5898 1 : thisDXCoil.Name);
5899 2 : SetupOutputVariable(state,
5900 : "Cooling Coil Basin Heater Electricity Energy",
5901 : Constant::Units::J,
5902 1 : thisDXCoil.BasinHeaterConsumption,
5903 : OutputProcessor::TimeStepType::System,
5904 : OutputProcessor::StoreType::Sum,
5905 1 : thisDXCoil.Name,
5906 : Constant::eResource::Electricity,
5907 : OutputProcessor::Group::HVAC,
5908 : OutputProcessor::EndUseCat::Cooling);
5909 : }
5910 : }
5911 :
5912 : }
5913 :
5914 127 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
5915 118 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
5916 : // Setup Report Variables for Cooling Equipment
5917 : // CurrentModuleObject='Coil:WaterHeating:AirToWaterHeatPump:Pumped'
5918 : // or 'Coil:WaterHeating:AirToWaterHeatPump:Wrapped'
5919 32 : SetupOutputVariable(state,
5920 : "Cooling Coil Total Cooling Rate",
5921 : Constant::Units::W,
5922 16 : thisDXCoil.TotalCoolingEnergyRate,
5923 : OutputProcessor::TimeStepType::System,
5924 : OutputProcessor::StoreType::Average,
5925 16 : thisDXCoil.Name);
5926 :
5927 16 : if (thisDXCoil.IsDXCoilInZone) {
5928 32 : SetupOutputVariable(state,
5929 : "Cooling Coil Total Cooling Energy",
5930 : Constant::Units::J,
5931 16 : thisDXCoil.TotalCoolingEnergy,
5932 : OutputProcessor::TimeStepType::System,
5933 : OutputProcessor::StoreType::Sum,
5934 16 : thisDXCoil.Name,
5935 : Constant::eResource::EnergyTransfer,
5936 : OutputProcessor::Group::HVAC,
5937 : OutputProcessor::EndUseCat::CoolingCoils);
5938 : } else {
5939 0 : SetupOutputVariable(state,
5940 : "Cooling Coil Total Cooling Energy",
5941 : Constant::Units::J,
5942 0 : thisDXCoil.TotalCoolingEnergy,
5943 : OutputProcessor::TimeStepType::System,
5944 : OutputProcessor::StoreType::Sum,
5945 0 : thisDXCoil.Name);
5946 : }
5947 :
5948 32 : SetupOutputVariable(state,
5949 : "Cooling Coil Sensible Cooling Rate",
5950 : Constant::Units::W,
5951 16 : thisDXCoil.SensCoolingEnergyRate,
5952 : OutputProcessor::TimeStepType::System,
5953 : OutputProcessor::StoreType::Average,
5954 16 : thisDXCoil.Name);
5955 32 : SetupOutputVariable(state,
5956 : "Cooling Coil Sensible Cooling Energy",
5957 : Constant::Units::J,
5958 16 : thisDXCoil.SensCoolingEnergy,
5959 : OutputProcessor::TimeStepType::System,
5960 : OutputProcessor::StoreType::Sum,
5961 16 : thisDXCoil.Name);
5962 32 : SetupOutputVariable(state,
5963 : "Cooling Coil Latent Cooling Rate",
5964 : Constant::Units::W,
5965 16 : thisDXCoil.LatCoolingEnergyRate,
5966 : OutputProcessor::TimeStepType::System,
5967 : OutputProcessor::StoreType::Average,
5968 16 : thisDXCoil.Name);
5969 32 : SetupOutputVariable(state,
5970 : "Cooling Coil Latent Cooling Energy",
5971 : Constant::Units::J,
5972 16 : thisDXCoil.LatCoolingEnergy,
5973 : OutputProcessor::TimeStepType::System,
5974 : OutputProcessor::StoreType::Sum,
5975 16 : thisDXCoil.Name);
5976 32 : SetupOutputVariable(state,
5977 : "Cooling Coil Runtime Fraction",
5978 : Constant::Units::None,
5979 16 : thisDXCoil.CoolingCoilRuntimeFraction,
5980 : OutputProcessor::TimeStepType::System,
5981 : OutputProcessor::StoreType::Average,
5982 16 : thisDXCoil.Name);
5983 :
5984 16 : if (thisDXCoil.ReportCoolingCoilCrankcasePower) {
5985 32 : SetupOutputVariable(state,
5986 : "Cooling Coil Crankcase Heater Electricity Rate",
5987 : Constant::Units::W,
5988 16 : thisDXCoil.CrankcaseHeaterPower,
5989 : OutputProcessor::TimeStepType::System,
5990 : OutputProcessor::StoreType::Average,
5991 16 : thisDXCoil.Name);
5992 32 : SetupOutputVariable(state,
5993 : "Cooling Coil Crankcase Heater Electricity Energy",
5994 : Constant::Units::J,
5995 16 : thisDXCoil.CrankcaseHeaterConsumption,
5996 : OutputProcessor::TimeStepType::System,
5997 : OutputProcessor::StoreType::Sum,
5998 16 : thisDXCoil.Name,
5999 : Constant::eResource::Electricity,
6000 : OutputProcessor::Group::Plant,
6001 : OutputProcessor::EndUseCat::WaterSystem); // DHW
6002 : }
6003 :
6004 : // new report variables for a HP water heater DX coil
6005 32 : SetupOutputVariable(state,
6006 : "Cooling Coil Total Water Heating Rate",
6007 : Constant::Units::W,
6008 16 : thisDXCoil.TotalHeatingEnergyRate,
6009 : OutputProcessor::TimeStepType::System,
6010 : OutputProcessor::StoreType::Average,
6011 16 : thisDXCoil.Name);
6012 32 : SetupOutputVariable(state,
6013 : "Cooling Coil Total Water Heating Energy",
6014 : Constant::Units::J,
6015 16 : thisDXCoil.TotalHeatingEnergy,
6016 : OutputProcessor::TimeStepType::System,
6017 : OutputProcessor::StoreType::Sum,
6018 16 : thisDXCoil.Name); //, &
6019 : // ResourceTypeKey='ENERGYTRANSFER',EndUseKey='HEATING',GroupKey='Plant')
6020 32 : SetupOutputVariable(state,
6021 : "Cooling Coil Water Heating Electricity Rate",
6022 : Constant::Units::W,
6023 16 : thisDXCoil.ElecWaterHeatingPower,
6024 : OutputProcessor::TimeStepType::System,
6025 : OutputProcessor::StoreType::Average,
6026 16 : thisDXCoil.Name);
6027 32 : SetupOutputVariable(state,
6028 : "Cooling Coil Water Heating Electricity Energy",
6029 : Constant::Units::J,
6030 16 : thisDXCoil.ElecWaterHeatingConsumption,
6031 : OutputProcessor::TimeStepType::System,
6032 : OutputProcessor::StoreType::Sum,
6033 16 : thisDXCoil.Name,
6034 : Constant::eResource::Electricity,
6035 : OutputProcessor::Group::Plant,
6036 : OutputProcessor::EndUseCat::WaterSystem); // DHW
6037 : }
6038 :
6039 111 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6040 : // Setup Report Variables for Cooling Equipment:
6041 : // CurrentModuleObject='Coil:Cooling:DX:MultiSpeed'
6042 54 : SetupOutputVariable(state,
6043 : "Cooling Coil Total Cooling Rate",
6044 : Constant::Units::W,
6045 27 : thisDXCoil.TotalCoolingEnergyRate,
6046 : OutputProcessor::TimeStepType::System,
6047 : OutputProcessor::StoreType::Average,
6048 27 : thisDXCoil.Name);
6049 54 : SetupOutputVariable(state,
6050 : "Cooling Coil Total Cooling Energy",
6051 : Constant::Units::J,
6052 27 : thisDXCoil.TotalCoolingEnergy,
6053 : OutputProcessor::TimeStepType::System,
6054 : OutputProcessor::StoreType::Sum,
6055 27 : thisDXCoil.Name,
6056 : Constant::eResource::EnergyTransfer,
6057 : OutputProcessor::Group::HVAC,
6058 : OutputProcessor::EndUseCat::CoolingCoils);
6059 54 : SetupOutputVariable(state,
6060 : "Cooling Coil Sensible Cooling Rate",
6061 : Constant::Units::W,
6062 27 : thisDXCoil.SensCoolingEnergyRate,
6063 : OutputProcessor::TimeStepType::System,
6064 : OutputProcessor::StoreType::Average,
6065 27 : thisDXCoil.Name);
6066 54 : SetupOutputVariable(state,
6067 : "Cooling Coil Sensible Cooling Energy",
6068 : Constant::Units::J,
6069 27 : thisDXCoil.SensCoolingEnergy,
6070 : OutputProcessor::TimeStepType::System,
6071 : OutputProcessor::StoreType::Sum,
6072 27 : thisDXCoil.Name);
6073 54 : SetupOutputVariable(state,
6074 : "Cooling Coil Latent Cooling Rate",
6075 : Constant::Units::W,
6076 27 : thisDXCoil.LatCoolingEnergyRate,
6077 : OutputProcessor::TimeStepType::System,
6078 : OutputProcessor::StoreType::Average,
6079 27 : thisDXCoil.Name);
6080 54 : SetupOutputVariable(state,
6081 : "Cooling Coil Latent Cooling Energy",
6082 : Constant::Units::J,
6083 27 : thisDXCoil.LatCoolingEnergy,
6084 : OutputProcessor::TimeStepType::System,
6085 : OutputProcessor::StoreType::Sum,
6086 27 : thisDXCoil.Name);
6087 54 : SetupOutputVariable(state,
6088 : "Cooling Coil Electricity Rate",
6089 : Constant::Units::W,
6090 27 : thisDXCoil.ElecCoolingPower,
6091 : OutputProcessor::TimeStepType::System,
6092 : OutputProcessor::StoreType::Average,
6093 27 : thisDXCoil.Name);
6094 54 : SetupOutputVariable(state,
6095 : "Cooling Coil Electricity Energy",
6096 : Constant::Units::J,
6097 27 : thisDXCoil.ElecCoolingConsumption,
6098 : OutputProcessor::TimeStepType::System,
6099 : OutputProcessor::StoreType::Sum,
6100 27 : thisDXCoil.Name,
6101 : Constant::eResource::Electricity,
6102 : OutputProcessor::Group::HVAC,
6103 : OutputProcessor::EndUseCat::Cooling);
6104 :
6105 27 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
6106 4 : std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
6107 12 : SetupOutputVariable(state,
6108 8 : format("Cooling Coil {} Rate", sFuelType),
6109 : Constant::Units::W,
6110 4 : thisDXCoil.FuelUsed,
6111 : OutputProcessor::TimeStepType::System,
6112 : OutputProcessor::StoreType::Average,
6113 4 : thisDXCoil.Name);
6114 12 : SetupOutputVariable(state,
6115 8 : format("Cooling Coil {} Energy", sFuelType),
6116 : Constant::Units::J,
6117 4 : thisDXCoil.FuelConsumed,
6118 : OutputProcessor::TimeStepType::System,
6119 : OutputProcessor::StoreType::Sum,
6120 4 : thisDXCoil.Name,
6121 4 : Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
6122 : OutputProcessor::Group::HVAC,
6123 : OutputProcessor::EndUseCat::Cooling);
6124 : }
6125 :
6126 54 : SetupOutputVariable(state,
6127 : "Cooling Coil Runtime Fraction",
6128 : Constant::Units::None,
6129 27 : thisDXCoil.CoolingCoilRuntimeFraction,
6130 : OutputProcessor::TimeStepType::System,
6131 : OutputProcessor::StoreType::Average,
6132 27 : thisDXCoil.Name);
6133 :
6134 27 : if (thisDXCoil.ReportEvapCondVars) {
6135 0 : SetupOutputVariable(state,
6136 : "Cooling Coil Condenser Inlet Temperature",
6137 : Constant::Units::C,
6138 0 : thisDXCoil.CondInletTemp,
6139 : OutputProcessor::TimeStepType::System,
6140 : OutputProcessor::StoreType::Average,
6141 0 : thisDXCoil.Name);
6142 0 : SetupOutputVariable(state,
6143 : "Cooling Coil Evaporative Condenser Water Volume",
6144 : Constant::Units::m3,
6145 0 : thisDXCoil.EvapWaterConsump,
6146 : OutputProcessor::TimeStepType::System,
6147 : OutputProcessor::StoreType::Sum,
6148 0 : thisDXCoil.Name,
6149 : Constant::eResource::Water,
6150 : OutputProcessor::Group::HVAC,
6151 : OutputProcessor::EndUseCat::Cooling);
6152 0 : SetupOutputVariable(state,
6153 : "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
6154 : Constant::Units::m3,
6155 0 : thisDXCoil.EvapWaterConsump,
6156 : OutputProcessor::TimeStepType::System,
6157 : OutputProcessor::StoreType::Sum,
6158 0 : thisDXCoil.Name,
6159 : Constant::eResource::MainsWater,
6160 : OutputProcessor::Group::HVAC,
6161 : OutputProcessor::EndUseCat::Cooling);
6162 0 : SetupOutputVariable(state,
6163 : "Cooling Coil Evaporative Condenser Pump Electricity Rate",
6164 : Constant::Units::W,
6165 0 : thisDXCoil.EvapCondPumpElecPower,
6166 : OutputProcessor::TimeStepType::System,
6167 : OutputProcessor::StoreType::Average,
6168 0 : thisDXCoil.Name);
6169 0 : SetupOutputVariable(state,
6170 : "Cooling Coil Evaporative Condenser Pump Electricity Energy",
6171 : Constant::Units::J,
6172 0 : thisDXCoil.EvapCondPumpElecConsumption,
6173 : OutputProcessor::TimeStepType::System,
6174 : OutputProcessor::StoreType::Sum,
6175 0 : thisDXCoil.Name,
6176 : Constant::eResource::Electricity,
6177 : OutputProcessor::Group::HVAC,
6178 : OutputProcessor::EndUseCat::Cooling);
6179 0 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
6180 0 : SetupOutputVariable(state,
6181 : "Cooling Coil Basin Heater Electricity Rate",
6182 : Constant::Units::W,
6183 0 : thisDXCoil.BasinHeaterPower,
6184 : OutputProcessor::TimeStepType::System,
6185 : OutputProcessor::StoreType::Average,
6186 0 : thisDXCoil.Name);
6187 0 : SetupOutputVariable(state,
6188 : "Cooling Coil Basin Heater Electricity Energy",
6189 : Constant::Units::J,
6190 0 : thisDXCoil.BasinHeaterConsumption,
6191 : OutputProcessor::TimeStepType::System,
6192 : OutputProcessor::StoreType::Sum,
6193 0 : thisDXCoil.Name,
6194 : Constant::eResource::Electricity,
6195 : OutputProcessor::Group::HVAC,
6196 : OutputProcessor::EndUseCat::Cooling);
6197 : }
6198 : }
6199 27 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
6200 0 : SetupOutputVariable(state,
6201 : "Secondary Coil Heat Rejection Rate",
6202 : Constant::Units::W,
6203 0 : thisDXCoil.SecCoilSensibleHeatGainRate,
6204 : OutputProcessor::TimeStepType::System,
6205 : OutputProcessor::StoreType::Average,
6206 0 : thisDXCoil.Name);
6207 : }
6208 :
6209 : }
6210 :
6211 84 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6212 : // Setup Report Variables for Heating Equipment:
6213 : // CurrentModuleObject='Coil:Heating:DX:MultiSpeed'
6214 28 : SetupOutputVariable(state,
6215 : "Heating Coil Heating Rate",
6216 : Constant::Units::W,
6217 14 : thisDXCoil.TotalHeatingEnergyRate,
6218 : OutputProcessor::TimeStepType::System,
6219 : OutputProcessor::StoreType::Average,
6220 14 : thisDXCoil.Name);
6221 28 : SetupOutputVariable(state,
6222 : "Heating Coil Heating Energy",
6223 : Constant::Units::J,
6224 14 : thisDXCoil.TotalHeatingEnergy,
6225 : OutputProcessor::TimeStepType::System,
6226 : OutputProcessor::StoreType::Sum,
6227 14 : thisDXCoil.Name,
6228 : Constant::eResource::EnergyTransfer,
6229 : OutputProcessor::Group::HVAC,
6230 : OutputProcessor::EndUseCat::HeatingCoils);
6231 28 : SetupOutputVariable(state,
6232 : "Heating Coil Electricity Rate",
6233 : Constant::Units::W,
6234 14 : thisDXCoil.ElecHeatingPower,
6235 : OutputProcessor::TimeStepType::System,
6236 : OutputProcessor::StoreType::Average,
6237 14 : thisDXCoil.Name);
6238 28 : SetupOutputVariable(state,
6239 : "Heating Coil Electricity Energy",
6240 : Constant::Units::J,
6241 14 : thisDXCoil.ElecHeatingConsumption,
6242 : OutputProcessor::TimeStepType::System,
6243 : OutputProcessor::StoreType::Sum,
6244 14 : thisDXCoil.Name,
6245 : Constant::eResource::Electricity,
6246 : OutputProcessor::Group::HVAC,
6247 : OutputProcessor::EndUseCat::Heating);
6248 :
6249 14 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
6250 3 : std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
6251 9 : SetupOutputVariable(state,
6252 6 : format("Heating Coil {} Rate", sFuelType),
6253 : Constant::Units::W,
6254 3 : thisDXCoil.FuelUsed,
6255 : OutputProcessor::TimeStepType::System,
6256 : OutputProcessor::StoreType::Average,
6257 3 : thisDXCoil.Name);
6258 9 : SetupOutputVariable(state,
6259 6 : format("Heating Coil {} Energy", sFuelType),
6260 : Constant::Units::J,
6261 3 : thisDXCoil.FuelConsumed,
6262 : OutputProcessor::TimeStepType::System,
6263 : OutputProcessor::StoreType::Sum,
6264 3 : thisDXCoil.Name,
6265 3 : Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
6266 : OutputProcessor::Group::HVAC,
6267 : OutputProcessor::EndUseCat::HeatingCoils);
6268 : }
6269 :
6270 14 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
6271 2 : std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
6272 6 : SetupOutputVariable(state,
6273 4 : format("Heating Coil Defrost {} Rate", sFuelType),
6274 : Constant::Units::W,
6275 2 : thisDXCoil.DefrostPower,
6276 : OutputProcessor::TimeStepType::System,
6277 : OutputProcessor::StoreType::Average,
6278 2 : thisDXCoil.Name);
6279 6 : SetupOutputVariable(state,
6280 4 : format("Heating Coil Defrost {} Energy", sFuelType),
6281 : Constant::Units::J,
6282 2 : thisDXCoil.DefrostConsumption,
6283 : OutputProcessor::TimeStepType::System,
6284 : OutputProcessor::StoreType::Sum,
6285 2 : thisDXCoil.Name,
6286 2 : Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
6287 : OutputProcessor::Group::HVAC,
6288 : OutputProcessor::EndUseCat::Heating);
6289 2 : } else {
6290 24 : SetupOutputVariable(state,
6291 : "Heating Coil Defrost Electricity Rate",
6292 : Constant::Units::W,
6293 12 : thisDXCoil.DefrostPower,
6294 : OutputProcessor::TimeStepType::System,
6295 : OutputProcessor::StoreType::Average,
6296 12 : thisDXCoil.Name);
6297 24 : SetupOutputVariable(state,
6298 : "Heating Coil Defrost Electricity Energy",
6299 : Constant::Units::J,
6300 12 : thisDXCoil.DefrostConsumption,
6301 : OutputProcessor::TimeStepType::System,
6302 : OutputProcessor::StoreType::Sum,
6303 12 : thisDXCoil.Name,
6304 : Constant::eResource::Electricity,
6305 : OutputProcessor::Group::HVAC,
6306 : OutputProcessor::EndUseCat::Heating);
6307 : }
6308 :
6309 28 : SetupOutputVariable(state,
6310 : "Heating Coil Crankcase Heater Electricity Rate",
6311 : Constant::Units::W,
6312 14 : thisDXCoil.CrankcaseHeaterPower,
6313 : OutputProcessor::TimeStepType::System,
6314 : OutputProcessor::StoreType::Average,
6315 14 : thisDXCoil.Name);
6316 28 : SetupOutputVariable(state,
6317 : "Heating Coil Crankcase Heater Electricity Energy",
6318 : Constant::Units::J,
6319 14 : thisDXCoil.CrankcaseHeaterConsumption,
6320 : OutputProcessor::TimeStepType::System,
6321 : OutputProcessor::StoreType::Sum,
6322 14 : thisDXCoil.Name,
6323 : Constant::eResource::Electricity,
6324 : OutputProcessor::Group::HVAC,
6325 : OutputProcessor::EndUseCat::Heating);
6326 28 : SetupOutputVariable(state,
6327 : "Heating Coil Runtime Fraction",
6328 : Constant::Units::None,
6329 14 : thisDXCoil.HeatingCoilRuntimeFraction,
6330 : OutputProcessor::TimeStepType::System,
6331 : OutputProcessor::StoreType::Average,
6332 14 : thisDXCoil.Name);
6333 :
6334 14 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
6335 0 : SetupOutputVariable(state,
6336 : "Secondary Coil Total Heat Removal Rate",
6337 : Constant::Units::W,
6338 0 : thisDXCoil.SecCoilTotalHeatRemovalRate,
6339 : OutputProcessor::TimeStepType::System,
6340 : OutputProcessor::StoreType::Average,
6341 0 : thisDXCoil.Name);
6342 0 : SetupOutputVariable(state,
6343 : "Secondary Coil Sensible Heat Removal Rate",
6344 : Constant::Units::W,
6345 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate,
6346 : OutputProcessor::TimeStepType::System,
6347 : OutputProcessor::StoreType::Average,
6348 0 : thisDXCoil.Name);
6349 0 : SetupOutputVariable(state,
6350 : "Secondary Coil Latent Heat Removal Rate",
6351 : Constant::Units::W,
6352 0 : thisDXCoil.SecCoilLatentHeatRemovalRate,
6353 : OutputProcessor::TimeStepType::System,
6354 : OutputProcessor::StoreType::Average,
6355 0 : thisDXCoil.Name);
6356 0 : SetupOutputVariable(state,
6357 : "Secondary Coil Sensible Heat Ratio",
6358 : Constant::Units::None,
6359 0 : thisDXCoil.SecCoilSHR,
6360 : OutputProcessor::TimeStepType::System,
6361 : OutputProcessor::StoreType::Average,
6362 0 : thisDXCoil.Name);
6363 : }
6364 :
6365 14 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
6366 0 : SetupEMSActuator(state,
6367 : thisDXCoil.DXCoilType,
6368 : thisDXCoil.Name,
6369 : "Frost Heating Capacity Multiplier",
6370 : "[]",
6371 0 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
6372 0 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
6373 :
6374 0 : SetupEMSActuator(state,
6375 : thisDXCoil.DXCoilType,
6376 : thisDXCoil.Name,
6377 : "Frost Heating Input Power Multiplier",
6378 : "[]",
6379 0 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
6380 0 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
6381 : }
6382 : }
6383 :
6384 : // VRF cooling coil report variables
6385 70 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
6386 : // Setup Report Variables for Cooling Equipment:
6387 : // CurrentModuleObject='Coil:Cooling:DX:VariableRefrigerantFlow
6388 48 : SetupOutputVariable(state,
6389 : "Cooling Coil Total Cooling Rate",
6390 : Constant::Units::W,
6391 24 : thisDXCoil.TotalCoolingEnergyRate,
6392 : OutputProcessor::TimeStepType::System,
6393 : OutputProcessor::StoreType::Average,
6394 24 : thisDXCoil.Name);
6395 48 : SetupOutputVariable(state,
6396 : "Cooling Coil Total Cooling Energy",
6397 : Constant::Units::J,
6398 24 : thisDXCoil.TotalCoolingEnergy,
6399 : OutputProcessor::TimeStepType::System,
6400 : OutputProcessor::StoreType::Sum,
6401 24 : thisDXCoil.Name,
6402 : Constant::eResource::EnergyTransfer,
6403 : OutputProcessor::Group::HVAC,
6404 : OutputProcessor::EndUseCat::CoolingCoils);
6405 48 : SetupOutputVariable(state,
6406 : "Cooling Coil Sensible Cooling Rate",
6407 : Constant::Units::W,
6408 24 : thisDXCoil.SensCoolingEnergyRate,
6409 : OutputProcessor::TimeStepType::System,
6410 : OutputProcessor::StoreType::Average,
6411 24 : thisDXCoil.Name);
6412 48 : SetupOutputVariable(state,
6413 : "Cooling Coil Sensible Cooling Energy",
6414 : Constant::Units::J,
6415 24 : thisDXCoil.SensCoolingEnergy,
6416 : OutputProcessor::TimeStepType::System,
6417 : OutputProcessor::StoreType::Sum,
6418 24 : thisDXCoil.Name);
6419 48 : SetupOutputVariable(state,
6420 : "Cooling Coil Latent Cooling Rate",
6421 : Constant::Units::W,
6422 24 : thisDXCoil.LatCoolingEnergyRate,
6423 : OutputProcessor::TimeStepType::System,
6424 : OutputProcessor::StoreType::Average,
6425 24 : thisDXCoil.Name);
6426 48 : SetupOutputVariable(state,
6427 : "Cooling Coil Latent Cooling Energy",
6428 : Constant::Units::J,
6429 24 : thisDXCoil.LatCoolingEnergy,
6430 : OutputProcessor::TimeStepType::System,
6431 : OutputProcessor::StoreType::Sum,
6432 24 : thisDXCoil.Name);
6433 48 : SetupOutputVariable(state,
6434 : "Cooling Coil Runtime Fraction",
6435 : Constant::Units::None,
6436 24 : thisDXCoil.CoolingCoilRuntimeFraction,
6437 : OutputProcessor::TimeStepType::System,
6438 : OutputProcessor::StoreType::Average,
6439 24 : thisDXCoil.Name);
6440 24 : if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
6441 0 : SetupOutputVariable(state,
6442 : "Cooling Coil Condensate Volume Flow Rate",
6443 : Constant::Units::m3_s,
6444 0 : thisDXCoil.CondensateVdot,
6445 : OutputProcessor::TimeStepType::System,
6446 : OutputProcessor::StoreType::Average,
6447 0 : thisDXCoil.Name);
6448 0 : SetupOutputVariable(state,
6449 : "Cooling Coil Condensate Volume",
6450 : Constant::Units::m3,
6451 0 : thisDXCoil.CondensateVol,
6452 : OutputProcessor::TimeStepType::System,
6453 : OutputProcessor::StoreType::Sum,
6454 0 : thisDXCoil.Name,
6455 : Constant::eResource::OnSiteWater,
6456 : OutputProcessor::Group::HVAC,
6457 : OutputProcessor::EndUseCat::Condensate);
6458 : }
6459 : }
6460 :
6461 : // VRF heating coil report variables
6462 46 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
6463 : // Setup Report Variables for Heating Equipment:
6464 : // CurrentModuleObject='Coil:Heating:DX:VariableRefrigerantFlow
6465 46 : SetupOutputVariable(state,
6466 : "Heating Coil Heating Rate",
6467 : Constant::Units::W,
6468 23 : thisDXCoil.TotalHeatingEnergyRate,
6469 : OutputProcessor::TimeStepType::System,
6470 : OutputProcessor::StoreType::Average,
6471 23 : thisDXCoil.Name);
6472 46 : SetupOutputVariable(state,
6473 : "Heating Coil Heating Energy",
6474 : Constant::Units::J,
6475 23 : thisDXCoil.TotalHeatingEnergy,
6476 : OutputProcessor::TimeStepType::System,
6477 : OutputProcessor::StoreType::Sum,
6478 23 : thisDXCoil.Name,
6479 : Constant::eResource::EnergyTransfer,
6480 : OutputProcessor::Group::HVAC,
6481 : OutputProcessor::EndUseCat::HeatingCoils);
6482 46 : SetupOutputVariable(state,
6483 : "Heating Coil Runtime Fraction",
6484 : Constant::Units::None,
6485 23 : thisDXCoil.HeatingCoilRuntimeFraction,
6486 : OutputProcessor::TimeStepType::System,
6487 : OutputProcessor::StoreType::Average,
6488 23 : thisDXCoil.Name);
6489 :
6490 23 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
6491 0 : SetupEMSActuator(state,
6492 : thisDXCoil.DXCoilType,
6493 : thisDXCoil.Name,
6494 : "Frost Heating Capacity Multiplier",
6495 : "[]",
6496 0 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
6497 0 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
6498 :
6499 0 : SetupEMSActuator(state,
6500 : thisDXCoil.DXCoilType,
6501 : thisDXCoil.Name,
6502 : "Frost Heating Input Power Multiplier",
6503 : "[]",
6504 0 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
6505 0 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
6506 : }
6507 : }
6508 :
6509 : // VRF cooling coil for FluidTCtrl, report variables
6510 23 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
6511 : // Setup Report Variables for Cooling Equipment:
6512 : // CurrentModuleObject='Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl
6513 24 : SetupOutputVariable(state,
6514 : "Cooling Coil Total Cooling Rate",
6515 : Constant::Units::W,
6516 12 : thisDXCoil.TotalCoolingEnergyRate,
6517 : OutputProcessor::TimeStepType::System,
6518 : OutputProcessor::StoreType::Average,
6519 12 : thisDXCoil.Name);
6520 24 : SetupOutputVariable(state,
6521 : "Cooling Coil Total Cooling Energy",
6522 : Constant::Units::J,
6523 12 : thisDXCoil.TotalCoolingEnergy,
6524 : OutputProcessor::TimeStepType::System,
6525 : OutputProcessor::StoreType::Sum,
6526 12 : thisDXCoil.Name,
6527 : Constant::eResource::EnergyTransfer,
6528 : OutputProcessor::Group::HVAC,
6529 : OutputProcessor::EndUseCat::CoolingCoils);
6530 24 : SetupOutputVariable(state,
6531 : "Cooling Coil Sensible Cooling Rate",
6532 : Constant::Units::W,
6533 12 : thisDXCoil.SensCoolingEnergyRate,
6534 : OutputProcessor::TimeStepType::System,
6535 : OutputProcessor::StoreType::Average,
6536 12 : thisDXCoil.Name);
6537 24 : SetupOutputVariable(state,
6538 : "Cooling Coil Sensible Cooling Energy",
6539 : Constant::Units::J,
6540 12 : thisDXCoil.SensCoolingEnergy,
6541 : OutputProcessor::TimeStepType::System,
6542 : OutputProcessor::StoreType::Sum,
6543 12 : thisDXCoil.Name);
6544 24 : SetupOutputVariable(state,
6545 : "Cooling Coil Latent Cooling Rate",
6546 : Constant::Units::W,
6547 12 : thisDXCoil.LatCoolingEnergyRate,
6548 : OutputProcessor::TimeStepType::System,
6549 : OutputProcessor::StoreType::Average,
6550 12 : thisDXCoil.Name);
6551 24 : SetupOutputVariable(state,
6552 : "Cooling Coil Latent Cooling Energy",
6553 : Constant::Units::J,
6554 12 : thisDXCoil.LatCoolingEnergy,
6555 : OutputProcessor::TimeStepType::System,
6556 : OutputProcessor::StoreType::Sum,
6557 12 : thisDXCoil.Name);
6558 24 : SetupOutputVariable(state,
6559 : "Cooling Coil Runtime Fraction",
6560 : Constant::Units::None,
6561 12 : thisDXCoil.CoolingCoilRuntimeFraction,
6562 : OutputProcessor::TimeStepType::System,
6563 : OutputProcessor::StoreType::Average,
6564 12 : thisDXCoil.Name);
6565 : // Followings for VRF_FluidTCtrl Only
6566 24 : SetupOutputVariable(state,
6567 : "Cooling Coil VRF Evaporating Temperature",
6568 : Constant::Units::C,
6569 12 : thisDXCoil.EvaporatingTemp,
6570 : OutputProcessor::TimeStepType::System,
6571 : OutputProcessor::StoreType::Average,
6572 12 : thisDXCoil.Name);
6573 24 : SetupOutputVariable(state,
6574 : "Cooling Coil VRF Super Heating Degrees",
6575 : Constant::Units::C,
6576 12 : thisDXCoil.ActualSH,
6577 : OutputProcessor::TimeStepType::System,
6578 : OutputProcessor::StoreType::Average,
6579 12 : thisDXCoil.Name);
6580 :
6581 12 : if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
6582 0 : SetupOutputVariable(state,
6583 : "Cooling Coil Condensate Volume Flow Rate",
6584 : Constant::Units::m3_s,
6585 0 : thisDXCoil.CondensateVdot,
6586 : OutputProcessor::TimeStepType::System,
6587 : OutputProcessor::StoreType::Average,
6588 0 : thisDXCoil.Name);
6589 0 : SetupOutputVariable(state,
6590 : "Cooling Coil Condensate Volume",
6591 : Constant::Units::m3,
6592 0 : thisDXCoil.CondensateVol,
6593 : OutputProcessor::TimeStepType::System,
6594 : OutputProcessor::StoreType::Sum,
6595 0 : thisDXCoil.Name,
6596 : Constant::eResource::OnSiteWater,
6597 : OutputProcessor::Group::HVAC,
6598 : OutputProcessor::EndUseCat::Condensate);
6599 : }
6600 : }
6601 :
6602 : // VRF heating coil for FluidTCtrl, report variables
6603 11 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
6604 : // Setup Report Variables for Heating Equipment:
6605 : // CurrentModuleObject='Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl
6606 22 : SetupOutputVariable(state,
6607 : "Heating Coil Heating Rate",
6608 : Constant::Units::W,
6609 11 : thisDXCoil.TotalHeatingEnergyRate,
6610 : OutputProcessor::TimeStepType::System,
6611 : OutputProcessor::StoreType::Average,
6612 11 : thisDXCoil.Name);
6613 22 : SetupOutputVariable(state,
6614 : "Heating Coil Heating Energy",
6615 : Constant::Units::J,
6616 11 : thisDXCoil.TotalHeatingEnergy,
6617 : OutputProcessor::TimeStepType::System,
6618 : OutputProcessor::StoreType::Sum,
6619 11 : thisDXCoil.Name,
6620 : Constant::eResource::EnergyTransfer,
6621 : OutputProcessor::Group::HVAC,
6622 : OutputProcessor::EndUseCat::HeatingCoils);
6623 22 : SetupOutputVariable(state,
6624 : "Heating Coil Runtime Fraction",
6625 : Constant::Units::None,
6626 11 : thisDXCoil.HeatingCoilRuntimeFraction,
6627 : OutputProcessor::TimeStepType::System,
6628 : OutputProcessor::StoreType::Average,
6629 11 : thisDXCoil.Name);
6630 : // Followings for VRF_FluidTCtrl Only
6631 22 : SetupOutputVariable(state,
6632 : "Heating Coil VRF Condensing Temperature",
6633 : Constant::Units::C,
6634 11 : thisDXCoil.CondensingTemp,
6635 : OutputProcessor::TimeStepType::System,
6636 : OutputProcessor::StoreType::Average,
6637 11 : thisDXCoil.Name);
6638 22 : SetupOutputVariable(state,
6639 : "Heating Coil VRF Subcooling Degrees",
6640 : Constant::Units::C,
6641 11 : thisDXCoil.ActualSC,
6642 : OutputProcessor::TimeStepType::System,
6643 : OutputProcessor::StoreType::Average,
6644 11 : thisDXCoil.Name);
6645 : }
6646 : }
6647 :
6648 134 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
6649 : // setup EMS sizing actuators for single speed DX
6650 0 : for (DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDoe2DXCoils; ++DXCoilNum) {
6651 :
6652 0 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
6653 :
6654 0 : SetupEMSActuator(state,
6655 : "Coil:Cooling:DX:SingleSpeed",
6656 : thisDXCoil.Name,
6657 : "Autosized Rated Air Flow Rate",
6658 : "[m3/s]",
6659 : thisDXCoil.RatedAirVolFlowRateEMSOverrideON(1),
6660 0 : thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(1));
6661 :
6662 0 : SetupEMSActuator(state,
6663 : "Coil:Cooling:DX:SingleSpeed",
6664 : thisDXCoil.Name,
6665 : "Autosized Rated Sensible Heat Ratio",
6666 : "[W/W]",
6667 : thisDXCoil.RatedSHREMSOverrideOn(1),
6668 0 : thisDXCoil.RatedSHREMSOverrideValue(1));
6669 :
6670 0 : SetupEMSActuator(state,
6671 : "Coil:Cooling:DX:SingleSpeed",
6672 : thisDXCoil.Name,
6673 : "Autosized Rated Total Cooling Capacity",
6674 : "[W]",
6675 : thisDXCoil.RatedTotCapEMSOverrideOn(1),
6676 0 : thisDXCoil.RatedTotCapEMSOverrideValue(1));
6677 : }
6678 : }
6679 134 : Alphas.deallocate();
6680 134 : cAlphaFields.deallocate();
6681 134 : cNumericFields.deallocate();
6682 134 : Numbers.deallocate();
6683 134 : lAlphaBlanks.deallocate();
6684 134 : lNumericBlanks.deallocate();
6685 :
6686 134 : Alphas2.deallocate();
6687 134 : cAlphaFields2.deallocate();
6688 134 : cNumericFields2.deallocate();
6689 134 : Numbers2.deallocate();
6690 134 : lAlphaBlanks2.deallocate();
6691 134 : lNumericBlanks2.deallocate();
6692 : bool anyEMSRan;
6693 134 : ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyEMSRan, ObjexxFCL::Optional_int_const());
6694 149 : }
6695 :
6696 539063 : void InitDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current DX coil unit being simulated
6697 : {
6698 :
6699 : // SUBROUTINE INFORMATION:
6700 : // AUTHOR Fred Buhl
6701 : // DATE WRITTEN May 2000
6702 : // Feb 2005, M. J. Witte, GARD Analytics, Inc. Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
6703 : // Jul 2005, R. Raustad, FSEC. Add new coil type COIL:DX:HEATPUMPWATERHEATER
6704 : // Jun 2007, L. Gu, FSEC. Add new coil type COIL:DX:MULTISPEED:COOLING and HEATING
6705 : // Aug 2015, R. Zhang, LBNL. Add new coil types for VRF_FluidTCtrl
6706 :
6707 : // PURPOSE OF THIS SUBROUTINE:
6708 : // This subroutine is for initializations of DX Coil Components.
6709 :
6710 : // METHODOLOGY EMPLOYED:
6711 : // Uses the status flags to trigger initializations.
6712 :
6713 : // SUBROUTINE PARAMETER DEFINITIONS:
6714 539063 : constexpr Real64 SmallDifferenceTest(0.00000001);
6715 : static constexpr std::string_view RoutineName("InitDXCoil");
6716 :
6717 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6718 : Real64 RatedHeatPumpIndoorAirTemp; // Indoor dry-bulb temperature to heat pump evaporator at rated conditions [C]
6719 : Real64 RatedHeatPumpIndoorHumRat; // Inlet humidity ratio to heat pump evaporator at rated conditions [kgWater/kgDryAir]
6720 : Real64 RatedVolFlowPerRatedTotCap; // Rated Air Volume Flow Rate divided by Rated Total Capacity [m3/s-W)
6721 : Real64 HPInletAirHumRat; // Rated inlet air humidity ratio for heat pump water heater [kgWater/kgDryAir]
6722 539063 : bool ErrorsFound(false); // TRUE when errors found
6723 : int CapacityStageNum; // Loop index for 1,Number of capacity stages
6724 : int DehumidModeNum; // Loop index for 1,Number of enhanced dehumidification modes
6725 : int Mode; // Performance mode for MultiMode DX coil; Always 1 for other coil types
6726 : int DXCoilNumTemp; // Counter for crankcase heater report variable DO loop
6727 : int AirInletNode; // Air inlet node number
6728 : int SpeedNum; // Speed number for multispeed coils
6729 :
6730 539063 : if (state.dataDXCoils->MyOneTimeFlag) {
6731 : // initialize the environment and sizing flags
6732 68 : state.dataDXCoils->MyEnvrnFlag.dimension(state.dataDXCoils->NumDXCoils, true);
6733 68 : state.dataDXCoils->MySizeFlag.dimension(state.dataDXCoils->NumDXCoils, true);
6734 68 : state.dataDXCoils->MyOneTimeFlag = false;
6735 : }
6736 :
6737 539063 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
6738 :
6739 : // if "ISHundredPercentDOASDXCoil" =.TRUE., then set coil as 100% DOAS dx coil
6740 539063 : state.dataHVACGlobal->DXCT = (thisDXCoil.ISHundredPercentDOASDXCoil) ? HVAC::DXCoilType::DOAS : HVAC::DXCoilType::Regular;
6741 :
6742 1617030 : if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
6743 539224 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
6744 161 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum)) {
6745 :
6746 4 : SizeDXCoil(state, DXCoilNum);
6747 :
6748 4 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(1) / thisDXCoil.RatedTotCap2;
6749 8 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
6750 4 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
6751 0 : ShowWarningError(state,
6752 0 : format("{} \"{}\": Rated air volume flow rate per watt of rated total water heating capacity is out of range",
6753 0 : thisDXCoil.DXCoilType,
6754 0 : thisDXCoil.Name));
6755 0 : ShowContinueError(state,
6756 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
6757 : "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
6758 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
6759 : RatedVolFlowPerRatedTotCap,
6760 0 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
6761 : }
6762 : HPInletAirHumRat =
6763 4 : PsyWFnTdbTwbPb(state, thisDXCoil.RatedInletDBTemp, thisDXCoil.RatedInletWBTemp, DataEnvironment::StdPressureSeaLevel, RoutineName);
6764 4 : state.dataHVACGlobal->HPWHInletDBTemp = thisDXCoil.RatedInletDBTemp;
6765 4 : state.dataHVACGlobal->HPWHInletWBTemp = thisDXCoil.RatedInletWBTemp;
6766 8 : thisDXCoil.RatedAirMassFlowRate(1) =
6767 4 : thisDXCoil.RatedAirVolFlowRate(1) *
6768 4 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, thisDXCoil.RatedInletDBTemp, HPInletAirHumRat, RoutineName);
6769 : // get rated coil bypass factor excluding fan heat
6770 :
6771 : // call CalcHPWHDXCoil to determine DXCoil%RatedTotCap(1) for rated CBF calculation below
6772 4 : CalcHPWHDXCoil(state, DXCoilNum, 1.0);
6773 4 : if (state.dataDXCoils->MySizeFlag(DXCoilNum)) {
6774 4 : SizeDXCoil(state, DXCoilNum);
6775 4 : state.dataDXCoils->MySizeFlag(DXCoilNum) = false;
6776 : }
6777 :
6778 4 : thisDXCoil.RatedCBF(1) = CalcCBF(state,
6779 4 : thisDXCoil.DXCoilType,
6780 4 : thisDXCoil.Name,
6781 : thisDXCoil.RatedInletDBTemp,
6782 : HPInletAirHumRat,
6783 4 : thisDXCoil.RatedTotCap(1),
6784 4 : thisDXCoil.RatedAirVolFlowRate(1),
6785 4 : thisDXCoil.RatedSHR(1),
6786 : true);
6787 4 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum) = false;
6788 : }
6789 :
6790 539513 : if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) &&
6791 450 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum)) {
6792 15 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
6793 4 : if (thisDXCoil.MSHPHeatRecActive) {
6794 5 : for (SpeedNum = 1; SpeedNum <= thisDXCoil.NumOfSpeeds; ++SpeedNum) {
6795 4 : if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
6796 0 : ShowWarningError(
6797 : state,
6798 0 : format("GetDXCoils:{}. The value of Waste Heat Function of Temperature Curve is assumed to be 1. Simulation continues. ",
6799 0 : thisDXCoil.Name));
6800 0 : break;
6801 : }
6802 : }
6803 : }
6804 : }
6805 15 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum) = false;
6806 : }
6807 :
6808 : // Find the companion upstream coil (DX cooling coil) that is used with DX heating coils (HP AC units only)
6809 539063 : if (thisDXCoil.FindCompanionUpStreamCoil) {
6810 135 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6811 40 : thisDXCoil.CompanionUpstreamDXCoil = GetHPCoolingCoilIndex(state, thisDXCoil.DXCoilType, thisDXCoil.Name, DXCoilNum);
6812 40 : if (thisDXCoil.CompanionUpstreamDXCoil > 0) {
6813 9 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).ReportCoolingCoilCrankcasePower = false;
6814 9 : thisDXCoil.FindCompanionUpStreamCoil = false;
6815 : // Copy condenser node number from DX cooling coil when used with a companion DX heating coil
6816 45 : for (Mode = 1; Mode <= MaxModes; ++Mode) {
6817 36 : thisDXCoil.CondenserInletNodeNum(Mode) =
6818 36 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CondenserInletNodeNum(Mode);
6819 : }
6820 : }
6821 : } else {
6822 95 : thisDXCoil.FindCompanionUpStreamCoil = false;
6823 : }
6824 : } // IF(DXCoil(DXCoilNum)%FindCompanionUpStreamCoil)THEN
6825 :
6826 : // CR7308 - Wait for zone and air loop equipment to be simulated, then print out report variables
6827 539063 : if (state.dataDXCoils->CrankcaseHeaterReportVarFlag) {
6828 1258 : if (state.dataAirLoop->AirLoopInputsFilled) {
6829 : // Set report variables for DX cooling coils that will have a crankcase heater (all DX coils not used in a HP AC unit)
6830 90 : for (DXCoilNumTemp = 1; DXCoilNumTemp <= state.dataDXCoils->NumDXCoils; ++DXCoilNumTemp) {
6831 60 : if ((state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) ||
6832 103 : (state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) ||
6833 43 : (state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling)) {
6834 18 : if (state.dataDXCoils->DXCoil(DXCoilNumTemp).ReportCoolingCoilCrankcasePower) {
6835 32 : SetupOutputVariable(state,
6836 : "Cooling Coil Crankcase Heater Electricity Rate",
6837 : Constant::Units::W,
6838 16 : state.dataDXCoils->DXCoil(DXCoilNumTemp).CrankcaseHeaterPower,
6839 : OutputProcessor::TimeStepType::System,
6840 : OutputProcessor::StoreType::Average,
6841 16 : state.dataDXCoils->DXCoil(DXCoilNumTemp).Name);
6842 32 : SetupOutputVariable(state,
6843 : "Cooling Coil Crankcase Heater Electricity Energy",
6844 : Constant::Units::J,
6845 16 : state.dataDXCoils->DXCoil(DXCoilNumTemp).CrankcaseHeaterConsumption,
6846 : OutputProcessor::TimeStepType::System,
6847 : OutputProcessor::StoreType::Sum,
6848 16 : state.dataDXCoils->DXCoil(DXCoilNumTemp).Name,
6849 : Constant::eResource::Electricity,
6850 : OutputProcessor::Group::HVAC,
6851 : OutputProcessor::EndUseCat::Cooling);
6852 16 : state.dataDXCoils->DXCoil(DXCoilNumTemp).ReportCoolingCoilCrankcasePower = false;
6853 : }
6854 : }
6855 : }
6856 30 : state.dataDXCoils->CrankcaseHeaterReportVarFlag = false;
6857 : } //(AirLoopInputsFilled)THEN
6858 : } //(CrankcaseHeaterReportVarFlag)THEN
6859 :
6860 539063 : if (!state.dataGlobal->SysSizingCalc && state.dataDXCoils->MySizeFlag(DXCoilNum)) {
6861 : // for each coil, do the sizing once.
6862 69 : SizeDXCoil(state, DXCoilNum);
6863 69 : state.dataDXCoils->MySizeFlag(DXCoilNum) = false;
6864 :
6865 69 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
6866 35 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
6867 :
6868 47 : Mode = 1;
6869 : // Check for zero capacity or zero max flow rate
6870 47 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
6871 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
6872 0 : ErrorsFound = true;
6873 : }
6874 47 : if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
6875 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
6876 0 : ErrorsFound = true;
6877 : }
6878 47 : if (ErrorsFound) {
6879 0 : ShowFatalError(state, "Preceding condition causes termination.");
6880 : }
6881 :
6882 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
6883 47 : if (thisDXCoil.DXCoilType_Num !=
6884 : HVAC::CoilVRF_FluidTCtrl_Cooling) { // the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil
6885 41 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
6886 82 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
6887 41 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
6888 2 : ShowWarningError(state,
6889 2 : format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range.",
6890 1 : thisDXCoil.DXCoilType,
6891 1 : thisDXCoil.Name));
6892 2 : ShowContinueError(state,
6893 2 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
6894 : "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
6895 1 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
6896 : RatedVolFlowPerRatedTotCap,
6897 1 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
6898 : }
6899 : }
6900 :
6901 94 : thisDXCoil.RatedAirMassFlowRate(Mode) =
6902 47 : thisDXCoil.RatedAirVolFlowRate(Mode) *
6903 47 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
6904 : // get high speed rated coil bypass factor
6905 47 : thisDXCoil.RatedCBF(Mode) = CalcCBF(state,
6906 47 : thisDXCoil.DXCoilType,
6907 47 : thisDXCoil.Name,
6908 : RatedInletAirTemp,
6909 : RatedInletAirHumRat,
6910 47 : thisDXCoil.RatedTotCap(Mode),
6911 47 : thisDXCoil.RatedAirVolFlowRate(Mode),
6912 47 : thisDXCoil.RatedSHR(Mode));
6913 :
6914 : // call coil model with everything set at rating point
6915 47 : thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(Mode);
6916 47 : thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(Mode);
6917 47 : thisDXCoil.InletAirTemp = RatedInletAirTemp;
6918 : Real64 tempInletAirHumRat =
6919 47 : Psychrometrics::PsyWFnTdbTwbPb(state, RatedInletAirTemp, RatedInletWetBulbTemp, DataEnvironment::StdPressureSeaLevel, RoutineName);
6920 : // DXCoil( DXCoilNum ).InletAirHumRat = RatedInletAirHumRat; // this seems inconsistent with dry bulb and wetbulb, filed NREL issue
6921 : // #5934 Real64 tempInletAirWetBulb = Psychrometrics::PsyTwbFnTdbWPb( RatedInletAirTemp, RatedInletAirHumRat,
6922 : // DataEnvironment::StdPressureSeaLevel );
6923 47 : thisDXCoil.InletAirHumRat = tempInletAirHumRat;
6924 47 : thisDXCoil.InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTemp, tempInletAirHumRat);
6925 :
6926 : // store environment data fill back in after rating point calc is over
6927 47 : Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
6928 47 : Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
6929 47 : Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
6930 47 : Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
6931 47 : Real64 ratedOutdoorAirWetBulb = 23.9; // from I/O ref. more precise value?
6932 47 : state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTemp;
6933 47 : state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
6934 47 : state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
6935 94 : state.dataEnvrn->OutHumRat =
6936 47 : Psychrometrics::PsyWFnTdbTwbPb(state, RatedOutdoorAirTemp, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
6937 47 : if (thisDXCoil.CondenserInletNodeNum(1) > 0) { // set condenser inlet node values
6938 14 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = RatedOutdoorAirTemp;
6939 14 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat = state.dataEnvrn->OutHumRat;
6940 14 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb = ratedOutdoorAirWetBulb;
6941 : }
6942 :
6943 : // calculate coil model at rating point
6944 47 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6945 31 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, _, 1.0);
6946 16 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
6947 3 : CalcMultiSpeedDXCoil(state, DXCoilNum, 1.0, 1.0);
6948 13 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
6949 7 : CalcVRFCoolingCoil(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, 1.0, _, _, _);
6950 6 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
6951 6 : CalcVRFCoolingCoil_FluidTCtrl(
6952 : state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, 1.0, _, _, Constant::MaxCap);
6953 : }
6954 :
6955 : // coil outlets
6956 47 : Real64 RatedOutletWetBulb(0.0);
6957 47 : RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
6958 : state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
6959 :
6960 47 : state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
6961 : state,
6962 47 : thisDXCoil.Name,
6963 47 : thisDXCoil.DXCoilType,
6964 : thisDXCoil.TotalCoolingEnergyRate, // this is the report variable
6965 : thisDXCoil.SensCoolingEnergyRate, // this is the report variable
6966 : thisDXCoil.InletAirMassFlowRate,
6967 : thisDXCoil.InletAirTemp,
6968 : thisDXCoil.InletAirHumRat,
6969 : RatedInletWetBulbTemp,
6970 : thisDXCoil.OutletAirTemp,
6971 : thisDXCoil.OutletAirHumRat,
6972 : RatedOutletWetBulb,
6973 : RatedOutdoorAirTemp,
6974 : ratedOutdoorAirWetBulb,
6975 47 : thisDXCoil.RatedCBF(Mode),
6976 : -999.0); // coil effectiveness not define for DX
6977 :
6978 : // now replace the outdoor air conditions set above for one time rating point calc
6979 47 : state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
6980 47 : state.dataEnvrn->OutHumRat = holdOutHumRat;
6981 47 : state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
6982 47 : state.dataEnvrn->OutBaroPress = holdOutBaroPress;
6983 : }
6984 :
6985 69 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
6986 0 : for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
6987 0 : for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
6988 0 : Mode = DehumidModeNum * 2 + CapacityStageNum;
6989 : // Check for zero capacity or zero max flow rate
6990 0 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
6991 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
6992 0 : ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
6993 0 : ErrorsFound = true;
6994 : }
6995 0 : if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
6996 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
6997 0 : ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
6998 0 : ErrorsFound = true;
6999 : }
7000 0 : if (ErrorsFound) {
7001 0 : ShowFatalError(state, "Preceding condition causes termination.");
7002 : }
7003 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7004 0 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
7005 0 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7006 0 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7007 0 : ShowWarningError(
7008 : state,
7009 0 : format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range.",
7010 0 : thisDXCoil.DXCoilType,
7011 0 : thisDXCoil.Name));
7012 0 : ShowContinueError(state,
7013 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
7014 : "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
7015 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7016 : RatedVolFlowPerRatedTotCap,
7017 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7018 0 : ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
7019 : }
7020 0 : thisDXCoil.RatedAirMassFlowRate(Mode) =
7021 0 : thisDXCoil.RatedAirVolFlowRate(Mode) *
7022 0 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
7023 : // get rated coil bypass factor
7024 0 : thisDXCoil.RatedCBF(Mode) = CalcCBF(state,
7025 0 : thisDXCoil.CoilPerformanceType(Mode),
7026 0 : thisDXCoil.CoilPerformanceName(Mode),
7027 : RatedInletAirTemp,
7028 : RatedInletAirHumRat,
7029 0 : thisDXCoil.RatedTotCap(Mode),
7030 0 : thisDXCoil.RatedAirVolFlowRate(Mode),
7031 0 : thisDXCoil.RatedSHR(Mode));
7032 : } // End capacity stages loop
7033 : } // End dehumidification modes loop
7034 : }
7035 :
7036 69 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating ||
7037 58 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7038 :
7039 17 : Mode = 1;
7040 17 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
7041 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
7042 0 : ErrorsFound = true;
7043 : }
7044 17 : if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
7045 0 : ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
7046 0 : ErrorsFound = true;
7047 : }
7048 17 : if (ErrorsFound) {
7049 0 : ShowFatalError(state, "Preceding condition causes termination.");
7050 : }
7051 17 : RatedHeatPumpIndoorAirTemp = 21.11; // 21.11C or 70F
7052 17 : RatedHeatPumpIndoorHumRat = 0.00881; // Humidity ratio corresponding to 70F dry bulb/60F wet bulb
7053 34 : thisDXCoil.RatedAirMassFlowRate(Mode) =
7054 17 : thisDXCoil.RatedAirVolFlowRate(Mode) *
7055 17 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedHeatPumpIndoorAirTemp, RatedHeatPumpIndoorHumRat, RoutineName);
7056 :
7057 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7058 17 : if (thisDXCoil.DXCoilType_Num !=
7059 : HVAC::CoilVRF_FluidTCtrl_Heating) { // the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil
7060 11 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
7061 22 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7062 11 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7063 2 : ShowWarningError(state,
7064 2 : format("Sizing: {} {}: Rated air volume flow rate per watt of rated total heating capacity is out of range.",
7065 1 : thisDXCoil.DXCoilType,
7066 1 : thisDXCoil.Name));
7067 2 : ShowContinueError(state,
7068 2 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
7069 : "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
7070 1 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7071 : RatedVolFlowPerRatedTotCap,
7072 1 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7073 : }
7074 : }
7075 :
7076 : // call coil model with everything set at rating point
7077 17 : thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(Mode);
7078 17 : thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(Mode);
7079 :
7080 17 : thisDXCoil.InletAirTemp = RatedInletAirTempHeat;
7081 17 : Real64 tempInletAirHumRat = Psychrometrics::PsyWFnTdbTwbPb(
7082 : state, RatedInletAirTempHeat, RatedInletWetBulbTempHeat, DataEnvironment::StdPressureSeaLevel, RoutineName);
7083 17 : thisDXCoil.InletAirHumRat = tempInletAirHumRat;
7084 17 : thisDXCoil.InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTempHeat, tempInletAirHumRat);
7085 :
7086 : // store environment data fill back in after rating point calc is over
7087 17 : Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
7088 17 : Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
7089 17 : Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
7090 17 : Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
7091 :
7092 17 : state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTempHeat;
7093 :
7094 17 : Real64 ratedOutdoorAirWetBulb = 6.11; // from I/O ref. more precise value?
7095 17 : state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
7096 17 : state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
7097 17 : state.dataEnvrn->OutHumRat = Psychrometrics::PsyWFnTdbTwbPb(
7098 : state, RatedOutdoorAirTempHeat, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
7099 :
7100 17 : if (thisDXCoil.CondenserInletNodeNum(1) > 0) { // set condenser inlet node values
7101 6 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = RatedOutdoorAirTempHeat;
7102 6 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat = state.dataEnvrn->OutHumRat;
7103 6 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb = ratedOutdoorAirWetBulb;
7104 : }
7105 :
7106 : // calculate coil model at rating point
7107 17 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
7108 4 : CalcDXHeatingCoil(state, DXCoilNum, 1.0, HVAC::FanOp::Cycling, 1.0);
7109 13 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
7110 7 : CalcDXHeatingCoil(state, DXCoilNum, 1.0, HVAC::FanOp::Cycling, _, _);
7111 6 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7112 6 : CalcVRFHeatingCoil_FluidTCtrl(state, HVAC::CompressorOp::On, DXCoilNum, 1.0, HVAC::FanOp::Cycling, _, _);
7113 : }
7114 : // coil outlets
7115 17 : Real64 RatedOutletWetBulb(0.0);
7116 17 : RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
7117 : state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
7118 :
7119 17 : state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
7120 : state,
7121 17 : thisDXCoil.Name,
7122 17 : thisDXCoil.DXCoilType,
7123 : thisDXCoil.TotalHeatingEnergyRate, // this is the report variable
7124 : thisDXCoil.TotalHeatingEnergyRate, // this is the report variable
7125 : thisDXCoil.InletAirMassFlowRate,
7126 : thisDXCoil.InletAirTemp,
7127 : thisDXCoil.InletAirHumRat,
7128 : RatedInletWetBulbTempHeat,
7129 : thisDXCoil.OutletAirTemp,
7130 : thisDXCoil.OutletAirHumRat,
7131 : RatedOutletWetBulb,
7132 : RatedOutdoorAirTempHeat,
7133 : ratedOutdoorAirWetBulb,
7134 17 : thisDXCoil.RatedCBF(Mode),
7135 : -999.0); // coil effectiveness not define for DX
7136 :
7137 : // now replace the outdoor air conditions set above for one time rating point calc
7138 17 : state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
7139 17 : state.dataEnvrn->OutHumRat = holdOutHumRat;
7140 17 : state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
7141 17 : state.dataEnvrn->OutBaroPress = holdOutBaroPress;
7142 : }
7143 :
7144 69 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7145 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7146 3 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate2 / thisDXCoil.RatedTotCap2;
7147 6 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7148 3 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7149 0 : ShowWarningError(state,
7150 0 : format("Coil:Cooling:DX:TwoSpeed \"{}\": At low speed rated air volume flow rate per watt of rated total cooling "
7151 : "capacity is out of range.",
7152 0 : thisDXCoil.Name));
7153 0 : ShowContinueError(state,
7154 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
7155 : "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
7156 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7157 : RatedVolFlowPerRatedTotCap,
7158 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7159 : }
7160 :
7161 3 : thisDXCoil.RatedAirMassFlowRate2 =
7162 6 : thisDXCoil.RatedAirVolFlowRate2 *
7163 3 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
7164 : // get low speed rated coil bypass factor
7165 6 : thisDXCoil.RatedCBF2 = CalcCBF(state,
7166 3 : thisDXCoil.DXCoilType,
7167 3 : thisDXCoil.Name,
7168 : RatedInletAirTemp,
7169 : RatedInletAirHumRat,
7170 : thisDXCoil.RatedTotCap2,
7171 : thisDXCoil.RatedAirVolFlowRate2,
7172 : thisDXCoil.RatedSHR2);
7173 :
7174 : // call for standard ratings for two-speed DX coil
7175 3 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air) {
7176 2 : CalcTwoSpeedDXCoilStandardRating(state, DXCoilNum);
7177 : }
7178 : }
7179 :
7180 : // Multispeed Cooling
7181 69 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7182 16 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
7183 : // Check for zero capacity or zero max flow rate
7184 11 : if (thisDXCoil.MSRatedTotCap(Mode) <= 0.0) {
7185 0 : ShowSevereError(state,
7186 0 : format("Sizing: {} {} has zero rated total capacity at speed {}", thisDXCoil.DXCoilType, thisDXCoil.Name, Mode));
7187 0 : ErrorsFound = true;
7188 : }
7189 11 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) <= 0.0) {
7190 0 : ShowSevereError(state,
7191 0 : format("Sizing: {} {} has zero rated air flow rate at speed {}", thisDXCoil.DXCoilType, thisDXCoil.Name, Mode));
7192 0 : ErrorsFound = true;
7193 : }
7194 11 : if (ErrorsFound) {
7195 0 : ShowFatalError(state, "Preceding condition causes termination.");
7196 : }
7197 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7198 11 : RatedVolFlowPerRatedTotCap = thisDXCoil.MSRatedAirVolFlowRate(Mode) / thisDXCoil.MSRatedTotCap(Mode);
7199 22 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7200 11 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7201 0 : ShowWarningError(
7202 : state,
7203 0 : format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range at speed {}",
7204 0 : thisDXCoil.DXCoilType,
7205 0 : thisDXCoil.Name,
7206 : Mode));
7207 0 : ShowContinueError(state,
7208 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
7209 : "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
7210 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7211 : RatedVolFlowPerRatedTotCap,
7212 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7213 : }
7214 22 : thisDXCoil.MSRatedAirMassFlowRate(Mode) =
7215 11 : thisDXCoil.MSRatedAirVolFlowRate(Mode) *
7216 11 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
7217 : // get high speed rated coil bypass factor
7218 11 : thisDXCoil.MSRatedCBF(Mode) = CalcCBF(state,
7219 11 : thisDXCoil.DXCoilType,
7220 11 : thisDXCoil.Name,
7221 : RatedInletAirTemp,
7222 : RatedInletAirHumRat,
7223 11 : thisDXCoil.MSRatedTotCap(Mode),
7224 11 : thisDXCoil.MSRatedAirVolFlowRate(Mode),
7225 11 : thisDXCoil.MSRatedSHR(Mode));
7226 : }
7227 : }
7228 :
7229 : // Multispeed Heating
7230 69 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7231 0 : RatedHeatPumpIndoorAirTemp = 21.11; // 21.11C or 70F
7232 0 : RatedHeatPumpIndoorHumRat = 0.00881; // Humidity ratio corresponding to 70F dry bulb/60F wet bulb
7233 0 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
7234 :
7235 0 : thisDXCoil.MSRatedAirMassFlowRate(Mode) =
7236 0 : thisDXCoil.MSRatedAirVolFlowRate(Mode) *
7237 0 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedHeatPumpIndoorAirTemp, RatedHeatPumpIndoorHumRat, RoutineName);
7238 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7239 0 : RatedVolFlowPerRatedTotCap = thisDXCoil.MSRatedAirVolFlowRate(Mode) / thisDXCoil.MSRatedTotCap(Mode);
7240 0 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7241 0 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7242 0 : ShowWarningError(state,
7243 0 : format("Coil:Heating:DX:MultiSpeed {}: Rated air volume flow rate per watt of rated total heating capacity "
7244 : "is out of range at speed {}",
7245 0 : thisDXCoil.Name,
7246 : Mode));
7247 0 : ShowContinueError(state,
7248 0 : format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
7249 : "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
7250 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7251 : RatedVolFlowPerRatedTotCap,
7252 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7253 : }
7254 : }
7255 : }
7256 :
7257 : // store fan info for coil
7258 69 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
7259 69 : state, thisDXCoil.Name, thisDXCoil.DXCoilType, thisDXCoil.SupplyFanName, thisDXCoil.supplyFanType, thisDXCoil.SupplyFanIndex);
7260 : }
7261 :
7262 539063 : AirInletNode = thisDXCoil.AirInNode;
7263 :
7264 : // Each iteration, load the coil data structure with the inlet conditions
7265 :
7266 539063 : thisDXCoil.InletAirMassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
7267 539063 : thisDXCoil.InletAirMassFlowRateMax =
7268 539063 : max(state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax, state.dataLoopNodes->Node(AirInletNode).MassFlowRate);
7269 539063 : thisDXCoil.InletAirTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
7270 539063 : thisDXCoil.InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
7271 539063 : thisDXCoil.InletAirEnthalpy = state.dataLoopNodes->Node(AirInletNode).Enthalpy;
7272 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
7273 : // DXCoil(DXCoilNum)%InletAirPressure = Node(AirInletNode)%Press
7274 :
7275 539063 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7276 128165 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
7277 0 : thisDXCoil.EvapInletWetBulb = PsyTwbFnTdbWPb(state,
7278 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr).ZT,
7279 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr).airHumRat,
7280 0 : state.dataEnvrn->OutBaroPress,
7281 : RoutineName);
7282 : }
7283 : }
7284 :
7285 539063 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
7286 161 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
7287 161 : thisDXCoil.ElecWaterHeatingPower = 0.0;
7288 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
7289 : // DXCoil(DXCoilNum)%InletAirPressure = StdBaroPress
7290 :
7291 : // HPWH's that use an inlet air temperature schedule also need to have a valid barometric pressure
7292 : // The DX Coil used in HPWH's does not know if it is using a scheduled inlet temperature so check the node pressure
7293 161 : if (thisDXCoil.CondenserInletNodeNum(1) > 0) {
7294 161 : if (state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press == 0.0) {
7295 2 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press = state.dataEnvrn->StdBaroPress;
7296 : }
7297 : }
7298 : }
7299 539063 : thisDXCoil.BasinHeaterPower = 0.0;
7300 :
7301 539063 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
7302 0 : thisDXCoil.CompressorPartLoadRatio = 0.0;
7303 0 : thisDXCoil.SecCoilSensibleHeatGainRate = 0.0;
7304 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
7305 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
7306 0 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
7307 : }
7308 539063 : }
7309 :
7310 96 : void SizeDXCoil(EnergyPlusData &state, int const DXCoilNum)
7311 : {
7312 :
7313 : // SUBROUTINE INFORMATION:
7314 : // AUTHOR Fred Buhl
7315 : // DATE WRITTEN January 2002
7316 : // Feb 2005, M. J. Witte, GARD Analytics, Inc. Add new coil type COIL:DX:MultiMode:CoolingEmpirical.
7317 : // Jul 2005, R. Raustad, FSEC. Add new coil type COIL:DX:HEATPUMPWATERHEATER
7318 : // Jun 2007, L. Gu, FSEC. Add new coil type COIL:DX:MULTISPEED:COOLING and HEATING
7319 : // Jan 2011, B. Griffith, NREL. add EMS overrides for autosized fields
7320 : // Aug 2013, D. Kang. add component sizing table entries
7321 : // May 2014, R. Raustad, FSEC. moved sizing calculations to common routine
7322 : // Aug 2015, R. Zhang, LBNL. Add new coil types for VRF_FluidTCtrl
7323 : // RE-ENGINEERED na
7324 :
7325 : // PURPOSE OF THIS SUBROUTINE:
7326 : // This subroutine is for sizing DX Coil components for which nominal capacity and air flow rate
7327 : // have not been specified in the input.
7328 :
7329 : // METHODOLOGY EMPLOYED:
7330 : // Obtains cooling capacities and air flow rates from the zone or system sizing arrays.
7331 :
7332 : // Using/Aliasing
7333 : using namespace DataSizing;
7334 : using Curve::CurveValue;
7335 :
7336 : using namespace OutputReportPredefined;
7337 : using StandardRatings::CalcDXCoilStandardRating;
7338 :
7339 : // SUBROUTINE PARAMETER DEFINITIONS:
7340 : static constexpr std::string_view RoutineName("SizeDXCoil");
7341 :
7342 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7343 : Real64 CoilInTemp; // DX coil inlet temperature
7344 : int CapacityStageNum; // Loop index for 1,Number of capacity stages
7345 : int DehumidModeNum; // Loop index for 1,Number of enhanced dehumidification modes
7346 : int Mode; // Operating mode for MultiMode DX coil; Always 1 for other coil types
7347 : int NumOfSpeedCompanion; // Number of speed for a companion cooling coil (Multispeed HO heating coil only
7348 96 : std::string equipName;
7349 : Real64 DefrostCapacityDes; // Design defrost heater capacity for reporting
7350 : Real64 DefrostCapacityUser; // Hard-sized defrost heater capacity for reporting
7351 : Real64 MSRatedAirVolFlowRateDes; // Design multispeed rated air volume flow rate for reporting
7352 : Real64 MSRatedTotCapDesAtMaxSpeed; // Design multispeed rated total capacity for reporting (at maximum speed)
7353 : Real64 MSRatedSHRDes; // Design multispeed rated SHR for reporting
7354 : Real64 MSEvapCondAirFlowDes; // Design evaporative condenser air flow for reporting
7355 : Real64 MSEvapCondAirFlowUser; // Hard-sized evaporative condenser air flow for reporting
7356 : Real64 MSEvapCondPumpElecNomPowerDes; // Design evaporative condenser pump rated power consumption for reporting
7357 : Real64 MSEvapCondPumpElecNomPowerUser; // Hard-sized evaporative condenser pump rated power consumption for reporting
7358 : bool HardSizeNoDesRun; // Indicator to a hard-sized field with no design sizing data
7359 : bool IsAutoSize; // Indicator to autosize for reporting
7360 : bool SizingDesRunThisAirSys; // true if a particular air system had a Sizing:System object and system sizing done
7361 : bool SizingDesRunThisZone; // true if a particular zone had a Sizing:Zone object and zone sizing was done
7362 96 : std::string CompName; // component name
7363 96 : std::string CompType; // component type
7364 96 : std::string SizingString; // input field sizing description (e.g., Nominal Capacity)
7365 96 : bool bPRINT = true; // TRUE if sizing is reported to output (eio)
7366 : Real64 TempSize; // autosized value of coil input field
7367 96 : int FieldNum = 2; // IDD numeric field number where input field description is found
7368 : bool PrintFlag; // TRUE when sizing information is reported in the eio file
7369 : bool SizeSecDXCoil; // if true do sizing calculation for secondary coil
7370 : Real64 SecCoilAirFlowDes; // Design secondary DX coil air flow for reporting
7371 : Real64 SecCoilAirFlowUser; // Hard-sized secondary DX coil air flow for reporting
7372 :
7373 : // Initiate all reporting variables
7374 96 : if (state.dataSize->SysSizingRunDone || state.dataSize->ZoneSizingRunDone) {
7375 72 : HardSizeNoDesRun = false;
7376 : } else {
7377 24 : HardSizeNoDesRun = true;
7378 : }
7379 :
7380 96 : if (state.dataSize->CurSysNum > 0) {
7381 38 : CheckThisAirSystemForSizing(state, state.dataSize->CurSysNum, SizingDesRunThisAirSys);
7382 : } else {
7383 58 : SizingDesRunThisAirSys = false;
7384 : }
7385 96 : if (state.dataSize->CurZoneEqNum > 0) {
7386 43 : CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
7387 : } else {
7388 53 : SizingDesRunThisZone = false;
7389 : }
7390 :
7391 96 : IsAutoSize = false;
7392 96 : SizeSecDXCoil = false;
7393 96 : MSRatedTotCapDesAtMaxSpeed = 0.0;
7394 96 : DefrostCapacityDes = 0.0;
7395 96 : DefrostCapacityUser = 0.0;
7396 96 : MSRatedAirVolFlowRateDes = 0.0;
7397 96 : MSRatedSHRDes = 0.0;
7398 96 : MSEvapCondAirFlowDes = 0.0;
7399 96 : MSEvapCondAirFlowUser = 0.0;
7400 96 : MSEvapCondPumpElecNomPowerDes = 0.0;
7401 96 : MSEvapCondPumpElecNomPowerUser = 0.0;
7402 96 : SecCoilAirFlowDes = 0.0;
7403 96 : SecCoilAirFlowUser = 0.0;
7404 :
7405 : // Sizer classes
7406 96 : CoolingSHRSizer sizerCoolingSHR;
7407 96 : bool ErrorsFound = false;
7408 :
7409 96 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
7410 :
7411 : // NOTE: we are sizing COIL:DX:HeatingEmpirical on the COOLING load. Thus the cooling and
7412 : // and heating capacities of a DX heat pump system will be identical. In real life the AHRI
7413 : // heating and cooling capacities are close but not identical.
7414 192 : for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
7415 192 : for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
7416 96 : Mode = DehumidModeNum * 2 + CapacityStageNum;
7417 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
7418 90 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
7419 8 : if (thisDXCoil.RatedAirVolFlowRate(1) == Constant::AutoCalculate) {
7420 : // report autocalculated sizing
7421 3 : PrintFlag = true;
7422 3 : CompName = thisDXCoil.Name;
7423 3 : CompType = thisDXCoil.DXCoilType;
7424 : // DXCoil( DXCoilNum ).RatedAirVolFlowRate( 1 ) = DXCoil( DXCoilNum ).RatedTotCap2 * 0.00005035
7425 3 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap2;
7426 3 : state.dataSize->DataFractionUsedForSizing = 0.00005035;
7427 3 : TempSize = AutoSize;
7428 3 : AutoCalculateSizer sizerHPRatedAirVolFlow;
7429 3 : std::string stringOverride = "Rated Evaporator Air Flow Rate [m3/s]";
7430 3 : if (state.dataGlobal->isEpJSON) {
7431 0 : stringOverride = "rated_evaporator_air_flow_rate [m3/s]";
7432 : }
7433 3 : sizerHPRatedAirVolFlow.overrideSizingString(stringOverride);
7434 3 : sizerHPRatedAirVolFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7435 3 : thisDXCoil.RatedAirVolFlowRate(1) = sizerHPRatedAirVolFlow.size(state, TempSize, ErrorsFound);
7436 3 : PrintFlag = false;
7437 3 : }
7438 :
7439 8 : if (thisDXCoil.RatedHPWHCondWaterFlow == Constant::AutoCalculate) {
7440 : // report autocalculated sizing
7441 3 : PrintFlag = true;
7442 3 : CompName = thisDXCoil.Name;
7443 3 : CompType = thisDXCoil.DXCoilType;
7444 : // DXCoil( DXCoilNum ).RatedAirVolFlowRate( 1 ) = DXCoil( DXCoilNum ).RatedTotCap2 * 0.00000004487
7445 3 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap2;
7446 3 : state.dataSize->DataFractionUsedForSizing = 0.00000004487;
7447 3 : TempSize = AutoSize;
7448 3 : AutoCalculateSizer sizerHPWHCondWaterFlow;
7449 3 : std::string stringOverride = "Rated Condenser Water Flow Rate [m3/s]";
7450 3 : if (state.dataGlobal->isEpJSON) {
7451 0 : stringOverride = "rated_condenser_water_flow_rate [m3/s]";
7452 : }
7453 3 : sizerHPWHCondWaterFlow.overrideSizingString(stringOverride);
7454 3 : sizerHPWHCondWaterFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7455 3 : thisDXCoil.RatedHPWHCondWaterFlow = sizerHPWHCondWaterFlow.size(state, TempSize, ErrorsFound);
7456 3 : PrintFlag = false;
7457 3 : }
7458 8 : } else {
7459 88 : PrintFlag = true;
7460 88 : FieldNum = 0;
7461 88 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7462 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7463 0 : FieldNum = 4;
7464 0 : state.dataSize->DataBypassFrac = thisDXCoil.BypassedFlowFrac(Mode);
7465 88 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
7466 5 : CompName = thisDXCoil.Name;
7467 5 : FieldNum = 3;
7468 : // doesn't look like this is needed for air flow sizing, only for heating capacity sizing
7469 10 : state.dataSize->DataCoolCoilCap =
7470 5 : state.dataSize->DXCoolCap; // pass global variable used only for heat pumps (i.e., DX cooling and heating coils)
7471 5 : if ((thisDXCoil.IsSecondaryDXCoilInZone) &&
7472 0 : (thisDXCoil.CondenserType(1) ==
7473 : DataHeatBalance::RefrigCondenserType::Air)) { // secondary DX coil in secondary zone is specified
7474 0 : SizeSecDXCoil = true;
7475 : }
7476 83 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
7477 7 : CompName = thisDXCoil.Name;
7478 7 : FieldNum = 2;
7479 76 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
7480 7 : CompName = thisDXCoil.Name;
7481 7 : FieldNum = 3;
7482 69 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7483 6 : CompName = thisDXCoil.Name;
7484 63 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7485 6 : CompName = thisDXCoil.Name;
7486 57 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7487 10 : thisDXCoil.RatedAirVolFlowRate(Mode) = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
7488 10 : CompName = thisDXCoil.Name;
7489 10 : PrintFlag = false;
7490 47 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7491 7 : thisDXCoil.RatedAirVolFlowRate(Mode) = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
7492 7 : CompName = thisDXCoil.Name;
7493 7 : PrintFlag = false;
7494 : } else {
7495 40 : CompName = thisDXCoil.Name;
7496 40 : FieldNum = 4;
7497 : }
7498 :
7499 88 : TempSize = thisDXCoil.RatedAirVolFlowRate(Mode);
7500 88 : if (FieldNum > 0) {
7501 59 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [m3/s]";
7502 : } else {
7503 29 : SizingString = "Rated Air Flow Rate [m3/s]";
7504 : }
7505 88 : CompType = thisDXCoil.DXCoilType;
7506 88 : state.dataSize->DataIsDXCoil = true;
7507 88 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
7508 88 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
7509 88 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating ||
7510 75 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
7511 25 : bool errorsFound = false;
7512 25 : HeatingAirFlowSizer sizingHeatingAirFlow;
7513 25 : sizingHeatingAirFlow.overrideSizingString(SizingString);
7514 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7515 25 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7516 25 : thisDXCoil.RatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
7517 25 : } else {
7518 63 : bool errorsFound = false;
7519 63 : CoolingAirFlowSizer sizingCoolingAirFlow;
7520 63 : sizingCoolingAirFlow.overrideSizingString(SizingString);
7521 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7522 63 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7523 63 : thisDXCoil.RatedAirVolFlowRate(Mode) = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7524 63 : }
7525 88 : state.dataSize->DataIsDXCoil = false;
7526 88 : state.dataSize->DataEMSOverrideON = false;
7527 88 : state.dataSize->DataEMSOverride = 0.0;
7528 88 : state.dataSize->DataBypassFrac = 0.0;
7529 : }
7530 :
7531 96 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
7532 : // get autosized air flow for capacity calc's if capacity is not autosized
7533 : // *** RAR this if block is a last minute addition to correct capacity reporting when not autosized and a sizing run is done. Test
7534 : // suite was not run with this code included. *** The question here is if the autosized air flow rate or the user specified air flow
7535 : // rate should be used to calculate capacity removing this for now until more is known
7536 : // if ( DXCoil( DXCoilNum ).RatedTotCap( Mode ) != AutoSize && ( ( SysSizingRunDone && CurSysNum > 0 ) ||
7537 : //( ZoneSizingRunDone && CurZoneEqNum > 0 ) ) ) { if ( DXCoil( DXCoilNum ).DXCoilType_Num ==
7538 : // HVAC::CoilDX_CoolingTwoStageWHumControl ) { SizingMethod = CoolingAirflowSizing;
7539 : // DataBypassFrac = DXCoil ( DXCoilNum ).BypassedFlowFrac ( Mode );
7540 : // } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical ) {
7541 : // SizingMethod = HeatingAirflowSizing;
7542 : //// DataCoolCoilCap = DXCoolCap; // pass global variable used only for heat pumps (i.e.,
7543 : /// DX cooling and heating coils)
7544 : // } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilVRF_Heating ) {
7545 : // SizingMethod = HeatingAirflowSizing;
7546 : // } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilVRF_Cooling ) {
7547 : // SizingMethod = CoolingAirflowSizing;
7548 : // } else {
7549 : // SizingMethod = CoolingAirflowSizing;
7550 : // }
7551 : // CompName = DXCoil( DXCoilNum ).Name;
7552 : // TempSize = AutoSize;
7553 : // SizingString.clear(); // don't care
7554 : // CompType = DXCoil( DXCoilNum ).DXCoilType;
7555 : // DataIsDXCoil = true;
7556 : // DataEMSOverrideON = DXCoil ( DXCoilNum ).RatedAirVolFlowRateEMSOverrideON ( Mode );
7557 : // DataEMSOverride = DXCoil( DXCoilNum ).RatedAirVolFlowRateEMSOverrideValue( Mode );
7558 : // CoolingAirFlowSizer sizingCoolingAirFlow;
7559 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7560 : // sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
7561 : // DataAirFlowUsedForSizing = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7562 : // DataIsDXCoil = false; // don't need this and next 2, they are just overwritten below. Delete
7563 : // on next pass so testing will show problems if any. DataEMSOverrideON = false;
7564 : // DataEMSOverride = 0.0;
7565 : // DataBypassFrac = 0.0;
7566 : // }
7567 96 : PrintFlag = true;
7568 96 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.CCapFTemp(Mode);
7569 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7570 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7571 0 : FieldNum = 1;
7572 0 : TempSize = thisDXCoil.RatedTotCap(Mode);
7573 0 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7574 96 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating ||
7575 84 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7576 18 : CompName = thisDXCoil.Name;
7577 18 : FieldNum = 1;
7578 18 : TempSize = thisDXCoil.RatedTotCap(Mode);
7579 18 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7580 18 : state.dataSize->DataCoolCoilCap = state.dataSize->DXCoolCap;
7581 78 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
7582 72 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
7583 8 : CompName = thisDXCoil.Name;
7584 8 : FieldNum = 1;
7585 8 : TempSize = thisDXCoil.RatedTotCap(Mode);
7586 8 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7587 8 : PrintFlag = false;
7588 8 : state.dataLoopNodes->Node(thisDXCoil.WaterInNode).Temp =
7589 8 : thisDXCoil.RatedInletWaterTemp; // set the rated water inlet node for HPWHs for use in CalcHPWHDXCoil
7590 70 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7591 6 : CompName = thisDXCoil.Name;
7592 6 : FieldNum = 1;
7593 6 : TempSize = thisDXCoil.RatedTotCap(Mode);
7594 6 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7595 6 : if (state.dataSize->CurZoneEqNum > 0) {
7596 6 : CoilInTemp =
7597 6 : state.dataSize->ZoneSizingRunDone ? state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp : 26;
7598 : } else {
7599 0 : if (state.dataSize->CurOASysNum > 0) {
7600 0 : CoilInTemp =
7601 0 : state.dataSize->SysSizingRunDone ? state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).OutTempAtCoolPeak : 32;
7602 : } else {
7603 0 : CoilInTemp =
7604 0 : state.dataSize->SysSizingRunDone ? state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).MixTempAtCoolPeak : 26;
7605 : }
7606 : }
7607 6 : CalcVRFCoilCapModFac(state, 0, _, CompName, CoilInTemp, _, _, _, state.dataSize->DataTotCapCurveValue);
7608 64 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7609 10 : CompName = thisDXCoil.Name;
7610 10 : FieldNum = 7 + (thisDXCoil.NumOfSpeeds - 1) * 13;
7611 10 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(thisDXCoil.NumOfSpeeds);
7612 10 : TempSize = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
7613 10 : PrintFlag = false;
7614 10 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7615 54 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7616 7 : CompName = thisDXCoil.Name;
7617 7 : FieldNum = 10 + (thisDXCoil.NumOfSpeeds - 1) * 6;
7618 7 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(thisDXCoil.NumOfSpeeds);
7619 7 : TempSize = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
7620 7 : PrintFlag = false;
7621 7 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7622 : } else {
7623 47 : CompName = thisDXCoil.Name;
7624 47 : FieldNum = 1;
7625 47 : TempSize = thisDXCoil.RatedTotCap(Mode);
7626 47 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7627 : }
7628 96 : CompType = thisDXCoil.DXCoilType;
7629 96 : state.dataSize->DataIsDXCoil = true;
7630 96 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
7631 96 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
7632 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical ||
7633 84 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7634 25 : HeatingCapacitySizer sizerHeatingCapacity;
7635 25 : sizerHeatingCapacity.overrideSizingString(SizingString);
7636 25 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7637 25 : thisDXCoil.RatedTotCap(Mode) = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
7638 25 : } else {
7639 71 : CoolingCapacitySizer sizerCoolingCapacity;
7640 71 : sizerCoolingCapacity.overrideSizingString(SizingString);
7641 71 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7642 71 : thisDXCoil.RatedTotCap(Mode) = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
7643 71 : }
7644 96 : state.dataSize->DataIsDXCoil = false;
7645 96 : state.dataSize->DataFlowUsedForSizing = 0.0;
7646 96 : state.dataSize->DataCoolCoilCap = 0.0;
7647 96 : state.dataSize->DataTotCapCurveIndex = 0;
7648 96 : state.dataSize->DataEMSOverrideON = false;
7649 96 : state.dataSize->DataEMSOverride = 0.0;
7650 96 : state.dataSize->DataConstantUsedForSizing = 0.0;
7651 96 : state.dataSize->DataFractionUsedForSizing = 0.0;
7652 96 : state.dataSize->DataTotCapCurveValue = 0.0;
7653 :
7654 : // Cooling coil capacity
7655 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7656 56 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling ||
7657 49 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7658 53 : state.dataSize->DXCoolCap = thisDXCoil.RatedTotCap(Mode);
7659 : }
7660 :
7661 : // Sizing DX cooling coil SHR
7662 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7663 56 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling ||
7664 49 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7665 :
7666 53 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7667 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7668 : } else {
7669 53 : CompName = thisDXCoil.Name;
7670 : }
7671 53 : CompType = thisDXCoil.DXCoilType;
7672 53 : TempSize = thisDXCoil.RatedSHR(Mode);
7673 53 : state.dataSize->DataDXSpeedNum = Mode;
7674 53 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
7675 53 : state.dataSize->DataCapacityUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7676 53 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedSHREMSOverrideOn(Mode);
7677 53 : state.dataSize->DataEMSOverride = thisDXCoil.RatedSHREMSOverrideValue(Mode);
7678 53 : bool ErrorsFound = false;
7679 53 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7680 53 : thisDXCoil.RatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
7681 53 : state.dataSize->DataDXSpeedNum = 0;
7682 53 : state.dataSize->DataFlowUsedForSizing = 0.0;
7683 53 : state.dataSize->DataCapacityUsedForSizing = 0.0;
7684 53 : state.dataSize->DataEMSOverrideON = false;
7685 53 : state.dataSize->DataEMSOverride = 0.0;
7686 :
7687 : } // End of Rated SHR
7688 :
7689 : // Sizing evaporator condenser air flow
7690 98 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondAirFlow(Mode) != 0.0 &&
7691 2 : (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7692 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
7693 :
7694 2 : AutoCalculateSizer sizerEvapCondAirFlow;
7695 2 : std::string stringOverride = "Evaporative Condenser Air Flow Rate [m3/s]";
7696 2 : if (state.dataGlobal->isEpJSON) {
7697 0 : stringOverride = "evaporative_condenser_air_flow_rate [m3/s]";
7698 : }
7699 2 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7700 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7701 : } else {
7702 2 : CompName = thisDXCoil.Name;
7703 2 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7704 1 : stringOverride = "High Speed Evaporative Condenser Air Flow Rate [m3/s]";
7705 1 : if (state.dataGlobal->isEpJSON) {
7706 0 : stringOverride = "high_speed_evaporative_condenser_air_flow_rate [m3/s]";
7707 : }
7708 : } else {
7709 1 : stringOverride = "Evaporative Condenser Air Flow Rate [m3/s]";
7710 1 : if (state.dataGlobal->isEpJSON) {
7711 0 : stringOverride = "evaporative_condenser_air_flow_rate [m3/s]";
7712 : }
7713 : }
7714 : }
7715 2 : CompType = thisDXCoil.DXCoilType;
7716 : // Auto-size condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
7717 2 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7718 2 : state.dataSize->DataFractionUsedForSizing = 0.000114;
7719 2 : TempSize = thisDXCoil.EvapCondAirFlow(Mode);
7720 2 : sizerEvapCondAirFlow.overrideSizingString(stringOverride);
7721 2 : sizerEvapCondAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7722 2 : thisDXCoil.EvapCondAirFlow(Mode) = sizerEvapCondAirFlow.size(state, TempSize, ErrorsFound);
7723 2 : }
7724 :
7725 96 : if (SizeSecDXCoil) { // autosize secondary coil air flow rate for AirCooled condenser type
7726 0 : IsAutoSize = false;
7727 0 : if (thisDXCoil.SecCoilAirFlow == AutoSize) {
7728 0 : IsAutoSize = true;
7729 : }
7730 : // Autosize Primary Coil Air Flow * Secondary Coil Scaling Factor
7731 0 : SecCoilAirFlowDes = thisDXCoil.RatedAirVolFlowRate(1) * thisDXCoil.SecCoilAirFlowScalingFactor;
7732 0 : if (IsAutoSize) {
7733 0 : thisDXCoil.SecCoilAirFlow = SecCoilAirFlowDes;
7734 0 : BaseSizer::reportSizerOutput(
7735 : state, thisDXCoil.DXCoilType, thisDXCoil.Name, "Design Size Secondary Coil Air Flow Rate [m3/s]", SecCoilAirFlowDes);
7736 : } else {
7737 0 : if (thisDXCoil.SecCoilAirFlow > 0.0 && SecCoilAirFlowDes > 0.0 && !HardSizeNoDesRun) {
7738 0 : SecCoilAirFlowUser = thisDXCoil.SecCoilAirFlow;
7739 0 : BaseSizer::reportSizerOutput(state,
7740 : thisDXCoil.DXCoilType,
7741 : thisDXCoil.Name,
7742 : "Design Size Secondary Coil Air Flow Rate [m3/s]",
7743 : SecCoilAirFlowDes,
7744 : "User-Specified Secondary Coil Air Flow Rate [m3/s]",
7745 : SecCoilAirFlowUser);
7746 0 : if (state.dataGlobal->DisplayExtraWarnings) {
7747 0 : if ((std::abs(SecCoilAirFlowDes - SecCoilAirFlowUser) / SecCoilAirFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
7748 0 : ShowMessage(
7749 : state,
7750 0 : format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
7751 0 : ShowContinueError(state, format("User-Specified Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowUser));
7752 0 : ShowContinueError(
7753 0 : state, format("differs from Design Size Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowDes));
7754 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
7755 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
7756 : }
7757 : }
7758 : }
7759 : }
7760 : }
7761 :
7762 : // Sizing evaporative condenser air flow 2
7763 96 : PrintFlag = true;
7764 97 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondAirFlow2 != 0.0 &&
7765 1 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7766 1 : CompName = thisDXCoil.Name;
7767 1 : FieldNum = 15; // Low Speed Evaporative Condenser Air Flow Rate
7768 1 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [m3/s]";
7769 1 : CompType = thisDXCoil.DXCoilType;
7770 : // Autosize low speed condenser air flow to 1/3 Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
7771 1 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7772 1 : state.dataSize->DataFractionUsedForSizing = 0.000114 * 0.3333;
7773 1 : TempSize = thisDXCoil.EvapCondAirFlow2;
7774 1 : AutoCalculateSizer sizerEvapCondAirFlow2;
7775 1 : std::string stringOverride = "Low Speed Evaporative Condenser Air Flow Rate [m3/s]";
7776 1 : if (state.dataGlobal->isEpJSON) {
7777 0 : stringOverride = "low_speed_evaporative_condenser_air_flow_rate [m3/s]";
7778 : }
7779 1 : sizerEvapCondAirFlow2.overrideSizingString(stringOverride);
7780 1 : sizerEvapCondAirFlow2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7781 1 : thisDXCoil.EvapCondAirFlow2 = sizerEvapCondAirFlow2.size(state, TempSize, ErrorsFound);
7782 1 : }
7783 :
7784 : // Sizing evaporative condenser pump electric nominal power
7785 108 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondPumpElecNomPower(Mode) != 0.0 &&
7786 12 : (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7787 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
7788 :
7789 12 : AutoCalculateSizer sizerEvapCondPumpPower;
7790 12 : std::string stringOverride = "Evaporative Condenser Pump Rated Power Consumption [W]";
7791 12 : if (state.dataGlobal->isEpJSON) {
7792 0 : stringOverride = "evaporative_condenser_pump_rated_power_consumption [W]";
7793 : }
7794 12 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7795 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7796 : } else {
7797 12 : CompName = thisDXCoil.Name;
7798 12 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7799 1 : stringOverride = "High Speed Evaporative Condenser Pump Rated Power Consumption [W]";
7800 1 : if (state.dataGlobal->isEpJSON) {
7801 0 : stringOverride = "high_speed_evaporative_condenser_pump_rated_power_consumption [W]";
7802 : }
7803 : } else {
7804 11 : stringOverride = "Evaporative Condenser Pump Rated Power Consumption [W]";
7805 11 : if (state.dataGlobal->isEpJSON) {
7806 0 : stringOverride = "evaporative_condenser_pump_rated_power_consumption [W]";
7807 : }
7808 : }
7809 : }
7810 12 : CompType = thisDXCoil.DXCoilType;
7811 : // Autosize high speed evap condenser pump power to Total Capacity * 0.004266 w/w (15 w/ton)
7812 12 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7813 12 : state.dataSize->DataFractionUsedForSizing = 0.004266;
7814 12 : TempSize = thisDXCoil.EvapCondPumpElecNomPower(Mode);
7815 12 : sizerEvapCondPumpPower.overrideSizingString(stringOverride);
7816 12 : sizerEvapCondPumpPower.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7817 12 : thisDXCoil.EvapCondPumpElecNomPower(Mode) = sizerEvapCondPumpPower.size(state, TempSize, ErrorsFound);
7818 12 : }
7819 :
7820 : // Sizing low speed evaporative condenser pump electric nominal power
7821 97 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondPumpElecNomPower2 != 0.0 &&
7822 1 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7823 1 : CompName = thisDXCoil.Name;
7824 1 : CompType = thisDXCoil.DXCoilType;
7825 : // Autosize low speed evap condenser pump power to 1/3 Total Capacity * 0.004266 w/w (15 w/ton)
7826 1 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7827 1 : state.dataSize->DataFractionUsedForSizing = 0.004266 * 0.3333;
7828 1 : TempSize = thisDXCoil.EvapCondPumpElecNomPower2;
7829 1 : AutoCalculateSizer sizerEvapCondPumpPower2;
7830 1 : std::string stringOverride = "Low Speed Evaporative Condenser Pump Rated Power Consumption [W]";
7831 1 : if (state.dataGlobal->isEpJSON) {
7832 0 : stringOverride = "low_speed_evaporative_condenser_pump_rated_power_consumption [W]";
7833 : }
7834 1 : sizerEvapCondPumpPower2.overrideSizingString(stringOverride);
7835 1 : sizerEvapCondPumpPower2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7836 1 : thisDXCoil.EvapCondPumpElecNomPower2 = sizerEvapCondPumpPower2.size(state, TempSize, ErrorsFound);
7837 1 : }
7838 :
7839 : // // Sizing rated low speed air flow rate
7840 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7841 4 : CompName = thisDXCoil.Name;
7842 4 : CompType = thisDXCoil.DXCoilType;
7843 : // Autosize low speed air flow rate to 1/3 high speed air flow rate
7844 4 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
7845 4 : state.dataSize->DataFractionUsedForSizing = 0.3333;
7846 4 : TempSize = thisDXCoil.RatedAirVolFlowRate2;
7847 4 : AutoCalculateSizer sizerLowSpdAirFlow;
7848 4 : std::string stringOverride = "Low Speed Rated Air Flow Rate [m3/s]";
7849 4 : if (state.dataGlobal->isEpJSON) {
7850 0 : stringOverride = "low_speed_rated_air_flow_rate [m3/s]";
7851 : }
7852 4 : sizerLowSpdAirFlow.overrideSizingString(stringOverride);
7853 4 : sizerLowSpdAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7854 4 : thisDXCoil.RatedAirVolFlowRate2 = sizerLowSpdAirFlow.size(state, TempSize, ErrorsFound);
7855 4 : }
7856 :
7857 : // // Sizing rated low speed total cooling capacity
7858 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7859 4 : CompName = thisDXCoil.Name;
7860 4 : CompType = thisDXCoil.DXCoilType;
7861 : // Autosize low speed capacity to 1/3 high speed capacity
7862 4 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7863 4 : state.dataSize->DataFractionUsedForSizing = 0.3333;
7864 4 : TempSize = thisDXCoil.RatedTotCap2;
7865 4 : AutoCalculateSizer sizerLowSpdCap;
7866 4 : std::string stringOverride = "Low Speed Gross Rated Total Cooling Capacity [W]";
7867 4 : if (state.dataGlobal->isEpJSON) {
7868 0 : stringOverride = "low_speed_gross_rated_total_cooling_capacity [W]";
7869 : }
7870 4 : sizerLowSpdCap.overrideSizingString(stringOverride);
7871 4 : sizerLowSpdCap.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7872 4 : thisDXCoil.RatedTotCap2 = sizerLowSpdCap.size(state, TempSize, ErrorsFound);
7873 4 : }
7874 :
7875 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7876 4 : if (thisDXCoil.EvapCondAirFlow2 > thisDXCoil.EvapCondAirFlow(Mode)) {
7877 0 : ShowSevereError(
7878 : state,
7879 0 : format("SizeDXCoil: {} {}, Evaporative Condenser low speed air flow must be less than or equal to high speed air flow.",
7880 0 : thisDXCoil.DXCoilType,
7881 0 : thisDXCoil.Name));
7882 0 : ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.EvapCondAirFlow2, thisDXCoil.EvapCondAirFlow(Mode)));
7883 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7884 : }
7885 :
7886 4 : if (thisDXCoil.EvapCondPumpElecNomPower2 > thisDXCoil.EvapCondPumpElecNomPower(Mode)) {
7887 0 : ShowSevereError(
7888 : state,
7889 0 : format("SizeDXCoil: {} {}, Evaporative Condenser low speed pump power must be less than or equal to high speed pump power.",
7890 0 : thisDXCoil.DXCoilType,
7891 0 : thisDXCoil.Name));
7892 0 : ShowContinueError(
7893 0 : state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.EvapCondPumpElecNomPower2, thisDXCoil.EvapCondPumpElecNomPower(Mode)));
7894 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7895 : }
7896 :
7897 4 : if (thisDXCoil.RatedTotCap2 > thisDXCoil.RatedTotCap(Mode)) {
7898 0 : ShowSevereError(state,
7899 0 : format("SizeDXCoil: {} {}, Rated Total Cooling Capacity, Low Speed must be less than or equal to Rated Total "
7900 : "Cooling Capacity, High Speed.",
7901 0 : thisDXCoil.DXCoilType,
7902 0 : thisDXCoil.Name));
7903 0 : ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.RatedTotCap2, thisDXCoil.RatedTotCap(Mode)));
7904 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7905 : }
7906 :
7907 4 : if (thisDXCoil.RatedAirVolFlowRate2 > thisDXCoil.RatedAirVolFlowRate(Mode)) {
7908 0 : ShowFatalError(state,
7909 0 : format("SizeDXCoil: {} {}, Rated Air Volume Flow Rate, low speed must be less than or equal to Rated Air Volume "
7910 : "Flow Rate, high speed.",
7911 0 : thisDXCoil.DXCoilType,
7912 0 : thisDXCoil.Name));
7913 0 : ShowContinueError(state,
7914 0 : format("Instead, {:.2R} > {:.2R}", thisDXCoil.RatedAirVolFlowRate2, thisDXCoil.RatedAirVolFlowRate(Mode)));
7915 0 : ShowFatalError(state, "Preceding conditions cause termination.");
7916 : }
7917 : }
7918 :
7919 : // // Sizing rated low speed SHR2
7920 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7921 4 : CompName = thisDXCoil.Name;
7922 4 : FieldNum = 7;
7923 4 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum);
7924 4 : CompType = thisDXCoil.DXCoilType;
7925 : // Autosize low speed SHR to be the same as high speed SHR
7926 4 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedSHR(Mode);
7927 4 : state.dataSize->DataFractionUsedForSizing = 1.0;
7928 4 : state.dataSize->DataDXSpeedNum = 2; // refers to low speed in sizer
7929 4 : bool ErrorsFound = false;
7930 4 : TempSize = thisDXCoil.RatedSHR2;
7931 4 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7932 4 : thisDXCoil.RatedSHR2 = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
7933 4 : state.dataSize->DataConstantUsedForSizing = 0.0;
7934 4 : state.dataSize->DataFractionUsedForSizing = 0.0;
7935 4 : state.dataSize->DataDXSpeedNum = 0;
7936 : }
7937 :
7938 : // // Sizing resistive defrost heater capacity
7939 96 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating &&
7940 83 : thisDXCoil.DXCoilType_Num != HVAC::CoilDX_MultiSpeedHeating) {
7941 : // IF (DXCoil(DXCoilNum)%DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating .OR. &
7942 : // DXCoil(DXCoilNum)%DXCoilType_Num == Coil_HeatingAirToAirVariableSpeed) THEN
7943 76 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
7944 3 : CompName = thisDXCoil.Name;
7945 3 : CompType = thisDXCoil.DXCoilType;
7946 : // Autosize low speed capacity to 1/3 high speed capacity
7947 3 : state.dataSize->DataConstantUsedForSizing = state.dataSize->DXCoolCap;
7948 3 : state.dataSize->DataFractionUsedForSizing = 1.0;
7949 3 : TempSize = thisDXCoil.DefrostCapacity;
7950 3 : AutoCalculateSizer sizerResDefCap;
7951 3 : std::string stringOverride = "Resistive Defrost Heater Capacity [W]";
7952 3 : if (state.dataGlobal->isEpJSON) {
7953 0 : stringOverride = "resistive_defrost_heater_capacity [W]";
7954 : }
7955 3 : sizerResDefCap.overrideSizingString(stringOverride);
7956 3 : sizerResDefCap.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7957 3 : thisDXCoil.DefrostCapacity = sizerResDefCap.size(state, TempSize, ErrorsFound);
7958 3 : } else {
7959 73 : thisDXCoil.DefrostCapacity = 0.0;
7960 : }
7961 : }
7962 :
7963 : } // End capacity stages loop
7964 : } // End dehumidification modes loop
7965 :
7966 : // Autosizing for multispeed cooling coil
7967 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7968 : // flow rate autosize
7969 31 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
7970 : // Sizing multispeed air volume flow rate
7971 21 : IsAutoSize = false;
7972 21 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) == AutoSize) {
7973 15 : IsAutoSize = true;
7974 : }
7975 21 : state.dataSize->DataIsDXCoil = true;
7976 21 : CompName = thisDXCoil.Name;
7977 21 : CompType = thisDXCoil.DXCoilType;
7978 21 : if (Mode == thisDXCoil.NumOfSpeeds) {
7979 10 : FieldNum = 10 + (Mode - 1) * 14;
7980 10 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
7981 10 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
7982 10 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
7983 10 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
7984 10 : bool errorsFound = false;
7985 10 : CoolingAirFlowSizer sizingCoolingAirFlow;
7986 10 : sizingCoolingAirFlow.overrideSizingString(SizingString);
7987 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7988 10 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7989 10 : TempSize = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7990 10 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = TempSize;
7991 10 : state.dataSize->DataEMSOverrideON = false;
7992 10 : state.dataSize->DataEMSOverride = 0.0;
7993 10 : if (!IsAutoSize && !HardSizeNoDesRun) {
7994 1 : TempSize = AutoSize;
7995 1 : bPRINT = false;
7996 1 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
7997 1 : MSRatedAirVolFlowRateDes = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7998 1 : bPRINT = true;
7999 : }
8000 10 : if (IsAutoSize) {
8001 7 : MSRatedAirVolFlowRateDes = TempSize;
8002 : }
8003 10 : } else {
8004 11 : FieldNum = 10 + (Mode - 1) * 14;
8005 11 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
8006 11 : if (IsAutoSize || !HardSizeNoDesRun) {
8007 : // Autosize low speed flow to fraction of the highest speed flow
8008 9 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
8009 9 : if (!IsAutoSize && !HardSizeNoDesRun) {
8010 1 : state.dataSize->DataConstantUsedForSizing = MSRatedAirVolFlowRateDes;
8011 : }
8012 9 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8013 : }
8014 11 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8015 11 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
8016 11 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
8017 11 : bool errorsFound = false;
8018 11 : CoolingAirFlowSizer sizingCoolingAirFlow;
8019 11 : sizingCoolingAirFlow.overrideSizingString(SizingString);
8020 11 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8021 11 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
8022 11 : }
8023 21 : state.dataSize->DataEMSOverride = 0.0;
8024 21 : state.dataSize->DataEMSOverrideON = false;
8025 21 : state.dataSize->DataIsDXCoil = false;
8026 21 : state.dataSize->DataTotCapCurveIndex = 0;
8027 21 : state.dataSize->DataConstantUsedForSizing = 0.0;
8028 21 : state.dataSize->DataFractionUsedForSizing = 0.0;
8029 : }
8030 :
8031 : // Ensure flow rate at lower speed must be lower or equal to the flow rate at higher speed. Otherwise, a severe error is issued.
8032 21 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8033 11 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) > thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)) {
8034 0 : ShowWarningError(state,
8035 0 : format("SizeDXCoil: {} {}, Speed {} Rated Air Flow Rate must be less than or equal to Speed {} Rated Air Flow Rate.",
8036 0 : thisDXCoil.DXCoilType,
8037 0 : thisDXCoil.Name,
8038 : Mode,
8039 0 : Mode + 1));
8040 0 : ShowContinueError(
8041 0 : state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedAirVolFlowRate(Mode), thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)));
8042 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8043 : }
8044 : }
8045 :
8046 : // Sizing multispeed rated total cooling capacity
8047 31 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8048 21 : IsAutoSize = false;
8049 21 : if (thisDXCoil.MSRatedTotCap(Mode) == AutoSize) {
8050 15 : IsAutoSize = true;
8051 : }
8052 21 : CompName = thisDXCoil.Name;
8053 21 : CompType = thisDXCoil.DXCoilType;
8054 21 : state.dataSize->DataIsDXCoil = true;
8055 21 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(Mode);
8056 21 : if (Mode == thisDXCoil.NumOfSpeeds) {
8057 10 : PrintFlag = true;
8058 10 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8059 10 : FieldNum = 7 + (Mode - 1) * 14;
8060 10 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8061 10 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8062 10 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8063 10 : MSRatedTotCapDesAtMaxSpeed = thisDXCoil.MSRatedTotCap(Mode);
8064 10 : if (!HardSizeNoDesRun) {
8065 8 : PrintFlag = false;
8066 8 : TempSize = DataSizing::AutoSize;
8067 : // Auto-size capacity at the highest speed
8068 8 : CoolingCapacitySizer sizerCoolingCapacity;
8069 8 : sizerCoolingCapacity.overrideSizingString(SizingString);
8070 8 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8071 8 : TempSize = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
8072 8 : state.dataSize->DataConstantUsedForSizing = TempSize;
8073 8 : state.dataSize->DataFractionUsedForSizing = 1.0;
8074 8 : MSRatedTotCapDesAtMaxSpeed = TempSize;
8075 8 : thisDXCoil.MSRatedTotCapDes(Mode) = TempSize;
8076 8 : PrintFlag = true;
8077 8 : }
8078 10 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8079 10 : CoolingCapacitySizer sizerCoolingCapacity2;
8080 10 : sizerCoolingCapacity2.overrideSizingString(SizingString);
8081 10 : sizerCoolingCapacity2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8082 10 : TempSize = sizerCoolingCapacity2.size(state, TempSize, ErrorsFound);
8083 10 : thisDXCoil.MSRatedTotCap(Mode) = TempSize;
8084 10 : if (IsAutoSize) {
8085 7 : MSRatedTotCapDesAtMaxSpeed = TempSize;
8086 7 : thisDXCoil.MSRatedTotCapDes(Mode) = TempSize;
8087 : }
8088 10 : } else {
8089 : // cooling capacity at lower speeds
8090 11 : PrintFlag = true;
8091 11 : FieldNum = 7 + (Mode - 1) * 14;
8092 11 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8093 11 : if (IsAutoSize || !HardSizeNoDesRun) {
8094 : // autosize low speed capacity to fraction of the highest speed capacity
8095 9 : if (!HardSizeNoDesRun) {
8096 9 : state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8097 : } else {
8098 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
8099 : }
8100 9 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8101 9 : thisDXCoil.MSRatedTotCapDes(Mode) = state.dataSize->DataConstantUsedForSizing * state.dataSize->DataFractionUsedForSizing;
8102 : }
8103 11 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8104 11 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8105 11 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8106 11 : CoolingCapacitySizer sizerCoolingCapacity;
8107 11 : sizerCoolingCapacity.overrideSizingString(SizingString);
8108 11 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8109 11 : thisDXCoil.MSRatedTotCap(Mode) = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
8110 11 : }
8111 21 : state.dataSize->DataEMSOverride = 0.0;
8112 21 : state.dataSize->DataEMSOverrideON = false;
8113 21 : state.dataSize->DataIsDXCoil = false;
8114 21 : state.dataSize->DataCoolCoilCap = 0.0;
8115 21 : state.dataSize->DataTotCapCurveIndex = 0;
8116 21 : state.dataSize->DataConstantUsedForSizing = 0.0;
8117 21 : state.dataSize->DataFractionUsedForSizing = 0.0;
8118 : }
8119 :
8120 : // Ensure capacity at lower speed must be lower or equal to the capacity at higher speed.
8121 21 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8122 11 : if (thisDXCoil.MSRatedTotCap(Mode) > thisDXCoil.MSRatedTotCap(Mode + 1)) {
8123 0 : ShowWarningError(state,
8124 0 : format("SizeDXCoil: {} {}, Speed {} Rated Total Cooling Capacity must be less than or equal to Speed {} Rated "
8125 : "Total Cooling Capacity.",
8126 0 : thisDXCoil.DXCoilType,
8127 0 : thisDXCoil.Name,
8128 : Mode,
8129 0 : Mode + 1));
8130 0 : ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedTotCap(Mode), thisDXCoil.MSRatedTotCap(Mode + 1)));
8131 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8132 : }
8133 : }
8134 :
8135 : // Rated SHR
8136 31 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8137 21 : IsAutoSize = false;
8138 21 : if (thisDXCoil.MSRatedSHR(Mode) == AutoSize) {
8139 15 : IsAutoSize = true;
8140 : }
8141 21 : if (Mode == thisDXCoil.NumOfSpeeds) {
8142 10 : CompType = thisDXCoil.DXCoilType;
8143 10 : CompName = thisDXCoil.Name;
8144 10 : TempSize = thisDXCoil.MSRatedSHR(Mode);
8145 10 : state.dataSize->DataFlowUsedForSizing = MSRatedAirVolFlowRateDes;
8146 10 : state.dataSize->DataCapacityUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8147 10 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedSHREMSOverrideOn(Mode);
8148 10 : state.dataSize->DataEMSOverride = thisDXCoil.RatedSHREMSOverrideValue(Mode);
8149 10 : bool ErrorsFound = false;
8150 10 : state.dataSize->DataDXSpeedNum = Mode;
8151 10 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8152 10 : thisDXCoil.MSRatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
8153 : // added for rated sensible cooling capacity estimate for html reporting, issue #7381
8154 10 : thisDXCoil.RatedSHR(1) = thisDXCoil.MSRatedSHR(Mode);
8155 : // design SHR value at the maximum speed calculated above was supposed to be used for all speeds
8156 : // Now user specified SHR value is used when the SHR field is not autosized and design day run is
8157 : // set to yes unless the code below is commented out
8158 10 : MSRatedSHRDes = thisDXCoil.MSRatedSHR(Mode);
8159 : } else {
8160 11 : TempSize = thisDXCoil.MSRatedSHR(Mode);
8161 11 : bool ErrorsFound = false;
8162 11 : state.dataSize->DataDXSpeedNum = Mode;
8163 11 : state.dataSize->DataFractionUsedForSizing = MSRatedSHRDes;
8164 11 : state.dataSize->DataConstantUsedForSizing = 1.0;
8165 11 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8166 11 : thisDXCoil.MSRatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
8167 : }
8168 : }
8169 10 : state.dataSize->DataFlowUsedForSizing = 0.0;
8170 10 : state.dataSize->DataCapacityUsedForSizing = 0.0;
8171 10 : state.dataSize->DataEMSOverrideON = false;
8172 10 : state.dataSize->DataEMSOverride = 0.0;
8173 10 : state.dataSize->DataDXSpeedNum = 0;
8174 10 : state.dataSize->DataFractionUsedForSizing = 0.0;
8175 10 : state.dataSize->DataConstantUsedForSizing = 0.0;
8176 :
8177 : // Rated Evaporative condenser airflow rates
8178 31 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8179 21 : IsAutoSize = false;
8180 21 : if (thisDXCoil.MSEvapCondAirFlow(Mode) == AutoSize) {
8181 16 : IsAutoSize = true;
8182 : }
8183 21 : if (IsAutoSize || !HardSizeNoDesRun) {
8184 : // Autosize condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
8185 21 : MSEvapCondAirFlowDes = ((float)Mode / thisDXCoil.NumOfSpeeds) * MSRatedTotCapDesAtMaxSpeed * 0.000114;
8186 : } else {
8187 : // this is done to duplicate any existing calc method
8188 0 : MSEvapCondAirFlowDes = thisDXCoil.MSRatedTotCap(Mode) * 0.000114;
8189 : }
8190 21 : if (IsAutoSize) {
8191 16 : thisDXCoil.MSEvapCondAirFlow(Mode) = MSEvapCondAirFlowDes;
8192 48 : BaseSizer::reportSizerOutput(state,
8193 : thisDXCoil.DXCoilType,
8194 : thisDXCoil.Name,
8195 32 : format("Design Size Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
8196 : MSEvapCondAirFlowDes);
8197 : } else {
8198 5 : if (thisDXCoil.MSEvapCondAirFlow(Mode) > 0.0 && MSEvapCondAirFlowDes > 0.0 && !HardSizeNoDesRun) {
8199 2 : MSEvapCondAirFlowUser = thisDXCoil.MSEvapCondAirFlow(Mode);
8200 6 : BaseSizer::reportSizerOutput(state,
8201 : thisDXCoil.DXCoilType,
8202 : thisDXCoil.Name,
8203 4 : format("Design Size Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
8204 : MSEvapCondAirFlowDes,
8205 4 : format("User-Specified Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
8206 : MSEvapCondAirFlowUser);
8207 2 : if (state.dataGlobal->DisplayExtraWarnings) {
8208 0 : if ((std::abs(MSEvapCondAirFlowDes - MSEvapCondAirFlowUser) / MSEvapCondAirFlowUser) >
8209 0 : state.dataSize->AutoVsHardSizingThreshold) {
8210 0 : ShowMessage(
8211 0 : state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
8212 0 : ShowContinueError(state,
8213 0 : format("User-Specified Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", MSEvapCondAirFlowUser));
8214 0 : ShowContinueError(
8215 0 : state, format("differs from Design Size Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", MSEvapCondAirFlowDes));
8216 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8217 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8218 : }
8219 : }
8220 : }
8221 : }
8222 : }
8223 :
8224 : // Ensure evaporative condenser airflow rate at lower speed must be lower or equal to one at higher speed.
8225 21 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8226 11 : if (thisDXCoil.MSEvapCondAirFlow(Mode) > thisDXCoil.MSEvapCondAirFlow(Mode + 1)) {
8227 0 : ShowWarningError(state,
8228 0 : format("SizeDXCoil: {} {}, Speed {} Evaporative Condenser Air Flow Rate must be less than or equal to Speed {} "
8229 : "Evaporative Condenser Air Flow Rate.",
8230 0 : thisDXCoil.DXCoilType,
8231 0 : thisDXCoil.Name,
8232 : Mode,
8233 0 : Mode + 1));
8234 0 : ShowContinueError(state,
8235 0 : format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSEvapCondAirFlow(Mode), thisDXCoil.MSEvapCondAirFlow(Mode + 1)));
8236 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8237 : }
8238 : }
8239 :
8240 : // Sizing multispeed rated evaporative condenser pump power
8241 31 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8242 21 : IsAutoSize = false;
8243 21 : if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) == AutoSize) {
8244 16 : IsAutoSize = true;
8245 : }
8246 :
8247 21 : if (IsAutoSize || !HardSizeNoDesRun) {
8248 : // Autosize low speed evap condenser pump power to 1/3 Total Capacity * 0.004266 w/w (15 w/ton)
8249 21 : MSEvapCondPumpElecNomPowerDes = ((float)Mode / thisDXCoil.NumOfSpeeds) * MSRatedTotCapDesAtMaxSpeed * 0.004266;
8250 : } else {
8251 : // this is done to duplicate any existing calc method
8252 0 : MSEvapCondPumpElecNomPowerDes = thisDXCoil.MSRatedTotCap(Mode) * 0.004266;
8253 : }
8254 : // Design Size data is always available
8255 21 : if (IsAutoSize) {
8256 16 : thisDXCoil.MSEvapCondPumpElecNomPower(Mode) = MSEvapCondPumpElecNomPowerDes;
8257 48 : BaseSizer::reportSizerOutput(state,
8258 : thisDXCoil.DXCoilType,
8259 : thisDXCoil.Name,
8260 32 : format("Design Size Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
8261 : MSEvapCondPumpElecNomPowerDes);
8262 : } else {
8263 5 : if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) > 0.0 && MSEvapCondPumpElecNomPowerDes > 0.0 && !HardSizeNoDesRun) {
8264 2 : MSEvapCondPumpElecNomPowerUser = thisDXCoil.MSEvapCondPumpElecNomPower(Mode);
8265 6 : BaseSizer::reportSizerOutput(state,
8266 : thisDXCoil.DXCoilType,
8267 : thisDXCoil.Name,
8268 4 : format("Design Size Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
8269 : MSEvapCondPumpElecNomPowerDes,
8270 4 : format("User-Specified Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
8271 : MSEvapCondPumpElecNomPowerUser);
8272 2 : if (state.dataGlobal->DisplayExtraWarnings) {
8273 0 : if ((std::abs(MSEvapCondPumpElecNomPowerDes - MSEvapCondPumpElecNomPowerUser) / MSEvapCondPumpElecNomPowerUser) >
8274 0 : state.dataSize->AutoVsHardSizingThreshold) {
8275 0 : ShowMessage(
8276 0 : state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
8277 0 : ShowContinueError(state,
8278 0 : format("User-Specified Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]",
8279 : MSEvapCondPumpElecNomPowerUser));
8280 0 : ShowContinueError(state,
8281 0 : format("differs from Design Size Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]",
8282 : MSEvapCondPumpElecNomPowerDes));
8283 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8284 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8285 : }
8286 : }
8287 : }
8288 : }
8289 : }
8290 :
8291 : // Ensure evaporative condenser pump power at lower speed must be lower or equal to one at higher speed.
8292 21 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8293 11 : if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) > thisDXCoil.MSEvapCondPumpElecNomPower(Mode + 1)) {
8294 0 : ShowWarningError(state,
8295 0 : format("SizeDXCoil: {} {}, Speed {} Rated Evaporative Condenser Pump Power Consumption must be less than or "
8296 : "equal to Speed {} Rated Evaporative Condenser Pump Power Consumption.",
8297 0 : thisDXCoil.DXCoilType,
8298 0 : thisDXCoil.Name,
8299 : Mode,
8300 0 : Mode + 1));
8301 0 : ShowContinueError(
8302 : state,
8303 0 : format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSEvapCondPumpElecNomPower(Mode), thisDXCoil.MSEvapCondPumpElecNomPower(Mode + 1)));
8304 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8305 : }
8306 : }
8307 : }
8308 :
8309 : // Autosizing for multispeed heating coil
8310 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
8311 : // flow rate autosize
8312 23 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8313 16 : IsAutoSize = false;
8314 16 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) == AutoSize) {
8315 12 : IsAutoSize = true;
8316 : }
8317 16 : state.dataSize->DataIsDXCoil = true;
8318 16 : CompName = thisDXCoil.Name;
8319 16 : CompType = thisDXCoil.DXCoilType;
8320 : // Sizing rated air flow rate
8321 16 : if (Mode == thisDXCoil.NumOfSpeeds) {
8322 7 : FieldNum = 12 + (Mode - 1) * 6;
8323 7 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
8324 7 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8325 7 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
8326 7 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
8327 7 : bool errorsFound = false;
8328 7 : HeatingAirFlowSizer sizingHeatingAirFlow;
8329 7 : sizingHeatingAirFlow.overrideSizingString(SizingString);
8330 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8331 7 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8332 7 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
8333 7 : if (!IsAutoSize && !HardSizeNoDesRun) {
8334 0 : TempSize = AutoSize;
8335 0 : bPRINT = false;
8336 0 : errorsFound = false;
8337 0 : HeatingAirFlowSizer sizingHeatingAirFlow2;
8338 0 : sizingHeatingAirFlow2.overrideSizingString(SizingString);
8339 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8340 0 : sizingHeatingAirFlow2.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8341 0 : MSRatedAirVolFlowRateDes = sizingHeatingAirFlow2.size(state, TempSize, errorsFound);
8342 0 : bPRINT = true;
8343 0 : }
8344 7 : } else {
8345 9 : FieldNum = 12 + (Mode - 1) * 6;
8346 9 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
8347 9 : if (IsAutoSize || !HardSizeNoDesRun) {
8348 : // Auto-size low speed flow to fraction of the highest speed capacity
8349 7 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
8350 7 : if (!IsAutoSize && !HardSizeNoDesRun) {
8351 0 : state.dataSize->DataConstantUsedForSizing = MSRatedAirVolFlowRateDes;
8352 : }
8353 7 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8354 : }
8355 9 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8356 9 : bool errorsFound = false;
8357 9 : HeatingAirFlowSizer sizingHeatingAirFlow;
8358 9 : sizingHeatingAirFlow.overrideSizingString(SizingString);
8359 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8360 9 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8361 9 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
8362 9 : }
8363 16 : state.dataSize->DataEMSOverride = 0.0;
8364 16 : state.dataSize->DataEMSOverrideON = false;
8365 16 : state.dataSize->DataIsDXCoil = false;
8366 16 : state.dataSize->DataTotCapCurveIndex = 0;
8367 16 : state.dataSize->DataConstantUsedForSizing = 0.0;
8368 16 : state.dataSize->DataFractionUsedForSizing = 0.0;
8369 : }
8370 :
8371 : // Ensure flow rate at lower speed must be lower or equal to the flow rate at higher speed. Otherwise, a severe error is issued.
8372 16 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8373 9 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) > thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)) {
8374 0 : ShowWarningError(state,
8375 0 : format("SizeDXCoil: {} {}, Speed {} Rated Air Flow Rate must be less than or equal to Speed {} Rated Air Flow Rate.",
8376 0 : thisDXCoil.DXCoilType,
8377 0 : thisDXCoil.Name,
8378 : Mode,
8379 0 : Mode + 1));
8380 0 : ShowContinueError(
8381 0 : state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedAirVolFlowRate(Mode), thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)));
8382 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8383 : }
8384 : }
8385 : // Rated Secondary Coil Airflow Rates for AirCooled condenser type
8386 7 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
8387 0 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8388 0 : IsAutoSize = false;
8389 0 : if (thisDXCoil.MSSecCoilAirFlow(Mode) == AutoSize) {
8390 0 : IsAutoSize = true;
8391 : }
8392 : // Autosize Primary Coil air flow * Secondary Coil Scaling Factor
8393 0 : SecCoilAirFlowDes = thisDXCoil.MSRatedAirVolFlowRate(Mode) * thisDXCoil.MSSecCoilAirFlowScalingFactor(Mode);
8394 0 : if (IsAutoSize) {
8395 0 : thisDXCoil.MSSecCoilAirFlow(Mode) = SecCoilAirFlowDes;
8396 0 : BaseSizer::reportSizerOutput(state,
8397 : thisDXCoil.DXCoilType,
8398 : thisDXCoil.Name,
8399 0 : format("Design Size Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
8400 : SecCoilAirFlowDes);
8401 : } else {
8402 0 : if (thisDXCoil.MSSecCoilAirFlow(Mode) > 0.0 && SecCoilAirFlowDes > 0.0 && !HardSizeNoDesRun) {
8403 0 : SecCoilAirFlowUser = thisDXCoil.MSSecCoilAirFlow(Mode);
8404 0 : BaseSizer::reportSizerOutput(state,
8405 : thisDXCoil.DXCoilType,
8406 : thisDXCoil.Name,
8407 0 : format("Design Size Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
8408 : SecCoilAirFlowDes,
8409 0 : format("User-Specified Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
8410 : SecCoilAirFlowUser);
8411 0 : if (state.dataGlobal->DisplayExtraWarnings) {
8412 0 : if ((std::abs(SecCoilAirFlowDes - SecCoilAirFlowUser) / SecCoilAirFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
8413 0 : ShowMessage(
8414 : state,
8415 0 : format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
8416 0 : ShowContinueError(state, format("User-Specified Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowUser));
8417 0 : ShowContinueError(
8418 0 : state, format("differs from Design Size Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowDes));
8419 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8420 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8421 : }
8422 : }
8423 : }
8424 : }
8425 : }
8426 : }
8427 :
8428 : // Sizing rated total heating capacity
8429 23 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8430 16 : IsAutoSize = false;
8431 16 : if (thisDXCoil.MSRatedTotCap(Mode) == AutoSize) {
8432 12 : IsAutoSize = true;
8433 : }
8434 16 : state.dataSize->DataIsDXCoil = true;
8435 16 : CompName = thisDXCoil.Name;
8436 16 : CompType = thisDXCoil.DXCoilType;
8437 16 : if (Mode == thisDXCoil.NumOfSpeeds) {
8438 7 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8439 7 : FieldNum = 10 + (Mode - 1) * 6;
8440 7 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8441 7 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(Mode);
8442 7 : if (IsAutoSize || !HardSizeNoDesRun) {
8443 : // Heating capacity is assumed to be equal to the cooling capacity
8444 5 : PrintFlag = false;
8445 5 : state.dataSize->DataFractionUsedForSizing = 1.0;
8446 5 : if (thisDXCoil.CompanionUpstreamDXCoil > 0) {
8447 1 : NumOfSpeedCompanion = state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).NumOfSpeeds;
8448 1 : state.dataSize->DataConstantUsedForSizing =
8449 1 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).MSRatedTotCapDes(NumOfSpeedCompanion);
8450 : } else {
8451 4 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(1); // sized above
8452 : }
8453 5 : TempSize = DataSizing::AutoSize;
8454 5 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8455 5 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8456 5 : HeatingCapacitySizer sizerHeatingCapacity;
8457 5 : sizerHeatingCapacity.overrideSizingString(SizingString);
8458 5 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8459 5 : MSRatedTotCapDesAtMaxSpeed = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
8460 5 : state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8461 5 : state.dataSize->DataFractionUsedForSizing = 1.0;
8462 5 : }
8463 7 : PrintFlag = true;
8464 7 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8465 7 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8466 7 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8467 7 : HeatingCapacitySizer sizerHeatingCapacity;
8468 7 : sizerHeatingCapacity.overrideSizingString(SizingString);
8469 7 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8470 7 : TempSize = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
8471 7 : thisDXCoil.MSRatedTotCap(Mode) = TempSize;
8472 7 : if (IsAutoSize) {
8473 5 : MSRatedTotCapDesAtMaxSpeed = TempSize;
8474 : }
8475 7 : } else {
8476 9 : PrintFlag = true;
8477 9 : FieldNum = 10 + (Mode - 1) * 6;
8478 9 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8479 9 : if (IsAutoSize || !HardSizeNoDesRun) {
8480 : // autosize low speed capacity to fraction of the highest speed capacity
8481 7 : if (!HardSizeNoDesRun) {
8482 7 : state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8483 : } else {
8484 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
8485 : }
8486 7 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8487 : }
8488 9 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8489 9 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8490 9 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8491 9 : HeatingCapacitySizer sizerHeatingCapacity;
8492 9 : sizerHeatingCapacity.overrideSizingString(SizingString);
8493 9 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8494 9 : TempSize = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
8495 9 : thisDXCoil.MSRatedTotCap(Mode) = TempSize;
8496 9 : }
8497 16 : PrintFlag = false;
8498 16 : state.dataSize->DataEMSOverrideON = false;
8499 16 : state.dataSize->DataEMSOverride = 0.0;
8500 16 : state.dataSize->DataIsDXCoil = false;
8501 16 : state.dataSize->DataFlowUsedForSizing = 0.0;
8502 16 : state.dataSize->DataCoolCoilCap = 0.0;
8503 16 : state.dataSize->DataTotCapCurveIndex = 0;
8504 16 : state.dataSize->DataConstantUsedForSizing = 0.0;
8505 16 : state.dataSize->DataFractionUsedForSizing = 0.0;
8506 : }
8507 : // Ensure capacity at lower speed must be lower or equal to the capacity at higher speed.
8508 16 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8509 9 : if (thisDXCoil.MSRatedTotCap(Mode) > thisDXCoil.MSRatedTotCap(Mode + 1)) {
8510 0 : ShowWarningError(state,
8511 0 : format("SizeDXCoil: {} {}, Speed {} Rated Total Heating Capacity must be less than or equal to Speed {} Rated "
8512 : "Total Heating Capacity.",
8513 0 : thisDXCoil.DXCoilType,
8514 0 : thisDXCoil.Name,
8515 : Mode,
8516 0 : Mode + 1));
8517 0 : ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedTotCap(Mode), thisDXCoil.MSRatedTotCap(Mode + 1)));
8518 0 : ShowFatalError(state, "Preceding conditions cause termination.");
8519 : }
8520 : }
8521 :
8522 : // Resistive Defrost Heater Capacity = capacity at the first stage
8523 : // Sizing defrost heater capacity
8524 7 : IsAutoSize = false;
8525 7 : if (thisDXCoil.DefrostCapacity == AutoSize) {
8526 6 : IsAutoSize = true;
8527 : }
8528 7 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
8529 2 : DefrostCapacityDes = thisDXCoil.MSRatedTotCap(1);
8530 : } else {
8531 5 : DefrostCapacityDes = 0.0;
8532 : }
8533 7 : if (IsAutoSize) {
8534 6 : thisDXCoil.DefrostCapacity = DefrostCapacityDes;
8535 6 : BaseSizer::reportSizerOutput(
8536 : state, thisDXCoil.DXCoilType, thisDXCoil.Name, "Design Size Resistive Defrost Heater Capacity", DefrostCapacityDes);
8537 : } else {
8538 1 : if (thisDXCoil.DefrostCapacity > 0.0 && DefrostCapacityDes > 0.0 && !HardSizeNoDesRun) {
8539 0 : DefrostCapacityUser = thisDXCoil.DefrostCapacity;
8540 0 : BaseSizer::reportSizerOutput(state,
8541 : thisDXCoil.DXCoilType,
8542 : thisDXCoil.Name,
8543 : "Design Size Resistive Defrost Heater Capacity",
8544 : DefrostCapacityDes,
8545 : "User-Specified Resistive Defrost Heater Capacity",
8546 : DefrostCapacityUser);
8547 0 : if (state.dataGlobal->DisplayExtraWarnings) {
8548 0 : if ((std::abs(DefrostCapacityDes - DefrostCapacityUser) / DefrostCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
8549 0 : ShowWarningMessage(
8550 0 : state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
8551 0 : ShowContinueError(state, format("User-Specified Resistive Defrost Heater Capacity of {:.2R}[W]", DefrostCapacityUser));
8552 0 : ShowContinueError(state,
8553 0 : format("differs from Design Size Resistive Defrost Heater Capacity of {:.2R}[W]", DefrostCapacityDes));
8554 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
8555 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
8556 : }
8557 : }
8558 : }
8559 : }
8560 : }
8561 :
8562 : // Call routine that computes AHRI certified rating for single-speed DX Coils
8563 228 : if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed &&
8564 36 : (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air ||
8565 192 : thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap)) ||
8566 60 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
8567 82 : CalcDXCoilStandardRating(state,
8568 41 : thisDXCoil.Name,
8569 41 : thisDXCoil.DXCoilType,
8570 : thisDXCoil.DXCoilType_Num,
8571 : 1,
8572 41 : thisDXCoil.RatedTotCap(1),
8573 41 : thisDXCoil.RatedCOP(1),
8574 41 : thisDXCoil.CCapFFlow(1),
8575 41 : thisDXCoil.CCapFTemp(1),
8576 41 : thisDXCoil.EIRFFlow(1),
8577 41 : thisDXCoil.EIRFTemp(1),
8578 41 : thisDXCoil.PLFFPLR(1),
8579 41 : thisDXCoil.RatedAirVolFlowRate(1),
8580 41 : thisDXCoil.FanPowerPerEvapAirFlowRate(1),
8581 41 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1),
8582 41 : thisDXCoil.CondenserType,
8583 41 : thisDXCoil.RegionNum,
8584 41 : thisDXCoil.MinOATCompressor,
8585 41 : thisDXCoil.OATempCompressorOn,
8586 41 : thisDXCoil.OATempCompressorOnOffBlank,
8587 41 : thisDXCoil.DefrostControl,
8588 41 : thisDXCoil.ASHRAE127StdRprt);
8589 : }
8590 : // Call routine that computes AHRI certified rating for multi-speed DX cooling Coils
8591 96 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
8592 68 : CalcDXCoilStandardRating(state,
8593 17 : thisDXCoil.Name,
8594 17 : thisDXCoil.DXCoilType,
8595 : thisDXCoil.DXCoilType_Num,
8596 : thisDXCoil.NumOfSpeeds,
8597 : thisDXCoil.MSRatedTotCap,
8598 : thisDXCoil.MSRatedCOP,
8599 : thisDXCoil.MSCCapFFlow,
8600 : thisDXCoil.MSCCapFTemp,
8601 : thisDXCoil.MSEIRFFlow,
8602 : thisDXCoil.MSEIRFTemp,
8603 : thisDXCoil.MSPLFFPLR,
8604 : thisDXCoil.MSRatedAirVolFlowRate,
8605 : thisDXCoil.MSFanPowerPerEvapAirFlowRate,
8606 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023,
8607 17 : thisDXCoil.CondenserType,
8608 17 : thisDXCoil.RegionNum,
8609 17 : thisDXCoil.MinOATCompressor,
8610 17 : thisDXCoil.OATempCompressorOn,
8611 17 : thisDXCoil.OATempCompressorOnOffBlank,
8612 17 : thisDXCoil.DefrostControl,
8613 34 : ObjexxFCL::Optional_bool_const());
8614 : }
8615 :
8616 98 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed && (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air ||
8617 2 : thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap)) {
8618 8 : StandardRatings::CalcTwoSpeedDXCoilRating(state,
8619 4 : thisDXCoil.Name,
8620 4 : thisDXCoil.DXCoilType,
8621 : thisDXCoil.DXCoilType_Num,
8622 : thisDXCoil.RatedTotCap,
8623 : thisDXCoil.RatedTotCap2,
8624 : thisDXCoil.RatedCOP,
8625 : thisDXCoil.RatedCOP2,
8626 : thisDXCoil.CCapFFlow, // High Speed
8627 : thisDXCoil.CCapFTemp,
8628 : thisDXCoil.CCapFTemp2,
8629 : thisDXCoil.EIRFFlow, // High Speed
8630 : thisDXCoil.EIRFTemp,
8631 : thisDXCoil.EIRFTemp2,
8632 : thisDXCoil.RatedAirVolFlowRate,
8633 : thisDXCoil.RatedAirVolFlowRate2,
8634 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023,
8635 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023_LowSpeed,
8636 4 : thisDXCoil.CondenserType,
8637 4 : thisDXCoil.PLFFPLR(1));
8638 : }
8639 :
8640 : // create predefined report entries
8641 96 : equipName = thisDXCoil.Name;
8642 : // put tables for cooling and heating separate
8643 96 : switch (thisDXCoil.DXCoilType_Num) {
8644 50 : case HVAC::CoilDX_CoolingSingleSpeed:
8645 : case HVAC::CoilDX_CoolingTwoSpeed:
8646 : case HVAC::CoilDX_CoolingTwoStageWHumControl:
8647 : case HVAC::CoilDX_MultiSpeedCooling: {
8648 50 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilType, equipName, thisDXCoil.DXCoilType);
8649 50 : if (thisDXCoil.NumOfSpeeds == 0) {
8650 40 : if (thisDXCoil.NumCapacityStages == 1) {
8651 40 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.RatedTotCap(1));
8652 80 : PreDefTableEntry(
8653 40 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1));
8654 80 : PreDefTableEntry(state,
8655 40 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
8656 : equipName,
8657 40 : thisDXCoil.RatedTotCap(1) - thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1));
8658 40 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.RatedSHR(1));
8659 40 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.RatedCOP(1));
8660 : } else {
8661 0 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.RatedTotCap(2));
8662 0 : PreDefTableEntry(
8663 0 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.RatedTotCap(2) * thisDXCoil.RatedSHR(2));
8664 0 : PreDefTableEntry(state,
8665 0 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
8666 : equipName,
8667 0 : thisDXCoil.RatedTotCap(2) - thisDXCoil.RatedTotCap(2) * thisDXCoil.RatedSHR(2));
8668 0 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.RatedSHR(2));
8669 0 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.RatedCOP(2));
8670 : }
8671 : } else {
8672 31 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8673 21 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.MSRatedTotCap(Mode));
8674 42 : PreDefTableEntry(
8675 21 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.MSRatedTotCap(Mode) * thisDXCoil.MSRatedSHR(Mode));
8676 42 : PreDefTableEntry(state,
8677 21 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
8678 : equipName,
8679 21 : thisDXCoil.MSRatedTotCap(Mode) - thisDXCoil.MSRatedTotCap(Mode) * thisDXCoil.MSRatedSHR(Mode));
8680 21 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.MSRatedSHR(Mode));
8681 21 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.MSRatedCOP(Mode));
8682 : }
8683 : }
8684 100 : addFootNoteSubTable(state,
8685 50 : state.dataOutRptPredefined->pdstCoolCoil,
8686 : "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
8687 50 : } break;
8688 20 : case HVAC::CoilDX_HeatingEmpirical:
8689 : case HVAC::CoilDX_MultiSpeedHeating:
8690 : case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
8691 : case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
8692 20 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilType, equipName, thisDXCoil.DXCoilType);
8693 20 : if (thisDXCoil.NumOfSpeeds == 0) {
8694 13 : if (thisDXCoil.NumCapacityStages == 1) {
8695 13 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.RatedTotCap(1));
8696 13 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.RatedCOP(1));
8697 : } else {
8698 0 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.RatedTotCap(2));
8699 0 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.RatedCOP(2));
8700 : }
8701 : } else {
8702 23 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8703 16 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.MSRatedTotCap(Mode));
8704 16 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.MSRatedCOP(Mode));
8705 : }
8706 : }
8707 40 : addFootNoteSubTable(state,
8708 20 : state.dataOutRptPredefined->pdstHeatCoil,
8709 : "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
8710 :
8711 : // std 229 existing table DX Heating coil new reporting variables
8712 40 : OutputReportPredefined::PreDefTableEntry(
8713 20 : state, state.dataOutRptPredefined->pdchDXHeatCoilMinOADBTforCompOp, equipName, thisDXCoil.MinOATCompressor);
8714 40 : OutputReportPredefined::PreDefTableEntry(state,
8715 20 : state.dataOutRptPredefined->pdchDXHeatCoilAirloopName,
8716 : equipName,
8717 60 : thisDXCoil.AirLoopNum > 0 ? state.dataAirSystemsData->PrimaryAirSystems(thisDXCoil.AirLoopNum).Name
8718 : : "N/A");
8719 : // std 229 existing table DX Heating coil 2023 AHRI new reporting variables
8720 40 : OutputReportPredefined::PreDefTableEntry(
8721 20 : state, state.dataOutRptPredefined->pdchDXHeatCoilMinOADBTforCompOp_2023, equipName, thisDXCoil.MinOATCompressor);
8722 40 : OutputReportPredefined::PreDefTableEntry(state,
8723 20 : state.dataOutRptPredefined->pdchDXHeatCoilAirloopName_2023,
8724 : equipName,
8725 60 : thisDXCoil.AirLoopNum > 0 ? state.dataAirSystemsData->PrimaryAirSystems(thisDXCoil.AirLoopNum).Name
8726 : : "N/A");
8727 20 : } break;
8728 26 : default:
8729 26 : break;
8730 : }
8731 96 : }
8732 :
8733 178 : void CalcHPWHDXCoil(EnergyPlusData &state,
8734 : int const DXCoilNum, // the number of the DX coil to be simulated
8735 : Real64 const PartLoadRatio // sensible water heating load / full load sensible water heating capacity
8736 : )
8737 : {
8738 :
8739 : // SUBROUTINE INFORMATION:
8740 : // AUTHOR Richard Raustad
8741 : // DATE WRITTEN May 2005
8742 :
8743 : // PURPOSE OF THIS SUBROUTINE:
8744 : // Calculates the gross cooling capacity of a heat pump water heater evaporator and
8745 : // heating capacity of the condenser coil given the rated heating capacity and COP.
8746 :
8747 : // METHODOLOGY EMPLOYED:
8748 : // The routine requires the user to enter the total heating capacity and COP for the
8749 : // heat pump water heater along with logicals defining if fan and condenser pump are included.
8750 : // Since manufacturer's can rate their HPWH equipment with or without including condenser
8751 : // pump heat, this information is required to accurately determine the condenser's leaving
8752 : // water temperature. In addition, knowledge of the fan heat is required to back into
8753 : // a compressor COP.
8754 :
8755 : // Using/Aliasing
8756 : using Curve::CurveValue;
8757 :
8758 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8759 : Real64 RatedHeatingCapacity; // Water heating rated capacity with or without condenser water pump heat (W)
8760 : Real64 RatedHeatingCOP; // Water heating rated COP with or without evap fan and cond water pump heat (W/W)
8761 : Real64 OperatingHeatingCapacity; // Water heating operating capacity including the impact of capacity and COP curves (W)
8762 : Real64 OperatingHeatingCOP; // Water heating operating COP including the impact of capacity and COP curves (W/W)
8763 : Real64 OperatingHeatingPower; // Water heating operating Power (W)
8764 : Real64 CompressorPower; // Power consumed by compressor only (W)
8765 :
8766 : Real64 TotalTankHeatingCapacity; // Water heating capacity corrected for condenser water pump heat (W)
8767 : Real64 TankHeatingCOP; // Water heating COP corrected for fan and condenser water pump power (W/W)
8768 : // (these previous 2 variables also include the impact of capacity and COP curves)
8769 : Real64 EvapCoolingCapacity; // Air cooling capacity corrected for evap fan and cond water pump heat (W)
8770 : Real64 InletWaterTemp; // Condenser water inlet temperature (C)
8771 : Real64 OutletWaterTemp; // Condenser water outlet temperature (C)
8772 : Real64 EvapInletMassFlowRate; // Evaporator air inlet mass flow rate (m3/s)
8773 : Real64 CondInletMassFlowRate; // Condenser water inlet mass flow rate (m3/s)
8774 : Real64 CpWater; // Specific heat of condenser inlet water (J/Kg/k)
8775 : Real64 InletAirTemp; // HPWH inlet air temperature (dry-bulb or wet-bulb) (C)
8776 : Real64 HeatCapFTemp; // Output of HPWH Heating Capacity as a Function of Temperature curve
8777 : Real64 HeatCapFAirFlow; // Output of HPWH Heating Capacity as a Function of Air Flow Rate Ratio curve
8778 : Real64 HeatCapFWaterFlow; // Output of HPWH Heating Capacity as a Function of Water Flow Rate Ratio curve
8779 : Real64 HeatCOPFTemp; // Output of HPWH COP as a Function of Temperature curve
8780 : Real64 HeatCOPFAirFlow; // Output of HPWH COP as a Function of Air Flow Rate Ratio curve
8781 : Real64 HeatCOPFWaterFlow; // Output of HPWH COP as a Function of Water Flow Rate Ratio curve
8782 : Real64 AirFlowRateRatio; // Ratio of evaporator inlet air mass flow rate to rated mass flow rate
8783 : Real64 WaterFlowRateRatio; // Ratio of evaporator inlet water mass flow rate to rated mass flow rate
8784 : Real64 PartLoadFraction; // Output of Part Load Fraction as a Function of Part Load Ratio curve
8785 : Real64 PumpHeatToWater; // Amount of pump heat attributed to heating water
8786 : Real64 HPRTF; // Heat pump run time fraction
8787 :
8788 : // References to Coil and Node struct
8789 178 : DXCoilData &Coil = state.dataDXCoils->DXCoil(DXCoilNum);
8790 178 : NodeData &AirInletNode = state.dataLoopNodes->Node(Coil.AirInNode);
8791 178 : NodeData &WaterInletNode = state.dataLoopNodes->Node(Coil.WaterInNode);
8792 178 : NodeData &WaterOutletNode = state.dataLoopNodes->Node(Coil.WaterOutNode);
8793 :
8794 : // If heat pump water heater is OFF, set outlet to inlet and RETURN
8795 : // Also set the heating energy rate to zero
8796 178 : if (PartLoadRatio == 0.0) {
8797 8 : WaterOutletNode = WaterInletNode;
8798 8 : Coil.TotalHeatingEnergyRate = 0.0;
8799 8 : return;
8800 : } else {
8801 170 : RatedHeatingCapacity = Coil.RatedTotCap2;
8802 170 : RatedHeatingCOP = Coil.RatedCOP(1);
8803 170 : InletWaterTemp = WaterInletNode.Temp;
8804 170 : CondInletMassFlowRate = WaterInletNode.MassFlowRate / PartLoadRatio;
8805 170 : EvapInletMassFlowRate = AirInletNode.MassFlowRate / PartLoadRatio;
8806 170 : CpWater = CPHW(InletWaterTemp);
8807 170 : CompressorPower = 0.0;
8808 170 : OperatingHeatingPower = 0.0;
8809 170 : TankHeatingCOP = 0.0;
8810 : }
8811 :
8812 : // determine inlet air temperature type for curve objects
8813 170 : if (Coil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
8814 170 : InletAirTemp = state.dataHVACGlobal->HPWHInletWBTemp;
8815 : } else {
8816 0 : InletAirTemp = state.dataHVACGlobal->HPWHInletDBTemp;
8817 : }
8818 :
8819 : // get output of Heating Capacity and Heating COP curves (curves default to 1 if user has not specified curve name)
8820 170 : if (Coil.HCapFTemp > 0) {
8821 170 : if (state.dataCurveManager->curves(Coil.HCapFTemp)->numDims == 1) {
8822 0 : HeatCapFTemp = CurveValue(state, Coil.HCapFTemp, InletAirTemp);
8823 : } else {
8824 170 : HeatCapFTemp = CurveValue(state, Coil.HCapFTemp, InletAirTemp, InletWaterTemp);
8825 : }
8826 : // Warn user if curve output goes negative
8827 170 : if (HeatCapFTemp < 0.0) {
8828 0 : if (Coil.HCapFTempErrorIndex == 0) {
8829 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8830 0 : ShowContinueError(
8831 0 : state, format(" HPWH Heating Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", HeatCapFTemp));
8832 0 : if (state.dataCurveManager->curves(Coil.HCapFTemp)->numDims == 2) {
8833 0 : ShowContinueError(
8834 : state,
8835 0 : format(" Negative value occurs using an inlet air temperature of {:.1T} and an inlet water temperature of {:.1T}.",
8836 : InletAirTemp,
8837 : InletWaterTemp));
8838 : } else {
8839 0 : ShowContinueError(state, format(" Negative value occurs using an inlet air temperature of {:.1T}.", InletAirTemp));
8840 : }
8841 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8842 : }
8843 0 : ShowRecurringWarningErrorAtEnd(
8844 : state,
8845 0 : Coil.DXCoilType + " \"" + Coil.Name +
8846 : "\": HPWH Heating Capacity Modifier curve (function of temperature) output is negative warning continues...",
8847 0 : Coil.HCapFTempErrorIndex,
8848 : HeatCapFTemp,
8849 : HeatCapFTemp,
8850 : _,
8851 : "[C]",
8852 : "[C]");
8853 0 : HeatCapFTemp = 0.0;
8854 : }
8855 : } else {
8856 0 : HeatCapFTemp = 1.0;
8857 : }
8858 :
8859 170 : if (Coil.HCOPFTemp > 0) {
8860 170 : if (state.dataCurveManager->curves(Coil.HCOPFTemp)->numDims == 1) {
8861 0 : HeatCOPFTemp = CurveValue(state, Coil.HCOPFTemp, InletAirTemp);
8862 : } else {
8863 170 : HeatCOPFTemp = CurveValue(state, Coil.HCOPFTemp, InletAirTemp, InletWaterTemp);
8864 : }
8865 : // Warn user if curve output goes negative
8866 170 : if (HeatCOPFTemp < 0.0) {
8867 0 : if (Coil.HCOPFTempErrorIndex == 0) {
8868 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8869 0 : ShowContinueError(state,
8870 0 : format(" HPWH Heating COP Modifier curve (function of temperature) output is negative ({:.3T}).", HeatCOPFTemp));
8871 0 : if (state.dataCurveManager->curves(Coil.HCOPFTemp)->numDims == 2) {
8872 0 : ShowContinueError(
8873 : state,
8874 0 : format(" Negative value occurs using an inlet air temperature of {:.1T} and an inlet water temperature of {:.1T}.",
8875 : InletAirTemp,
8876 : InletWaterTemp));
8877 : } else {
8878 0 : ShowContinueError(state, format(" Negative value occurs using an inlet air temperature of {:.1T}.", InletAirTemp));
8879 : }
8880 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8881 : }
8882 0 : ShowRecurringWarningErrorAtEnd(
8883 : state,
8884 0 : Coil.DXCoilType + " \"" + Coil.Name +
8885 : "\": HPWH Heating COP Modifier curve (function of temperature) output is negative warning continues...",
8886 0 : Coil.HCOPFTempErrorIndex,
8887 : HeatCOPFTemp,
8888 : HeatCOPFTemp,
8889 : _,
8890 : "[C]",
8891 : "[C]");
8892 0 : HeatCOPFTemp = 0.0;
8893 : }
8894 : } else {
8895 0 : HeatCOPFTemp = 1.0;
8896 : }
8897 :
8898 170 : if (Coil.HCapFAirFlow > 0) {
8899 0 : AirFlowRateRatio = EvapInletMassFlowRate / (Coil.RatedAirMassFlowRate(1));
8900 0 : HeatCapFAirFlow = CurveValue(state, Coil.HCapFAirFlow, AirFlowRateRatio);
8901 : // Warn user if curve output goes negative
8902 0 : if (HeatCapFAirFlow < 0.0) {
8903 0 : if (Coil.HCapFAirFlowErrorIndex == 0) {
8904 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8905 0 : ShowContinueError(
8906 : state,
8907 0 : format(" HPWH Heating Capacity Modifier curve (function of air flow fraction) output is negative ({:.3T}).", HeatCapFAirFlow));
8908 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirFlowRateRatio));
8909 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8910 : }
8911 0 : ShowRecurringWarningErrorAtEnd(
8912 : state,
8913 0 : Coil.DXCoilType + " \"" + Coil.Name +
8914 : "\": HPWH Heating Capacity Modifier curve (function of air flow fraction) output is negative warning continues...",
8915 0 : Coil.HCapFAirFlowErrorIndex,
8916 : HeatCapFAirFlow,
8917 : HeatCapFAirFlow);
8918 0 : HeatCapFAirFlow = 0.0;
8919 : }
8920 : } else {
8921 170 : HeatCapFAirFlow = 1.0;
8922 : }
8923 :
8924 170 : if (Coil.HCOPFAirFlow > 0) {
8925 0 : AirFlowRateRatio = EvapInletMassFlowRate / (Coil.RatedAirMassFlowRate(1));
8926 0 : HeatCOPFAirFlow = CurveValue(state, Coil.HCOPFAirFlow, AirFlowRateRatio);
8927 : // Warn user if curve output goes negative
8928 0 : if (HeatCOPFAirFlow < 0.0) {
8929 0 : if (Coil.HCOPFAirFlowErrorIndex == 0) {
8930 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8931 0 : ShowContinueError(
8932 0 : state, format(" HPWH Heating COP Modifier curve (function of air flow fraction) output is negative ({:.3T}).", HeatCOPFAirFlow));
8933 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirFlowRateRatio));
8934 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8935 : }
8936 0 : ShowRecurringWarningErrorAtEnd(
8937 : state,
8938 0 : Coil.DXCoilType + " \"" + Coil.Name +
8939 : "\": HPWH Heating COP Modifier curve (function of air flow fraction) output is negative warning continues...",
8940 0 : Coil.HCOPFAirFlowErrorIndex,
8941 : HeatCOPFAirFlow,
8942 : HeatCOPFAirFlow);
8943 0 : HeatCOPFAirFlow = 0.0;
8944 : }
8945 : } else {
8946 170 : HeatCOPFAirFlow = 1.0;
8947 : }
8948 :
8949 170 : if (Coil.HCapFWaterFlow > 0) {
8950 0 : WaterFlowRateRatio = CondInletMassFlowRate / (Coil.RatedHPWHCondWaterFlow * RhoH2O(InletWaterTemp));
8951 0 : HeatCapFWaterFlow = CurveValue(state, Coil.HCapFWaterFlow, WaterFlowRateRatio);
8952 : // Warn user if curve output goes negative
8953 0 : if (HeatCapFWaterFlow < 0.0) {
8954 0 : if (Coil.HCapFWaterFlowErrorIndex == 0) {
8955 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8956 0 : ShowContinueError(state,
8957 0 : format(" HPWH Heating Capacity Modifier curve (function of water flow fraction) output is negative ({:.3T}).",
8958 : HeatCapFWaterFlow));
8959 0 : ShowContinueError(state, format(" Negative value occurs using a water flow fraction of {:.3T}.", WaterFlowRateRatio));
8960 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8961 : }
8962 0 : ShowRecurringWarningErrorAtEnd(
8963 : state,
8964 0 : Coil.DXCoilType + " \"" + Coil.Name +
8965 : "\": HPWH Heating Capacity Modifier curve (function of water flow fraction) output is negative warning continues...",
8966 0 : Coil.HCapFWaterFlowErrorIndex,
8967 : HeatCapFWaterFlow,
8968 : HeatCapFWaterFlow);
8969 0 : HeatCapFWaterFlow = 0.0;
8970 : }
8971 : } else {
8972 170 : HeatCapFWaterFlow = 1.0;
8973 : }
8974 :
8975 170 : if (Coil.HCOPFWaterFlow > 0) {
8976 0 : WaterFlowRateRatio = CondInletMassFlowRate / (Coil.RatedHPWHCondWaterFlow * RhoH2O(InletWaterTemp));
8977 0 : HeatCOPFWaterFlow = CurveValue(state, Coil.HCOPFWaterFlow, WaterFlowRateRatio);
8978 : // Warn user if curve output goes negative
8979 0 : if (HeatCOPFWaterFlow < 0.0) {
8980 0 : if (Coil.HCOPFWaterFlowErrorIndex == 0) {
8981 0 : ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
8982 0 : ShowContinueError(
8983 : state,
8984 0 : format(" HPWH Heating COP Modifier curve (function of water flow fraction) output is negative ({:.3T}).", HeatCOPFWaterFlow));
8985 0 : ShowContinueError(state, format(" Negative value occurs using a water flow fraction of {:.3T}.", WaterFlowRateRatio));
8986 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
8987 : }
8988 0 : ShowRecurringWarningErrorAtEnd(
8989 : state,
8990 0 : Coil.DXCoilType + " \"" + Coil.Name +
8991 : "\": HPWH Heating COP Modifier curve (function of water flow fraction) output is negative warning continues...",
8992 0 : Coil.HCOPFWaterFlowErrorIndex,
8993 : HeatCOPFWaterFlow,
8994 : HeatCOPFWaterFlow);
8995 0 : HeatCOPFWaterFlow = 0.0;
8996 : }
8997 : } else {
8998 170 : HeatCOPFWaterFlow = 1.0;
8999 : }
9000 :
9001 : // adjust Heating Capacity and COP for off-design conditions
9002 170 : OperatingHeatingCapacity = RatedHeatingCapacity * HeatCapFTemp * HeatCapFAirFlow * HeatCapFWaterFlow;
9003 170 : OperatingHeatingCOP = RatedHeatingCOP * HeatCOPFTemp * HeatCOPFAirFlow * HeatCOPFWaterFlow;
9004 :
9005 170 : if (OperatingHeatingCOP > 0.0) {
9006 170 : OperatingHeatingPower = OperatingHeatingCapacity / OperatingHeatingCOP;
9007 : }
9008 :
9009 170 : PumpHeatToWater = Coil.HPWHCondPumpElecNomPower * Coil.HPWHCondPumpFracToWater;
9010 170 : TankHeatingCOP = OperatingHeatingCOP;
9011 :
9012 : // account for pump heat if not included in total water heating capacity
9013 170 : if (Coil.CondPumpHeatInCapacity) {
9014 0 : TotalTankHeatingCapacity = OperatingHeatingCapacity;
9015 : } else {
9016 170 : TotalTankHeatingCapacity = OperatingHeatingCapacity + PumpHeatToWater;
9017 : }
9018 :
9019 : // find part load fraction to calculate RTF
9020 170 : if (Coil.PLFFPLR(1) > 0) {
9021 162 : PartLoadFraction = max(0.7, CurveValue(state, Coil.PLFFPLR(1), PartLoadRatio));
9022 : } else {
9023 8 : PartLoadFraction = 1.0;
9024 : }
9025 :
9026 170 : HPRTF = min(1.0, (PartLoadRatio / PartLoadFraction));
9027 :
9028 170 : Real64 locFanElecPower = state.dataFans->fans(Coil.SupplyFanIndex)->totalPower;
9029 :
9030 : // calculate evaporator total cooling capacity
9031 170 : if (HPRTF > 0.0) {
9032 170 : if (Coil.FanPowerIncludedInCOP) {
9033 8 : if (Coil.CondPumpPowerInCOP) {
9034 : // make sure fan power is full load fan power
9035 0 : CompressorPower = OperatingHeatingPower - locFanElecPower / HPRTF - Coil.HPWHCondPumpElecNomPower;
9036 0 : if (OperatingHeatingPower > 0.0) {
9037 0 : TankHeatingCOP = TotalTankHeatingCapacity / OperatingHeatingPower;
9038 : }
9039 : } else {
9040 8 : CompressorPower = OperatingHeatingPower - locFanElecPower / HPRTF;
9041 8 : if ((OperatingHeatingPower + Coil.HPWHCondPumpElecNomPower) > 0.0) {
9042 8 : TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + Coil.HPWHCondPumpElecNomPower);
9043 : }
9044 : }
9045 : } else {
9046 162 : if (Coil.CondPumpPowerInCOP) {
9047 : // make sure fan power is full load fan power
9048 0 : CompressorPower = OperatingHeatingPower - Coil.HPWHCondPumpElecNomPower;
9049 0 : if ((OperatingHeatingPower + locFanElecPower / HPRTF) > 0.0) {
9050 0 : TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + locFanElecPower / HPRTF);
9051 : }
9052 : } else {
9053 162 : CompressorPower = OperatingHeatingPower;
9054 162 : if ((OperatingHeatingPower + locFanElecPower / HPRTF + Coil.HPWHCondPumpElecNomPower) > 0.0) {
9055 162 : TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + locFanElecPower / HPRTF + Coil.HPWHCondPumpElecNomPower);
9056 : }
9057 : }
9058 : }
9059 : }
9060 :
9061 170 : if (Coil.CondPumpHeatInCapacity) {
9062 0 : EvapCoolingCapacity = TotalTankHeatingCapacity - PumpHeatToWater - CompressorPower;
9063 : } else {
9064 170 : EvapCoolingCapacity = TotalTankHeatingCapacity - CompressorPower;
9065 : }
9066 :
9067 : // set evaporator total cooling capacity prior to CalcDOE2DXCoil subroutine
9068 170 : Coil.RatedTotCap(1) = EvapCoolingCapacity;
9069 :
9070 : // determine condenser water inlet/outlet condition at full capacity
9071 170 : if (CondInletMassFlowRate == 0.0) {
9072 8 : OutletWaterTemp = InletWaterTemp;
9073 : } else {
9074 162 : OutletWaterTemp = InletWaterTemp + TotalTankHeatingCapacity / (CpWater * CondInletMassFlowRate);
9075 : }
9076 :
9077 170 : WaterOutletNode.Temp = OutletWaterTemp;
9078 :
9079 170 : WaterOutletNode.MassFlowRate = WaterInletNode.MassFlowRate;
9080 :
9081 : // send heating capacity and COP to water heater module for standards rating calculation
9082 : // total heating capacity including condenser pump
9083 170 : state.dataDXCoils->HPWHHeatingCapacity = TotalTankHeatingCapacity;
9084 : // total heating COP including compressor, fan, and condenser pump
9085 170 : state.dataDXCoils->HPWHHeatingCOP = TankHeatingCOP;
9086 :
9087 : // send DX coil total cooling capacity to HPWH for reporting
9088 170 : state.dataHVACGlobal->DXCoilTotalCapacity = EvapCoolingCapacity;
9089 :
9090 170 : Coil.TotalHeatingEnergyRate = TotalTankHeatingCapacity * PartLoadRatio;
9091 :
9092 : // calculate total compressor plus condenser pump power, fan power reported in fan module
9093 170 : Coil.ElecWaterHeatingPower = (CompressorPower + Coil.HPWHCondPumpElecNomPower) * HPRTF;
9094 : }
9095 :
9096 331312 : void CalcDoe2DXCoil(EnergyPlusData &state,
9097 : int const DXCoilNum, // the number of the DX coil to be simulated
9098 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
9099 : bool const FirstHVACIteration, // true if this is the first iteration of HVAC
9100 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
9101 : HVAC::FanOp const fanOp, // Allows parent object to control fan operation
9102 : ObjexxFCL::Optional_int_const PerfMode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
9103 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
9104 : ObjexxFCL::Optional<Real64 const> CoolingHeatingPLR // used for cycling fan RH control
9105 : )
9106 : {
9107 :
9108 : // SUBROUTINE INFORMATION:
9109 : // AUTHOR Fred Buhl
9110 : // DATE WRITTEN May 2000
9111 : // MODIFIED Shirey, Feb/October 2001, Feb/Mar 2004
9112 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
9113 : // Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
9114 : // April 2010 Chandan Sharma, FSEC, Added basin heater
9115 : // RE-ENGINEERED Don Shirey, Aug/Sept 2000
9116 :
9117 : // PURPOSE OF THIS SUBROUTINE:
9118 : // Calculates the air-side performance and electrical energy use of a direct-
9119 : // expansion, air-cooled cooling unit.
9120 :
9121 : // METHODOLOGY EMPLOYED:
9122 : // This routine simulates the performance of air-cooled DX cooling equipment.
9123 : // The routine requires the user to enter the total cooling capacity, sensible heat ratio,
9124 : // and COP for the unit at ARI 210/240 rating conditions (26.67C [80F] dry-bulb, 19.44C [67F]
9125 : // wet-bulb air entering the cooling coil, 35C [95F] dry-bulb air entering the outdoor
9126 : // condenser. Since different manufacturer's rate their equipment at different air flow rates,
9127 : // the supply air flow rate corresponding to the rated capacities and rated COP must also be
9128 : // entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information entered by
9129 : // the user should NOT include the thermal or electrical impacts of the supply air fan, as
9130 : // this is addressed by another module.
9131 :
9132 : // With the rated performance data entered by the user, the model employs some of the
9133 : // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
9134 : // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
9135 : // does NOT employ the exact same methodology to calculate performance as DOE-2, although
9136 : // some of the DOE-2 curve fits are employed by this model.
9137 :
9138 : // The model checks for coil dryout conditions, and adjusts the calculated performance
9139 : // appropriately.
9140 :
9141 : // REFERENCES:
9142 : // ASHRAE HVAC 2 Toolkit page 4-81.
9143 : // Henderson, H.I. Jr., K. Rengarajan and D.B. Shirey, III. 1992.The impact of comfort
9144 : // control on air conditioner energy use in humid climates. ASHRAE Transactions 98(2):
9145 : // 104-113.
9146 : // Henderson, H.I. Jr., Danny Parker and Y.J. Huang. 2000.Improving DOE-2's RESYS routine:
9147 : // User Defined Functions to Provide More Accurate Part Load Energy Use and Humidity
9148 : // Predictions. Proceedings of ACEEE Conference.
9149 :
9150 : // Using/Aliasing
9151 : using Curve::CurveValue;
9152 331312 : Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
9153 331312 : Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
9154 : using General::CreateSysTimeIntervalString;
9155 :
9156 : // SUBROUTINE PARAMETER DEFINITIONS:
9157 : static constexpr std::string_view RoutineName("CalcDoe2DXCoil: ");
9158 : static constexpr std::string_view calcDoe2DXCoil("CalcDoe2DXCoil");
9159 :
9160 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9161 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
9162 : Real64 AirMassFlowRatio; // Ratio of actual air mass flow to rated air mass flow (adjusted for bypass if any)
9163 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
9164 : // (average flow if cycling fan, full flow if constant fan)
9165 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
9166 : Real64 BypassFlowFraction; // Fraction of total flow which is bypassed around the cooling coil
9167 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
9168 : Real64 TotCapTempModFac; // Total capacity modifier (function of entering wetbulb, outside drybulb)
9169 : Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs rated flow)
9170 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
9171 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
9172 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
9173 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
9174 : Real64 InletAirHumRatTemp; // inlet air humidity ratio used in ADP/BF loop [kg/kg]
9175 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9176 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
9177 : Real64 RatedCBF; // coil bypass factor at rated conditions
9178 : Real64 SHR; // Sensible Heat Ratio (sensible/total) of the cooling coil
9179 : Real64 CBF; // coil bypass factor at off rated conditions
9180 : Real64 A0; // NTU * air mass flow rate, used in CBF calculation
9181 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
9182 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
9183 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
9184 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
9185 : Real64 tADP; // Apparatus dew point temperature [C]
9186 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
9187 : Real64 FullLoadOutAirEnth; // outlet full load enthalpy [J/kg]
9188 : Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
9189 : Real64 FullLoadOutAirTemp; // outlet air temperature at full load [C]
9190 : Real64 EIRTempModFac; // EIR modifier (function of entering wetbulb, outside drybulb)
9191 : Real64 EIRFlowModFac; // EIR modifier (function of actual supply air flow vs rated flow)
9192 : Real64 EIR; // EIR at part load and off rated conditions
9193 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
9194 : Real64 QLatActual; // operating latent capacity of DX coil
9195 : Real64 QLatRated; // Rated latent capacity of DX coil
9196 : Real64 SHRUnadjusted; // SHR prior to latent degradation effective SHR calculation
9197 : int Counter; // Counter for dry evaporator iterations
9198 : int MaxIter; // Maximum number of iterations for dry evaporator calculations
9199 : Real64 RF; // Relaxation factor for dry evaporator iterations
9200 : Real64 Tolerance; // Error tolerance for dry evaporator iterations
9201 : Real64 werror; // Deviation of humidity ratio in dry evaporator iteration loop
9202 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
9203 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
9204 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
9205 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
9206 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
9207 : Real64 RhoAir; // Density of air [kg/m3]
9208 : Real64 RhoWater; // Density of water [kg/m3]
9209 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
9210 331312 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
9211 : Real64 AirFlowRatio; // ratio of compressor on airflow to average timestep airflow
9212 : // used when constant fan mode yields different air flow rates when compressor is ON and OFF
9213 : // (e.g. Packaged Terminal Heat Pump)
9214 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
9215 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
9216 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
9217 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
9218 :
9219 : int Mode; // Performance mode for Multimode DX coil; Always 1 for other coil types
9220 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
9221 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
9222 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
9223 : Real64 ADiff; // Used for exponential
9224 : Real64 DXcoolToHeatPLRRatio; // ratio of cooling PLR to heating PLR, used for cycling fan RH control
9225 : Real64 HeatRTF; // heating coil part-load ratio, used for cycling fan RH control
9226 : Real64 HeatingCoilPLF; // heating coil PLF (function of PLR), used for cycling fan RH control
9227 :
9228 : // If Performance mode not present, then set to 1. Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
9229 331312 : if (present(PerfMode)) {
9230 0 : Mode = PerfMode;
9231 : } else {
9232 331312 : Mode = 1;
9233 : }
9234 :
9235 : // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
9236 : // during cooling and when no cooling is required (constant fan, fan speed changes)
9237 331312 : if (present(OnOffAirFlowRatio)) {
9238 247143 : AirFlowRatio = OnOffAirFlowRatio;
9239 : } else {
9240 84169 : AirFlowRatio = 1.0;
9241 : }
9242 :
9243 : // If CoolingHeatingPLR not present, then set to 1. Used for cycling fan systems where
9244 : // heating PLR is greater than cooling PLR, otherwise CoolingHeatingPLR = 1.
9245 331312 : if (present(CoolingHeatingPLR)) {
9246 59945 : DXcoolToHeatPLRRatio = CoolingHeatingPLR;
9247 : } else {
9248 271367 : DXcoolToHeatPLRRatio = 1.0;
9249 : }
9250 :
9251 331312 : MaxIter = 30;
9252 331312 : RF = 0.4;
9253 331312 : Counter = 0;
9254 331312 : Tolerance = 0.01;
9255 331312 : CondInletTemp = 0.0;
9256 331312 : CondInletHumRat = 0.0;
9257 :
9258 331312 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
9259 :
9260 331312 : BypassFlowFraction = thisDXCoil.BypassedFlowFrac(Mode);
9261 331312 : AirMassFlow = thisDXCoil.InletAirMassFlowRate * (1.0 - BypassFlowFraction);
9262 331312 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
9263 331312 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
9264 331312 : InletAirHumRat = thisDXCoil.InletAirHumRat;
9265 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9266 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
9267 331312 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
9268 331312 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
9269 331312 : thisDXCoil.PartLoadRatio = 0.0;
9270 331312 : thisDXCoil.BasinHeaterPower = 0.0;
9271 :
9272 331312 : if (thisDXCoil.CondenserType(Mode) != DataHeatBalance::RefrigCondenserType::WaterHeater) {
9273 331149 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
9274 117452 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
9275 : // If node is not connected to anything, pressure = default, use weather data
9276 117452 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
9277 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
9278 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
9279 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9280 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
9281 : } else {
9282 117452 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
9283 117452 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
9284 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
9285 117452 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
9286 : }
9287 : } else {
9288 213697 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
9289 213697 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
9290 213697 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9291 213697 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
9292 : }
9293 331149 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
9294 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
9295 0 : OutdoorDryBulb = secZoneHB.ZT;
9296 0 : OutdoorHumRat = secZoneHB.airHumRat;
9297 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
9298 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9299 : }
9300 : } else {
9301 163 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
9302 163 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
9303 : // If node is not connected to anything, pressure = default, use weather data
9304 163 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
9305 163 : OutdoorPressure = state.dataEnvrn->OutBaroPress; // node not connected
9306 : }
9307 : } else {
9308 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9309 : }
9310 : }
9311 :
9312 331312 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
9313 263297 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
9314 263297 : CompAmbTemp = OutdoorDryBulb;
9315 263297 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
9316 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
9317 0 : CondInletTemp = secZoneHB.ZT;
9318 0 : CompAmbTemp = CondInletTemp; // assumes compressor is in same location as secondary coil
9319 0 : OutdoorDryBulb = CondInletTemp;
9320 0 : OutdoorHumRat = secZoneHB.airHumRat;
9321 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
9322 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9323 : }
9324 68015 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
9325 67852 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
9326 67852 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
9327 : // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
9328 67852 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
9329 67852 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
9330 67852 : CompAmbTemp = OutdoorDryBulb;
9331 163 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::WaterHeater) {
9332 163 : CompAmbTemp = state.dataHVACGlobal->HPWHCrankcaseDBTemp; // Temperature at HP water heater compressor
9333 163 : CondInletTemp = state.dataHVACGlobal->HPWHCrankcaseDBTemp; // Temperature at HP water heater compressor
9334 : }
9335 :
9336 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
9337 : // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
9338 331312 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
9339 82507 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
9340 82507 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
9341 3 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
9342 : }
9343 : } else {
9344 248805 : CrankcaseHeatingPower = 0.0;
9345 : }
9346 :
9347 : // calculate end time of current time step to determine if error messages should be printed
9348 331312 : state.dataDXCoils->CurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
9349 :
9350 : // Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
9351 : // Wait for next time step to print warnings. If simulation iterates, print out
9352 : // the warning for the last iteration only. Must wait for next time step to accomplish this.
9353 : // If a warning occurs and the simulation down shifts, the warning is not valid.
9354 :
9355 331312 : if (thisDXCoil.PrintLowAmbMessage) { // .AND. &
9356 240 : if (state.dataDXCoils->CurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
9357 0 : if (thisDXCoil.LowAmbErrIndex == 0) {
9358 0 : ShowWarningMessage(state, format("{}{}", RoutineName, thisDXCoil.LowAmbBuffer1));
9359 0 : ShowContinueError(state, thisDXCoil.LowAmbBuffer2);
9360 0 : ShowContinueError(state, "... Operation at low ambient temperatures may require special performance curves.");
9361 : }
9362 0 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
9363 0 : ShowRecurringWarningErrorAtEnd(state,
9364 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9365 : "\" - Low condenser dry-bulb temperature error continues...",
9366 0 : thisDXCoil.LowAmbErrIndex,
9367 0 : thisDXCoil.LowTempLast,
9368 0 : thisDXCoil.LowTempLast,
9369 : _,
9370 : "[C]",
9371 : "[C]");
9372 : } else {
9373 0 : ShowRecurringWarningErrorAtEnd(state,
9374 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9375 : "\" - Low condenser wet-bulb temperature error continues...",
9376 0 : thisDXCoil.LowAmbErrIndex,
9377 0 : thisDXCoil.LowTempLast,
9378 0 : thisDXCoil.LowTempLast,
9379 : _,
9380 : "[C]",
9381 : "[C]");
9382 : }
9383 : }
9384 : }
9385 :
9386 331312 : if (thisDXCoil.PrintLowOutTempMessage) {
9387 1017 : if (state.dataDXCoils->CurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
9388 376 : if (thisDXCoil.LowOutletTempIndex == 0) {
9389 4 : ShowWarningMessage(state, format("{}{}", RoutineName, thisDXCoil.LowOutTempBuffer1));
9390 4 : ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
9391 8 : ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
9392 8 : ShowContinueError(state,
9393 8 : format(" 1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
9394 4 : thisDXCoil.FullLoadInletAirTempLast));
9395 8 : ShowContinueError(state, " 2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
9396 12 : ShowContinueError(state,
9397 : " 3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
9398 : }
9399 3008 : ShowRecurringWarningErrorAtEnd(state,
9400 1128 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9401 : "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
9402 : "Outlet air temperature statistics follow:",
9403 376 : thisDXCoil.LowOutletTempIndex,
9404 376 : thisDXCoil.FullLoadOutAirTempLast,
9405 376 : thisDXCoil.FullLoadOutAirTempLast);
9406 : }
9407 : }
9408 :
9409 : // save last system time step and last end time of current time step (used to determine if warning is valid)
9410 331312 : thisDXCoil.TimeStepSysLast = TimeStepSys;
9411 331312 : thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CurrentEndTime;
9412 331312 : thisDXCoil.PrintLowAmbMessage = false;
9413 331312 : thisDXCoil.PrintLowOutTempMessage = false;
9414 :
9415 269753 : if ((AirMassFlow > 0.0) &&
9416 269908 : (thisDXCoil.availSched->getCurrentVal() > 0.0 || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9417 3 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
9418 771102 : (PartLoadRatio > 0.0) && (compressorOp == HVAC::CompressorOp::On) &&
9419 170037 : CompAmbTemp > thisDXCoil.MinOATCompressor) { // criteria for coil operation
9420 170031 : if (fanOp == HVAC::FanOp::Cycling) {
9421 57669 : AirMassFlow /= (PartLoadRatio / DXcoolToHeatPLRRatio);
9422 112362 : } else if (fanOp == HVAC::FanOp::Continuous && thisDXCoil.DXCoilType_Num != HVAC::CoilDX_CoolingTwoSpeed) {
9423 112362 : AirMassFlow *= AirFlowRatio;
9424 : } else {
9425 0 : AirMassFlow = thisDXCoil.RatedAirMassFlowRate(Mode);
9426 : }
9427 :
9428 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton)
9429 :
9430 : // for some reason there are diff's when using coil inlet air pressure
9431 : // these lines (more to follow) are commented out for the time being
9432 :
9433 170031 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
9434 170031 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
9435 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9436 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
9437 : // AirVolumeFlowRate = AirMassFlow/ PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
9438 170031 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
9439 0 : ShowFatalError(
9440 0 : state, format("{}{}=\"{}\" - Rated total cooling capacity is zero or less.", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9441 : }
9442 170031 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9443 169884 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9444 147 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap2;
9445 : } else {
9446 169884 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
9447 : }
9448 81326 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag && thisDXCoil.DXCoilType_Num != HVAC::CoilDX_HeatPumpWaterHeaterPumped &&
9449 263161 : thisDXCoil.DXCoilType_Num != HVAC::CoilDX_HeatPumpWaterHeaterWrapped &&
9450 11804 : ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
9451 10710 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
9452 1095 : if (thisDXCoil.ErrIndex1 == 0) {
9453 8 : ShowWarningMessage(
9454 : state,
9455 8 : format("{}{}=\"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at {:.3R} m3/s/W.",
9456 : RoutineName,
9457 4 : thisDXCoil.DXCoilType,
9458 4 : thisDXCoil.Name,
9459 : VolFlowperRatedTotCap));
9460 8 : ShowContinueErrorTimeStamp(state, "");
9461 8 : ShowContinueError(state,
9462 8 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
9463 4 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
9464 4 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
9465 8 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components,");
9466 12 : ShowContinueError(state, "or variable air volume [VAV] system using incorrect coil type.");
9467 : }
9468 8760 : ShowRecurringWarningErrorAtEnd(
9469 : state,
9470 3285 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9471 : "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
9472 1095 : thisDXCoil.ErrIndex1,
9473 : VolFlowperRatedTotCap,
9474 : VolFlowperRatedTotCap);
9475 168936 : } else if (!state.dataGlobal->WarmupFlag &&
9476 22954 : (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9477 191890 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
9478 49 : ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
9479 49 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
9480 0 : if (thisDXCoil.ErrIndex1 == 0) {
9481 0 : ShowWarningMessage(
9482 : state,
9483 0 : format("{}{}=\"{}\" - Air volume flow rate per watt of rated total water heating capacity is out of range at {:.2R} m3/s/W.",
9484 : RoutineName,
9485 0 : thisDXCoil.DXCoilType,
9486 0 : thisDXCoil.Name,
9487 : VolFlowperRatedTotCap));
9488 0 : ShowContinueErrorTimeStamp(state, "");
9489 0 : ShowContinueError(state,
9490 0 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
9491 0 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
9492 0 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
9493 0 : ShowContinueError(state,
9494 : "Possible causes may be that the parent object is calling for an actual supply air flow rate that is much "
9495 : "higher or lower than the DX coil rated supply air flow rate.");
9496 : }
9497 0 : ShowRecurringWarningErrorAtEnd(
9498 : state,
9499 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9500 : "\" - Air volume flow rate per watt of rated total water heating capacity is out of range error continues...",
9501 0 : thisDXCoil.ErrIndex1,
9502 : VolFlowperRatedTotCap,
9503 : VolFlowperRatedTotCap);
9504 : }
9505 : // Adjust coil bypass factor for actual air flow rate. Use relation CBF = exp(-NTU) where
9506 : // NTU = A0/(m*cp). Relationship models the cooling coil as a heat exchanger with Cmin/Cmax = 0.
9507 :
9508 170031 : RatedCBF = thisDXCoil.RatedCBF(Mode);
9509 170031 : if (RatedCBF > 0.0) {
9510 170031 : A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
9511 : } else {
9512 0 : A0 = 0.0;
9513 : }
9514 170031 : ADiff = -A0 / AirMassFlow;
9515 170031 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
9516 166270 : CBF = std::exp(ADiff);
9517 : } else {
9518 3761 : CBF = 0.0;
9519 : }
9520 :
9521 : // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
9522 170031 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
9523 127084 : if (OutdoorDryBulb < 0.0 && !state.dataGlobal->WarmupFlag) { // Same threshold as for air-cooled electric chiller
9524 0 : thisDXCoil.PrintLowAmbMessage = true;
9525 0 : thisDXCoil.LowTempLast = OutdoorDryBulb;
9526 0 : if (thisDXCoil.LowAmbErrIndex == 0) {
9527 : thisDXCoil.LowAmbBuffer1 =
9528 0 : format("{} \"{}\" - Air-cooled condenser inlet dry-bulb temperature below 0 C. Outdoor dry-bulb temperature = {:.2R}",
9529 0 : thisDXCoil.DXCoilType,
9530 0 : thisDXCoil.Name,
9531 0 : OutdoorDryBulb);
9532 0 : thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
9533 0 : CreateSysTimeIntervalString(state);
9534 : }
9535 : }
9536 42947 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
9537 42800 : if (OutdoorWetBulb < 10.0 && !state.dataGlobal->WarmupFlag) { // Same threshold as for evap-cooled electric chiller
9538 240 : thisDXCoil.PrintLowAmbMessage = true;
9539 240 : thisDXCoil.LowTempLast = OutdoorWetBulb;
9540 240 : if (thisDXCoil.LowAmbErrIndex == 0) {
9541 : thisDXCoil.LowAmbBuffer1 =
9542 480 : format("{} \"{}\" - Evap-cooled condenser inlet wet-bulb temperature below 10 C. Outdoor wet-bulb temperature = {:.2R}",
9543 240 : thisDXCoil.DXCoilType,
9544 240 : thisDXCoil.Name,
9545 240 : OutdoorWetBulb);
9546 480 : thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
9547 720 : CreateSysTimeIntervalString(state);
9548 : }
9549 : }
9550 : }
9551 :
9552 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
9553 : // InletAirHumRat may be modified in this ADP/BF loop, use temporary variable for calculations
9554 170031 : InletAirHumRatTemp = InletAirHumRat;
9555 170031 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
9556 : while (true) {
9557 199692 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9558 199545 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9559 : // Coil:DX:HeatPumpWaterHeater does not have total cooling capacity as a function of temp or flow curve
9560 147 : TotCapTempModFac = 1.0;
9561 147 : TotCapFlowModFac = 1.0;
9562 : } else {
9563 199545 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
9564 199504 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC, CondInletTemp);
9565 : } else {
9566 41 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), CondInletTemp);
9567 : }
9568 :
9569 : // Warn user if curve output goes negative
9570 199545 : if (TotCapTempModFac < 0.0) {
9571 0 : if (thisDXCoil.CCapFTempErrorIndex == 0) {
9572 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9573 0 : ShowContinueError(state,
9574 0 : format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).",
9575 : TotCapTempModFac));
9576 0 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
9577 0 : ShowContinueError(state,
9578 0 : format(" Negative value occurs using a condenser inlet air temperature of {:.1T} and an inlet air "
9579 : "wet-bulb temperature of {:.1T}.",
9580 : CondInletTemp,
9581 : InletAirWetBulbC));
9582 : } else {
9583 0 : ShowContinueError(state,
9584 0 : format(" Negative value occurs using a condenser inlet air temperature of {:.1T}.", CondInletTemp));
9585 : }
9586 0 : if (Mode > 1) {
9587 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
9588 : }
9589 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
9590 : }
9591 0 : ShowRecurringWarningErrorAtEnd(
9592 : state,
9593 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
9594 : "\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
9595 0 : thisDXCoil.CCapFTempErrorIndex,
9596 : TotCapTempModFac,
9597 : TotCapTempModFac);
9598 0 : TotCapTempModFac = 0.0;
9599 : }
9600 :
9601 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
9602 199545 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
9603 : // Warn user if curve output goes negative
9604 199545 : if (TotCapFlowModFac < 0.0) {
9605 0 : if (thisDXCoil.CCapFFlowErrorIndex == 0) {
9606 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9607 0 : ShowContinueError(state,
9608 0 : format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).",
9609 : TotCapFlowModFac));
9610 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
9611 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
9612 0 : if (Mode > 1) {
9613 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
9614 : }
9615 : }
9616 0 : ShowRecurringWarningErrorAtEnd(
9617 : state,
9618 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
9619 : "\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
9620 0 : thisDXCoil.CCapFFlowErrorIndex,
9621 : TotCapFlowModFac,
9622 : TotCapFlowModFac);
9623 0 : TotCapFlowModFac = 0.0;
9624 : }
9625 : }
9626 199692 : TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
9627 : // if user specified SHR modifier curves are available calculate the SHR as follows:
9628 199692 : if (thisDXCoil.UserSHRCurveExists) {
9629 0 : SHR = CalcSHRUserDefinedCurves(state,
9630 : InletAirDryBulbTemp,
9631 : InletAirWetBulbC,
9632 : AirMassFlowRatio,
9633 0 : thisDXCoil.SHRFTemp(Mode),
9634 0 : thisDXCoil.SHRFFlow(Mode),
9635 0 : thisDXCoil.RatedSHR(Mode));
9636 0 : hDelta = TotCap / AirMassFlow;
9637 0 : break;
9638 : } else {
9639 : // Calculate apparatus dew point conditions using TotCap and CBF
9640 199692 : hDelta = TotCap / AirMassFlow;
9641 199692 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
9642 199692 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, calcDoe2DXCoil);
9643 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9644 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
9645 199692 : wADP = PsyWFnTdbH(state, tADP, hADP, calcDoe2DXCoil);
9646 199692 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
9647 199692 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
9648 199692 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
9649 : } else {
9650 0 : SHR = 1.0;
9651 : }
9652 : // Check for dry evaporator conditions (win < wadp)
9653 199692 : if (wADP > InletAirHumRatTemp || (Counter >= 1 && Counter < MaxIter)) {
9654 34640 : if (InletAirHumRatTemp == 0.0) {
9655 9 : InletAirHumRatTemp = 0.00001;
9656 : }
9657 34640 : werror = (InletAirHumRatTemp - wADP) / InletAirHumRatTemp;
9658 : // Increase InletAirHumRatTemp at constant InletAirTemp to find coil dry-out point. Then use the
9659 : // capacity at the dry-out point to determine exiting conditions from coil. This is required
9660 : // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
9661 34640 : InletAirHumRatTemp = RF * wADP + (1.0 - RF) * InletAirHumRatTemp;
9662 34640 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRatTemp, OutdoorPressure);
9663 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment
9664 : // line InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRatTemp,InletAirPressure)
9665 34640 : ++Counter;
9666 34640 : if (std::abs(werror) > Tolerance) {
9667 29661 : continue; // Recalculate with modified inlet conditions
9668 : }
9669 4979 : break;
9670 : } else {
9671 : break;
9672 : }
9673 : }
9674 : } // end of DO iteration loop
9675 :
9676 170031 : if (thisDXCoil.PLFFPLR(Mode) > 0) {
9677 170031 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PartLoadRatio); // Calculate part-load factor
9678 : } else {
9679 0 : PLF = 1.0;
9680 : }
9681 :
9682 170031 : if (PLF < 0.7) {
9683 0 : if (thisDXCoil.ErrIndex2 == 0) {
9684 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9685 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9686 0 : ShowWarningMessage(state, format("{}{}=\"{}\", PLF curve value", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9687 0 : ShowContinueError(state, format("The PLF curve value = {:.3T} for part-load ratio = {:.3T}", PLF, PartLoadRatio));
9688 0 : ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
9689 0 : ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
9690 : } else {
9691 0 : ShowWarningMessage(state, format("{}{}=\"{}\", PLF curve value", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9692 0 : ShowContinueError(state, format("The PLF curve value = {:.3T} for part-load ratio = {:.3T}", PLF, PartLoadRatio));
9693 0 : ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
9694 0 : ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
9695 : }
9696 : }
9697 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9698 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9699 0 : ShowRecurringWarningErrorAtEnd(
9700 0 : state, thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
9701 : } else {
9702 0 : ShowRecurringWarningErrorAtEnd(
9703 0 : state, thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
9704 : }
9705 0 : PLF = 0.7;
9706 : }
9707 :
9708 170031 : thisDXCoil.PartLoadRatio = PartLoadRatio;
9709 170031 : thisDXCoil.CoolingCoilRuntimeFraction = PartLoadRatio / PLF;
9710 170031 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
9711 0 : if (thisDXCoil.ErrIndex3 == 0) {
9712 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9713 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9714 0 : ShowWarningMessage(state, format("{}{}=\"{}\", runtime fraction", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9715 0 : ShowWarningMessage(state, format("The runtime fraction exceeded 1.0. [{:.4R}].", thisDXCoil.CoolingCoilRuntimeFraction));
9716 0 : ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
9717 0 : ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
9718 0 : ShowContinueErrorTimeStamp(state, "");
9719 : } else {
9720 0 : ShowWarningMessage(state, format("{}{}=\"{}\", runtime fraction", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9721 0 : ShowWarningMessage(state, format("The runtime fraction exceeded 1.0. [{:.4R}].", thisDXCoil.CoolingCoilRuntimeFraction));
9722 0 : ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
9723 0 : ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
9724 0 : ShowContinueErrorTimeStamp(state, "");
9725 : }
9726 : }
9727 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9728 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9729 0 : ShowRecurringWarningErrorAtEnd(state,
9730 0 : thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " runtime fraction > 1.0 warning continues...",
9731 0 : thisDXCoil.ErrIndex3,
9732 0 : thisDXCoil.CoolingCoilRuntimeFraction,
9733 0 : thisDXCoil.CoolingCoilRuntimeFraction);
9734 : } else {
9735 0 : ShowRecurringWarningErrorAtEnd(state,
9736 0 : thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " runtime fraction > 1.0 warning continues...",
9737 0 : thisDXCoil.ErrIndex3,
9738 0 : thisDXCoil.CoolingCoilRuntimeFraction,
9739 0 : thisDXCoil.CoolingCoilRuntimeFraction);
9740 : }
9741 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
9742 170031 : } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
9743 5482 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
9744 : }
9745 :
9746 : // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
9747 170031 : if (fanOp == HVAC::FanOp::Cycling) {
9748 57669 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
9749 : }
9750 :
9751 : // Calculate full load output conditions
9752 170031 : if (thisDXCoil.UserSHRCurveExists) {
9753 0 : FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
9754 0 : if (SHR < 1.0) {
9755 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9756 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9757 0 : if (FullLoadOutAirHumRat <= 0.0) {
9758 0 : FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
9759 : }
9760 : } else {
9761 0 : SHR = 1.0;
9762 0 : FullLoadOutAirHumRat = InletAirHumRat;
9763 : }
9764 : } else {
9765 170031 : if (SHR > 1.0 || Counter > 0) {
9766 4979 : SHR = 1.0;
9767 : }
9768 170031 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
9769 170031 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9770 170031 : if (SHR < 1.0) {
9771 165052 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9772 : } else {
9773 4979 : FullLoadOutAirHumRat = InletAirHumRat;
9774 : }
9775 : }
9776 170031 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
9777 :
9778 : // Check for saturation error and modify temperature at constant enthalpy
9779 170031 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure)) {
9780 17527 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
9781 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9782 : // IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
9783 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
9784 17527 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
9785 : }
9786 :
9787 : // Store actual outlet conditions when DX coil is ON for use in heat recovery module
9788 170031 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = FullLoadOutAirTemp;
9789 170031 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = FullLoadOutAirHumRat;
9790 :
9791 : // Add warning message for cold cooling coil (FullLoadOutAirTemp < 2 C)
9792 170031 : if (FullLoadOutAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
9793 1018 : thisDXCoil.PrintLowOutTempMessage = true;
9794 1018 : thisDXCoil.FullLoadOutAirTempLast = FullLoadOutAirTemp;
9795 1018 : if (thisDXCoil.LowOutletTempIndex == 0) {
9796 8 : thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
9797 16 : thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
9798 : "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
9799 8 : thisDXCoil.DXCoilType,
9800 8 : thisDXCoil.Name,
9801 8 : FullLoadOutAirTemp);
9802 16 : thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
9803 24 : CreateSysTimeIntervalString(state);
9804 : }
9805 : }
9806 :
9807 : // If constant fan with cycling compressor, call function to determine "effective SHR"
9808 : // which includes the part-load degradation on latent capacity
9809 170031 : if (fanOp == HVAC::FanOp::Continuous) {
9810 112362 : QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode));
9811 112362 : QLatActual = TotCap * (1.0 - SHR);
9812 112362 : SHRUnadjusted = SHR;
9813 112362 : SHR = CalcEffectiveSHR(
9814 : state, DXCoilNum, SHR, thisDXCoil.CoolingCoilRuntimeFraction, QLatRated, QLatActual, InletAirDryBulbTemp, InletAirWetBulbC, Mode);
9815 : // For multimode coil, if stage-2 operation (modes 2 or 4), adjust Stage1&2 SHR to account for
9816 : // Stage 1 operating at full load, so there is no degradation for that portion
9817 : // Use the stage 1 bypass fraction to allocate
9818 112362 : if (Mode == 2 || Mode == 4) {
9819 0 : SHR = SHRUnadjusted * (1.0 - thisDXCoil.BypassedFlowFrac(Mode - 1)) + SHR * thisDXCoil.BypassedFlowFrac(Mode - 1);
9820 : }
9821 :
9822 : // Calculate full load output conditions
9823 112362 : if (thisDXCoil.UserSHRCurveExists) {
9824 0 : FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
9825 0 : if (SHR < 1.0) {
9826 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9827 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9828 0 : if (FullLoadOutAirHumRat <= 0.0) {
9829 0 : FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
9830 : }
9831 : } else {
9832 0 : SHR = 1.0;
9833 0 : FullLoadOutAirHumRat = InletAirHumRat;
9834 : }
9835 : } else {
9836 112362 : if (SHR > 1.0 || Counter > 0) {
9837 4899 : SHR = 1.0;
9838 : }
9839 112362 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
9840 112362 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9841 112362 : if (SHR < 1.0) {
9842 102175 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9843 : } else {
9844 10187 : FullLoadOutAirHumRat = InletAirHumRat;
9845 : }
9846 : }
9847 112362 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
9848 :
9849 : // apply latent degradation model to cycling fan when RH control is desired and heating coil operates
9850 : // longer than the cooling coil. DXcoolToHeatPLRRatio = Cooling coil PLR / Heating coil PLR.
9851 57669 : } else if (fanOp == HVAC::FanOp::Cycling) {
9852 57669 : if (DXcoolToHeatPLRRatio < 1.0) {
9853 0 : QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode));
9854 0 : QLatActual = TotCap * (1.0 - SHR);
9855 0 : HeatRTF = PartLoadRatio / DXcoolToHeatPLRRatio;
9856 0 : if (thisDXCoil.HeatingCoilPLFCurvePTR > 0) {
9857 0 : HeatingCoilPLF = CurveValue(state, thisDXCoil.HeatingCoilPLFCurvePTR, HeatRTF);
9858 0 : if (HeatingCoilPLF > 0) {
9859 0 : HeatRTF /= HeatingCoilPLF;
9860 : }
9861 : }
9862 0 : SHRUnadjusted = SHR;
9863 0 : SHR = CalcEffectiveSHR(state,
9864 : DXCoilNum,
9865 : SHR,
9866 : thisDXCoil.CoolingCoilRuntimeFraction,
9867 : QLatRated,
9868 : QLatActual,
9869 : InletAirDryBulbTemp,
9870 : InletAirWetBulbC,
9871 : Mode,
9872 : HeatRTF);
9873 : // Calculate full load output conditions
9874 0 : if (thisDXCoil.UserSHRCurveExists) {
9875 0 : FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
9876 0 : if (SHR < 1.0) {
9877 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9878 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9879 0 : if (FullLoadOutAirHumRat <= 0.0) {
9880 0 : FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
9881 : }
9882 : } else {
9883 0 : SHR = 1.0;
9884 0 : FullLoadOutAirHumRat = InletAirHumRat;
9885 : }
9886 : } else {
9887 0 : if (SHR > 1.0 || Counter > 0) {
9888 0 : SHR = 1.0;
9889 : }
9890 0 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
9891 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9892 0 : if (SHR < 1.0) {
9893 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9894 : } else {
9895 0 : FullLoadOutAirHumRat = InletAirHumRat;
9896 : }
9897 : }
9898 0 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
9899 : }
9900 : }
9901 :
9902 : // Calculate actual outlet conditions for the input part load ratio
9903 : // Actual outlet conditions are "average" for time step
9904 :
9905 : // For multimode coil, if stage-2 operation (modes 2 or 4), return "full load" outlet conditions
9906 170031 : if (((fanOp == HVAC::FanOp::Continuous) && (Mode == 1)) || (Mode == 3)) {
9907 : // Continuous fan, cycling compressor
9908 112362 : OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
9909 112362 : OutletAirHumRat = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirHumRat + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirHumRat);
9910 112362 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
9911 : } else {
9912 : // Default to cycling fan, cycling compressor
9913 : // Also return this result for stage 2 operation of multimode coil
9914 : // Cycling fan typically provides full outlet conditions. When RH control is used, account for additional
9915 : // heating run time by using cooling/heating ratio the same as constant fan (otherwise PLRRatio = 1).
9916 57669 : OutletAirEnthalpy = FullLoadOutAirEnth * DXcoolToHeatPLRRatio + InletAirEnthalpy * (1.0 - DXcoolToHeatPLRRatio);
9917 57669 : OutletAirHumRat = FullLoadOutAirHumRat * DXcoolToHeatPLRRatio + InletAirHumRat * (1.0 - DXcoolToHeatPLRRatio);
9918 57669 : OutletAirTemp = FullLoadOutAirTemp * DXcoolToHeatPLRRatio + InletAirDryBulbTemp * (1.0 - DXcoolToHeatPLRRatio);
9919 : }
9920 :
9921 : // Check for saturation error and modify temperature at constant enthalpy
9922 170031 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, calcDoe2DXCoil)) {
9923 10242 : OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
9924 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9925 : // IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
9926 : // OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
9927 10242 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
9928 : }
9929 :
9930 : // Mix with air that was bypassed around coil, if any
9931 170031 : if (BypassFlowFraction > 0.0) {
9932 0 : OutletAirEnthalpy = (1.0 - BypassFlowFraction) * OutletAirEnthalpy + BypassFlowFraction * InletAirEnthalpy;
9933 0 : OutletAirHumRat = (1.0 - BypassFlowFraction) * OutletAirHumRat + BypassFlowFraction * InletAirHumRat;
9934 0 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
9935 : // Check for saturation error and modify temperature at constant enthalpy
9936 0 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) {
9937 0 : OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
9938 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
9939 : // IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
9940 : // OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
9941 0 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
9942 : }
9943 : }
9944 :
9945 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
9946 170031 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9947 169884 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9948 : // Coil:DX:HeatPumpWaterHeater does not have EIR temp or flow curves
9949 147 : EIRTempModFac = 1.0;
9950 147 : EIRFlowModFac = 1.0;
9951 : } else {
9952 169884 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirWetBulbC, CondInletTemp);
9953 :
9954 : // Warn user if curve output goes negative
9955 169884 : if (EIRTempModFac < 0.0) {
9956 0 : if (thisDXCoil.EIRFTempErrorIndex == 0) {
9957 0 : ShowWarningMessage(state, format("{}{}=\"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9958 0 : ShowContinueError(
9959 0 : state, format(" Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).", EIRTempModFac));
9960 0 : if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 2) {
9961 0 : ShowContinueError(state,
9962 0 : format(" Negative value occurs using a condenser inlet air temperature of {:.1T} and an inlet air "
9963 : "wet-bulb temperature of {:.1T}.",
9964 : CondInletTemp,
9965 : InletAirWetBulbC));
9966 : } else {
9967 0 : ShowContinueError(state, format(" Negative value occurs using a condenser inlet air temperature of {:.1T}.", CondInletTemp));
9968 : }
9969 0 : if (Mode > 1) {
9970 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
9971 : }
9972 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
9973 : }
9974 0 : ShowRecurringWarningErrorAtEnd(
9975 : state,
9976 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9977 : "\": Energy Input Ratio Modifier curve (function of temperature) output is negative warning continues...",
9978 0 : thisDXCoil.EIRFTempErrorIndex,
9979 : EIRTempModFac,
9980 : EIRTempModFac);
9981 0 : EIRTempModFac = 0.0;
9982 : }
9983 :
9984 169884 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
9985 :
9986 : // Warn user if curve output goes negative
9987 169884 : if (EIRFlowModFac < 0.0) {
9988 0 : if (thisDXCoil.EIRFFlowErrorIndex == 0) {
9989 0 : ShowWarningMessage(state, format("{}{}=\"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
9990 0 : ShowContinueError(
9991 0 : state, format(" Energy Input Ratio Modifier curve (function of flow fraction) output is negative ({:.3T}).", EIRFlowModFac));
9992 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
9993 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
9994 0 : if (Mode > 1) {
9995 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
9996 : }
9997 : }
9998 0 : ShowRecurringWarningErrorAtEnd(
9999 : state,
10000 0 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
10001 : "\": Energy Input Ratio Modifier curve (function of flow fraction) output is negative warning continues...",
10002 0 : thisDXCoil.EIRFFlowErrorIndex,
10003 : EIRFlowModFac,
10004 : EIRFlowModFac);
10005 0 : EIRFlowModFac = 0.0;
10006 : }
10007 : }
10008 :
10009 170031 : EIR = thisDXCoil.RatedEIR(Mode) * EIRFlowModFac * EIRTempModFac;
10010 :
10011 : // For multimode coil, if stage-2 operation (Modes 2 or 4), return "full load" power adjusted for PLF
10012 170031 : if (Mode == 1 || Mode == 3) {
10013 170031 : thisDXCoil.ElecCoolingPower = TotCap * EIR * thisDXCoil.CoolingCoilRuntimeFraction;
10014 : } else {
10015 0 : thisDXCoil.ElecCoolingPower = TotCap * EIR * thisDXCoil.CoolingCoilRuntimeFraction / PartLoadRatio;
10016 : }
10017 :
10018 : // Reset AirMassFlow to inlet node air mass flow for final total, sensible and latent calculations
10019 : // since AirMassFlow might have been modified above (in this subroutine):
10020 : // IF (FanOpMode .EQ. FanOp::Cycling) AirMassFlow = AirMassFlow / PartLoadRatio
10021 : // For multimode coil, this should be full flow including bypassed fraction
10022 170031 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10023 170031 : CalcComponentSensibleLatentOutput(AirMassFlow,
10024 : InletAirDryBulbTemp,
10025 : InletAirHumRat,
10026 : OutletAirTemp,
10027 : OutletAirHumRat,
10028 170031 : thisDXCoil.SensCoolingEnergyRate,
10029 170031 : thisDXCoil.LatCoolingEnergyRate,
10030 170031 : thisDXCoil.TotalCoolingEnergyRate);
10031 :
10032 : // Set DataHeatGlobal heat reclaim variable for use by heat reclaim coil (part load ratio is accounted for)
10033 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
10034 170031 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
10035 :
10036 : // Calculate crankcase heater power using the runtime fraction for this DX cooling coil only if there is no companion DX coil.
10037 : // Else use the largest runtime fraction of this DX cooling coil and the companion DX heating coil.
10038 170031 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
10039 170031 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
10040 : } else {
10041 0 : thisDXCoil.CrankcaseHeaterPower =
10042 0 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.CoolingCoilRuntimeFraction,
10043 0 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction));
10044 : }
10045 :
10046 170031 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
10047 : //******************
10048 : // WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
10049 : // H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
10050 : // /RhoWater [kgWater/m3]
10051 : //******************
10052 42800 : RhoWater = RhoH2O(OutdoorDryBulb);
10053 42800 : thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater * thisDXCoil.CoolingCoilRuntimeFraction;
10054 42800 : thisDXCoil.EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower(Mode) * thisDXCoil.CoolingCoilRuntimeFraction;
10055 : // Calculate basin heater power
10056 42800 : CalcBasinHeaterPower(state,
10057 : thisDXCoil.BasinHeaterPowerFTempDiff,
10058 : thisDXCoil.basinHeaterSched,
10059 : thisDXCoil.BasinHeaterSetPointTemp,
10060 42800 : thisDXCoil.BasinHeaterPower);
10061 42800 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
10062 42800 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
10063 : }
10064 : }
10065 :
10066 170031 : thisDXCoil.OutletAirTemp = OutletAirTemp;
10067 170031 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
10068 170031 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
10069 :
10070 : } else {
10071 :
10072 : // DX coil is off; just pass through conditions
10073 161281 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10074 161281 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
10075 161281 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
10076 :
10077 161281 : thisDXCoil.ElecCoolingPower = 0.0;
10078 161281 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
10079 161281 : thisDXCoil.SensCoolingEnergyRate = 0.0;
10080 161281 : thisDXCoil.LatCoolingEnergyRate = 0.0;
10081 161281 : thisDXCoil.EvapCondPumpElecPower = 0.0;
10082 161281 : thisDXCoil.EvapWaterConsumpRate = 0.0;
10083 :
10084 : // Reset globals when DX coil is OFF for use in heat recovery module
10085 161281 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
10086 161281 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
10087 :
10088 : // Calculate crankcase heater power using the runtime fraction for this DX cooling coil (here DXCoolingCoilRTF=0) if
10089 : // there is no companion DX coil, or the runtime fraction of the companion DX heating coil (here DXHeatingCoilRTF>=0).
10090 161281 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
10091 161281 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
10092 : } else {
10093 0 : thisDXCoil.CrankcaseHeaterPower =
10094 0 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction);
10095 : }
10096 :
10097 : // Calculate basin heater power
10098 161281 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
10099 1 : if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
10100 0 : CalcBasinHeaterPower(state,
10101 : thisDXCoil.BasinHeaterPowerFTempDiff,
10102 : thisDXCoil.basinHeaterSched,
10103 : thisDXCoil.BasinHeaterSetPointTemp,
10104 0 : thisDXCoil.BasinHeaterPower);
10105 : }
10106 : } else {
10107 161280 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
10108 25052 : CalcBasinHeaterPower(state,
10109 : thisDXCoil.BasinHeaterPowerFTempDiff,
10110 : thisDXCoil.basinHeaterSched,
10111 : thisDXCoil.BasinHeaterSetPointTemp,
10112 25052 : thisDXCoil.BasinHeaterPower);
10113 : }
10114 : }
10115 :
10116 : } // end of on/off if - else
10117 :
10118 : // set water system demand request (if needed)
10119 331312 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
10120 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
10121 0 : thisDXCoil.EvapWaterConsumpRate;
10122 : }
10123 :
10124 331312 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
10125 331312 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
10126 331312 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
10127 331312 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
10128 331312 : thisDXCoil.CondInletTemp = CondInletTemp;
10129 :
10130 : // set outlet node conditions
10131 331312 : int airOutletNode = thisDXCoil.AirOutNode;
10132 331312 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
10133 331312 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
10134 :
10135 : // calc secondary coil if specified
10136 331312 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
10137 0 : CalcSecondaryDXCoils(state, DXCoilNum);
10138 : }
10139 331312 : }
10140 :
10141 49499 : void CalcVRFCoolingCoil(EnergyPlusData &state,
10142 : int const DXCoilNum, // the number of the DX coil to be simulated
10143 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
10144 : bool const FirstHVACIteration, // true if this is the first iteration of HVAC
10145 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
10146 : HVAC::FanOp const fanOp, // Allows parent object to control fan operation
10147 : Real64 const CompCycRatio, // cycling ratio of VRF condenser
10148 : ObjexxFCL::Optional_int_const PerfMode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
10149 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
10150 : ObjexxFCL::Optional<Real64 const> MaxCoolCap // maximum capacity of DX coil
10151 : )
10152 : {
10153 :
10154 : // SUBROUTINE INFORMATION:
10155 : // AUTHOR Richard Raustad
10156 : // DATE WRITTEN August 2010
10157 :
10158 : // PURPOSE OF THIS SUBROUTINE:
10159 : // Calculates the air-side performance of a direct-expansion, air-cooled
10160 : // VRF terminal unit cooling coil.
10161 : // A new subroutine was created in case this DX coil model is significantly
10162 : // different from the existing CalcDoe2DXCoil subroutine. The VRF heating coil
10163 : // uses the existing DX heating coil subroutine (CalcDXHeatingCoil).
10164 :
10165 : // METHODOLOGY EMPLOYED:
10166 : // This routine simulates the performance of a variable refrigerant flow cooling coil.
10167 : // The routine requires the user to enter the total cooling capacity and sensible heat ratio.
10168 : // Since different manufacturer's rate their equipment at different air flow rates,
10169 : // the supply air flow rate corresponding to the rated capacities must also be
10170 : // entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information entered by
10171 : // the user should NOT include the thermal or electrical impacts of the supply air fan, as
10172 : // this is addressed by another module.
10173 :
10174 : // With the rated performance data entered by the user, the model employs some of the
10175 : // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
10176 : // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
10177 : // does NOT employ the exact same methodology to calculate performance as DOE-2.
10178 : // This VRF cooling coil model adjusts the rated total cooling capacity by the CAPFT
10179 : // and CAP function of flow curve/model currently used by the existing DX coil model.
10180 : // The part-load ratio is then applied to the total operating capacity to find the capacity
10181 : // required to meet the load. This VRF model then uses the ADP/bypass method to find the
10182 : // SHR and resulting outlet conditions given that total capacity (or delta H).
10183 :
10184 : // The model checks for coil dryout conditions, and adjusts the calculated performance
10185 : // appropriately.
10186 :
10187 : // Using/Aliasing
10188 : using Curve::CurveValue;
10189 49499 : Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
10190 49499 : Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
10191 : using General::CreateSysTimeIntervalString;
10192 :
10193 : // SUBROUTINE ARGUMENT DEFINITIONS:
10194 : // REAL(r64), INTENT(IN), OPTIONAL :: CoolingHeatingPLR ! used for cycling fan RH control
10195 :
10196 : // SUBROUTINE PARAMETER DEFINITIONS:
10197 : static constexpr std::string_view RoutineName("CalcVRFCoolingCoil");
10198 :
10199 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10200 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
10201 : Real64 AirMassFlowRatio; // Ratio of actual air mass flow to rated air mass flow (adjusted for bypass if any)
10202 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
10203 : // (average flow if cycling fan, full flow if constant fan)
10204 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
10205 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
10206 : Real64 TotCapTempModFac; // Total capacity modifier (function of entering wetbulb, outside drybulb)
10207 : Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs rated flow)
10208 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
10209 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
10210 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
10211 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
10212 : Real64 InletAirHumRatTemp; // inlet air humidity ratio used in ADP/BF loop [kg/kg]
10213 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10214 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
10215 : Real64 RatedCBF; // coil bypass factor at rated conditions
10216 : Real64 SHR; // Sensible Heat Ratio (sensible/total) of the cooling coil
10217 : Real64 CBF; // coil bypass factor at off rated conditions
10218 : Real64 A0; // NTU * air mass flow rate, used in CBF calculation
10219 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
10220 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
10221 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
10222 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
10223 : Real64 tADP; // Apparatus dew point temperature [C]
10224 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
10225 : Real64 FullLoadOutAirEnth; // outlet full load enthalpy [J/kg]
10226 : Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
10227 : Real64 FullLoadOutAirTemp; // outlet air temperature at full load [C]
10228 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
10229 : Real64 QLatActual; // operating latent capacity of DX coil
10230 : Real64 QLatRated; // Rated latent capacity of DX coil
10231 : Real64 SHRUnadjusted; // SHR prior to latent degradation effective SHR calculation
10232 : int Counter; // Counter for dry evaporator iterations
10233 : int MaxIter; // Maximum number of iterations for dry evaporator calculations
10234 : Real64 RF; // Relaxation factor for dry evaporator iterations
10235 : Real64 Tolerance; // Error tolerance for dry evaporator iterations
10236 : Real64 werror; // Deviation of humidity ratio in dry evaporator iteration loop
10237 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
10238 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
10239 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
10240 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
10241 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
10242 : Real64 RhoAir; // Density of air [kg/m3]
10243 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
10244 49499 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
10245 : Real64 AirFlowRatio; // ratio of compressor on airflow to average timestep airflow
10246 : // used when constant fan mode yields different air flow rates when compressor is ON and OFF
10247 : // (e.g. Packaged Terminal Heat Pump)
10248 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
10249 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
10250 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
10251 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
10252 :
10253 : int Mode; // Performance mode for Multimode DX coil; Always 1 for other coil types
10254 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
10255 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
10256 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
10257 : Real64 ADiff; // Used for exponential
10258 :
10259 : // If Performance mode not present, then set to 1. Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
10260 49499 : if (present(PerfMode)) {
10261 0 : Mode = PerfMode;
10262 : } else {
10263 49499 : Mode = 1;
10264 : }
10265 :
10266 : // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
10267 : // during cooling and when no cooling is required (constant fan, fan speed changes)
10268 49499 : if (present(OnOffAirFlowRatio)) {
10269 49492 : AirFlowRatio = OnOffAirFlowRatio;
10270 : } else {
10271 7 : AirFlowRatio = 1.0;
10272 : }
10273 :
10274 49499 : MaxIter = 30;
10275 49499 : RF = 0.4;
10276 49499 : Counter = 0;
10277 49499 : Tolerance = 0.01;
10278 49499 : CondInletTemp = 0.0;
10279 49499 : CondInletHumRat = 0.0;
10280 :
10281 49499 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
10282 :
10283 49499 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10284 49499 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
10285 49499 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10286 49499 : InletAirHumRat = thisDXCoil.InletAirHumRat;
10287 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10288 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
10289 49499 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
10290 49499 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
10291 49499 : thisDXCoil.PartLoadRatio = 0.0;
10292 49499 : thisDXCoil.BasinHeaterPower = 0.0;
10293 :
10294 49499 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
10295 49438 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
10296 49438 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
10297 32 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10298 32 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10299 32 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10300 : } else {
10301 49406 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
10302 : // If node is not connected to anything, pressure = default, use weather data
10303 49406 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
10304 94 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10305 94 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10306 94 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10307 94 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10308 : } else {
10309 49312 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
10310 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
10311 49312 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
10312 : }
10313 : }
10314 : } else {
10315 61 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10316 61 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10317 61 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10318 61 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10319 : }
10320 :
10321 49499 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
10322 0 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
10323 0 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
10324 : // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
10325 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
10326 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
10327 0 : CompAmbTemp = OutdoorDryBulb;
10328 : } else { // for air or water-cooled, inlet temp is stored in OutdoorDryBulb temp
10329 49499 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp or water inlet temp
10330 49499 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
10331 32 : CompAmbTemp = state.dataEnvrn->OutDryBulbTemp; // for crankcase heater use actual outdoor temp for water-cooled
10332 : } else {
10333 49467 : CompAmbTemp = OutdoorDryBulb;
10334 : }
10335 : }
10336 :
10337 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
10338 : // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
10339 49499 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
10340 71 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
10341 71 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
10342 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
10343 : }
10344 : } else {
10345 49428 : CrankcaseHeatingPower = 0.0;
10346 : }
10347 :
10348 : // calculate end time of current time step to determine if error messages should be printed
10349 49499 : state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
10350 :
10351 : // Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
10352 : // Wait for next time step to print warnings. If simulation iterates, print out
10353 : // the warning for the last iteration only. Must wait for next time step to accomplish this.
10354 : // If a warning occurs and the simulation down shifts, the warning is not valid.
10355 49499 : if (thisDXCoil.PrintLowAmbMessage) { // .AND. &
10356 0 : if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
10357 0 : if (thisDXCoil.LowAmbErrIndex == 0) {
10358 0 : ShowWarningMessage(state, thisDXCoil.LowAmbBuffer1);
10359 0 : ShowContinueError(state, thisDXCoil.LowAmbBuffer2);
10360 0 : ShowContinueError(state, "... Operation at low inlet temperatures may require special performance curves.");
10361 : }
10362 0 : ShowRecurringWarningErrorAtEnd(state,
10363 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10364 : "\" - Low condenser inlet temperature error continues...",
10365 0 : thisDXCoil.LowAmbErrIndex,
10366 0 : thisDXCoil.LowTempLast,
10367 0 : thisDXCoil.LowTempLast,
10368 : _,
10369 : "[C]",
10370 : "[C]");
10371 : }
10372 : }
10373 :
10374 49499 : if (thisDXCoil.PrintHighAmbMessage) { // .AND. &
10375 60 : if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
10376 0 : if (thisDXCoil.HighAmbErrIndex == 0) {
10377 0 : ShowWarningMessage(state, thisDXCoil.HighAmbBuffer1);
10378 0 : ShowContinueError(state, thisDXCoil.HighAmbBuffer2);
10379 0 : ShowContinueError(state, "... Operation at high inlet temperatures may require special performance curves.");
10380 : }
10381 0 : ShowRecurringWarningErrorAtEnd(state,
10382 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10383 : "\" - High condenser inlet temperature error continues...",
10384 0 : thisDXCoil.HighAmbErrIndex,
10385 0 : thisDXCoil.HighTempLast,
10386 0 : thisDXCoil.HighTempLast,
10387 : _,
10388 : "[C]",
10389 : "[C]");
10390 : }
10391 : }
10392 :
10393 49499 : if (thisDXCoil.PrintLowOutTempMessage) {
10394 0 : if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
10395 0 : if (thisDXCoil.LowOutletTempIndex == 0) {
10396 0 : ShowWarningMessage(state, thisDXCoil.LowOutTempBuffer1);
10397 0 : ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
10398 0 : ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
10399 0 : ShowContinueError(state,
10400 0 : format(" 1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
10401 0 : thisDXCoil.FullLoadInletAirTempLast));
10402 0 : ShowContinueError(state, " 2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
10403 0 : ShowContinueError(state,
10404 : " 3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
10405 : }
10406 0 : ShowRecurringWarningErrorAtEnd(state,
10407 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10408 : "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
10409 : "Outlet air temperature statistics follow:",
10410 0 : thisDXCoil.LowOutletTempIndex,
10411 0 : thisDXCoil.FullLoadOutAirTempLast,
10412 0 : thisDXCoil.FullLoadOutAirTempLast);
10413 : }
10414 : }
10415 :
10416 : // save last system time step and last end time of current time step (used to determine if warning is valid)
10417 49499 : thisDXCoil.TimeStepSysLast = TimeStepSys;
10418 49499 : thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime;
10419 49499 : thisDXCoil.PrintLowAmbMessage = false;
10420 49499 : thisDXCoil.PrintLowOutTempMessage = false;
10421 :
10422 49499 : if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
10423 : (compressorOp == HVAC::CompressorOp::On)) { // for cycling fan, reset mass flow to full on rate
10424 21285 : if (fanOp == HVAC::FanOp::Cycling) {
10425 43 : AirMassFlow /= PartLoadRatio;
10426 21242 : } else if (fanOp == HVAC::FanOp::Continuous) {
10427 21242 : AirMassFlow *= AirFlowRatio;
10428 : } else {
10429 0 : AirMassFlow = thisDXCoil.RatedAirMassFlowRate(Mode);
10430 : }
10431 :
10432 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton)
10433 :
10434 : // for some reason there are diff's when using coil inlet air pressure
10435 : // these lines (more to follow) are commented out for the time being
10436 :
10437 21285 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
10438 21285 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
10439 21285 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
10440 :
10441 21285 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
10442 0 : ShowFatalError(state, format("{} \"{}\" - Rated total cooling capacity is zero or less.", thisDXCoil.DXCoilType, thisDXCoil.Name));
10443 : }
10444 :
10445 23678 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag &&
10446 2393 : ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
10447 2393 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
10448 0 : if (thisDXCoil.ErrIndex1 == 0) {
10449 0 : ShowWarningMessage(
10450 : state,
10451 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at {:.3R} m3/s/W.",
10452 0 : thisDXCoil.DXCoilType,
10453 0 : thisDXCoil.Name,
10454 : VolFlowperRatedTotCap));
10455 0 : ShowContinueErrorTimeStamp(state, "");
10456 0 : ShowContinueError(state,
10457 0 : format("...Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
10458 0 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
10459 0 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
10460 0 : ShowContinueError(state, "...Possible causes include inconsistent air flow rates in system components,");
10461 0 : ShowContinueError(state, "...or mixing manual inputs with autosize inputs. Also check the following values and calculations.");
10462 0 : ShowContinueError(state, "...Volume Flow Rate per Rated Total Capacity = Volume Flow Rate / Rated Total Capacity");
10463 0 : ShowContinueError(state, "...Volume Flow Rate = Air Mass Flow Rate / Air Density");
10464 0 : ShowContinueError(state, "...Data used for calculations:");
10465 0 : ShowContinueError(state, format("...Rated Total Capacity = {:.2R} W.", thisDXCoil.RatedTotCap(Mode)));
10466 0 : ShowContinueError(state, "...Volume Flow Rate = Air Mass Flow Rate / Air Density");
10467 0 : ShowContinueError(state, format("...Volume Flow Rate = {:.8R} m3/s.", AirVolumeFlowRate));
10468 0 : ShowContinueError(state, format("...Air Mass Flow Rate = {:.8R} kg/s.", AirMassFlow));
10469 0 : ShowContinueError(
10470 : state,
10471 0 : format("...Air Density = {:.8R} kg/m3.", PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat)));
10472 0 : ShowContinueError(state, "...Data used for air density calculation:");
10473 0 : ShowContinueError(state, format("...Outdoor Air Pressure = {:.3R} Pa.", OutdoorPressure));
10474 0 : ShowContinueError(state, format("...Inlet Air Dry-Bulb Temp = {:.3R} C.", InletAirDryBulbTemp));
10475 0 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.8R} kgWater/kgDryAir.", InletAirHumRat));
10476 : }
10477 0 : ShowRecurringWarningErrorAtEnd(
10478 : state,
10479 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10480 : "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
10481 0 : thisDXCoil.ErrIndex1,
10482 : VolFlowperRatedTotCap,
10483 : VolFlowperRatedTotCap);
10484 : }
10485 : // Adjust coil bypass factor for actual air flow rate. Use relation CBF = exp(-NTU) where
10486 : // NTU = A0/(m*cp). Relationship models the cooling coil as a heat exchanger with Cmin/Cmax = 0.
10487 :
10488 21285 : RatedCBF = thisDXCoil.RatedCBF(Mode);
10489 21285 : if (RatedCBF > 0.0) {
10490 21285 : A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
10491 : } else {
10492 0 : A0 = 0.0;
10493 : }
10494 21285 : ADiff = -A0 / AirMassFlow;
10495 21285 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
10496 21285 : CBF = std::exp(ADiff);
10497 : } else {
10498 0 : CBF = 0.0;
10499 : }
10500 :
10501 : // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
10502 21285 : if (OutdoorDryBulb < thisDXCoil.MinOATCompressor && !state.dataGlobal->WarmupFlag) {
10503 0 : thisDXCoil.PrintLowAmbMessage = true;
10504 0 : thisDXCoil.LowTempLast = OutdoorDryBulb;
10505 0 : if (thisDXCoil.LowAmbErrIndex == 0) {
10506 0 : thisDXCoil.LowAmbBuffer1 = format("{} \"{}\" - Condenser inlet temperature below {:.2R} C. Condenser inlet temperature = {:.2R}",
10507 0 : thisDXCoil.DXCoilType,
10508 0 : thisDXCoil.Name,
10509 0 : thisDXCoil.MinOATCompressor,
10510 0 : OutdoorDryBulb);
10511 0 : thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
10512 0 : CreateSysTimeIntervalString(state);
10513 : }
10514 : }
10515 :
10516 : // check boundary for high ambient temperature and post warnings to individual DX coil buffers to print at end of time step
10517 21285 : if (OutdoorDryBulb > thisDXCoil.MaxOATCompressor && !state.dataGlobal->WarmupFlag) {
10518 27 : thisDXCoil.PrintHighAmbMessage = true;
10519 27 : thisDXCoil.HighTempLast = OutdoorDryBulb;
10520 27 : if (thisDXCoil.HighAmbErrIndex == 0) {
10521 54 : thisDXCoil.HighAmbBuffer1 = format("{} \"{}\" - Condenser inlet temperature above {:.2R} C. Condenser temperature = {:.2R}",
10522 27 : thisDXCoil.DXCoilType,
10523 27 : thisDXCoil.Name,
10524 27 : thisDXCoil.MaxOATCompressor,
10525 27 : OutdoorDryBulb);
10526 54 : thisDXCoil.HighAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
10527 81 : CreateSysTimeIntervalString(state);
10528 : }
10529 : }
10530 :
10531 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
10532 : // InletAirHumRat may be modified in this ADP/BF loop, use temporary variable for calculations
10533 21285 : InletAirHumRatTemp = InletAirHumRat;
10534 :
10535 21285 : Label50:;
10536 21285 : switch (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims) {
10537 21285 : case 1:
10538 21285 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC);
10539 21285 : break;
10540 0 : case 2:
10541 : default: // this default allows the simulation to continue, but will issue a warning, should be removed eventually
10542 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC, CondInletTemp);
10543 0 : break;
10544 : }
10545 :
10546 : // Warn user if curve output goes negative
10547 21285 : if (TotCapTempModFac < 0.0) {
10548 0 : if (thisDXCoil.CCapFTempErrorIndex == 0) {
10549 0 : ShowWarningMessage(state, format("{} \"{}\":", thisDXCoil.DXCoilType, thisDXCoil.Name));
10550 0 : ShowContinueError(
10551 0 : state, format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
10552 0 : ShowContinueError(
10553 : state,
10554 0 : format(" Negative value occurs using a condenser inlet temperature of {:.1T} and an inlet air wet-bulb temperature of {:.1T}.",
10555 : CondInletTemp,
10556 : InletAirWetBulbC));
10557 0 : if (Mode > 1) {
10558 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
10559 : }
10560 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
10561 : }
10562 0 : ShowRecurringWarningErrorAtEnd(
10563 : state,
10564 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10565 : "\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
10566 0 : thisDXCoil.CCapFTempErrorIndex,
10567 : TotCapTempModFac,
10568 : TotCapTempModFac);
10569 0 : TotCapTempModFac = 0.0;
10570 : }
10571 :
10572 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
10573 21285 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
10574 21285 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
10575 :
10576 : // Warn user if curve output goes negative
10577 21285 : if (TotCapFlowModFac < 0.0) {
10578 0 : if (thisDXCoil.CCapFFlowErrorIndex == 0) {
10579 0 : ShowWarningMessage(state, format("{} \"{}\":", thisDXCoil.DXCoilType, thisDXCoil.Name));
10580 0 : ShowContinueError(
10581 : state,
10582 0 : format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).", TotCapFlowModFac));
10583 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
10584 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
10585 0 : if (Mode > 1) {
10586 0 : ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
10587 : }
10588 : }
10589 0 : ShowRecurringWarningErrorAtEnd(
10590 : state,
10591 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10592 : "\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
10593 0 : thisDXCoil.CCapFFlowErrorIndex,
10594 : TotCapFlowModFac,
10595 : TotCapFlowModFac);
10596 0 : TotCapFlowModFac = 0.0;
10597 : }
10598 :
10599 21285 : if (present(MaxCoolCap)) {
10600 21278 : TotCap = min(MaxCoolCap, thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac);
10601 : } else {
10602 7 : TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
10603 : }
10604 :
10605 21285 : TotCap *= PartLoadRatio;
10606 :
10607 : // Calculate apparatus dew point conditions using TotCap and CBF
10608 21285 : hDelta = TotCap / AirMassFlow;
10609 : // there is an issue here with using CBF to calculate the ADP enthalpy.
10610 : // at low loads the bypass factor increases significantly.
10611 21285 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
10612 21285 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
10613 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10614 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
10615 21285 : wADP = min(InletAirHumRat, PsyWFnTdbH(state, tADP, hADP, RoutineName));
10616 21285 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
10617 21285 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
10618 18971 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
10619 : } else {
10620 2314 : SHR = 1.0;
10621 : }
10622 : // Check for dry evaporator conditions (win < wadp)
10623 21285 : if (wADP > InletAirHumRatTemp || (Counter >= 1 && Counter < MaxIter)) {
10624 0 : if (InletAirHumRatTemp == 0.0) {
10625 0 : InletAirHumRatTemp = 0.00001;
10626 : }
10627 0 : werror = (InletAirHumRatTemp - wADP) / InletAirHumRatTemp;
10628 : // Increase InletAirHumRatTemp at constant InletAirTemp to find coil dry-out point. Then use the
10629 : // capacity at the dry-out point to determine exiting conditions from coil. This is required
10630 : // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
10631 0 : InletAirHumRatTemp = RF * wADP + (1.0 - RF) * InletAirHumRatTemp;
10632 0 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRatTemp, OutdoorPressure);
10633 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10634 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRatTemp,InletAirPressure)
10635 0 : ++Counter;
10636 0 : if (std::abs(werror) > Tolerance) {
10637 0 : goto Label50; // Recalculate with modified inlet conditions
10638 : }
10639 : }
10640 :
10641 21285 : if (thisDXCoil.PLFFPLR(Mode) > 0 && CompCycRatio < 1.0) {
10642 26 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CompCycRatio); // Calculate part-load factor
10643 : } else {
10644 21259 : PLF = 1.0;
10645 : }
10646 :
10647 21285 : if (PLF < 0.7) {
10648 0 : if (thisDXCoil.ErrIndex2 == 0) {
10649 0 : ShowWarningMessage(
10650 : state,
10651 0 : format(
10652 0 : "The PLF curve value for the DX cooling coil {} ={:.3R} for part-load ratio ={:.3R}", thisDXCoil.Name, PLF, PartLoadRatio));
10653 0 : ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
10654 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
10655 : }
10656 0 : ShowRecurringWarningErrorAtEnd(
10657 0 : state, thisDXCoil.Name + ", DX cooling coil PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
10658 0 : PLF = 0.7;
10659 : }
10660 :
10661 21285 : thisDXCoil.PartLoadRatio = PartLoadRatio;
10662 21285 : thisDXCoil.CoolingCoilRuntimeFraction = CompCycRatio / PLF;
10663 21285 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
10664 0 : if (thisDXCoil.ErrIndex3 == 0) {
10665 0 : ShowWarningMessage(state,
10666 0 : format("The runtime fraction for DX cooling coil {} exceeded 1.0. [{:.4R}].",
10667 0 : thisDXCoil.Name,
10668 0 : thisDXCoil.CoolingCoilRuntimeFraction));
10669 0 : ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
10670 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
10671 0 : ShowContinueErrorTimeStamp(state, "");
10672 : }
10673 0 : ShowRecurringWarningErrorAtEnd(state,
10674 0 : thisDXCoil.Name + ", DX cooling coil runtime fraction > 1.0 warning continues...",
10675 0 : thisDXCoil.ErrIndex3,
10676 0 : thisDXCoil.CoolingCoilRuntimeFraction,
10677 0 : thisDXCoil.CoolingCoilRuntimeFraction);
10678 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
10679 21285 : } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
10680 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
10681 : }
10682 :
10683 : // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
10684 21285 : if (fanOp == HVAC::FanOp::Cycling) {
10685 43 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
10686 : }
10687 :
10688 : // Calculate full load output conditions
10689 : // if ( SHR > 1.0 || Counter > 0 ) SHR = 1.0;
10690 21285 : if (SHR > 1.0) {
10691 0 : SHR = 1.0;
10692 : }
10693 21285 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
10694 21285 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
10695 21285 : if (SHR < 1.0) {
10696 12378 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
10697 : } else {
10698 8907 : FullLoadOutAirHumRat = InletAirHumRat;
10699 : }
10700 21285 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
10701 :
10702 : // Check for saturation error and modify temperature at constant enthalpy
10703 21285 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure)) {
10704 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
10705 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10706 : // IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
10707 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
10708 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
10709 : }
10710 :
10711 : // Store actual outlet conditions when DX coil is ON for use in heat recovery module
10712 21285 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = FullLoadOutAirTemp;
10713 21285 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = FullLoadOutAirHumRat;
10714 :
10715 : // Add warning message for cold cooling coil (FullLoadOutAirTemp < 2 C)
10716 21285 : if (FullLoadOutAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
10717 0 : thisDXCoil.PrintLowOutTempMessage = true;
10718 0 : thisDXCoil.FullLoadOutAirTempLast = FullLoadOutAirTemp;
10719 0 : if (thisDXCoil.LowOutletTempIndex == 0) {
10720 0 : thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
10721 0 : thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
10722 : "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
10723 0 : thisDXCoil.DXCoilType,
10724 0 : thisDXCoil.Name,
10725 0 : FullLoadOutAirTemp);
10726 0 : thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
10727 0 : CreateSysTimeIntervalString(state);
10728 : }
10729 : }
10730 :
10731 : // If constant fan with cycling compressor, call function to determine "effective SHR"
10732 : // which includes the part-load degradation on latent capacity
10733 21285 : if (fanOp == HVAC::FanOp::Continuous && CompCycRatio < 1.0) {
10734 3662 : QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode)); // always the same number
10735 3662 : QLatActual = TotCap * (1.0 - SHR);
10736 3662 : SHRUnadjusted = SHR;
10737 3662 : SHR = CalcEffectiveSHR(
10738 : state, DXCoilNum, SHR, thisDXCoil.CoolingCoilRuntimeFraction, QLatRated, QLatActual, InletAirDryBulbTemp, InletAirWetBulbC, Mode);
10739 :
10740 : // Calculate full load output conditions
10741 : // if ( SHR > 1.0 || Counter > 0 ) SHR = 1.0;
10742 3662 : if (SHR > 1.0) {
10743 0 : SHR = 1.0;
10744 : }
10745 3662 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
10746 3662 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
10747 3662 : if (SHR < 1.0) {
10748 3180 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
10749 : } else {
10750 482 : FullLoadOutAirHumRat = InletAirHumRat;
10751 : }
10752 3662 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
10753 : }
10754 :
10755 : // Calculate actual outlet conditions for the input part load ratio
10756 : // Actual outlet conditions are "average" for time step when compressor cycles
10757 :
10758 21285 : if (fanOp == HVAC::FanOp::Continuous && CompCycRatio < 1.0) {
10759 : // Continuous fan, cycling compressor
10760 : // hmmm ... this seems wrong. PLR * AirFlowRatio = 1. So we get FullLoadOutAirEnth all this time. This is OK since above TotCap *=
10761 : // PLR.
10762 3662 : OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
10763 3662 : OutletAirHumRat = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirHumRat + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirHumRat);
10764 3662 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
10765 : } else {
10766 : // Default to cycling fan, cycling compressor
10767 17623 : OutletAirEnthalpy = FullLoadOutAirEnth;
10768 17623 : OutletAirHumRat = FullLoadOutAirHumRat;
10769 17623 : OutletAirTemp = FullLoadOutAirTemp;
10770 : }
10771 :
10772 : // Check for saturation error and modify temperature at constant enthalpy
10773 21285 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, RoutineName)) {
10774 436 : OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
10775 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10776 : // IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
10777 : // OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
10778 436 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
10779 : }
10780 :
10781 : // Reset AirMassFlow to inlet node air mass flow for final total, sensible and latent calculations
10782 : // since AirMassFlow might have been modified above (in this subroutine):
10783 : // IF (FanOpMode .EQ. FanOp::Cycling) AirMassFlow = AirMassFlow / PartLoadRatio
10784 : // For multimode coil, this should be full flow including bypassed fraction
10785 21285 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10786 :
10787 : // Coil total/sensible/latent cooling rates
10788 21285 : CalcComponentSensibleLatentOutput(AirMassFlow,
10789 : InletAirDryBulbTemp,
10790 : InletAirHumRat,
10791 : OutletAirTemp,
10792 : OutletAirHumRat,
10793 21285 : thisDXCoil.SensCoolingEnergyRate,
10794 21285 : thisDXCoil.LatCoolingEnergyRate,
10795 21285 : thisDXCoil.TotalCoolingEnergyRate);
10796 :
10797 21285 : thisDXCoil.OutletAirTemp = OutletAirTemp;
10798 21285 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
10799 21285 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
10800 :
10801 : } else {
10802 :
10803 : // DX coil is off; just pass through conditions
10804 28214 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10805 28214 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
10806 28214 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
10807 :
10808 28214 : thisDXCoil.ElecCoolingPower = 0.0;
10809 28214 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
10810 28214 : thisDXCoil.SensCoolingEnergyRate = 0.0;
10811 28214 : thisDXCoil.LatCoolingEnergyRate = 0.0;
10812 28214 : thisDXCoil.EvapCondPumpElecPower = 0.0;
10813 28214 : thisDXCoil.EvapWaterConsumpRate = 0.0;
10814 :
10815 : // Reset globals when DX coil is OFF for use in heat recovery module
10816 28214 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
10817 28214 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
10818 :
10819 : } // end of on/off if - else
10820 :
10821 : // set water system demand request (if needed)
10822 49499 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
10823 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
10824 0 : thisDXCoil.EvapWaterConsumpRate;
10825 : }
10826 :
10827 49499 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
10828 49499 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
10829 49499 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
10830 49499 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
10831 49499 : thisDXCoil.CondInletTemp = CondInletTemp;
10832 49499 : state.dataDXCoils->DXCoilTotalCooling(DXCoilNum) = thisDXCoil.TotalCoolingEnergyRate;
10833 49499 : state.dataDXCoils->DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
10834 :
10835 : // set outlet node conditions
10836 49499 : int airOutletNode = thisDXCoil.AirOutNode;
10837 49499 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
10838 49499 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
10839 49499 : }
10840 :
10841 177475 : void CalcDXHeatingCoil(EnergyPlusData &state,
10842 : int const DXCoilNum, // the number of the DX heating coil to be simulated
10843 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
10844 : HVAC::FanOp const fanOp, // Allows parent object to control fan mode
10845 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
10846 : ObjexxFCL::Optional<Real64 const> MaxHeatCap // maximum allowed heating capacity
10847 : )
10848 : {
10849 :
10850 : // SUBROUTINE INFORMATION:
10851 : // AUTHOR Richard Raustad
10852 : // DATE WRITTEN October 2001
10853 : // MODIFIED Raustad/Shirey Mar 2004
10854 : // Kenneth Tang 2004 (Sensitivity of TotCapTempModFac & EIRTempModFac to indoor dry bulb temp)
10855 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
10856 : // Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
10857 :
10858 : // PURPOSE OF THIS SUBROUTINE:
10859 : // Calculates the air-side heating performance and electrical heating energy
10860 : // use of a direct-expansion, air-cooled heat pump unit.
10861 :
10862 : // METHODOLOGY EMPLOYED:
10863 : // This routine simulates the performance of air-cooled DX heating equipment.
10864 : // The routine requires the user to enter the total heating capacity
10865 : // and COP for the unit at ARI 210/240 rating conditions (21.11C [70F] dry-bulb,
10866 : // 15.55C [60F] wet-bulb air entering the heating coil, 8.33C [47F] dry-bulb,
10867 : // 6.11C [43F] wet-bulb air entering the outdoor condenser. Since different
10868 : // manufacturer's rate their equipment at different air flow rates, the supply
10869 : // air flow rate corresponding to the rated capacities and rated COP must also
10870 : // be entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information
10871 : // entered by the user should NOT include the thermal or electrical impacts of the
10872 : // supply air fan, as this is addressed by another module.
10873 :
10874 : // With the rated performance data entered by the user, the model employs some of the
10875 : // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
10876 : // of outdoor air temperatures and supply air flow rate (actual vs rated flow). The
10877 : // model does NOT employ the exact same methodology to calculate performance as DOE-2,
10878 : // although some of the DOE-2 curve fits are employed by this model.
10879 :
10880 : // REFERENCES:
10881 : // Winkelmann, F.C., Birdsall, B.E., Buhl W.F., Ellington, K.L., Erdem, A.E. 1993.
10882 : // DOE-2 Supplement Version 2.1E. Energy and Environment Division, Lawrence Berkeley
10883 : // Laboratory.
10884 : // Henderson, H.I. Jr., Y.J. Huang and Danny Parker. 1999. Residential Equipment Part
10885 : // Load Curves for Use in DOE-2. Environmental Energy Technologies Division, Ernest
10886 : // Orlando Lawrence Berkeley National Laboratory.
10887 :
10888 : // Using/Aliasing
10889 : using Curve::CurveValue;
10890 :
10891 : // SUBROUTINE PARAMETER DEFINITIONS:
10892 : static constexpr std::string_view RoutineNameFullLoad("CalcDXHeatingCoil:fullload");
10893 :
10894 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10895 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
10896 : Real64 AirMassFlowRatio; // Ratio of actual air mass flow to rated air mass flow
10897 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s]
10898 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W]
10899 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
10900 : Real64 TotCapAdj; // adjusted total cooling capacity at off-rated conditions [W]
10901 : Real64 TotCapTempModFac; // Total capacity modifier (function of entering drybulb, outside drybulb) depending
10902 : // on the type of curve
10903 : Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs rated flow)
10904 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
10905 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
10906 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
10907 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
10908 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10909 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
10910 : Real64 FullLoadOutAirEnth; // outlet full load enthalpy [J/kg]
10911 : Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
10912 : Real64 FullLoadOutAirTemp; // outlet air temperature at full load [C]
10913 : Real64 FullLoadOutAirRH; // outlet air relative humidity at full load
10914 177475 : Real64 EIRTempModFac(0.0); // EIR modifier (function of entering drybulb, outside drybulb) depending on the
10915 : // type of curve
10916 : Real64 DefrostEIRTempModFac; // EIR modifier for defrost (function of entering wetbulb, outside drybulb)
10917 : Real64 EIRFlowModFac; // EIR modifier (function of actual supply air flow vs rated flow)
10918 : Real64 EIR; // EIR at part load and off rated conditions
10919 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup
10920 : Real64 PLRHeating; // PartLoadRatio in heating
10921 : Real64 OutdoorCoilT; // Outdoor coil temperature (C)
10922 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
10923 : Real64 FractionalDefrostTime; // Fraction of time step system is in defrost
10924 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
10925 : Real64 InputPowerMultiplier; // Multiplier for power when system is in defrost
10926 : Real64 LoadDueToDefrost; // Additional load due to defrost
10927 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
10928 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
10929 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
10930 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
10931 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
10932 177475 : constexpr int Mode(1); // Performance mode for MultiMode DX coil; Always 1 for other coil types
10933 : Real64 AirFlowRatio; // Ratio of compressor on airflow to average timestep airflow
10934 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
10935 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
10936 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
10937 177475 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
10938 :
10939 177475 : if (present(OnOffAirFlowRatio)) {
10940 177462 : AirFlowRatio = OnOffAirFlowRatio;
10941 : } else {
10942 13 : AirFlowRatio = 1.0;
10943 : }
10944 :
10945 177475 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
10946 : // Get condenser outdoor node info from DX Heating Coil
10947 177475 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
10948 49438 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp;
10949 49438 : CompAmbTemp = OutdoorDryBulb;
10950 49438 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
10951 32 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10952 32 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10953 32 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10954 32 : CompAmbTemp = state.dataEnvrn->OutDryBulbTemp;
10955 : } else {
10956 49406 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press;
10957 : // If node is not connected to anything, pressure = default, use weather data
10958 49406 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
10959 94 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10960 94 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10961 94 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10962 94 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10963 : } else {
10964 49312 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat;
10965 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
10966 49312 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb;
10967 : }
10968 49406 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
10969 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
10970 0 : OutdoorDryBulb = secZoneHB.ZT;
10971 0 : OutdoorHumRat = secZoneHB.airHumRat;
10972 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
10973 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10974 0 : CompAmbTemp = OutdoorDryBulb;
10975 : }
10976 : }
10977 128037 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
10978 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
10979 0 : OutdoorDryBulb = secZoneHB.ZT;
10980 0 : OutdoorHumRat = secZoneHB.airHumRat;
10981 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
10982 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10983 0 : CompAmbTemp = OutdoorDryBulb;
10984 : } else {
10985 128037 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10986 128037 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10987 128037 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10988 128037 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10989 128037 : CompAmbTemp = OutdoorDryBulb;
10990 : }
10991 :
10992 177475 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10993 177475 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
10994 177475 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10995 177475 : InletAirHumRat = thisDXCoil.InletAirHumRat;
10996 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
10997 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
10998 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
10999 177475 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
11000 177475 : PLRHeating = 0.0;
11001 177475 : thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
11002 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
11003 177475 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
11004 40005 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
11005 40005 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
11006 2 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
11007 : }
11008 : } else {
11009 137470 : CrankcaseHeatingPower = 0.0;
11010 : }
11011 :
11012 220922 : if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
11013 43447 : OutdoorDryBulb > thisDXCoil.MinOATCompressor) {
11014 : // for cycling fan, reset mass flow to full on rate
11015 14022 : if (fanOp == HVAC::FanOp::Cycling) {
11016 32 : AirMassFlow /= PartLoadRatio;
11017 : }
11018 14022 : if (fanOp == HVAC::FanOp::Continuous) {
11019 13990 : AirMassFlow *= AirFlowRatio;
11020 : }
11021 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton)
11022 14022 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
11023 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11024 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
11025 14022 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
11026 :
11027 28044 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
11028 14022 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
11029 1 : if (thisDXCoil.ErrIndex1 == 0) {
11030 2 : ShowWarningMessage(
11031 : state,
11032 2 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at {:.3R} m3/s/W.",
11033 1 : thisDXCoil.DXCoilType,
11034 1 : thisDXCoil.Name,
11035 : VolFlowperRatedTotCap));
11036 2 : ShowContinueErrorTimeStamp(state, "");
11037 2 : ShowContinueError(state,
11038 2 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
11039 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
11040 1 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
11041 2 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
11042 3 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
11043 : }
11044 8 : ShowRecurringWarningErrorAtEnd(
11045 : state,
11046 2 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
11047 : "\" - Air volume flow rate per watt of rated total heating capacity is out of range error continues...",
11048 1 : thisDXCoil.ErrIndex1,
11049 : VolFlowperRatedTotCap,
11050 : VolFlowperRatedTotCap);
11051 : }
11052 :
11053 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
11054 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
11055 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
11056 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
11057 14022 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
11058 15 : switch (thisDXCoil.HeatingPerformanceOATType) {
11059 15 : case HVAC::OATType::DryBulb: {
11060 15 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
11061 15 : } break;
11062 0 : case HVAC::OATType::WetBulb: {
11063 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp, OutdoorWetBulb);
11064 0 : } break;
11065 0 : default: {
11066 0 : TotCapTempModFac = 1.0;
11067 0 : } break;
11068 : }
11069 : } else {
11070 14007 : switch (thisDXCoil.HeatingPerformanceOATType) {
11071 14 : case HVAC::OATType::DryBulb: {
11072 14 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
11073 3 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), OutdoorDryBulb);
11074 : } else {
11075 11 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp);
11076 : }
11077 14 : } break;
11078 13993 : case HVAC::OATType::WetBulb: {
11079 13993 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
11080 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), OutdoorWetBulb);
11081 : } else {
11082 13993 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp);
11083 : }
11084 13993 : } break;
11085 0 : default: {
11086 0 : TotCapTempModFac = 1.0;
11087 0 : } break;
11088 : }
11089 : }
11090 :
11091 14022 : if (TotCapTempModFac < 0.0) {
11092 0 : if (thisDXCoil.CAPFTErrIndex == 0) {
11093 0 : ShowWarningMessage(state,
11094 0 : format("The TotCapTempModFac curve value for DX heating coil {} ={:.2R}", thisDXCoil.Name, TotCapTempModFac));
11095 0 : ShowContinueError(state,
11096 : "TotCapTempModFac curve value must be > 0. TotCapTempModFac curve value has been reset to 0.0 and "
11097 : "simulation is continuing.");
11098 0 : ShowContinueError(state, format("Check the IO reference manual for TotCapTempModFac curve guidance [ {} ].", thisDXCoil.DXCoilType));
11099 0 : ShowContinueErrorTimeStamp(state, "");
11100 : }
11101 0 : ShowRecurringWarningErrorAtEnd(state,
11102 : "DX heating coil TotCapTempModFac curve value < 0 warning continues... ",
11103 0 : thisDXCoil.CAPFTErrIndex,
11104 : TotCapTempModFac,
11105 : TotCapTempModFac);
11106 0 : TotCapTempModFac = 0.0;
11107 : }
11108 :
11109 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
11110 14022 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
11111 14022 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
11112 :
11113 : // Calculate total heating capacity for off-rated conditions
11114 14022 : TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
11115 :
11116 : // Calculating adjustment factors for defrost
11117 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
11118 14022 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
11119 14022 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
11120 :
11121 : // Initializing defrost adjustment factors
11122 14022 : LoadDueToDefrost = 0.0;
11123 14022 : HeatingCapacityMultiplier = 1.0;
11124 14022 : FractionalDefrostTime = 0.0;
11125 14022 : InputPowerMultiplier = 1.0;
11126 :
11127 : // Check outdoor temperature to determine of defrost is active
11128 14022 : if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost && thisDXCoil.CondenserType(Mode) != DataHeatBalance::RefrigCondenserType::Water) {
11129 : // Calculate defrost adjustment factors depending on defrost control type
11130 37 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
11131 37 : FractionalDefrostTime = thisDXCoil.DefrostTime;
11132 37 : if (FractionalDefrostTime > 0.0) {
11133 37 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
11134 1 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
11135 1 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
11136 : } else {
11137 36 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
11138 36 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
11139 36 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
11140 0 : ShowWarningMessage(state,
11141 0 : format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
11142 : "actuator must be both provided for DX heating coil {}",
11143 0 : thisDXCoil.Name));
11144 0 : ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
11145 : }
11146 : }
11147 : }
11148 : } else { // else defrost control is on-demand
11149 0 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
11150 0 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
11151 0 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
11152 0 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
11153 : } else {
11154 0 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
11155 0 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
11156 0 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
11157 0 : ShowWarningMessage(state,
11158 0 : format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
11159 : "actuator must be both provided for DX heating coil {}",
11160 0 : thisDXCoil.Name));
11161 0 : ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
11162 : }
11163 : }
11164 : }
11165 :
11166 37 : if (FractionalDefrostTime > 0.0) {
11167 : // Calculate defrost adjustment factors depending on defrost control strategy
11168 37 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
11169 32 : LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.RatedTotCap(Mode) / 1.01667);
11170 32 : DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
11171 32 : thisDXCoil.DefrostPower = DefrostEIRTempModFac * (thisDXCoil.RatedTotCap(Mode) / 1.01667) * FractionalDefrostTime;
11172 : } else { // Defrost strategy is resistive
11173 5 : thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
11174 : }
11175 : } else { // Defrost is not active because (FractionalDefrostTime .EQ. 0.0)
11176 0 : thisDXCoil.DefrostPower = 0.0;
11177 : }
11178 : }
11179 :
11180 : // Modify total heating capacity based on defrost heating capacity multiplier
11181 : // MaxHeatCap passed from parent object VRF Condenser and is used to limit capacity of TU's to that available from condenser
11182 14022 : if (present(MaxHeatCap)) {
11183 13997 : TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
11184 13997 : TotCap = min(MaxHeatCap, TotCap);
11185 : } else {
11186 25 : TotCapAdj = TotCap * HeatingCapacityMultiplier;
11187 : }
11188 :
11189 : // Calculate full load outlet conditions
11190 14022 : FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
11191 14022 : FullLoadOutAirHumRat = InletAirHumRat;
11192 14022 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
11193 14022 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
11194 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11195 : // FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
11196 14022 : if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
11197 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
11198 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11199 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
11200 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
11201 : }
11202 :
11203 : // Calculate actual outlet conditions for the input part load ratio
11204 : // Actual outlet conditions are "average" for time step
11205 14022 : if (fanOp == HVAC::FanOp::Continuous) {
11206 : // continuous fan, cycling compressor
11207 13990 : OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
11208 13990 : OutletAirHumRat = (PartLoadRatio * FullLoadOutAirHumRat + (1.0 - PartLoadRatio) * InletAirHumRat);
11209 13990 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11210 : } else {
11211 : // default to cycling fan, cycling compressor
11212 32 : OutletAirEnthalpy = FullLoadOutAirEnth;
11213 32 : OutletAirHumRat = FullLoadOutAirHumRat;
11214 32 : OutletAirTemp = FullLoadOutAirTemp;
11215 : }
11216 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
11217 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
11218 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
11219 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
11220 14022 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
11221 18 : if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 1) {
11222 2 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), OutdoorDryBulb);
11223 : } else {
11224 16 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
11225 : }
11226 18 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
11227 : } else {
11228 14004 : EIRTempModFac = 1.0;
11229 14004 : EIRFlowModFac = 1.0;
11230 : }
11231 :
11232 14022 : if (EIRTempModFac < 0.0) {
11233 0 : if (thisDXCoil.EIRFTErrIndex == 0) {
11234 0 : ShowWarningMessage(state, format("The EIRTempModFac curve value for DX heating coil {} ={:.2R}", thisDXCoil.Name, EIRTempModFac));
11235 0 : ShowContinueError(
11236 : state, "EIRTempModFac curve value must be > 0. EIRTempModFac curve value has been reset to 0.0 and simulation is continuing.");
11237 0 : ShowContinueError(state, format("Check the IO reference manual for EIRTempModFac curve guidance [ {} ].", thisDXCoil.DXCoilType));
11238 0 : ShowContinueErrorTimeStamp(state, "");
11239 : }
11240 0 : ShowRecurringWarningErrorAtEnd(state,
11241 : "DX heating coil EIRTempModFac curve value < 0.0 warning continues... ",
11242 0 : thisDXCoil.EIRFTErrIndex,
11243 : EIRTempModFac,
11244 : EIRTempModFac);
11245 0 : EIRTempModFac = 0.0;
11246 : }
11247 :
11248 14022 : EIR = thisDXCoil.RatedEIR(Mode) * EIRTempModFac * EIRFlowModFac;
11249 : // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
11250 14022 : if (TotCapAdj > 0.0) {
11251 14021 : PLRHeating = min(1.0, (PartLoadRatio + (LoadDueToDefrost * PartLoadRatio) / TotCapAdj));
11252 : } else {
11253 1 : PLRHeating = 0.0;
11254 : }
11255 14022 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating) {
11256 18 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PLRHeating); // Calculate part-load factor
11257 : } else {
11258 14004 : PLF = 1.0;
11259 : }
11260 :
11261 14022 : if (PLF < 0.7) {
11262 1 : if (thisDXCoil.PLRErrIndex == 0) {
11263 2 : ShowWarningMessage(
11264 : state,
11265 2 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
11266 2 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
11267 2 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
11268 3 : ShowContinueErrorTimeStamp(state, "");
11269 : }
11270 7 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
11271 1 : PLF = 0.7;
11272 : }
11273 :
11274 14022 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
11275 14022 : if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
11276 0 : if (thisDXCoil.ErrIndex4 == 0) {
11277 0 : ShowWarningMessage(state,
11278 0 : format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
11279 0 : thisDXCoil.Name,
11280 0 : thisDXCoil.HeatingCoilRuntimeFraction));
11281 0 : ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
11282 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
11283 0 : ShowContinueErrorTimeStamp(state, "");
11284 : }
11285 0 : ShowRecurringWarningErrorAtEnd(state,
11286 0 : thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
11287 0 : thisDXCoil.ErrIndex4,
11288 0 : thisDXCoil.HeatingCoilRuntimeFraction,
11289 0 : thisDXCoil.HeatingCoilRuntimeFraction);
11290 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
11291 14022 : } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
11292 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
11293 : }
11294 : // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
11295 14022 : if (fanOp == HVAC::FanOp::Cycling) {
11296 32 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
11297 : }
11298 14022 : thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
11299 :
11300 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
11301 : // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
11302 :
11303 14022 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
11304 14017 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
11305 : } else {
11306 5 : thisDXCoil.CrankcaseHeaterPower =
11307 5 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
11308 5 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
11309 : }
11310 :
11311 14022 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
11312 14022 : thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy);
11313 : // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
11314 : // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
11315 14022 : thisDXCoil.DefrostPower *= thisDXCoil.HeatingCoilRuntimeFraction;
11316 :
11317 14022 : thisDXCoil.OutletAirTemp = OutletAirTemp;
11318 14022 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
11319 14022 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
11320 14022 : thisDXCoil.CompressorPartLoadRatio = PartLoadRatio;
11321 :
11322 : } else {
11323 :
11324 : // DX coil is off; just pass through conditions
11325 163453 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
11326 163453 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
11327 163453 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
11328 :
11329 163453 : thisDXCoil.ElecHeatingPower = 0.0;
11330 163453 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
11331 163453 : thisDXCoil.DefrostPower = 0.0;
11332 :
11333 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
11334 : // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
11335 163453 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
11336 35512 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
11337 : } else {
11338 127941 : thisDXCoil.CrankcaseHeaterPower =
11339 127941 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
11340 : }
11341 163453 : thisDXCoil.CompressorPartLoadRatio = 0.0;
11342 :
11343 : } // end of on/off if - else
11344 :
11345 177475 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
11346 177475 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
11347 177475 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
11348 177475 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
11349 177475 : state.dataDXCoils->DXCoilTotalHeating(DXCoilNum) = thisDXCoil.TotalHeatingEnergyRate;
11350 177475 : state.dataDXCoils->DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
11351 177475 : state.dataDXCoils->DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;
11352 :
11353 : // set outlet node conditions
11354 177475 : int airOutletNode = thisDXCoil.AirOutNode;
11355 177475 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
11356 177475 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
11357 :
11358 : // calc secondary coil if specified
11359 177475 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
11360 0 : CalcSecondaryDXCoils(state, DXCoilNum);
11361 : }
11362 177475 : }
11363 :
11364 36791 : void CalcMultiSpeedDXCoil(EnergyPlusData &state,
11365 : int const DXCoilNum, // the number of the DX heating coil to be simulated
11366 : Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
11367 : Real64 const CycRatio, // cycling part load ratio
11368 : ObjexxFCL::Optional_bool_const ForceOn)
11369 : {
11370 :
11371 : // SUBROUTINE INFORMATION:
11372 : // AUTHOR Fred Buhl
11373 : // DATE WRITTEN September 2002
11374 : // MODIFIED Raustad/Shirey, Feb 2004
11375 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
11376 : // Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
11377 : // April 2010, Chandan sharma, FSEC, added basin heater
11378 :
11379 : // PURPOSE OF THIS SUBROUTINE:
11380 : // Calculates the air-side performance and electrical energy use of a direct-
11381 : // expansion, air-cooled cooling unit with a 2 speed or variable speed compressor.
11382 :
11383 : // METHODOLOGY EMPLOYED:
11384 : // Uses the same methodology as the single speed DX unit model (SUBROUTINE CalcDoe2DXCoil).
11385 : // In addition it assumes that the unit performance is obtained by interpolating between
11386 : // the performance at high speed and that at low speed. If the output needed is below
11387 : // that produced at low speed, the compressor cycles between off and low speed.
11388 :
11389 : // Using/Aliasing
11390 : using Curve::CurveValue;
11391 :
11392 : // SUBROUTINE ARGUMENT DEFINITIONS:
11393 : // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
11394 :
11395 : // SUBROUTINE PARAMETER DEFINITIONS:
11396 : static constexpr std::string_view RoutineNameHighSpeedOutlet("CalcMultiSpeedDXCoil:highspeedoutlet");
11397 : static constexpr std::string_view RoutineNameLowSpeedOutlet("CalcMultiSpeedDXCoil:lowspeedoutlet");
11398 : static constexpr std::string_view RoutineNameNewDewPointConditions("CalcMultiSpeedDXCoil:newdewpointconditions");
11399 :
11400 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11401 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
11402 : Real64 AirMassFlowRatio; // Ratio of max air mass flow to rated air mass flow
11403 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
11404 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
11405 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
11406 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
11407 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11408 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
11409 : Real64 OutletAirDryBulbTemp; // outlet air dry bulb temperature [C]
11410 : Real64 OutletAirEnthalpy; // outlet air enthalpy [J/kg]
11411 : Real64 OutletAirHumRat; // outlet air humidity ratio [kg/kg]
11412 : Real64 OutletAirDryBulbTempSat; // outlet air dry bulb temp at saturation at the outlet enthalpy [C]
11413 : Real64 LSOutletAirDryBulbTemp; // low speed outlet air dry bulb temperature [C]
11414 : Real64 LSOutletAirEnthalpy; // low speed outlet air enthalpy [J/kg]
11415 : Real64 LSOutletAirHumRat; // low speed outlet air humidity ratio [kg/kg]
11416 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
11417 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
11418 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
11419 : Real64 tADP; // Apparatus dew point temperature [C]
11420 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
11421 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
11422 : Real64 RatedCBFHS; // coil bypass factor at rated conditions (high speed)
11423 : Real64 CBFHS; // coil bypass factor at max flow (high speed)
11424 : Real64 TotCapHS; // total capacity at high speed [W]
11425 : Real64 SHRHS; // sensible heat ratio at high speed
11426 : Real64 TotCapLS; // total capacity at low speed [W]
11427 : Real64 SHRLS; // sensible heat ratio at low speed
11428 : Real64 EIRTempModFacHS; // EIR modifier (function of entering wetbulb, outside drybulb) (high speed)
11429 : Real64 EIRFlowModFacHS; // EIR modifier (function of actual supply air flow vs rated flow) (high speed)
11430 : Real64 EIRHS; // EIR at off rated conditions (high speed)
11431 : Real64 EIRTempModFacLS; // EIR modifier (function of entering wetbulb, outside drybulb) (low speed)
11432 : Real64 EIRLS; // EIR at off rated conditions (low speed)
11433 : Real64 TotCap; // total capacity at current speed [W]
11434 : Real64 SHR; // sensible heat ratio at current speed
11435 : Real64 EIR; // EIR at current speed
11436 : Real64 AirMassFlowNom; // speed ratio weighted average of high and low speed air mass flow rates [kg/s]
11437 : Real64 CBFNom; // coil bypass factor corresponding to AirMassFlowNom and SpeedRatio
11438 : Real64 CBF; // CBFNom adjusted for actual air mass flow rate
11439 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in
11440 : // power calculation
11441 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
11442 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
11443 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
11444 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
11445 : Real64 RhoAir; // Density of air [kg/m3]
11446 : Real64 RhoWater; // Density of water [kg/m3]
11447 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
11448 : Real64 EvapCondPumpElecPower; // Evaporative condenser electric pump power [W]
11449 36791 : constexpr int Mode(1); // Performance mode for MultiMode DX coil; Always 1 for other coil types
11450 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
11451 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
11452 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
11453 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
11454 : bool LocalForceOn;
11455 : Real64 AirMassFlowRatio2; // Ratio of low speed air mass flow to rated air mass flow
11456 36791 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
11457 :
11458 36791 : if (present(ForceOn)) {
11459 3306 : LocalForceOn = true;
11460 : } else {
11461 33485 : LocalForceOn = false;
11462 : }
11463 :
11464 36791 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
11465 :
11466 36791 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
11467 0 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
11468 : // If node is not connected to anything, pressure = default, use weather data
11469 0 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
11470 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
11471 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
11472 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11473 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
11474 : } else {
11475 0 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
11476 0 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
11477 0 : OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure);
11478 : }
11479 0 : CompAmbTemp = OutdoorDryBulb;
11480 0 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
11481 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
11482 0 : OutdoorDryBulb = secZoneHB.ZT;
11483 0 : OutdoorHumRat = secZoneHB.airHumRat;
11484 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
11485 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11486 0 : CompAmbTemp = OutdoorDryBulb;
11487 : }
11488 36791 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
11489 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
11490 0 : OutdoorDryBulb = secZoneHB.ZT;
11491 0 : OutdoorHumRat = secZoneHB.airHumRat;
11492 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
11493 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11494 0 : CompAmbTemp = OutdoorDryBulb;
11495 : } else {
11496 36791 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
11497 36791 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
11498 36791 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11499 36791 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
11500 36791 : CompAmbTemp = OutdoorDryBulb;
11501 : }
11502 :
11503 36791 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
11504 36791 : AirMassFlowRatio = thisDXCoil.InletAirMassFlowRateMax / thisDXCoil.RatedAirMassFlowRate(Mode);
11505 36791 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
11506 36791 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
11507 36791 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
11508 36791 : InletAirHumRat = thisDXCoil.InletAirHumRat;
11509 36791 : AirMassFlowRatio2 = 1.0; // DXCoil(DXCoilNum)%RatedAirMassFlowRate2 / DXCoil(DXCoilNum)%RatedAirMassFlowRate(Mode)
11510 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11511 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
11512 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
11513 36791 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
11514 36791 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
11515 36780 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
11516 11 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11517 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
11518 11 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
11519 11 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
11520 : }
11521 :
11522 58329 : if ((AirMassFlow > 0.0 && CompAmbTemp >= thisDXCoil.MinOATCompressor) && ((thisDXCoil.availSched->getCurrentVal() > 0.0) || (LocalForceOn)) &&
11523 21538 : (SpeedRatio > 0.0 || CycRatio > 0.0)) {
11524 :
11525 29226 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
11526 29226 : if (SpeedRatio > 0.0) {
11527 : // Adjust high speed coil bypass factor for actual maximum air flow rate.
11528 15248 : RatedCBFHS = thisDXCoil.RatedCBF(Mode);
11529 15248 : CBFHS = AdjustCBF(RatedCBFHS, thisDXCoil.RatedAirMassFlowRate(Mode), thisDXCoil.InletAirMassFlowRateMax);
11530 : // get high speed total capacity and SHR at current conditions
11531 45744 : CalcTotCapSHR(state,
11532 : InletAirDryBulbTemp,
11533 : InletAirHumRat,
11534 : InletAirEnthalpy,
11535 : InletAirWetBulbC,
11536 : AirMassFlowRatio,
11537 : thisDXCoil.InletAirMassFlowRateMax,
11538 15248 : thisDXCoil.RatedTotCap(Mode),
11539 : CBFHS,
11540 15248 : thisDXCoil.CCapFTemp(Mode),
11541 15248 : thisDXCoil.CCapFFlow(Mode),
11542 : TotCapHS,
11543 : SHRHS,
11544 : CondInletTemp,
11545 : OutdoorPressure,
11546 15248 : thisDXCoil.capModFacTotal);
11547 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11548 : // CondInletTemp, Node(DXCoil(DXCoilNum)%AirInNode)%Press)
11549 : // get the high speed SHR from user specified SHR modifier curves
11550 15248 : if (thisDXCoil.UserSHRCurveExists) {
11551 0 : SHRHS = CalcSHRUserDefinedCurves(state,
11552 : InletAirDryBulbTemp,
11553 : InletAirWetBulbC,
11554 : AirMassFlowRatio,
11555 0 : thisDXCoil.SHRFTemp(Mode),
11556 0 : thisDXCoil.SHRFFlow(Mode),
11557 0 : thisDXCoil.RatedSHR(Mode));
11558 : }
11559 : // get low speed total capacity and SHR at current conditions
11560 15248 : CalcTotCapSHR(state,
11561 : InletAirDryBulbTemp,
11562 : InletAirHumRat,
11563 : InletAirEnthalpy,
11564 : InletAirWetBulbC,
11565 : 1.0,
11566 : thisDXCoil.RatedAirMassFlowRate2,
11567 : thisDXCoil.RatedTotCap2,
11568 : thisDXCoil.RatedCBF2,
11569 : thisDXCoil.CCapFTemp2,
11570 15248 : thisDXCoil.CCapFFlow(Mode),
11571 : TotCapLS,
11572 : SHRLS,
11573 : CondInletTemp,
11574 : OutdoorPressure,
11575 15248 : thisDXCoil.capModFacTotal);
11576 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11577 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)
11578 : // get the low speed SHR from user specified SHR modifier curves
11579 15248 : if (thisDXCoil.UserSHRCurveExists) {
11580 0 : SHRLS = CalcSHRUserDefinedCurves(state,
11581 : InletAirDryBulbTemp,
11582 : InletAirWetBulbC,
11583 : AirMassFlowRatio2,
11584 : thisDXCoil.SHRFTemp2,
11585 : thisDXCoil.SHRFFlow2,
11586 : thisDXCoil.RatedSHR2);
11587 : }
11588 : // get high speed EIR at current conditions
11589 15248 : EIRTempModFacHS = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirWetBulbC, CondInletTemp);
11590 15248 : EIRFlowModFacHS = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
11591 15248 : EIRHS = thisDXCoil.RatedEIR(Mode) * EIRFlowModFacHS * EIRTempModFacHS;
11592 : // get low speed EIR at current conditions
11593 : // EIRTempModFacLS = CurveValue(state, DXCoil(DXCoilNum)%EIRFTemp(Mode),InletAirWetBulbC,CondInletTemp)
11594 : // CR7307 changed EIRTempModFacLS calculation to that shown below.
11595 15248 : EIRTempModFacLS = CurveValue(state, thisDXCoil.EIRFTemp2, InletAirWetBulbC, CondInletTemp);
11596 15248 : EIRLS = thisDXCoil.RatedEIR2 * EIRTempModFacLS;
11597 :
11598 : // get current total capacity, SHR, EIR
11599 15248 : if (SpeedRatio >= 1.0) {
11600 5106 : TotCap = TotCapHS;
11601 5106 : SHR = SHRHS;
11602 5106 : EIR = EIRHS;
11603 5106 : CBFNom = CBFHS;
11604 5106 : AirMassFlowNom = thisDXCoil.InletAirMassFlowRateMax;
11605 5106 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
11606 5106 : EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower(Mode);
11607 : } else {
11608 10142 : TotCap = SpeedRatio * TotCapHS + (1.0 - SpeedRatio) * TotCapLS;
11609 10142 : EIR = SpeedRatio * EIRHS + (1.0 - SpeedRatio) * EIRLS;
11610 10142 : CBFNom = SpeedRatio * CBFHS + (1.0 - SpeedRatio) * thisDXCoil.RatedCBF2;
11611 10142 : AirMassFlowNom = SpeedRatio * thisDXCoil.InletAirMassFlowRateMax + (1.0 - SpeedRatio) * thisDXCoil.RatedAirMassFlowRate2;
11612 10142 : CondAirMassFlow = RhoAir * (SpeedRatio * thisDXCoil.EvapCondAirFlow(Mode) + (1.0 - SpeedRatio) * thisDXCoil.EvapCondAirFlow2);
11613 10142 : EvapCondPumpElecPower =
11614 10142 : SpeedRatio * thisDXCoil.EvapCondPumpElecNomPower(Mode) + (1.0 - SpeedRatio) * thisDXCoil.EvapCondPumpElecNomPower2;
11615 : }
11616 15248 : hDelta = TotCap / AirMassFlow;
11617 15248 : if (thisDXCoil.UserSHRCurveExists) {
11618 0 : if (SpeedRatio >= 1.0) {
11619 0 : SHR = SHRHS;
11620 : } else {
11621 0 : SHR = min(SpeedRatio * SHRHS + (1.0 - SpeedRatio) * SHRLS, 1.0);
11622 : }
11623 0 : OutletAirEnthalpy = InletAirEnthalpy - hDelta;
11624 0 : if (SHR < 1.0) {
11625 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11626 0 : OutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11627 0 : if (OutletAirHumRat <= 0.0) {
11628 0 : OutletAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
11629 : }
11630 : } else {
11631 0 : SHR = 1.0;
11632 0 : OutletAirHumRat = InletAirHumRat;
11633 : }
11634 0 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11635 0 : OutletAirDryBulbTempSat = PsyTdpFnWPb(state, OutletAirHumRat, OutdoorPressure, RoutineNameHighSpeedOutlet);
11636 0 : if (OutletAirDryBulbTempSat > OutletAirDryBulbTemp) {
11637 0 : OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11638 0 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy, RoutineNameHighSpeedOutlet);
11639 : }
11640 :
11641 : } else {
11642 : // Adjust CBF for off-nominal flow
11643 15248 : CBF = AdjustCBF(CBFNom, AirMassFlowNom, AirMassFlow);
11644 : // Calculate new apparatus dew point conditions
11645 15248 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
11646 15248 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure);
11647 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11648 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
11649 15248 : wADP = PsyWFnTdbH(state, tADP, hADP);
11650 15248 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
11651 : // get corresponding SHR
11652 15248 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
11653 15248 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
11654 : } else {
11655 0 : SHR = 1.0;
11656 : }
11657 :
11658 : // cr8918 SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
11659 15248 : OutletAirEnthalpy = InletAirEnthalpy - hDelta;
11660 : // get outlet conditions
11661 15248 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11662 15248 : OutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11663 :
11664 15248 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11665 15248 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
11666 15248 : if (OutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
11667 12 : OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11668 12 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy);
11669 : }
11670 : }
11671 : // Coil total/sensible/latent cooling rates and electrical power
11672 15248 : CalcComponentSensibleLatentOutput(AirMassFlow,
11673 : InletAirDryBulbTemp,
11674 : InletAirHumRat,
11675 : OutletAirDryBulbTemp,
11676 : OutletAirHumRat,
11677 15248 : thisDXCoil.SensCoolingEnergyRate,
11678 15248 : thisDXCoil.LatCoolingEnergyRate,
11679 15248 : thisDXCoil.TotalCoolingEnergyRate);
11680 15248 : thisDXCoil.ElecCoolingPower = TotCap * EIR;
11681 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
11682 15248 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
11683 15248 : thisDXCoil.PartLoadRatio = 1.0;
11684 15248 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0;
11685 :
11686 15248 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
11687 15248 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
11688 15248 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
11689 :
11690 13978 : } else if (CycRatio > 0.0) {
11691 :
11692 13978 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11693 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
11694 2 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect2);
11695 2 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
11696 : }
11697 :
11698 : // Adjust low speed coil bypass factor for actual flow rate.
11699 : // CBF = AdjustCBF(DXCoil(DXCoilNum)%RatedCBF2,DXCoil(DXCoilNum)%RatedAirMassFlowRate2,AirMassFlow)
11700 : // get low speed total capacity and SHR at current conditions
11701 13978 : CalcTotCapSHR(state,
11702 : InletAirDryBulbTemp,
11703 : InletAirHumRat,
11704 : InletAirEnthalpy,
11705 : InletAirWetBulbC,
11706 : 1.0,
11707 : thisDXCoil.RatedAirMassFlowRate2,
11708 : thisDXCoil.RatedTotCap2,
11709 : thisDXCoil.RatedCBF2,
11710 : thisDXCoil.CCapFTemp2,
11711 13978 : thisDXCoil.CCapFFlow(Mode),
11712 : TotCapLS,
11713 : SHRLS,
11714 : CondInletTemp,
11715 : OutdoorPressure,
11716 13978 : thisDXCoil.capModFacTotal);
11717 : // get the low speed SHR from user specified SHR modifier curves
11718 13978 : if (thisDXCoil.UserSHRCurveExists) {
11719 0 : SHRLS = CalcSHRUserDefinedCurves(
11720 : state, InletAirDryBulbTemp, InletAirWetBulbC, 1.0, thisDXCoil.SHRFTemp2, thisDXCoil.SHRFFlow2, thisDXCoil.RatedSHR2);
11721 : }
11722 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11723 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)
11724 13978 : hDelta = TotCapLS / AirMassFlow;
11725 13978 : if (thisDXCoil.UserSHRCurveExists) {
11726 0 : SHR = SHRLS;
11727 0 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
11728 0 : if (SHR < 1.0) {
11729 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11730 0 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11731 0 : if (LSOutletAirHumRat <= 0.0) {
11732 0 : LSOutletAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
11733 : }
11734 : } else {
11735 0 : SHR = 1.0;
11736 0 : LSOutletAirHumRat = InletAirHumRat;
11737 : }
11738 0 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
11739 0 : OutletAirDryBulbTempSat = PsyTdpFnWPb(state, LSOutletAirHumRat, OutdoorPressure, RoutineNameLowSpeedOutlet);
11740 0 : if (OutletAirDryBulbTempSat > LSOutletAirDryBulbTemp) {
11741 0 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11742 0 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineNameLowSpeedOutlet);
11743 : }
11744 :
11745 : } else {
11746 : // Adjust CBF for off-nominal flow
11747 13978 : CBF = AdjustCBF(thisDXCoil.RatedCBF2, thisDXCoil.RatedAirMassFlowRate2, AirMassFlow);
11748 : // Calculate new apparatus dew point conditions
11749 13978 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
11750 13978 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineNameNewDewPointConditions);
11751 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
11752 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
11753 13978 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineNameNewDewPointConditions);
11754 13978 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
11755 : // get corresponding SHR
11756 13978 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
11757 13978 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
11758 : } else {
11759 0 : SHR = 1.0;
11760 : }
11761 : // cr8918 SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
11762 : // get low speed outlet conditions
11763 13978 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
11764 13978 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11765 13978 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11766 13978 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
11767 13978 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineNameLowSpeedOutlet);
11768 13978 : if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
11769 6 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11770 6 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineNameLowSpeedOutlet);
11771 : }
11772 : }
11773 : // outlet conditions are average of inlet and low speed weighted by CycRatio
11774 13978 : OutletAirEnthalpy = CycRatio * LSOutletAirEnthalpy + (1.0 - CycRatio) * InletAirEnthalpy;
11775 13978 : OutletAirHumRat = CycRatio * LSOutletAirHumRat + (1.0 - CycRatio) * InletAirHumRat;
11776 13978 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11777 : // get low speed EIR at current conditions
11778 : // EIRTempModFacLS = CurveValue(state, DXCoil(DXCoilNum)%EIRFTemp(Mode),InletAirWetBulbC,CondInletTemp)
11779 : // CR7307 changed EIRTempModFacLS calculation to that shown below.
11780 13978 : EIRTempModFacLS = CurveValue(state, thisDXCoil.EIRFTemp2, InletAirWetBulbC, CondInletTemp);
11781 13978 : EIRLS = thisDXCoil.RatedEIR2 * EIRTempModFacLS;
11782 : // get the part load factor that will account for cycling losses
11783 13978 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CycRatio);
11784 13978 : if (PLF < 0.7) {
11785 0 : PLF = 0.7;
11786 : }
11787 : // calculate the run time fraction
11788 13978 : thisDXCoil.CoolingCoilRuntimeFraction = CycRatio / PLF;
11789 13978 : thisDXCoil.PartLoadRatio = CycRatio;
11790 13978 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
11791 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
11792 : }
11793 : // get the electrical power consumption
11794 13978 : thisDXCoil.ElecCoolingPower = TotCapLS * EIRLS * thisDXCoil.CoolingCoilRuntimeFraction;
11795 :
11796 : // Coil total/sensible/latent cooling rates and electrical power
11797 13978 : CalcComponentSensibleLatentOutput(AirMassFlow,
11798 : InletAirDryBulbTemp,
11799 : InletAirHumRat,
11800 : OutletAirDryBulbTemp,
11801 : OutletAirHumRat,
11802 13978 : thisDXCoil.SensCoolingEnergyRate,
11803 13978 : thisDXCoil.LatCoolingEnergyRate,
11804 13978 : thisDXCoil.TotalCoolingEnergyRate);
11805 13978 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
11806 13978 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
11807 13978 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
11808 13978 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
11809 13978 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow2 * thisDXCoil.CoolingCoilRuntimeFraction;
11810 13978 : EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower2 * thisDXCoil.CoolingCoilRuntimeFraction;
11811 : }
11812 :
11813 29226 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11814 : //******************
11815 : // WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
11816 : // H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
11817 : // /RhoWater [kgWater/m3]
11818 : //******************
11819 9 : RhoWater = RhoH2O(OutdoorDryBulb);
11820 9 : thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater;
11821 9 : thisDXCoil.EvapCondPumpElecPower = EvapCondPumpElecPower;
11822 : // set water system demand request (if needed)
11823 9 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
11824 :
11825 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
11826 0 : thisDXCoil.EvapWaterConsumpRate;
11827 : }
11828 :
11829 : // Calculate basin heater power
11830 9 : CalcBasinHeaterPower(state,
11831 : thisDXCoil.BasinHeaterPowerFTempDiff,
11832 : thisDXCoil.basinHeaterSched,
11833 : thisDXCoil.BasinHeaterSetPointTemp,
11834 9 : thisDXCoil.BasinHeaterPower);
11835 9 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
11836 : }
11837 :
11838 : } else {
11839 :
11840 : // DX coil is off; just pass through conditions
11841 7565 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
11842 7565 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
11843 7565 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
11844 :
11845 7565 : thisDXCoil.ElecCoolingPower = 0.0;
11846 7565 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
11847 7565 : thisDXCoil.SensCoolingEnergyRate = 0.0;
11848 7565 : thisDXCoil.LatCoolingEnergyRate = 0.0;
11849 7565 : thisDXCoil.EvapCondPumpElecPower = 0.0;
11850 7565 : thisDXCoil.EvapWaterConsumpRate = 0.0;
11851 :
11852 : // Calculate basin heater power
11853 7565 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11854 2 : CalcBasinHeaterPower(state,
11855 : thisDXCoil.BasinHeaterPowerFTempDiff,
11856 : thisDXCoil.basinHeaterSched,
11857 : thisDXCoil.BasinHeaterSetPointTemp,
11858 2 : thisDXCoil.BasinHeaterPower);
11859 : }
11860 : }
11861 :
11862 36791 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
11863 36791 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
11864 36791 : thisDXCoil.CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure
11865 :
11866 : // set outlet node conditions
11867 36791 : int airOutletNode = thisDXCoil.AirOutNode;
11868 36791 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
11869 36791 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
11870 :
11871 : // calc secondary coil if specified
11872 36791 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
11873 0 : CalcSecondaryDXCoils(state, DXCoilNum);
11874 : }
11875 36791 : }
11876 :
11877 0 : void CalcBasinHeaterPowerForMultiModeDXCoil(EnergyPlusData &state,
11878 : int const DXCoilNum, // Index of coil being simulated
11879 : HVAC::CoilMode const DehumidMode // Dehumidification mode (0=normal, 1=enhanced)
11880 : )
11881 : {
11882 :
11883 : // SUBROUTINE INFORMATION:
11884 : // AUTHOR Chandan Sharma, FSEC
11885 : // DATE WRITTEN May 2010
11886 :
11887 : // PURPOSE OF THIS SUBROUTINE:
11888 : // To calculate the basin heater power for multi mode DX cooling coil
11889 :
11890 : // METHODOLOGY EMPLOYED:
11891 : // The methodology employed is as follows:
11892 : // 1) If the number of capacity stages is equal to 1 and the CondenserType for stage 1
11893 : // is EvapCooled, then the basin heater power is calculated for (1-runtimefractionstage1) of DX coil
11894 : // 2) If the number of capacity stages is greater than 1, then
11895 : // a) If the CondenserType for stage 1 is EvapCooled, then the basin heater power is calculated for
11896 : // (1-runtimefractionofstage1) of DX coil
11897 : // b) Elseif the CondenserType for stage 2 is EvapCooled, then the basin heater power is calculated for
11898 : // (1-runtimefractionofstage2) of DX coil
11899 :
11900 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11901 : int PerfMode; // Performance mode for MultiMode DX coil; Always 1 for other coil types
11902 : // 1-2=normal mode: 1=stage 1 only, 2=stage 1&2
11903 : // 3-4=enhanced dehumidification mode: 3=stage 1 only, 4=stage 1&2
11904 :
11905 0 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
11906 :
11907 0 : if (thisDXCoil.NumCapacityStages == 1) {
11908 0 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
11909 : } else {
11910 0 : PerfMode = (int)DehumidMode * 2 + 1;
11911 0 : if (thisDXCoil.CondenserType(PerfMode) == DataHeatBalance::RefrigCondenserType::Evap) {
11912 0 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
11913 0 : } else if (thisDXCoil.CondenserType(PerfMode + 1) == DataHeatBalance::RefrigCondenserType::Evap) {
11914 0 : CalcBasinHeaterPower(state,
11915 : thisDXCoil.BasinHeaterPowerFTempDiff,
11916 : thisDXCoil.basinHeaterSched,
11917 : thisDXCoil.BasinHeaterSetPointTemp,
11918 0 : thisDXCoil.BasinHeaterPower);
11919 0 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilStg2RuntimeFrac);
11920 : }
11921 : }
11922 0 : }
11923 :
11924 59001 : Real64 AdjustCBF(Real64 const CBFNom, // nominal coil bypass factor
11925 : Real64 const AirMassFlowRateNom, // nominal air mass flow rate [kg/s]
11926 : Real64 const AirMassFlowRate // actual air mass flow rate [kg/s]
11927 : )
11928 : {
11929 :
11930 : // FUNCTION INFORMATION:
11931 : // AUTHOR Fred Buhl using Don Shirey's code
11932 : // DATE WRITTEN September 2002
11933 :
11934 : // PURPOSE OF THIS FUNCTION:
11935 : // Adjust coil bypass factor for actual air flow rate.
11936 :
11937 : // METHODOLOGY EMPLOYED:
11938 : // Uses relation CBF = exp(-NTU) whereNTU = A0/(m*cp). Relationship models the cooling coil
11939 : // as a heat exchanger with Cmin/Cmax = 0.
11940 :
11941 : // Return value
11942 : Real64 CBFAdj; // the result - the adjusted coil bypass factor
11943 :
11944 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
11945 : Real64 A0; // intermediate variable
11946 : Real64 ADiff; // intermediate variable
11947 :
11948 59001 : if (CBFNom > 0.0) {
11949 58998 : A0 = -std::log(CBFNom) * AirMassFlowRateNom;
11950 : } else {
11951 3 : A0 = 0.0;
11952 : }
11953 59001 : ADiff = -A0 / AirMassFlowRate;
11954 59001 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
11955 58541 : CBFAdj = std::exp(ADiff);
11956 : } else {
11957 460 : CBFAdj = 1.0e-6;
11958 : }
11959 :
11960 59001 : return CBFAdj;
11961 : }
11962 :
11963 3120 : Real64 CalcCBF(EnergyPlusData &state,
11964 : std::string const &UnitType,
11965 : std::string const &UnitName,
11966 : Real64 const InletAirTemp, // inlet air temperature [C]
11967 : Real64 const InletAirHumRat, // inlet air humidity ratio [kg water / kg dry air]
11968 : Real64 const TotCap, // total cooling capacity [Watts]
11969 : Real64 const AirVolFlowRate, // the air volume flow rate at the given capacity [m3/s]
11970 : Real64 const SHR, // sensible heat ratio at the given capacity and flow rate
11971 : bool const PrintFlag // flag used to print warnings if desired
11972 : )
11973 : {
11974 :
11975 : // FUNCTION INFORMATION:
11976 : // AUTHOR Fred Buhl using Don Shirey's code
11977 : // DATE WRITTEN September 2002
11978 :
11979 : // PURPOSE OF THIS FUNCTION:
11980 : // Calculate the coil bypass factor for a coil given the total capacity at the entering conditions,
11981 : // air mass flow rate at the entering conditions, and the sensible heat ratio (SHR) at the
11982 : // entering conditions. Standard barometric pressure is used for this model parameter.
11983 :
11984 : // METHODOLOGY EMPLOYED:
11985 : // calculate SlopeRated (deltahumrat/deltaT) using rated unit information provided by
11986 : // user. Then hunt along saturation curve of psychrometric chart until the slope of the line
11987 : // between the saturation point and rated inlet air humidity ratio and T is the same as SlopeRated.
11988 : // When the slopes are equal, then we have located the apparatus dewpoint of the coil at rated
11989 : // conditions. From this information, coil bypass factor is calculated.
11990 :
11991 : // Using/Aliasing
11992 :
11993 : // Return value
11994 3120 : Real64 CBF(0.0); // the result - the coil bypass factor
11995 :
11996 : // FUNCTION PARAMETER DEFINITIONS:
11997 : static constexpr std::string_view RoutineName("CalcCBF");
11998 3120 : constexpr Real64 SmallDifferenceTest(0.00000001);
11999 :
12000 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
12001 : Real64 InletAirEnthalpy; // Enthalpy of inlet air to evaporator at given conditions [J/kg]
12002 3120 : Real64 DeltaH(0.0); // Enthalpy drop across evaporator at given conditions [J/kg]
12003 3120 : Real64 DeltaT(0.0); // Temperature drop across evaporator at given conditions [C]
12004 3120 : Real64 DeltaHumRat(0.0); // Humidity ratio drop across evaporator at given conditions [kg/kg]
12005 3120 : Real64 OutletAirTemp(InletAirTemp); // Outlet dry-bulb temperature from evaporator at given conditions [C]
12006 3120 : Real64 OutletAirTempSat(InletAirTemp); // Saturation dry-bulb temperature from evaporator at outlet air enthalpy [C]
12007 : Real64 OutletAirEnthalpy; // Enthalpy of outlet air at given conditions [J/kg]
12008 3120 : Real64 OutletAirHumRat(InletAirHumRat); // Outlet humidity ratio from evaporator at given conditions [kg/kg]
12009 : Real64 OutletAirRH; // relative humidity of the outlet air
12010 : Real64 Error; // Error term used in given coil bypass factor (CBF) calculations
12011 : Real64 ErrorLast; // Error term, from previous iteration
12012 : int Iter; // Iteration loop counter in CBF calculations
12013 3120 : int IterMax(50); // Maximum number of iterations in CBF calculations
12014 : Real64 ADPTemp; // Apparatus dewpoint temperature used in CBF calculations [C]
12015 : Real64 ADPHumRat; // Apparatus dewpoint humidity used in CBF calculations [kg/kg]
12016 : Real64 ADPEnthalpy; // Air enthalpy at apparatus dew point [J/kg]
12017 : Real64 DeltaADPTemp; // Change in Apparatus Dew Point used in CBF calculations [C]
12018 3120 : Real64 SlopeAtConds(0.0); // Slope (DeltaHumRat/DeltaT) at given conditions
12019 3120 : Real64 Slope(0.0); // Calculated Slope used while hunting for Tadp
12020 : Real64 Tolerance; // Convergence tolerance for CBF calculations
12021 : Real64 HTinHumRatOut; // Air enthalpy at inlet air temp and outlet air humidity ratio [J/kg]
12022 : Real64 AirMassFlowRate; // the standard air mass flow rate at the given capacity [kg/s]
12023 : Real64 adjustedSHR; // SHR calculated using adjusted outlet air properties []
12024 3120 : bool CBFErrors(false); // Set to true if errors in CBF calculation, fatal at end of routine
12025 :
12026 3120 : if (AirVolFlowRate <= 0.0 || TotCap <= 0.0) { // Coil not running or has no capacity, don't calculate CBF
12027 5 : return CBF;
12028 : }
12029 :
12030 3115 : AirMassFlowRate = AirVolFlowRate * PsyRhoAirFnPbTdbW(state, DataEnvironment::StdPressureSeaLevel, InletAirTemp, InletAirHumRat, RoutineName);
12031 3115 : DeltaH = TotCap / AirMassFlowRate;
12032 3115 : InletAirEnthalpy = PsyHFnTdbW(InletAirTemp, InletAirHumRat);
12033 3115 : HTinHumRatOut = InletAirEnthalpy - (1.0 - SHR) * DeltaH;
12034 3115 : OutletAirHumRat = PsyWFnTdbH(state, InletAirTemp, HTinHumRatOut);
12035 3115 : DeltaHumRat = InletAirHumRat - OutletAirHumRat;
12036 3115 : OutletAirEnthalpy = InletAirEnthalpy - DeltaH;
12037 3115 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
12038 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12039 : // Pressure will have to be pass into this subroutine to fix this one
12040 3115 : OutletAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
12041 3115 : if (OutletAirRH >= 1.0 && PrintFlag) {
12042 16 : ShowWarningError(state, format("For object = {}, name = \"{}\"", UnitType, UnitName));
12043 32 : ShowContinueError(state, "Calculated outlet air relative humidity greater than 1. The combination of");
12044 32 : ShowContinueError(state, "rated air volume flow rate, total cooling capacity and sensible heat ratio yields coil exiting");
12045 32 : ShowContinueError(state, "air conditions above the saturation curve. Possible fixes are to reduce the rated total cooling");
12046 32 : ShowContinueError(state, "capacity, increase the rated air volume flow rate, or reduce the rated sensible heat ratio for this coil.");
12047 32 : ShowContinueError(state, "If autosizing, it is recommended that all three of these values be autosized.");
12048 32 : ShowContinueError(state, "...Inputs used for calculating cooling coil bypass factor.");
12049 16 : ShowContinueError(state, format("...Inlet Air Temperature = {:.2R} C", InletAirTemp));
12050 16 : ShowContinueError(state, format("...Outlet Air Temperature = {:.2R} C", OutletAirTemp));
12051 16 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", InletAirHumRat));
12052 16 : ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
12053 16 : ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
12054 16 : ShowContinueError(state, format("...Air Mass Flow Rate used in calculation = {:.6R} kg/s", AirMassFlowRate));
12055 16 : ShowContinueError(state, format("...Air Volume Flow Rate used in calculation = {:.6R} m3/s", AirVolFlowRate));
12056 16 : if (TotCap > 0.0) {
12057 28 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
12058 12 : ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
12059 12 : ShowContinueError(state,
12060 12 : format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
12061 12 : AirVolFlowRate / TotCap));
12062 : }
12063 : }
12064 32 : ShowContinueErrorTimeStamp(state, "");
12065 16 : OutletAirTempSat = PsyTsatFnHPb(state, OutletAirEnthalpy, DataEnvironment::StdPressureSeaLevel, RoutineName);
12066 16 : if (OutletAirTemp < OutletAirTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
12067 16 : OutletAirTemp = OutletAirTempSat + 0.005;
12068 16 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy, RoutineName);
12069 16 : DeltaHumRat = InletAirHumRat - OutletAirHumRat;
12070 16 : HTinHumRatOut = PsyHFnTdbW(InletAirTemp, OutletAirHumRat);
12071 16 : adjustedSHR = (HTinHumRatOut - OutletAirEnthalpy) / DeltaH;
12072 32 : ShowContinueError(state, "CalcCBF: SHR adjusted to achieve valid outlet air properties and the simulation continues.");
12073 16 : ShowContinueError(state, format("CalcCBF: initial SHR = {:.5R}", SHR));
12074 16 : ShowContinueError(state, format("CalcCBF: adjusted SHR = {:.5R}", adjustedSHR));
12075 : }
12076 : }
12077 3115 : DeltaT = InletAirTemp - OutletAirTemp;
12078 3115 : if (DeltaT <= 0.0) {
12079 0 : ShowSevereError(state, format("For object = {}, name = \"{}\"", UnitType, UnitName));
12080 0 : ShowContinueError(state, "Calculated coil delta T is less than or equal to 0. The combination of");
12081 0 : ShowContinueError(state, "rated air volume flow rate, total cooling capacity and sensible heat ratio yields coil exiting");
12082 0 : ShowContinueError(state, "air conditions that are not reasonable. Possible fixes are to adjust the rated total cooling");
12083 0 : ShowContinueError(state, "capacity, rated air volume flow rate, or rated sensible heat ratio for this coil.");
12084 0 : ShowContinueError(state, "If autosizing, it is recommended that all three of these values be autosized.");
12085 0 : ShowContinueError(state, "...Inputs used for calculating cooling coil bypass factor.");
12086 0 : ShowContinueError(state, format("...Inlet Air Temperature = {:.2R} C", InletAirTemp));
12087 0 : ShowContinueError(state, format("...Outlet Air Temperature = {:.2R} C", OutletAirTemp));
12088 0 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", InletAirHumRat));
12089 0 : ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
12090 0 : ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
12091 0 : ShowContinueError(state, format("...Air Mass Flow Rate used in calculation = {:.6R} kg/s", AirMassFlowRate));
12092 0 : ShowContinueError(state, format("...Air Volume Flow Rate used in calculation = {:.6R} m3/s", AirVolFlowRate));
12093 0 : if (TotCap > 0.0) {
12094 0 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
12095 0 : ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
12096 0 : ShowContinueError(state,
12097 0 : format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
12098 0 : AirVolFlowRate / TotCap));
12099 : }
12100 : }
12101 0 : ShowContinueErrorTimeStamp(state, "");
12102 0 : ShowFatalError(state, "Check and revise the input data for this coil before rerunning the simulation.");
12103 : }
12104 : // Calculate slope at given conditions
12105 3115 : if (DeltaT > 0.0) {
12106 3115 : SlopeAtConds = DeltaHumRat / DeltaT;
12107 : }
12108 :
12109 : // IF (SlopeAtConds .le. .0000001d0 .or. OutletAirHumRat .le. 0.0d0) THEN
12110 3115 : if (SlopeAtConds < 0.0 || OutletAirHumRat <= 0.0) {
12111 : // Invalid conditions, slope can't be less than zero (SHR > 1) or
12112 : // outlet air humidity ratio can't be less than zero.
12113 0 : ShowSevereError(state, format("{} \"{}\"", UnitType, UnitName));
12114 0 : ShowContinueError(state, "...Invalid slope or outlet air condition when calculating cooling coil bypass factor.");
12115 0 : ShowContinueError(state, format("...Slope = {:.8R}", SlopeAtConds));
12116 0 : ShowContinueError(state, format("...Inlet Air Temperature = {:.2R} C", InletAirTemp));
12117 0 : ShowContinueError(state, format("...Outlet Air Temperature = {:.2R} C", OutletAirTemp));
12118 0 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", InletAirHumRat));
12119 0 : ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
12120 0 : ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
12121 0 : ShowContinueError(state, format("...Air Mass Flow Rate used in calculation = {:.6R} kg/s", AirMassFlowRate));
12122 0 : ShowContinueError(state, format("...Air Volume Flow Rate used in calculation = {:.6R} m3/s", AirVolFlowRate));
12123 0 : if (TotCap > 0.0) {
12124 0 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
12125 0 : ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
12126 0 : ShowContinueError(state,
12127 0 : format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
12128 0 : AirVolFlowRate / TotCap));
12129 : }
12130 : }
12131 0 : ShowContinueErrorTimeStamp(state, "");
12132 0 : CBFErrors = true;
12133 0 : CBF = 0.0; //? Added: Is this what should be returned
12134 : } else {
12135 :
12136 : // First guess for Tadp is outlet air dew point
12137 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12138 : // Pressure will have to be pass into this subroutine to fix this one
12139 3115 : ADPTemp = PsyTdpFnWPb(state, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel);
12140 :
12141 3115 : Tolerance = 1.0; // initial conditions for iteration
12142 3115 : ErrorLast = 100.0;
12143 3115 : Iter = 0;
12144 3115 : DeltaADPTemp = 5.0;
12145 51003 : while ((Iter <= IterMax) && (Tolerance > 0.001)) {
12146 : // Do for IterMax iterations or until the error gets below .1%
12147 47888 : if (Iter > 0) {
12148 44773 : ADPTemp += DeltaADPTemp;
12149 : }
12150 47888 : ++Iter;
12151 :
12152 : // Find new slope using guessed Tadp
12153 :
12154 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12155 : // Pressure will have to be pass into this subroutine to fix this one
12156 47888 : ADPHumRat = min(OutletAirHumRat, PsyWFnTdpPb(state, ADPTemp, DataEnvironment::StdPressureSeaLevel));
12157 47888 : Slope = (InletAirHumRat - ADPHumRat) / max(0.001, (InletAirTemp - ADPTemp));
12158 :
12159 : // check for convergence (slopes are equal to within error tolerance)
12160 :
12161 47888 : Error = (Slope - SlopeAtConds) / SlopeAtConds;
12162 47888 : if ((Error > 0.0) && (ErrorLast < 0.0)) {
12163 11633 : DeltaADPTemp = -DeltaADPTemp / 2.0;
12164 36255 : } else if ((Error < 0.0) && (ErrorLast > 0.0)) {
12165 13158 : DeltaADPTemp = -DeltaADPTemp / 2.0;
12166 23097 : } else if (std::abs(Error) > std::abs(ErrorLast)) {
12167 2957 : DeltaADPTemp = -DeltaADPTemp / 2.0;
12168 : }
12169 47888 : ErrorLast = Error;
12170 :
12171 47888 : Tolerance = std::abs(Error);
12172 : }
12173 :
12174 : // Calculate Bypass Factor from Enthalpies
12175 :
12176 3115 : InletAirEnthalpy = PsyHFnTdbW(InletAirTemp, InletAirHumRat);
12177 3115 : OutletAirEnthalpy = PsyHFnTdbW(OutletAirTemp, OutletAirHumRat);
12178 3115 : ADPEnthalpy = PsyHFnTdbW(ADPTemp, ADPHumRat);
12179 3115 : CBF = min(1.0, (OutletAirEnthalpy - ADPEnthalpy) / (InletAirEnthalpy - ADPEnthalpy));
12180 3115 : if (Iter > IterMax && PrintFlag) {
12181 0 : ShowSevereError(state, format("{} \"{}\" -- coil bypass factor calculation did not converge after max iterations.", UnitType, UnitName));
12182 0 : ShowContinueError(state, format("The RatedSHR of [{:.3R}], entered by the user or autosized (see *.eio file),", SHR));
12183 0 : ShowContinueError(state, "may be causing this. The line defined by the coil rated inlet air conditions");
12184 0 : ShowContinueError(state, "(26.7C drybulb and 19.4C wetbulb) and the RatedSHR (i.e., slope of the line) must intersect");
12185 0 : ShowContinueError(state, "the saturation curve of the psychrometric chart. If the RatedSHR is too low, then this");
12186 0 : ShowContinueError(state, "intersection may not occur and the coil bypass factor calculation will not converge.");
12187 0 : ShowContinueError(state, "If autosizing the SHR, recheck the design supply air humidity ratio and design supply air");
12188 0 : ShowContinueError(state, "temperature values in the Sizing:System and Sizing:Zone objects. In general, the temperatures");
12189 0 : ShowContinueError(state, "and humidity ratios specified in these two objects should be the same for each system");
12190 0 : ShowContinueError(state, "and the zones that it serves.");
12191 0 : ShowContinueErrorTimeStamp(state, "");
12192 0 : CBFErrors = true; // Didn't converge within MaxIter iterations
12193 : }
12194 3115 : if (CBF < 0.0 && PrintFlag) {
12195 0 : ShowSevereError(state, format("{} \"{}\" -- negative coil bypass factor calculated.", UnitType, UnitName));
12196 0 : ShowContinueErrorTimeStamp(state, "");
12197 0 : CBFErrors = true; // Negative CBF not valid
12198 : }
12199 : }
12200 :
12201 : // Show fatal error for specific coil that caused a CBF error
12202 3115 : if (CBFErrors) {
12203 0 : ShowFatalError(state, format("{} \"{}\" Errors found in calculating coil bypass factors", UnitType, UnitName));
12204 : }
12205 :
12206 3115 : return CBF;
12207 : }
12208 :
12209 90 : Real64 ValidateADP(EnergyPlusData &state,
12210 : std::string const &UnitType, // component name
12211 : std::string const &UnitName, // component type
12212 : Real64 const RatedInletAirTemp, // coil inlet air temperature [C]
12213 : Real64 const RatedInletAirHumRat, // coil inlet air humidity ratio [kg/kg]
12214 : Real64 const TotCap, // coil total capacity [W]
12215 : Real64 const AirVolFlowRate, // coil air volume flow rate [m3/s]
12216 : Real64 const InitialSHR, // coil sensible heat ratio []
12217 : std::string const &CallingRoutine // function name calling this routine
12218 : )
12219 : {
12220 :
12221 : // FUNCTION INFORMATION:
12222 : // AUTHOR Richard Raustad, FSEC
12223 : // DATE WRITTEN December 2015
12224 :
12225 : // PURPOSE OF THIS FUNCTION:
12226 : // Validates that the calculated bypass factor represents valid SHR based on total capacity and air mass flow rate.
12227 :
12228 : // METHODOLOGY EMPLOYED:
12229 : // With model parameters autosized by the user, the SHR is selected based on an empirical model.
12230 : // This can sometimes lead to an SHR that does not cross the saturation curve, or one that crosses excessively where
12231 : // the coil outlet air conditions exceed the saturation curve (i.e., RH > 1).
12232 : // This function checks to see if the ADP based on coil delta T and calculated bypass factor and the ADP based
12233 : // on coil delta W and calculated bypass factor land on the saturation curve at the same place within a tolerance.
12234 : // The result is passed back to the sizing routine as the new value for SHR.
12235 : // If the SHR is not autosized, this routine will still adjust the design SHR appropriately, however, the hard-sized SHR will not
12236 : // change.
12237 :
12238 : // Return value
12239 90 : Real64 SHR(0.0); // the result - the adjusted design SHR
12240 :
12241 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
12242 90 : Real64 CBF_calculated(0.0); // coil bypass factor based on TotCap, AirFlow, SHR, and BaroPress
12243 90 : Real64 InletAirEnthalpy(0.0); // Enthalpy of inlet air to evaporator at given conditions [J/kg]
12244 90 : Real64 DeltaH(0.0); // Enthalpy drop across evaporator at given conditions [J/kg]
12245 90 : Real64 HTinHumRatOut(0.0); // Air enthalpy at inlet air temp and outlet air humidity ratio [J/kg]
12246 90 : Real64 DeltaHumRat(0.0); // Humidity ratio drop across evaporator at given conditions [kg/kg]
12247 90 : Real64 OutletAirTemp(0.0); // Outlet dry-bulb temperature from evaporator at given conditions [C]
12248 90 : Real64 OutletAirEnthalpy(0.0); // Enthalpy of outlet air at given conditions [J/kg]
12249 90 : Real64 OutletAirHumRat(0.0); // Outlet humidity ratio from evaporator at given conditions [kg/kg]
12250 90 : Real64 OutletAirRH(0.0); // relative humidity of the outlet air
12251 90 : Real64 CalcADPTemp(0.0); // actual ADP temperature based on bypass factor [C]
12252 90 : Real64 CalcADPHumRat(0.0); // actual ADP humidity ratio based on bypass factor [kg/kg]
12253 90 : Real64 CalcADPTempFnHR(0.0); // actual ADP temperature as a function of humidity ratio based on bypass factor [C]
12254 90 : Real64 ADPerror(0.0); // difference between ADP function of temperature and humidity ratio [deltaC]
12255 90 : Real64 AirMassFlow(0.0); // air mass flow rate based on standard barometric pressure [kg/s]
12256 90 : bool bStillValidating(true); // while loop flag
12257 90 : bool bNoReporting(false); // don't report specific warnings in calcCBF while iterating on result
12258 90 : bool bReversePerturb(false); // identifies when SHR is being lowered based on outlet air RH
12259 :
12260 90 : SHR = InitialSHR;
12261 90 : AirMassFlow =
12262 90 : AirVolFlowRate * PsyRhoAirFnPbTdbW(state, DataEnvironment::StdPressureSeaLevel, RatedInletAirTemp, RatedInletAirHumRat, CallingRoutine);
12263 3059 : while (bStillValidating) {
12264 2969 : CBF_calculated = max(0.0, CalcCBF(state, UnitType, UnitName, RatedInletAirTemp, RatedInletAirHumRat, TotCap, AirMassFlow, SHR, bNoReporting));
12265 2969 : DeltaH = TotCap / AirMassFlow;
12266 2969 : InletAirEnthalpy = PsyHFnTdbW(RatedInletAirTemp, RatedInletAirHumRat);
12267 2969 : HTinHumRatOut = InletAirEnthalpy - (1.0 - SHR) * DeltaH;
12268 2969 : OutletAirHumRat = PsyWFnTdbH(state, RatedInletAirTemp, HTinHumRatOut, CallingRoutine);
12269 2969 : DeltaHumRat = RatedInletAirHumRat - OutletAirHumRat;
12270 2969 : OutletAirEnthalpy = InletAirEnthalpy - DeltaH;
12271 2969 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
12272 2969 : OutletAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, CallingRoutine);
12273 2969 : if (CBF_calculated < 1) {
12274 2969 : CalcADPTemp = RatedInletAirTemp - ((RatedInletAirTemp - OutletAirTemp) / (1 - CBF_calculated));
12275 2969 : CalcADPHumRat = RatedInletAirHumRat - ((DeltaHumRat) / (1 - CBF_calculated));
12276 2969 : CalcADPTempFnHR = PsyTdpFnWPb(state, CalcADPHumRat, DataEnvironment::StdPressureSeaLevel, CallingRoutine);
12277 2969 : ADPerror = CalcADPTemp - CalcADPTempFnHR;
12278 : } else {
12279 0 : ADPerror = 0; // might be able to check for RH >= 1 and reduce SHR, need defect file for that since can't create one
12280 : }
12281 :
12282 2969 : if (std::abs(ADPerror) > 0.012) {
12283 2969 : if (OutletAirRH >= 1.0) { // if RH > 1, reduce SHR until it crosses the saturation curve
12284 344 : SHR -= 0.001;
12285 344 : bReversePerturb = true;
12286 344 : if (SHR < 0.5) {
12287 0 : bStillValidating = false; // have to stop somewhere, this is lower than the lower limit of SHR empirical model (see
12288 : }
12289 : // Autosizing/CoolingSHRSizing)
12290 : } else {
12291 2625 : if (bReversePerturb) {
12292 60 : bStillValidating = false; // stop iterating once SHR causes ADP to cross back under saturation curve, take what you get
12293 : } else {
12294 2565 : SHR += 0.001; // increase SHR slowly until ADP temps are resolved
12295 : }
12296 : }
12297 2969 : if (SHR > 0.8) {
12298 30 : bStillValidating = false; // have to stop somewhere, this is the upper limit of SHR empirical model (see Autosizing/CoolingSHRSizing)
12299 : }
12300 : } else {
12301 0 : bStillValidating = false; // ADP temps are close enough. Normal input files hit this on first pass
12302 : }
12303 : }
12304 :
12305 90 : return SHR;
12306 : }
12307 :
12308 116065 : Real64 CalcEffectiveSHR(EnergyPlusData &state,
12309 : int const DXCoilNum, // Index number for cooling coil
12310 : Real64 const SHRss, // Steady-state sensible heat ratio
12311 : Real64 const RTF, // Compressor run-time fraction
12312 : Real64 const QLatRated, // Rated latent capacity
12313 : Real64 const QLatActual, // Actual latent capacity
12314 : Real64 const EnteringDB, // Entering air dry-bulb temperature
12315 : Real64 const EnteringWB, // Entering air wet-bulb temperature
12316 : ObjexxFCL::Optional_int_const Mode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
12317 : ObjexxFCL::Optional<Real64 const> HeatingRTF // Used to recalculate Toff for cycling fan systems
12318 : )
12319 : {
12320 :
12321 : // FUNCTION INFORMATION:
12322 : // AUTHOR Richard Raustad, FSEC
12323 : // DATE WRITTEN September 2003
12324 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
12325 : // Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
12326 : // Nov 2008 R. Raustad, FSEC
12327 : // Modified to allow latent degradation with cycling fan
12328 :
12329 : // PURPOSE OF THIS FUNCTION:
12330 : // Adjust sensible heat ratio to account for degradation of DX coil latent
12331 : // capacity at part-load (cycling) conditions.
12332 :
12333 : // METHODOLOGY EMPLOYED:
12334 : // With model parameters entered by the user, the part-load latent performance
12335 : // of a DX cooling coil is determined for a constant air flow system with
12336 : // a cooling coil that cycles on/off. The model calculates the time
12337 : // required for condensate to begin falling from the cooling coil.
12338 : // Runtimes greater than this are integrated to a "part-load" latent
12339 : // capacity which is used to determine the "part-load" sensible heat ratio.
12340 : // See reference below for additional details (linear decay model, Eq. 8b).
12341 : // REFERENCES:
12342 : // "A Model to Predict the Latent Capacity of Air Conditioners and
12343 : // Heat Pumps at Part-Load Conditions with Constant Fan Operation"
12344 : // 1996 ASHRAE Transactions, Volume 102, Part 1, Pp. 266 - 274,
12345 : // Hugh I. Henderson, Jr., P.E., Kannan Rengarajan, P.E.
12346 :
12347 : // Return value
12348 : Real64 SHReff; // Effective sensible heat ratio, includes degradation due to cycling effects
12349 :
12350 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
12351 : Real64 Twet; // Nominal time for condensate to begin leaving the coil's condensate drain line
12352 : // at the current operating conditions (sec)
12353 : Real64 Gamma; // Initial moisture evaporation rate divided by steady-state AC latent capacity
12354 : // at the current operating conditions
12355 : Real64 Twet_Rated; // Twet at rated conditions (coil air flow rate and air temperatures), sec
12356 : Real64 Gamma_Rated; // Gamma at rated conditions (coil air flow rate and air temperatures)
12357 : Real64 Twet_max; // Maximum allowed value for Twet
12358 : Real64 Nmax; // Maximum ON/OFF cycles per hour for the compressor (cycles/hr)
12359 : Real64 Tcl; // Time constant for latent capacity to reach steady state after startup (sec)
12360 : Real64 Ton; // Coil on time (sec)
12361 : Real64 Toff; // Coil off time (sec)
12362 : Real64 Toffa; // Actual coil off time (sec). Equations valid for Toff <= (2.0 * Twet/Gamma)
12363 : Real64 aa; // Intermediate variable
12364 : Real64 To1; // Intermediate variable (first guess at To). To = time to the start of moisture removal
12365 : Real64 To2; // Intermediate variable (second guess at To). To = time to the start of moisture removal
12366 : Real64 Error; // Error for iteration (DO) loop
12367 : Real64 LHRmult; // Latent Heat Ratio (LHR) multiplier. The effective latent heat ratio LHR = (1-SHRss)*LHRmult
12368 : Real64 Ton_heating;
12369 : Real64 Toff_heating;
12370 :
12371 116065 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
12372 :
12373 116065 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilDX_MultiSpeedCooling) {
12374 116024 : Twet_Rated = thisDXCoil.Twet_Rated(Mode);
12375 116024 : Gamma_Rated = thisDXCoil.Gamma_Rated(Mode);
12376 116024 : Nmax = thisDXCoil.MaxONOFFCyclesperHour(Mode);
12377 116024 : Tcl = thisDXCoil.LatentCapacityTimeConstant(Mode);
12378 : } else {
12379 41 : Twet_Rated = thisDXCoil.MSTwet_Rated(Mode);
12380 41 : Gamma_Rated = thisDXCoil.MSGamma_Rated(Mode);
12381 41 : Nmax = thisDXCoil.MSMaxONOFFCyclesperHour(Mode);
12382 41 : Tcl = thisDXCoil.MSLatentCapacityTimeConstant(Mode);
12383 : }
12384 :
12385 : // No moisture evaporation (latent degradation) occurs for runtime fraction of 1.0
12386 : // All latent degradation model parameters cause divide by 0.0 if not greater than 0.0
12387 : // Latent degradation model parameters initialize to 0.0 meaning no evaporation model used.
12388 116065 : if (RTF >= 1.0 || Twet_Rated <= 0.0 || Gamma_Rated <= 0.0 || Nmax <= 0.0 || Tcl <= 0.0) {
12389 107135 : SHReff = SHRss;
12390 107135 : return SHReff;
12391 : }
12392 :
12393 8930 : Twet_max = 9999.0; // high limit for Twet
12394 :
12395 : // Calculate the model parameters at the actual operating conditions
12396 8930 : Twet = min(Twet_Rated * QLatRated / (QLatActual + 1.e-10), Twet_max);
12397 8930 : Gamma = Gamma_Rated * QLatRated * (EnteringDB - EnteringWB) / ((26.7 - 19.4) * QLatActual + 1.e-10);
12398 :
12399 : // Calculate the compressor on and off times using a conventional thermostat curve
12400 8930 : Ton = 3600.0 / (4.0 * Nmax * (1.0 - RTF)); // duration of cooling coil on-cycle (sec)
12401 8930 : Toff = 3600.0 / (4.0 * Nmax * RTF); // duration of cooling coil off-cycle (sec)
12402 :
12403 : // Cap Toff to meet the equation restriction
12404 8930 : if (Gamma > 0.0) {
12405 8930 : Toffa = min(Toff, 2.0 * Twet / Gamma);
12406 : } else {
12407 0 : Toffa = Toff;
12408 : }
12409 :
12410 : // Need to include the reheat coil operation to account for actual fan run time. E+ uses a
12411 : // separate heating coil for heating and reheat (to separate the heating and reheat loads)
12412 : // and real world applications would use a single heating coil for both purposes, the actual
12413 : // fan operation is based on HeatingPLR + ReheatPLR. For cycling fan RH control, latent
12414 : // degradation only occurs when a heating load exists, in this case the reheat load is
12415 : // equal to and opposite in magnitude to the cooling coil sensible output but the reheat
12416 : // coil is not always active. This additional fan run time has not been accounted for at this time.
12417 : // Recalculate Toff for cycling fan systems when heating is active
12418 8930 : if (present(HeatingRTF)) {
12419 0 : if (HeatingRTF < 1.0 && HeatingRTF > RTF) {
12420 0 : Ton_heating = 3600.0 / (4.0 * Nmax * (1.0 - HeatingRTF));
12421 0 : Toff_heating = 3600.0 / (4.0 * Nmax * HeatingRTF);
12422 : // add additional heating coil operation during cooling coil off cycle (due to cycling rate difference of coils)
12423 0 : Ton_heating += max(0.0, min(Ton_heating, (Ton + Toffa) - (Ton_heating + Toff_heating)));
12424 0 : Toffa = min(Toffa, Ton_heating - Ton);
12425 : }
12426 : }
12427 :
12428 : // Use successive substitution to solve for To
12429 8930 : aa = (Gamma * Toffa) - (0.25 / Twet) * pow_2(Gamma) * pow_2(Toffa);
12430 8930 : To1 = aa + Tcl;
12431 8930 : Error = 1.0;
12432 19126 : while (Error > 0.001) {
12433 10196 : To2 = aa - Tcl * (std::exp(-To1 / Tcl) - 1.0);
12434 10196 : Error = std::abs((To2 - To1) / To1);
12435 10196 : To1 = To2;
12436 : }
12437 :
12438 : // Adjust Sensible Heat Ratio (SHR) using Latent Heat Ratio (LHR) multiplier
12439 : // Floating underflow errors occur when -Ton/Tcl is a large negative number.
12440 : // Cap lower limit at -700 to avoid the underflow errors.
12441 8930 : aa = std::exp(max(-700.0, -Ton / Tcl));
12442 : // Calculate latent heat ratio multiplier
12443 8930 : LHRmult = max(((Ton - To2) / (Ton + Tcl * (aa - 1.0))), 0.0);
12444 :
12445 : // Calculate part-load or "effective" sensible heat ratio
12446 8930 : SHReff = 1.0 - (1.0 - SHRss) * LHRmult;
12447 :
12448 8930 : if (SHReff < SHRss) {
12449 3 : SHReff = SHRss; // Effective SHR can be less than the steady-state SHR
12450 : }
12451 8930 : if (SHReff > 1.0) {
12452 0 : SHReff = 1.0; // Effective sensible heat ratio can't be greater than 1.0
12453 : }
12454 :
12455 8930 : return SHReff;
12456 : }
12457 :
12458 44594 : void CalcTotCapSHR(EnergyPlusData &state,
12459 : Real64 const InletDryBulb, // inlet air dry bulb temperature [C]
12460 : Real64 const InletHumRat, // inlet air humidity ratio [kg water / kg dry air]
12461 : Real64 const InletEnthalpy, // inlet air specific enthalpy [J/kg]
12462 : Real64 const InletWetBulb, // inlet air wet bulb temperature [C]
12463 : Real64 const AirMassFlowRatio, // Ratio of actual air mass flow to nominal air mass flow
12464 : Real64 const AirMassFlow, // actual mass flow for capacity and SHR calculation
12465 : Real64 const TotCapNom, // nominal total capacity [W]
12466 : Real64 const CBF, // coil bypass factor
12467 : int const CCapFTemp, // capacity modifier curve index, function of entering wetbulb
12468 : int const CCapFFlow, // capacity modifier curve, function of actual flow vs rated flow
12469 : Real64 &TotCap, // total capacity at the given conditions [W]
12470 : Real64 &SHR, // sensible heat ratio at the given conditions
12471 : Real64 const CondInletTemp, // Condenser inlet temperature [C]
12472 : Real64 const Pressure, // air pressure [Pa]
12473 : Real64 &TotCapModFac // capacity modification factor, func of temp and func of flow
12474 : )
12475 : {
12476 :
12477 : // SUBROUTINE INFORMATION:
12478 : // AUTHOR Fred Buhl using Don Shirey's code
12479 : // DATE WRITTEN September 2002
12480 :
12481 : // PURPOSE OF THIS SUBROUTINE:
12482 : // Calculates total capacity and sensible heat ratio of a DX coil at the specified conditions
12483 :
12484 : // METHODOLOGY EMPLOYED:
12485 : // With the rated performance data entered by the user, the model employs some of the
12486 : // DOE-2.1E curve fits to adjust the capacity and SHR of the unit as a function
12487 : // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
12488 : // does NOT employ the exact same methodology to calculate performance as DOE-2, although
12489 : // some of the DOE-2 curve fits are employed by this model.
12490 :
12491 : // The model checks for coil dryout conditions, and adjusts the calculated performance
12492 : // appropriately.
12493 :
12494 : // REFERENCES:
12495 : // ASHRAE HVAC 2 Toolkit page 4-81.
12496 : // Henderson, H.I. Jr., K. Rengarajan and D.B. Shirey, III. 1992.The impact of comfort
12497 : // control on air conditioner energy use in humid climates. ASHRAE Transactions 98(2):
12498 : // 104-113.
12499 : // Henderson, H.I. Jr., Danny Parker and Y.J. Huang. 2000.Improving DOE-2's RESYS routine:
12500 : // User Defined Functions to Provide More Accurate Part Load Energy Use and Humidity
12501 : // Predictions. Proceedings of ACEEE Conference.
12502 :
12503 : // Using/Aliasing
12504 : using Curve::CurveValue;
12505 :
12506 : // Locals
12507 : // SUBROUTINE ARGUMENT DEFINITIONS:
12508 : // and outside drybulb
12509 :
12510 : // SUBROUTINE PARAMETER DEFINITIONS:
12511 44594 : constexpr int MaxIter(30); // Maximum number of iterations for dry evaporator calculations
12512 44594 : constexpr Real64 RF(0.4); // Relaxation factor for dry evaporator iterations
12513 44594 : constexpr Real64 Tolerance(0.01); // Error tolerance for dry evaporator iterations
12514 44594 : constexpr Real64 MinHumRatCalc(0.00001); // Error tolerance for dry evaporator iterations
12515 :
12516 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12517 : Real64 InletWetBulbCalc; // calculated inlet wetbulb temperature used for finding dry coil point [C]
12518 : Real64 InletHumRatCalc; // calculated inlet humidity ratio used for finding dry coil point [kg water / kg dry air]
12519 : Real64 TotCapTempModFac; // Total capacity modifier (function of entering wetbulb, outside drybulb)
12520 : Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs nominal flow)
12521 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
12522 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
12523 : Real64 tADP; // Apparatus dew point temperature [C]
12524 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
12525 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
12526 : Real64 SHRCalc; // temporary calculated value of SHR
12527 : Real64 TotCapCalc; // temporary calculated value of total capacity [W]
12528 : int Counter; // Counter for dry evaporator iterations
12529 : Real64 werror; // Deviation of humidity ratio in dry evaporator iteration loop
12530 :
12531 : // MaxIter = 30
12532 : // RF = 0.4d0
12533 44594 : Counter = 0;
12534 : // Tolerance = 0.01d0
12535 44594 : werror = 0.0;
12536 :
12537 44594 : InletWetBulbCalc = InletWetBulb;
12538 44594 : InletHumRatCalc = InletHumRat;
12539 :
12540 44594 : if (AirMassFlow <= 0.00001) {
12541 3 : TotCap = 0.0;
12542 3 : SHR = 0.0;
12543 3 : return;
12544 : }
12545 :
12546 : // DO WHILE (ABS(werror) .gt. Tolerance .OR. Counter == 0)
12547 : // Get capacity modifying factor (function of inlet wetbulb & outside drybulb) for off-rated conditions
12548 : while (true) {
12549 158090 : TotCapTempModFac = CurveValue(state, CCapFTemp, InletWetBulbCalc, CondInletTemp);
12550 : // Get capacity modifying factor (function of mass flow) for off-rated conditions
12551 158090 : TotCapFlowModFac = CurveValue(state, CCapFFlow, AirMassFlowRatio);
12552 : // Get total capacity
12553 158090 : TotCapCalc = TotCapNom * TotCapFlowModFac * TotCapTempModFac;
12554 :
12555 : // Calculate apparatus dew point conditions using TotCap and CBF
12556 158090 : hDelta = TotCapCalc / AirMassFlow;
12557 158090 : hADP = InletEnthalpy - hDelta / (1.0 - CBF);
12558 158090 : tADP = PsyTsatFnHPb(state, hADP, Pressure);
12559 158090 : wADP = PsyWFnTdbH(state, tADP, hADP);
12560 158090 : hTinwADP = PsyHFnTdbW(InletDryBulb, wADP);
12561 158090 : if ((InletEnthalpy - hADP) > 1.e-10) {
12562 158090 : SHRCalc = min((hTinwADP - hADP) / (InletEnthalpy - hADP), 1.0);
12563 : } else {
12564 0 : SHRCalc = 1.0;
12565 : }
12566 : // Check for dry evaporator conditions (win < wadp)
12567 158090 : if (wADP > InletHumRatCalc || (Counter >= 1 && Counter < MaxIter)) {
12568 128338 : if (InletHumRatCalc == 0.0) {
12569 14 : InletHumRatCalc = MinHumRatCalc;
12570 : }
12571 : // InletHumRatCalc=MAX(InletHumRatCalc,MinHumRatCalc) ! proposed.
12572 :
12573 128338 : werror = (InletHumRatCalc - wADP) / InletHumRatCalc;
12574 : // Increase InletHumRatCalc at constant inlet air temp to find coil dry-out point. Then use the
12575 : // capacity at the dry-out point to determine exiting conditions from coil. This is required
12576 : // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
12577 128338 : InletHumRatCalc = RF * wADP + (1.0 - RF) * InletHumRatCalc;
12578 128338 : InletWetBulbCalc = PsyTwbFnTdbWPb(state, InletDryBulb, InletHumRatCalc, Pressure);
12579 128338 : ++Counter;
12580 128338 : if (std::abs(werror) > Tolerance) {
12581 113499 : continue; // Recalculate with modified inlet conditions
12582 : }
12583 14839 : break; // conditions are satisfied
12584 : } else {
12585 : break; // conditions are satisfied
12586 : }
12587 : }
12588 :
12589 : // END DO
12590 :
12591 : // Calculate full load output conditions
12592 44591 : if (SHRCalc > 1.0 || Counter > 0) {
12593 14839 : SHRCalc = 1.0;
12594 : }
12595 :
12596 44591 : SHR = SHRCalc;
12597 44591 : TotCap = TotCapCalc;
12598 44591 : TotCapModFac = TotCapTempModFac * TotCapFlowModFac;
12599 : }
12600 :
12601 265 : void CalcMultiSpeedDXCoilCooling(EnergyPlusData &state,
12602 : int const DXCoilNum, // the number of the DX heating coil to be simulated
12603 : Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
12604 : Real64 const CycRatio, // cycling part load ratio
12605 : int const SpeedNum, // Speed number
12606 : HVAC::FanOp const fanOp, // Sets fan control to FanOp::Cycling or FanOp::Continuous
12607 : HVAC::CompressorOp const compressorOp, // Compressor on/off; 1=on, 0=off
12608 : int const SingleMode // Single mode operation Yes/No; 1=Yes, 0=No
12609 : )
12610 : {
12611 :
12612 : // SUBROUTINE INFORMATION:
12613 : // AUTHOR Lixing Gu, FSEC
12614 : // DATE WRITTEN June 2007
12615 : // MODIFIED April 2010, Chandan sharma, FSEC, added basin heater
12616 : // RE-ENGINEERED Revised based on CalcMultiSpeedDXCoil
12617 :
12618 : // PURPOSE OF THIS SUBROUTINE:
12619 : // Calculates the air-side performance and electrical energy use of a direct-
12620 : // expansion, air-cooled cooling unit with a multispeed compressor.
12621 :
12622 : // METHODOLOGY EMPLOYED:
12623 : // Uses the same methodology as the single speed DX unit model (SUBROUTINE CalcDoe2DXCoil).
12624 : // In addition it assumes that the unit performance is obtained by interpolating between
12625 : // the performance at high speed and that at low speed. If the output needed is below
12626 : // that produced at low speed, the compressor cycles between off and low speed.
12627 :
12628 : // Using/Aliasing
12629 : using Curve::CurveValue;
12630 265 : Real64 MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
12631 265 : Real64 MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
12632 265 : auto &MSHPWasteHeat = state.dataHVACGlobal->MSHPWasteHeat;
12633 :
12634 : // Locals
12635 : // SUBROUTINE ARGUMENT DEFINITIONS:
12636 : // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
12637 :
12638 : // SUBROUTINE PARAMETER DEFINITIONS:
12639 : static constexpr std::string_view RoutineName("CalcMultiSpeedDXCoilCooling");
12640 : static constexpr std::string_view RoutineNameHighSpeedAlt("CalcMultiSpeedDXCoilCooling highspeed");
12641 :
12642 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12643 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
12644 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
12645 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
12646 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
12647 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
12648 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12649 : // REAL(r64) :: InletAirPressure ! inlet air pressure [Pa]
12650 : Real64 OutletAirDryBulbTemp; // outlet air dry bulb temperature [C]
12651 : Real64 OutletAirEnthalpy; // outlet air enthalpy [J/kg]
12652 : Real64 OutletAirHumRat; // outlet air humidity ratio [kg/kg]
12653 : Real64 OutletAirDryBulbTempSat; // outlet air dry bulb temp at saturation at the outlet enthalpy [C]
12654 : Real64 LSOutletAirDryBulbTemp; // low speed outlet air dry bulb temperature [C]
12655 : Real64 LSOutletAirEnthalpy; // low speed outlet air enthalpy [J/kg]
12656 : Real64 LSOutletAirHumRat; // low speed outlet air humidity ratio [kg/kg]
12657 : Real64 HSOutletAirDryBulbTemp; // high speed outlet air dry bulb temperature [C]
12658 : Real64 HSOutletAirEnthalpy; // high speed outlet air enthalpy [J/kg]
12659 : Real64 HSOutletAirHumRat; // high speed outlet air humidity ratio [kg/kg]
12660 : Real64 hDelta; // Change in air enthalpy across the cooling coil [J/kg]
12661 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
12662 : Real64 hADP; // Apparatus dew point enthalpy [J/kg]
12663 : Real64 tADP; // Apparatus dew point temperature [C]
12664 : Real64 wADP; // Apparatus dew point humidity ratio [kg/kg]
12665 : Real64 hTinwADP; // Enthalpy at inlet dry-bulb and wADP [J/kg]
12666 : Real64 RatedCBFHS; // coil bypass factor at rated conditions (high speed)
12667 : Real64 CBFHS; // coil bypass factor at max flow (high speed)
12668 : Real64 RatedCBFLS; // coil bypass factor at rated conditions (low speed)
12669 : Real64 CBFLS; // coil bypass factor at max flow (low speed)
12670 : Real64 TotCapHS; // total capacity at high speed [W]
12671 : Real64 SHRHS; // sensible heat ratio at high speed
12672 : Real64 TotCapLS; // total capacity at low speed [W]
12673 : Real64 SHRLS; // sensible heat ratio at low speed
12674 : Real64 EIRTempModFacHS; // EIR modifier (function of entering wetbulb, outside drybulb) (high speed)
12675 : Real64 EIRFlowModFacHS; // EIR modifier (function of actual supply air flow vs rated flow) (high speed)
12676 : Real64 EIRHS; // EIR at off rated conditions (high speed)
12677 : Real64 EIRTempModFacLS; // EIR modifier (function of entering wetbulb, outside drybulb) (low speed)
12678 : Real64 EIRFlowModFacLS; // EIR modifier (function of actual supply air flow vs rated flow) (low speed)
12679 : Real64 EIRLS; // EIR at off rated conditions (low speed)
12680 : Real64 SHR; // sensible heat ratio at current speed
12681 : Real64 EIR; // EIR at current speed
12682 : Real64 CBF; // CBFNom adjusted for actual air mass flow rate
12683 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in
12684 : // power calculation
12685 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
12686 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
12687 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
12688 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
12689 : Real64 RhoAir; // Density of air [kg/m3]
12690 : Real64 RhoWater; // Density of water [kg/m3]
12691 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
12692 : Real64 EvapCondPumpElecPower; // Evaporative condenser electric pump power [W]
12693 265 : constexpr int DXMode(1); // Performance mode for MultiMode DX coil; Always 1 for other coil types
12694 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
12695 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
12696 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
12697 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
12698 : int SpeedNumHS; // High speed number
12699 : int SpeedNumLS; // Low speed number
12700 : Real64 SHRUnadjusted; // Temp SHR
12701 : Real64 QLatRated; // Qlatent at rated conditions of indoor(TDB,TWB)=(26.7C,19.4C)
12702 : Real64 QLatActual; // Qlatent at actual operating conditions
12703 : Real64 AirMassFlowRatioLS; // airflow ratio at low speed
12704 : Real64 AirMassFlowRatioHS; // airflow ratio at high speed
12705 : Real64 WasteHeatLS; // Waste heat at low speed
12706 : Real64 WasteHeatHS; // Waste heat at high speed
12707 : Real64 LSElecCoolingPower; // low speed power [W]
12708 : Real64 HSElecCoolingPower; // high speed power [W]
12709 : Real64 CrankcaseHeatingPower; // Power due to crank case heater
12710 : Real64 AirVolumeFlowRate; // Air volume flow rate across the heating coil
12711 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total heating capacity
12712 :
12713 265 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
12714 :
12715 265 : if (thisDXCoil.CondenserInletNodeNum(DXMode) != 0) {
12716 74 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).Press;
12717 : // If node is not connected to anything, pressure = default, use weather data
12718 74 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
12719 74 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12720 74 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
12721 74 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12722 74 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
12723 : } else {
12724 0 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).Temp;
12725 0 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).HumRat;
12726 0 : OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, RoutineName);
12727 : }
12728 74 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
12729 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
12730 0 : OutdoorDryBulb = secZoneHB.ZT;
12731 0 : OutdoorHumRat = secZoneHB.airHumRat;
12732 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
12733 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12734 : }
12735 191 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
12736 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
12737 0 : OutdoorDryBulb = secZoneHB.ZT;
12738 0 : OutdoorHumRat = secZoneHB.airHumRat;
12739 0 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
12740 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12741 : } else {
12742 191 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12743 191 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
12744 191 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12745 191 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
12746 : }
12747 :
12748 265 : if (SpeedNum > 1) {
12749 59 : SpeedNumLS = SpeedNum - 1;
12750 59 : SpeedNumHS = SpeedNum;
12751 59 : if (SpeedNum > thisDXCoil.NumOfSpeeds) {
12752 0 : SpeedNumLS = thisDXCoil.NumOfSpeeds - 1;
12753 0 : SpeedNumHS = thisDXCoil.NumOfSpeeds;
12754 : }
12755 : } else {
12756 206 : SpeedNumLS = 1;
12757 206 : SpeedNumHS = 1;
12758 : }
12759 :
12760 265 : MSHPWasteHeat = 0.0;
12761 265 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
12762 265 : AirMassFlowRatioLS = MSHPMassFlowRateLow / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS);
12763 265 : AirMassFlowRatioHS = MSHPMassFlowRateHigh / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS);
12764 265 : if ((AirMassFlow > 0.0) && (CycRatio > 0.0) && (MSHPMassFlowRateHigh == 0.0)) {
12765 0 : ShowSevereError(
12766 : state,
12767 0 : format("CalcMultiSpeedDXCoilCooling: {} \"{} Developer error - inconsistent airflow rates.", thisDXCoil.DXCoilType, thisDXCoil.Name));
12768 0 : if (MSHPMassFlowRateLow == 0.0 && SpeedNum > 1) {
12769 0 : ShowContinueError(state,
12770 : "When AirMassFlow > 0.0 and CycRatio > 0.0 and SpeedNum > 1, then MSHPMassFlowRateLow and MSHPMassFlowRateHigh "
12771 : "must also be > 0.0");
12772 0 : ShowContinueErrorTimeStamp(state, "");
12773 0 : ShowContinueError(state,
12774 0 : format("AirMassFlow={:.3R},CycRatio={:.3R},SpeedNum={:.0R}, MSHPMassFlowRateLow={:.3R}, MSHPMassFlowRateHigh={:.3R}",
12775 : AirMassFlow,
12776 0 : double(SpeedNum),
12777 : CycRatio,
12778 : MSHPMassFlowRateLow,
12779 : MSHPMassFlowRateHigh));
12780 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
12781 : } else {
12782 0 : ShowContinueError(state, "When AirMassFlow > 0.0 and CycRatio > 0.0, then MSHPMassFlowRateHigh must also be > 0.0");
12783 0 : ShowContinueErrorTimeStamp(state, "");
12784 0 : ShowContinueError(state,
12785 0 : format("AirMassFlow={:.3R},CycRatio={:.3R}, MSHPMassFlowRateHigh={:.3R}", AirMassFlow, CycRatio, MSHPMassFlowRateHigh));
12786 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
12787 : }
12788 265 : } else if (CycRatio > 1.0 || SpeedRatio > 1.0) {
12789 0 : ShowSevereError(
12790 : state,
12791 0 : format("CalcMultiSpeedDXCoilCooling: {} \"{} Developer error - inconsistent speed ratios.", thisDXCoil.DXCoilType, thisDXCoil.Name));
12792 0 : ShowContinueError(state, "CycRatio and SpeedRatio must be between 0.0 and 1.0");
12793 0 : ShowContinueErrorTimeStamp(state, "");
12794 0 : ShowContinueError(state, format("CycRatio={:.1R}, SpeedRatio = {:.1R}", CycRatio, SpeedRatio));
12795 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
12796 : }
12797 :
12798 265 : thisDXCoil.PartLoadRatio = 0.0;
12799 265 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
12800 265 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
12801 265 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
12802 265 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
12803 265 : InletAirHumRat = thisDXCoil.InletAirHumRat;
12804 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12805 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
12806 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
12807 265 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure, RoutineName);
12808 265 : if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Air) {
12809 265 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
12810 0 : } else if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
12811 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
12812 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.MSEvapCondEffect(SpeedNumHS));
12813 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure, RoutineName);
12814 : }
12815 265 : if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
12816 168 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
12817 168 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
12818 2 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
12819 : }
12820 : } else {
12821 97 : CrankcaseHeatingPower = 0.0;
12822 : }
12823 :
12824 230 : if ((AirMassFlow > 0.0 && CondInletTemp >= thisDXCoil.MinOATCompressor) && (thisDXCoil.availSched->getCurrentVal() > 0.0) &&
12825 495 : ((SpeedRatio > 0.0 && SingleMode == 0) || CycRatio > 0.0) && (compressorOp == HVAC::CompressorOp::On)) {
12826 :
12827 99 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat, RoutineName);
12828 99 : if (SpeedNum > 1 && SingleMode == 0) {
12829 :
12830 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at low speed
12831 21 : AirVolumeFlowRate = MSHPMassFlowRateLow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
12832 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12833 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
12834 21 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumLS);
12835 21 : if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
12836 26 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
12837 5 : state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
12838 5 : if (thisDXCoil.MSErrIndex(SpeedNumLS) == 0) {
12839 2 : ShowWarningMessage(
12840 : state,
12841 2 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
12842 1 : thisDXCoil.DXCoilType,
12843 1 : thisDXCoil.Name,
12844 : SpeedNumLS));
12845 2 : ShowContinueErrorTimeStamp(state, "");
12846 2 : ShowContinueError(state,
12847 2 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
12848 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12849 1 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12850 : VolFlowperRatedTotCap));
12851 2 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
12852 3 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
12853 : }
12854 40 : ShowRecurringWarningErrorAtEnd(state,
12855 10 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
12856 : "at speed {} error continues...",
12857 5 : thisDXCoil.DXCoilType,
12858 5 : thisDXCoil.Name,
12859 : SpeedNumLS),
12860 : thisDXCoil.MSErrIndex(SpeedNumLS),
12861 : VolFlowperRatedTotCap,
12862 : VolFlowperRatedTotCap);
12863 : }
12864 :
12865 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at high speed
12866 21 : AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
12867 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12868 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
12869 21 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumHS);
12870 21 : if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
12871 21 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
12872 0 : state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
12873 0 : if (thisDXCoil.MSErrIndex(SpeedNumHS) == 0) {
12874 0 : ShowWarningMessage(
12875 : state,
12876 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
12877 0 : thisDXCoil.DXCoilType,
12878 0 : thisDXCoil.Name,
12879 : SpeedNumHS));
12880 0 : ShowContinueErrorTimeStamp(state, "");
12881 0 : ShowContinueError(state,
12882 0 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
12883 0 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12884 0 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12885 : VolFlowperRatedTotCap));
12886 0 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
12887 0 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
12888 : }
12889 0 : ShowRecurringWarningErrorAtEnd(state,
12890 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
12891 : "at speed {} error continues...",
12892 0 : thisDXCoil.DXCoilType,
12893 0 : thisDXCoil.Name,
12894 : SpeedNumHS),
12895 : thisDXCoil.MSErrIndex(SpeedNumHS),
12896 : VolFlowperRatedTotCap,
12897 : VolFlowperRatedTotCap);
12898 : }
12899 :
12900 : // Adjust high speed coil bypass factor for actual maximum air flow rate.
12901 21 : RatedCBFHS = thisDXCoil.MSRatedCBF(SpeedNumHS);
12902 21 : CBFHS = AdjustCBF(RatedCBFHS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS), MSHPMassFlowRateHigh);
12903 21 : RatedCBFLS = thisDXCoil.MSRatedCBF(SpeedNumLS);
12904 21 : CBFLS = AdjustCBF(RatedCBFLS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS), MSHPMassFlowRateLow);
12905 : // get low speed total capacity and SHR at current conditions
12906 63 : CalcTotCapSHR(state,
12907 : InletAirDryBulbTemp,
12908 : InletAirHumRat,
12909 : InletAirEnthalpy,
12910 : InletAirWetBulbC,
12911 : AirMassFlowRatioLS,
12912 : MSHPMassFlowRateLow,
12913 21 : thisDXCoil.MSRatedTotCap(SpeedNumLS),
12914 : CBFLS,
12915 21 : thisDXCoil.MSCCapFTemp(SpeedNumLS),
12916 21 : thisDXCoil.MSCCapFFlow(SpeedNumLS),
12917 : TotCapLS,
12918 : SHRLS,
12919 : CondInletTemp,
12920 : OutdoorPressure,
12921 21 : thisDXCoil.capModFacTotal);
12922 : // get low speed outlet conditions
12923 21 : hDelta = TotCapLS / MSHPMassFlowRateLow;
12924 : // Calculate new apparatus dew point conditions
12925 21 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBFLS);
12926 21 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineNameHighSpeedAlt);
12927 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12928 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
12929 21 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
12930 21 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
12931 : // get corresponding SHR
12932 21 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
12933 21 : SHRLS = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
12934 : } else {
12935 0 : SHRLS = 1.0;
12936 : }
12937 : // cr8918 SHRLS = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
12938 : // get low speed outlet conditions
12939 21 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
12940 21 : hTinwout = InletAirEnthalpy - (1.0 - SHRLS) * hDelta;
12941 21 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
12942 21 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
12943 21 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineName);
12944 21 : if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
12945 1 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
12946 1 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineName);
12947 : }
12948 :
12949 : // get high speed total capacity and SHR at current conditions
12950 :
12951 63 : CalcTotCapSHR(state,
12952 : InletAirDryBulbTemp,
12953 : InletAirHumRat,
12954 : InletAirEnthalpy,
12955 : InletAirWetBulbC,
12956 : AirMassFlowRatioHS,
12957 : MSHPMassFlowRateHigh,
12958 21 : thisDXCoil.MSRatedTotCap(SpeedNumHS),
12959 : CBFHS,
12960 21 : thisDXCoil.MSCCapFTemp(SpeedNumHS),
12961 21 : thisDXCoil.MSCCapFFlow(SpeedNumHS),
12962 : TotCapHS,
12963 : SHRHS,
12964 : CondInletTemp,
12965 : OutdoorPressure,
12966 21 : thisDXCoil.capModFacTotal);
12967 21 : hDelta = TotCapHS / MSHPMassFlowRateHigh;
12968 : // Calculate new apparatus dew point conditions
12969 21 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBFHS);
12970 21 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
12971 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
12972 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
12973 21 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
12974 21 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
12975 : // get corresponding SHR
12976 21 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
12977 21 : SHRHS = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
12978 : } else {
12979 0 : SHRHS = 1.0;
12980 : }
12981 : // cr8918 SHRHS = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
12982 : // get the part load factor that will account for cycling losses
12983 21 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNumHS), SpeedRatio);
12984 21 : if (PLF < 0.7) {
12985 0 : PLF = 0.7;
12986 : }
12987 : // calculate the run time fraction
12988 21 : thisDXCoil.CoolingCoilRuntimeFraction = SpeedRatio / PLF;
12989 21 : thisDXCoil.PartLoadRatio = SpeedRatio;
12990 :
12991 21 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
12992 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
12993 : }
12994 :
12995 : // get high speed outlet conditions
12996 21 : HSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
12997 21 : hTinwout = InletAirEnthalpy - (1.0 - SHRHS) * hDelta;
12998 21 : HSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
12999 21 : HSOutletAirDryBulbTemp = PsyTdbFnHW(HSOutletAirEnthalpy, HSOutletAirHumRat);
13000 21 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, HSOutletAirEnthalpy, OutdoorPressure, RoutineName);
13001 21 : if (HSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
13002 1 : HSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
13003 1 : HSOutletAirHumRat = PsyWFnTdbH(state, HSOutletAirDryBulbTemp, HSOutletAirEnthalpy, RoutineName);
13004 : }
13005 :
13006 : // If constant fan with cycling compressor, call function to determine "effective SHR"
13007 : // which includes the part-load degradation on latent capacity
13008 21 : if (thisDXCoil.LatentImpact && fanOp == HVAC::FanOp::Continuous && SpeedRatio > 0.0) {
13009 0 : QLatRated = thisDXCoil.MSRatedTotCap(SpeedNumHS) * (1.0 - thisDXCoil.MSRatedSHR(SpeedNumHS));
13010 0 : QLatActual = TotCapHS * (1.0 - SHRHS);
13011 0 : SHRUnadjusted = SHRHS;
13012 0 : SHR = CalcEffectiveSHR(state,
13013 : DXCoilNum,
13014 : SHRHS,
13015 : thisDXCoil.CoolingCoilRuntimeFraction,
13016 : QLatRated,
13017 : QLatActual,
13018 : InletAirDryBulbTemp,
13019 : InletAirWetBulbC,
13020 : SpeedNumHS);
13021 : // Calculate full load output conditions
13022 0 : if (SHR > 1.0) {
13023 0 : SHR = 1.0;
13024 : }
13025 0 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
13026 0 : if (SHR < 1.0) {
13027 0 : HSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
13028 : } else {
13029 0 : HSOutletAirHumRat = InletAirHumRat;
13030 : }
13031 0 : HSOutletAirDryBulbTemp = PsyTdbFnHW(HSOutletAirEnthalpy, HSOutletAirHumRat);
13032 : }
13033 :
13034 : // get high speed EIR at current conditions
13035 21 : EIRTempModFacHS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), InletAirWetBulbC, CondInletTemp);
13036 21 : EIRFlowModFacHS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumHS), AirMassFlowRatioHS);
13037 21 : EIRHS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumHS) * EIRFlowModFacHS * EIRTempModFacHS;
13038 : // get low speed EIR at current conditions
13039 21 : EIRTempModFacLS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), InletAirWetBulbC, CondInletTemp);
13040 21 : EIRFlowModFacLS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumLS), AirMassFlowRatioLS);
13041 21 : EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumLS) * EIRTempModFacLS * EIRFlowModFacLS;
13042 :
13043 : // get current total capacity, SHR, EIR
13044 21 : if (SpeedRatio >= 1.0) {
13045 15 : SHR = SHRHS;
13046 15 : EIR = EIRHS;
13047 15 : CondAirMassFlow = RhoAir * thisDXCoil.MSEvapCondAirFlow(SpeedNumHS);
13048 15 : EvapCondPumpElecPower = thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumHS);
13049 : } else {
13050 6 : EIR = SpeedRatio * EIRHS + (1.0 - SpeedRatio) * EIRLS;
13051 6 : SHR = SpeedRatio * SHRHS + (1.0 - SpeedRatio) * SHRLS;
13052 6 : CondAirMassFlow =
13053 6 : RhoAir * (SpeedRatio * thisDXCoil.MSEvapCondAirFlow(SpeedNumHS) + (1.0 - SpeedRatio) * thisDXCoil.MSEvapCondAirFlow(SpeedNumLS));
13054 6 : EvapCondPumpElecPower = SpeedRatio * thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumHS) +
13055 6 : (1.0 - SpeedRatio) * thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumLS);
13056 : }
13057 :
13058 : // Outlet calculation
13059 21 : Real64 SensibleOutputLS(0.0); // low speed sensible output rate
13060 21 : Real64 LatentOutputLS(0.0); // low speed latent output rate
13061 21 : Real64 TotalOutputLS(0.0); // low speed total output rate
13062 21 : Real64 SensibleOutputHS(0.0); // high speed sensible output rate
13063 21 : Real64 LatentOutputHS(0.0); // high speed latent output rate
13064 21 : Real64 TotalOutputHS(0.0); // high speed total output rate
13065 21 : CalcComponentSensibleLatentOutput(MSHPMassFlowRateLow,
13066 : InletAirDryBulbTemp,
13067 : InletAirHumRat,
13068 : LSOutletAirDryBulbTemp,
13069 : LSOutletAirHumRat,
13070 : SensibleOutputLS,
13071 : LatentOutputLS,
13072 : TotalOutputLS);
13073 21 : CalcComponentSensibleLatentOutput(MSHPMassFlowRateHigh,
13074 : InletAirDryBulbTemp,
13075 : InletAirHumRat,
13076 : HSOutletAirDryBulbTemp,
13077 : HSOutletAirHumRat,
13078 : SensibleOutputHS,
13079 : LatentOutputHS,
13080 : TotalOutputHS);
13081 21 : thisDXCoil.TotalCoolingEnergyRate = TotalOutputHS * SpeedRatio + TotalOutputLS * (1.0 - SpeedRatio);
13082 21 : thisDXCoil.SensCoolingEnergyRate = SensibleOutputHS * SpeedRatio + SensibleOutputLS * (1.0 - SpeedRatio);
13083 21 : thisDXCoil.LatCoolingEnergyRate = LatentOutputHS * SpeedRatio + LatentOutputLS * (1.0 - SpeedRatio);
13084 : // Average outlet enthalpy
13085 21 : OutletAirEnthalpy = InletAirEnthalpy - thisDXCoil.TotalCoolingEnergyRate / thisDXCoil.InletAirMassFlowRate;
13086 :
13087 21 : if (fanOp == HVAC::FanOp::Cycling) {
13088 9 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
13089 : }
13090 : // Update outlet conditions
13091 21 : if (SpeedRatio == 0.0 && fanOp == HVAC::FanOp::Cycling) {
13092 3 : OutletAirEnthalpy = LSOutletAirEnthalpy;
13093 3 : OutletAirHumRat = LSOutletAirHumRat;
13094 3 : OutletAirDryBulbTemp = LSOutletAirDryBulbTemp;
13095 18 : } else if (SpeedRatio >= 1.0 && fanOp == HVAC::FanOp::Cycling) {
13096 6 : OutletAirEnthalpy = HSOutletAirEnthalpy;
13097 6 : OutletAirHumRat = HSOutletAirHumRat;
13098 6 : OutletAirDryBulbTemp = HSOutletAirDryBulbTemp;
13099 : } else {
13100 12 : OutletAirHumRat =
13101 12 : ((HSOutletAirHumRat * SpeedRatio * MSHPMassFlowRateHigh) + (LSOutletAirHumRat * (1.0 - SpeedRatio) * MSHPMassFlowRateLow)) /
13102 12 : thisDXCoil.InletAirMassFlowRate;
13103 12 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
13104 12 : if (OutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
13105 0 : OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
13106 0 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy, RoutineName);
13107 0 : CalcComponentSensibleLatentOutput(AirMassFlow,
13108 : InletAirDryBulbTemp,
13109 : InletAirHumRat,
13110 : OutletAirDryBulbTemp,
13111 : OutletAirHumRat,
13112 0 : thisDXCoil.SensCoolingEnergyRate,
13113 0 : thisDXCoil.LatCoolingEnergyRate,
13114 0 : thisDXCoil.TotalCoolingEnergyRate);
13115 : }
13116 : }
13117 :
13118 21 : LSElecCoolingPower = TotCapLS * EIRLS;
13119 21 : HSElecCoolingPower = TotCapHS * EIRHS;
13120 :
13121 : // Power calculation
13122 21 : if (!thisDXCoil.PLRImpact) {
13123 21 : thisDXCoil.ElecCoolingPower = SpeedRatio * HSElecCoolingPower + (1.0 - SpeedRatio) * LSElecCoolingPower;
13124 : } else {
13125 0 : thisDXCoil.ElecCoolingPower =
13126 0 : thisDXCoil.CoolingCoilRuntimeFraction * HSElecCoolingPower + (1.0 - thisDXCoil.CoolingCoilRuntimeFraction) * LSElecCoolingPower;
13127 : }
13128 : // Now reset runtime fraction to 1.0 (because LS is running the full timestep)
13129 21 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0;
13130 :
13131 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
13132 21 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
13133 :
13134 : // Waste heat calculation
13135 : // TODO: waste heat not considered even if defined in Cooling:DX:MultiSpeed, N16, \field Speed 1 Rated Waste Heat Fraction of
13136 : // Power Input
13137 21 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13138 8 : if (thisDXCoil.MSWasteHeat(SpeedNumLS) == 0) {
13139 7 : WasteHeatLS = thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13140 : } else {
13141 1 : WasteHeatLS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumLS), OutdoorDryBulb, InletAirDryBulbTemp) *
13142 1 : thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13143 : }
13144 8 : if (thisDXCoil.MSWasteHeat(SpeedNumHS) == 0) {
13145 7 : WasteHeatHS = thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13146 : } else {
13147 1 : WasteHeatHS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumHS), OutdoorDryBulb, InletAirDryBulbTemp) *
13148 1 : thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13149 : }
13150 8 : thisDXCoil.MSFuelWasteHeat = (SpeedRatio * WasteHeatHS + (1.0 - SpeedRatio) * WasteHeatLS) * thisDXCoil.ElecCoolingPower;
13151 8 : if (thisDXCoil.MSHPHeatRecActive) {
13152 1 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
13153 : }
13154 : }
13155 :
13156 : // Energy use for other fuel types
13157 21 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13158 8 : thisDXCoil.FuelUsed = thisDXCoil.ElecCoolingPower;
13159 8 : thisDXCoil.ElecCoolingPower = 0.0;
13160 : }
13161 :
13162 21 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
13163 21 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
13164 21 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
13165 21 : thisDXCoil.CrankcaseHeaterPower = 0.0;
13166 :
13167 99 : } else if (CycRatio > 0.0) {
13168 :
13169 78 : if (fanOp == HVAC::FanOp::Cycling) {
13170 37 : AirMassFlow /= CycRatio;
13171 : }
13172 78 : if (fanOp == HVAC::FanOp::Continuous) {
13173 41 : AirMassFlow = MSHPMassFlowRateHigh;
13174 : }
13175 :
13176 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at low speed
13177 78 : AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
13178 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13179 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
13180 78 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNum);
13181 78 : if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13182 99 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
13183 21 : state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
13184 21 : if (thisDXCoil.MSErrIndex(SpeedNum) == 0) {
13185 4 : ShowWarningMessage(
13186 : state,
13187 4 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
13188 2 : thisDXCoil.DXCoilType,
13189 2 : thisDXCoil.Name,
13190 : SpeedNum));
13191 4 : ShowContinueErrorTimeStamp(state, "");
13192 4 : ShowContinueError(state,
13193 4 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13194 2 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13195 2 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13196 : VolFlowperRatedTotCap));
13197 4 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13198 6 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13199 : }
13200 168 : ShowRecurringWarningErrorAtEnd(state,
13201 42 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
13202 : "at speed {} error continues...",
13203 21 : thisDXCoil.DXCoilType,
13204 21 : thisDXCoil.Name,
13205 : SpeedNumHS),
13206 : thisDXCoil.MSErrIndex(SpeedNumHS),
13207 : VolFlowperRatedTotCap,
13208 : VolFlowperRatedTotCap);
13209 : }
13210 :
13211 78 : if (thisDXCoil.CondenserType(SpeedNum) == DataHeatBalance::RefrigCondenserType::Evap) {
13212 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
13213 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.MSEvapCondEffect(SpeedNum));
13214 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure, RoutineName);
13215 : }
13216 :
13217 78 : RatedCBFLS = thisDXCoil.MSRatedCBF(SpeedNum);
13218 78 : CBFLS = AdjustCBF(RatedCBFLS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNum), MSHPMassFlowRateHigh);
13219 :
13220 : // Adjust low speed coil bypass factor for actual flow rate.
13221 : // CBF = AdjustCBF(DXCoil(DXCoilNum)%RatedCBF2,DXCoil(DXCoilNum)%RatedAirMassFlowRate2,AirMassFlow)
13222 : // get low speed total capacity and SHR at current conditions
13223 234 : CalcTotCapSHR(state,
13224 : InletAirDryBulbTemp,
13225 : InletAirHumRat,
13226 : InletAirEnthalpy,
13227 : InletAirWetBulbC,
13228 : AirMassFlowRatioLS,
13229 : MSHPMassFlowRateHigh,
13230 78 : thisDXCoil.MSRatedTotCap(SpeedNum),
13231 : CBFLS,
13232 78 : thisDXCoil.MSCCapFTemp(SpeedNum),
13233 78 : thisDXCoil.MSCCapFFlow(SpeedNum),
13234 : TotCapLS,
13235 : SHRLS,
13236 : CondInletTemp,
13237 : OutdoorPressure,
13238 78 : thisDXCoil.capModFacTotal);
13239 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13240 : // Node(DXCoil(DXCoilNum)%AirInNode)%Press)
13241 78 : hDelta = TotCapLS / AirMassFlow;
13242 : // Adjust CBF for off-nominal flow
13243 78 : CBF = AdjustCBF(thisDXCoil.MSRatedCBF(SpeedNum), thisDXCoil.MSRatedAirMassFlowRate(SpeedNum), AirMassFlow);
13244 : // Calculate new apparatus dew point conditions
13245 78 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
13246 78 : tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
13247 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13248 : // tADP = PsyTsatFnHPb(hADP,InletAirPressure)
13249 78 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
13250 78 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
13251 : // get corresponding SHR
13252 78 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
13253 78 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
13254 : } else {
13255 0 : SHR = 1.0;
13256 : }
13257 : // cr8918 SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
13258 :
13259 : // get the part load factor that will account for cycling losses
13260 78 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNum), CycRatio);
13261 78 : if (fanOp == HVAC::FanOp::Cycling && CycRatio == 1.0 && PLF != 1.0) {
13262 0 : if (thisDXCoil.PLFErrIndex == 0) {
13263 0 : ShowWarningMessage(state,
13264 0 : format("The PLF curve value for DX cooling coil {} ={:.2R} for part-load ratio = 1", thisDXCoil.Name, PLF));
13265 0 : ShowContinueError(state, "PLF curve value must be = 1.0 and has been reset to 1.0. Simulation is continuing.");
13266 0 : ShowContinueErrorTimeStamp(state, "");
13267 : }
13268 0 : ShowRecurringWarningErrorAtEnd(
13269 0 : state, thisDXCoil.Name + "\": DX cooling coil PLF curve value <> 1.0 warning continues...", thisDXCoil.PLFErrIndex, PLF, PLF);
13270 0 : PLF = 1.0;
13271 : }
13272 :
13273 78 : if (PLF < 0.7) {
13274 0 : PLF = 0.7;
13275 : }
13276 : // calculate the run time fraction
13277 78 : thisDXCoil.CoolingCoilRuntimeFraction = CycRatio / PLF;
13278 78 : thisDXCoil.PartLoadRatio = CycRatio;
13279 :
13280 78 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
13281 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
13282 : }
13283 :
13284 : // get low speed outlet conditions
13285 78 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
13286 78 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
13287 78 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
13288 78 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
13289 78 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineName);
13290 78 : if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
13291 0 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
13292 0 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineName);
13293 : }
13294 :
13295 : // If constant fan with cycling compressor, call function to determine "effective SHR"
13296 : // which includes the part-load degradation on latent capacity
13297 78 : if (fanOp == HVAC::FanOp::Continuous) {
13298 41 : QLatRated = thisDXCoil.MSRatedTotCap(SpeedNum) * (1.0 - thisDXCoil.MSRatedSHR(SpeedNum));
13299 41 : QLatActual = TotCapLS * (1.0 - SHR);
13300 41 : SHRUnadjusted = SHR;
13301 41 : SHR = CalcEffectiveSHR(state,
13302 : DXCoilNum,
13303 : SHR,
13304 : thisDXCoil.CoolingCoilRuntimeFraction,
13305 : QLatRated,
13306 : QLatActual,
13307 : InletAirDryBulbTemp,
13308 : InletAirWetBulbC,
13309 : SpeedNum);
13310 : // Calculate full load output conditions
13311 41 : if (SHR > 1.0) {
13312 0 : SHR = 1.0;
13313 : }
13314 41 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
13315 41 : if (SHR < 1.0) {
13316 33 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
13317 : } else {
13318 8 : LSOutletAirHumRat = InletAirHumRat;
13319 : }
13320 41 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
13321 : }
13322 :
13323 78 : if (fanOp == HVAC::FanOp::Cycling) {
13324 37 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
13325 : }
13326 78 : if (fanOp == HVAC::FanOp::Continuous) {
13327 : // outlet conditions are average of inlet and low speed weighted by CycRatio
13328 : // Continuous fan, cycling compressor
13329 41 : Real64 CycAirFlowRatio =
13330 41 : CycRatio * AirMassFlow / thisDXCoil.InletAirMassFlowRate; // ratio of compressor on airflow to average timestep airflow
13331 41 : OutletAirEnthalpy = CycAirFlowRatio * LSOutletAirEnthalpy + (1.0 - CycAirFlowRatio) * InletAirEnthalpy;
13332 41 : OutletAirHumRat = CycAirFlowRatio * LSOutletAirHumRat + (1.0 - CycAirFlowRatio) * InletAirHumRat;
13333 41 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
13334 : } else {
13335 37 : OutletAirHumRat = LSOutletAirHumRat;
13336 37 : OutletAirDryBulbTemp = LSOutletAirDryBulbTemp;
13337 37 : OutletAirEnthalpy = LSOutletAirEnthalpy;
13338 : }
13339 :
13340 : // get low speed EIR at current conditions
13341 78 : EIRTempModFacLS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNum), InletAirWetBulbC, CondInletTemp);
13342 78 : EIRFlowModFacLS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNum), AirMassFlowRatioLS);
13343 78 : EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNum) * EIRTempModFacLS * EIRFlowModFacLS;
13344 :
13345 : // get the electrical power consumption
13346 78 : thisDXCoil.ElecCoolingPower = TotCapLS * EIRLS * thisDXCoil.CoolingCoilRuntimeFraction;
13347 : // calculate cooling output power
13348 : // AirMassFlow = DXCoil(DXCoilNum)%InletAirMassFlowRate
13349 78 : CalcComponentSensibleLatentOutput(AirMassFlow,
13350 : InletAirDryBulbTemp,
13351 : InletAirHumRat,
13352 : LSOutletAirDryBulbTemp,
13353 : LSOutletAirHumRat,
13354 78 : thisDXCoil.SensCoolingEnergyRate,
13355 78 : thisDXCoil.LatCoolingEnergyRate,
13356 78 : thisDXCoil.TotalCoolingEnergyRate);
13357 78 : thisDXCoil.TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate * CycRatio;
13358 78 : thisDXCoil.SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate * CycRatio;
13359 78 : thisDXCoil.LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate * CycRatio;
13360 :
13361 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
13362 78 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
13363 78 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
13364 78 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
13365 78 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
13366 78 : CondAirMassFlow = RhoAir * thisDXCoil.MSEvapCondAirFlow(SpeedNum) * thisDXCoil.CoolingCoilRuntimeFraction;
13367 78 : EvapCondPumpElecPower = thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNum) * thisDXCoil.CoolingCoilRuntimeFraction;
13368 :
13369 : // Waste heat
13370 78 : if (thisDXCoil.MSHPHeatRecActive) {
13371 0 : if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
13372 0 : thisDXCoil.MSFuelWasteHeat = thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecCoolingPower;
13373 : } else {
13374 0 : thisDXCoil.MSFuelWasteHeat = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNum), OutdoorDryBulb, InletAirDryBulbTemp) *
13375 0 : thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecCoolingPower;
13376 : }
13377 0 : if (thisDXCoil.MSHPHeatRecActive) {
13378 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
13379 : }
13380 : }
13381 : // Energy use for other fuel types
13382 78 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13383 22 : thisDXCoil.FuelUsed = thisDXCoil.ElecCoolingPower;
13384 22 : thisDXCoil.ElecCoolingPower = 0.0;
13385 : }
13386 :
13387 78 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
13388 78 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
13389 : } else {
13390 0 : thisDXCoil.CrankcaseHeaterPower =
13391 0 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.CoolingCoilRuntimeFraction,
13392 0 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction));
13393 : }
13394 : }
13395 :
13396 99 : if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
13397 : //******************
13398 : // WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
13399 : // H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
13400 : // /RhoWater [kgWater/m3]
13401 : //******************
13402 0 : RhoWater = RhoH2O(OutdoorDryBulb);
13403 0 : thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater;
13404 0 : thisDXCoil.EvapCondPumpElecPower = EvapCondPumpElecPower;
13405 : // set water system demand request (if needed)
13406 0 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
13407 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
13408 0 : thisDXCoil.EvapWaterConsumpRate;
13409 : }
13410 :
13411 : // Calculate basin heater power
13412 0 : CalcBasinHeaterPower(state,
13413 : thisDXCoil.BasinHeaterPowerFTempDiff,
13414 : thisDXCoil.basinHeaterSched,
13415 : thisDXCoil.BasinHeaterSetPointTemp,
13416 0 : thisDXCoil.BasinHeaterPower);
13417 0 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
13418 : }
13419 :
13420 : } else {
13421 :
13422 : // DX coil is off; just pass through conditions
13423 166 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
13424 166 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
13425 166 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
13426 :
13427 166 : thisDXCoil.FuelUsed = 0.0;
13428 166 : thisDXCoil.ElecCoolingPower = 0.0;
13429 166 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
13430 166 : thisDXCoil.SensCoolingEnergyRate = 0.0;
13431 166 : thisDXCoil.LatCoolingEnergyRate = 0.0;
13432 166 : thisDXCoil.EvapCondPumpElecPower = 0.0;
13433 166 : thisDXCoil.EvapWaterConsumpRate = 0.0;
13434 :
13435 166 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
13436 166 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
13437 : } else {
13438 0 : thisDXCoil.CrankcaseHeaterPower =
13439 0 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction);
13440 : }
13441 :
13442 : // Calculate basin heater power
13443 166 : if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
13444 0 : CalcBasinHeaterPower(state,
13445 : thisDXCoil.BasinHeaterPowerFTempDiff,
13446 : thisDXCoil.basinHeaterSched,
13447 : thisDXCoil.BasinHeaterSetPointTemp,
13448 0 : thisDXCoil.BasinHeaterPower);
13449 : }
13450 : }
13451 :
13452 265 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
13453 265 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
13454 265 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
13455 265 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
13456 265 : thisDXCoil.CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure
13457 :
13458 : // set outlet node conditions
13459 265 : int airOutletNode = thisDXCoil.AirOutNode;
13460 265 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
13461 265 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
13462 :
13463 : // calc secondary coil if specified
13464 265 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
13465 0 : CalcSecondaryDXCoils(state, DXCoilNum);
13466 : }
13467 265 : }
13468 :
13469 211 : void CalcMultiSpeedDXCoilHeating(EnergyPlusData &state,
13470 : int const DXCoilNum, // the number of the DX heating coil to be simulated
13471 : Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
13472 : Real64 const CycRatio, // cycling part load ratio
13473 : int const SpeedNum, // Speed number
13474 : HVAC::FanOp const fanOp, // Fan operation mode
13475 : int const SingleMode // Single mode operation Yes/No; 1=Yes, 0=No
13476 : )
13477 : {
13478 :
13479 : // SUBROUTINE INFORMATION:
13480 : // AUTHOR Lixing Gu, FSEC
13481 : // DATE WRITTEN June 2007
13482 : // RE-ENGINEERED Revised based on CalcDXHeatingCoil
13483 :
13484 : // PURPOSE OF THIS SUBROUTINE:
13485 : // Calculates the air-side performance and electrical energy use of a direct-
13486 : // expansion, air-cooled cooling unit with a multispeed compressor.
13487 :
13488 : // METHODOLOGY EMPLOYED:
13489 : // Uses the same methodology as the single speed DX heating unit model (SUBROUTINE CalcDXHeatingCoil).
13490 : // In addition it assumes that the unit performance is obtained by interpolating between
13491 : // the performance at high speed and that at low speed. If the output needed is below
13492 : // that produced at low speed, the compressor cycles between off and low speed.
13493 :
13494 : // Using/Aliasing
13495 : using Curve::CurveValue;
13496 211 : Real64 MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
13497 211 : Real64 MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
13498 211 : auto &MSHPWasteHeat = state.dataHVACGlobal->MSHPWasteHeat;
13499 :
13500 : // SUBROUTINE ARGUMENT DEFINITIONS:
13501 : // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
13502 :
13503 : // SUBROUTINE PARAMETER DEFINITIONS:
13504 : static constexpr std::string_view RoutineName("CalcMultiSpeedDXCoilHeating");
13505 : static constexpr std::string_view RoutineNameAverageLoad("CalcMultiSpeedDXCoilHeating:Averageload");
13506 : static constexpr std::string_view RoutineNameFullLoad("CalcMultiSpeedDXCoilHeating:fullload");
13507 :
13508 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13509 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
13510 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
13511 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
13512 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
13513 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
13514 : Real64 OutletAirEnthalpy; // outlet air enthalpy [J/kg]
13515 : Real64 OutletAirHumRat; // outlet air humidity ratio [kg/kg]
13516 : Real64 TotCapHS; // total capacity at high speed [W]
13517 : Real64 TotCapLS; // total capacity at low speed [W]
13518 : Real64 TotCapHSAdj; // total adjusted capacity at high speed [W]
13519 : Real64 TotCapLSAdj; // total adjusted capacity at low speed [W]
13520 : Real64 EIRHS; // EIR at off rated conditions (high speed)
13521 : Real64 EIRLS; // EIR at off rated conditions (low speed)
13522 : Real64 TotCap; // total capacity at current speed [W]
13523 : Real64 TotCapAdj; // total adjusted capacity at current speed [W]
13524 : Real64 EIR; // EIR at current speed
13525 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in
13526 : // power calculation
13527 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
13528 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
13529 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
13530 : int SpeedNumHS; // High speed number
13531 : int SpeedNumLS; // Low speed number
13532 : Real64 AirMassFlowRatioLS; // airflow ratio at low speed
13533 : Real64 AirMassFlowRatioHS; // airflow ratio at high speed
13534 : Real64 AirFlowRatio; // Airflow ratio
13535 : Real64 PLRHeating; // Part load ratio in heating
13536 : Real64 CrankcaseHeatingPower; // Power due to crank case heater
13537 : Real64 AirVolumeFlowRate; // Air volume flow rate across the heating coil
13538 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total heating capacity
13539 211 : Real64 TotCapTempModFac(0.0); // Total capacity modifier as a function of temperature
13540 : Real64 TotCapFlowModFac; // Total capacity modifier as a function of flow ratio
13541 : Real64 OutdoorCoilT; // Outdoor coil temperature
13542 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temperature of OutdoorCoilT
13543 : Real64 LoadDueToDefrost; // Additional load due to defrost
13544 : Real64 LoadDueToDefrostLS; // Additional load due to defrost at low speed
13545 : Real64 LoadDueToDefrostHS; // Additional load due to defrost at high speed
13546 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
13547 : Real64 FractionalDefrostTime; // Fraction of time step when system is in defrost
13548 : Real64 InputPowerMultiplier; // Multiplier for power when system is in defrost
13549 : Real64 DefrostEIRTempModFac; // EIR modifier for defrost
13550 : Real64 FullLoadOutAirEnth; // Outlet full load enthalpy
13551 : Real64 FullLoadOutAirHumRat; // Outlet humidity ratio at full load
13552 : Real64 FullLoadOutAirTemp; // Outlet temperature at full load
13553 : Real64 FullLoadOutAirRH; // Outlet relative humidity at full load
13554 : Real64 OutletAirTemp; // Supply air temperature
13555 211 : Real64 EIRTempModFac(0.0); // EIR modifier as a function of temperature
13556 : Real64 EIRFlowModFac; // EIR modifier as a function of airflow ratio
13557 : Real64 WasteHeatLS; // Waste heat at low speed
13558 : Real64 WasteHeatHS; // Waste heat at high speed
13559 : Real64 LSFullLoadOutAirEnth; // Outlet full load enthalpy at low speed
13560 : Real64 HSFullLoadOutAirEnth; // Outlet full load enthalpy at high speed
13561 : Real64 LSElecHeatingPower; // Full load power at low speed
13562 : Real64 HSElecHeatingPower; // Full load power at high speed
13563 : Real64 DefrostPowerLS; // Defrost power at low speed [W]
13564 : Real64 DefrostPowerHS; // Defrost power at high speed [W]
13565 :
13566 : // Autodesk:Uninit Initialize variables used uninitialized
13567 211 : FullLoadOutAirEnth = 0.0; // Autodesk:Uninit Force default initialization
13568 :
13569 211 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
13570 :
13571 211 : if (SpeedNum > 1) {
13572 54 : SpeedNumLS = SpeedNum - 1;
13573 54 : SpeedNumHS = SpeedNum;
13574 54 : if (SpeedNum > thisDXCoil.NumOfSpeeds) {
13575 0 : SpeedNumLS = thisDXCoil.NumOfSpeeds - 1;
13576 0 : SpeedNumHS = thisDXCoil.NumOfSpeeds;
13577 : }
13578 : } else {
13579 157 : SpeedNumLS = 1;
13580 157 : SpeedNumHS = 1;
13581 : }
13582 :
13583 211 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
13584 211 : AirMassFlowRatioLS = MSHPMassFlowRateLow / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS);
13585 211 : AirMassFlowRatioHS = MSHPMassFlowRateHigh / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS);
13586 211 : if ((AirMassFlow > 0.0) && (CycRatio > 0.0) && (MSHPMassFlowRateHigh == 0.0)) {
13587 0 : ShowSevereError(
13588 : state,
13589 0 : format("CalcMultiSpeedDXCoilHeating: {} \"{} Developer error - inconsistent airflow rates.", thisDXCoil.DXCoilType, thisDXCoil.Name));
13590 0 : if (MSHPMassFlowRateLow == 0.0 && SpeedNum > 1) {
13591 0 : ShowContinueError(state,
13592 : "When AirMassFlow > 0.0 and CycRatio > 0.0 and SpeedNum > 1, then MSHPMassFlowRateLow and MSHPMassFlowRateHigh "
13593 : "must also be > 0.0");
13594 0 : ShowContinueErrorTimeStamp(state, "");
13595 0 : ShowContinueError(state,
13596 0 : format("AirMassFlow={:.3R},CycRatio={:.3R},SpeedNum={:.0R}, MSHPMassFlowRateLow={:.3R}, MSHPMassFlowRateHigh={:.3R}",
13597 : AirMassFlow,
13598 0 : double(SpeedNum),
13599 : CycRatio,
13600 : MSHPMassFlowRateLow,
13601 : MSHPMassFlowRateHigh));
13602 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
13603 : } else {
13604 0 : ShowContinueError(state, "When AirMassFlow > 0.0 and CycRatio > 0.0, then MSHPMassFlowRateHigh must also be > 0.0");
13605 0 : ShowContinueErrorTimeStamp(state, "");
13606 0 : ShowContinueError(state,
13607 0 : format("AirMassFlow={:.3R},CycRatio={:.3R}, MSHPMassFlowRateHigh={:.3R}", AirMassFlow, CycRatio, MSHPMassFlowRateHigh));
13608 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
13609 : }
13610 211 : } else if (CycRatio > 1.0 || SpeedRatio > 1.0) {
13611 0 : ShowSevereError(
13612 : state,
13613 0 : format("CalcMultiSpeedDXCoilHeating: {} \"{} Developer error - inconsistent speed ratios.", thisDXCoil.DXCoilType, thisDXCoil.Name));
13614 0 : ShowContinueError(state, "CycRatio and SpeedRatio must be between 0.0 and 1.0");
13615 0 : ShowContinueErrorTimeStamp(state, "");
13616 0 : ShowContinueError(state, format("CycRatio={:.1R}, SpeedRatio = {:.1R}", CycRatio, SpeedRatio));
13617 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
13618 : }
13619 :
13620 211 : AirFlowRatio = 1.0;
13621 211 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
13622 22 : MSHPWasteHeat = 0.0;
13623 : }
13624 :
13625 : // Get condenser outdoor node info from DX Heating Coil
13626 211 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
13627 71 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press;
13628 : // If node is not connected to anything, pressure = default, use weather data
13629 71 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
13630 71 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13631 71 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13632 71 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13633 : } else {
13634 0 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp;
13635 0 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat;
13636 : }
13637 71 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
13638 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
13639 0 : OutdoorDryBulb = secZoneHB.ZT;
13640 0 : OutdoorHumRat = secZoneHB.airHumRat;
13641 : // OutdoorWetBulb = DXCoil( DXCoilNum ).EvapInletWetBulb;
13642 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13643 : }
13644 140 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
13645 0 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
13646 0 : OutdoorDryBulb = secZoneHB.ZT;
13647 0 : OutdoorHumRat = secZoneHB.airHumRat;
13648 : // OutdoorWetBulb = DXCoil( DXCoilNum ).EvapInletWetBulb;
13649 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13650 : } else {
13651 140 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13652 140 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13653 140 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13654 : }
13655 :
13656 211 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
13657 211 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
13658 211 : InletAirHumRat = thisDXCoil.InletAirHumRat;
13659 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13660 : // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
13661 : // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
13662 211 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure, RoutineName);
13663 211 : PLRHeating = 0.0;
13664 211 : thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
13665 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
13666 211 : if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
13667 123 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
13668 123 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
13669 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
13670 : }
13671 : } else {
13672 88 : CrankcaseHeatingPower = 0.0;
13673 : }
13674 211 : thisDXCoil.PartLoadRatio = 0.0;
13675 211 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
13676 :
13677 302 : if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && ((CycRatio > 0.0) || (SpeedRatio > 0.0 && SingleMode == 0)) &&
13678 91 : OutdoorDryBulb > thisDXCoil.MinOATCompressor) {
13679 :
13680 91 : if (SpeedNum > 1 && SingleMode == 0) {
13681 :
13682 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton) at low speed
13683 28 : AirVolumeFlowRate = MSHPMassFlowRateLow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
13684 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13685 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
13686 28 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumLS);
13687 56 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13688 28 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
13689 0 : if (thisDXCoil.MSErrIndex(SpeedNumLS) == 0) {
13690 0 : ShowWarningMessage(
13691 : state,
13692 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed {}.",
13693 0 : thisDXCoil.DXCoilType,
13694 0 : thisDXCoil.Name,
13695 : SpeedNumLS));
13696 0 : ShowContinueErrorTimeStamp(state, "");
13697 0 : ShowContinueError(state,
13698 0 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13699 0 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13700 0 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13701 : VolFlowperRatedTotCap));
13702 0 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13703 0 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13704 : }
13705 0 : ShowRecurringWarningErrorAtEnd(state,
13706 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range "
13707 : "at speed {} error continues...",
13708 0 : thisDXCoil.DXCoilType,
13709 0 : thisDXCoil.Name,
13710 : SpeedNumLS),
13711 : thisDXCoil.MSErrIndex(SpeedNumLS),
13712 : VolFlowperRatedTotCap,
13713 : VolFlowperRatedTotCap);
13714 : }
13715 :
13716 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton) at high speed
13717 28 : AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
13718 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13719 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
13720 28 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumHS);
13721 56 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13722 28 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
13723 0 : if (thisDXCoil.MSErrIndex(SpeedNumHS) == 0) {
13724 0 : ShowWarningMessage(
13725 : state,
13726 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed {}.",
13727 0 : thisDXCoil.DXCoilType,
13728 0 : thisDXCoil.Name,
13729 : SpeedNumHS));
13730 0 : ShowContinueErrorTimeStamp(state, "");
13731 0 : ShowContinueError(state,
13732 0 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13733 0 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13734 0 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13735 : VolFlowperRatedTotCap));
13736 0 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13737 0 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13738 : }
13739 0 : ShowRecurringWarningErrorAtEnd(state,
13740 0 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range "
13741 : "at speed {} error continues...",
13742 0 : thisDXCoil.DXCoilType,
13743 0 : thisDXCoil.Name,
13744 : SpeedNumHS),
13745 : thisDXCoil.MSErrIndex(SpeedNumHS),
13746 : VolFlowperRatedTotCap,
13747 : VolFlowperRatedTotCap);
13748 : }
13749 :
13750 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
13751 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
13752 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
13753 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
13754 : // Low speed
13755 28 : if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNumLS))->numDims == 1) {
13756 1 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumLS), OutdoorDryBulb);
13757 : } else {
13758 27 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumLS), InletAirDryBulbTemp, OutdoorDryBulb);
13759 : }
13760 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
13761 28 : TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNumLS), AirMassFlowRatioLS);
13762 : // Calculate total heating capacity for off-rated conditions
13763 28 : TotCapLS = thisDXCoil.MSRatedTotCap(SpeedNumLS) * TotCapFlowModFac * TotCapTempModFac;
13764 : // High speed
13765 28 : if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNumHS))->numDims == 1) {
13766 1 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumHS), OutdoorDryBulb);
13767 : } else {
13768 27 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumHS), InletAirDryBulbTemp, OutdoorDryBulb);
13769 : }
13770 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
13771 28 : TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNumHS), AirMassFlowRatioHS);
13772 : // Calculate total heating capacity for off-rated conditions
13773 28 : TotCapHS = thisDXCoil.MSRatedTotCap(SpeedNumHS) * TotCapFlowModFac * TotCapTempModFac;
13774 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
13775 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
13776 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
13777 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
13778 : // Low Speed
13779 28 : if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(SpeedNumLS))->numDims == 1) {
13780 1 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), OutdoorDryBulb);
13781 : } else {
13782 27 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), InletAirDryBulbTemp, OutdoorDryBulb);
13783 : }
13784 28 : EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumLS), AirMassFlowRatioLS);
13785 28 : EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumLS) * EIRTempModFac * EIRFlowModFac;
13786 : // High Speed
13787 28 : if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(SpeedNumHS))->numDims == 1) {
13788 1 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), OutdoorDryBulb);
13789 : } else {
13790 27 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), InletAirDryBulbTemp, OutdoorDryBulb);
13791 : }
13792 28 : EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumHS), AirMassFlowRatioHS);
13793 28 : EIRHS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumHS) * EIRTempModFac * EIRFlowModFac;
13794 :
13795 : // Calculating adjustment factors for defrost
13796 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
13797 28 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
13798 28 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure, RoutineName)));
13799 :
13800 : // Initializing defrost adjustment factors
13801 28 : LoadDueToDefrostLS = 0.0;
13802 28 : LoadDueToDefrostHS = 0.0;
13803 28 : HeatingCapacityMultiplier = 1.0;
13804 28 : FractionalDefrostTime = 0.0;
13805 28 : InputPowerMultiplier = 1.0;
13806 28 : DefrostPowerLS = 0.0;
13807 28 : DefrostPowerHS = 0.0;
13808 :
13809 : // Check outdoor temperature to determine if defrost is active
13810 28 : if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost) {
13811 : // Calculate defrost adjustment factors depending on defrost control type
13812 6 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
13813 6 : FractionalDefrostTime = thisDXCoil.DefrostTime;
13814 6 : if (FractionalDefrostTime > 0.0) {
13815 5 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13816 2 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
13817 2 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
13818 : } else {
13819 3 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
13820 3 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
13821 3 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13822 2 : ShowWarningMessage(
13823 : state,
13824 2 : format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
13825 : "actuator must be both provided for DX heating coil {}",
13826 1 : thisDXCoil.Name));
13827 3 : ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
13828 : }
13829 : }
13830 : }
13831 : } else { // else defrost control is on-demand
13832 0 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
13833 0 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13834 0 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
13835 0 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
13836 : } else {
13837 0 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
13838 0 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
13839 0 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13840 0 : ShowWarningMessage(state,
13841 0 : format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
13842 : "actuator must be both provided for DX heating coil {}",
13843 0 : thisDXCoil.Name));
13844 0 : ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
13845 : }
13846 : }
13847 : }
13848 :
13849 6 : if (FractionalDefrostTime > 0.0) {
13850 : // Calculate defrost adjustment factors depending on defrost control strategy
13851 5 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
13852 1 : DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
13853 1 : LoadDueToDefrostLS =
13854 1 : (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(SpeedNumLS) / 1.01667);
13855 1 : DefrostPowerLS = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(SpeedNumLS) / 1.01667) * FractionalDefrostTime;
13856 1 : LoadDueToDefrostHS =
13857 1 : (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(SpeedNumHS) / 1.01667);
13858 1 : DefrostPowerHS = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(SpeedNumHS) / 1.01667) * FractionalDefrostTime;
13859 : } else { // Defrost strategy is resistive
13860 4 : thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
13861 : }
13862 : } else { // Defrost is not active because (OutDryBulbTemp .GT. DXCoil(DXCoilNum)%MaxOATDefrost)
13863 1 : thisDXCoil.DefrostPower = 0.0;
13864 : }
13865 : }
13866 :
13867 28 : TotCapLSAdj = TotCapLS * HeatingCapacityMultiplier;
13868 28 : TotCapHSAdj = TotCapHS * HeatingCapacityMultiplier;
13869 :
13870 : // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
13871 28 : PLRHeating = min(1.0, (SpeedRatio + LoadDueToDefrostHS / TotCapHSAdj));
13872 28 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNumHS), PLRHeating); // Calculate part-load factor
13873 :
13874 28 : if (PLF < 0.7) {
13875 0 : if (thisDXCoil.PLRErrIndex == 0) {
13876 0 : ShowWarningMessage(
13877 : state,
13878 0 : format("The PLF curve value at high speed for DX multispeed heating coil {} ={:.2R} for part-load ratio ={:.2R}",
13879 0 : thisDXCoil.Name,
13880 : PLF,
13881 : PLRHeating));
13882 0 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
13883 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:MultiSpeed].");
13884 0 : ShowContinueErrorTimeStamp(state, "");
13885 : }
13886 0 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
13887 0 : PLF = 0.7;
13888 : }
13889 :
13890 28 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
13891 28 : if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
13892 0 : if (thisDXCoil.ErrIndex4 == 0) {
13893 0 : ShowWarningMessage(state,
13894 0 : format("The runtime fraction at high speed for DX multispeed heating coil {} exceeded 1.0. [{:.4R}].",
13895 0 : thisDXCoil.Name,
13896 0 : thisDXCoil.HeatingCoilRuntimeFraction));
13897 0 : ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
13898 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
13899 0 : ShowContinueErrorTimeStamp(state, "");
13900 : }
13901 0 : ShowRecurringWarningErrorAtEnd(state,
13902 0 : thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
13903 0 : thisDXCoil.ErrIndex4,
13904 0 : thisDXCoil.HeatingCoilRuntimeFraction,
13905 0 : thisDXCoil.HeatingCoilRuntimeFraction);
13906 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
13907 28 : } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
13908 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
13909 : }
13910 :
13911 : // Get full load output and power
13912 28 : LSFullLoadOutAirEnth = InletAirEnthalpy + TotCapLSAdj / MSHPMassFlowRateLow;
13913 28 : HSFullLoadOutAirEnth = InletAirEnthalpy + TotCapHSAdj / MSHPMassFlowRateHigh;
13914 28 : LSElecHeatingPower = TotCapLS * EIRLS * InputPowerMultiplier;
13915 28 : HSElecHeatingPower = TotCapHS * EIRHS * InputPowerMultiplier;
13916 28 : OutletAirHumRat = InletAirHumRat;
13917 :
13918 : // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
13919 28 : if (fanOp == HVAC::FanOp::Cycling) {
13920 1 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
13921 : }
13922 :
13923 : // Power calculation
13924 28 : if (!thisDXCoil.PLRImpact) {
13925 28 : thisDXCoil.ElecHeatingPower = SpeedRatio * HSElecHeatingPower + (1.0 - SpeedRatio) * LSElecHeatingPower;
13926 : } else {
13927 0 : thisDXCoil.ElecHeatingPower =
13928 0 : thisDXCoil.HeatingCoilRuntimeFraction * HSElecHeatingPower + (1.0 - thisDXCoil.HeatingCoilRuntimeFraction) * LSElecHeatingPower;
13929 : }
13930 :
13931 28 : thisDXCoil.TotalHeatingEnergyRate = MSHPMassFlowRateHigh * (HSFullLoadOutAirEnth - InletAirEnthalpy) * SpeedRatio +
13932 28 : MSHPMassFlowRateLow * (LSFullLoadOutAirEnth - InletAirEnthalpy) * (1.0 - SpeedRatio);
13933 28 : OutletAirEnthalpy = InletAirEnthalpy + thisDXCoil.TotalHeatingEnergyRate / thisDXCoil.InletAirMassFlowRate;
13934 28 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
13935 28 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, OutdoorPressure, RoutineNameAverageLoad);
13936 28 : if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
13937 0 : OutletAirTemp = PsyTsatFnHPb(state,
13938 : FullLoadOutAirEnth,
13939 : OutdoorPressure,
13940 : RoutineName); // Autodesk:Uninit FullLoadOutAirEnth was possibly uninitialized
13941 0 : OutletAirHumRat = PsyWFnTdbH(
13942 : state, OutletAirTemp, FullLoadOutAirEnth, RoutineName); // Autodesk:Uninit FullLoadOutAirEnth was possibly uninitialized
13943 : }
13944 :
13945 : // Waste heat calculation
13946 28 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13947 1 : if (thisDXCoil.MSWasteHeat(SpeedNumLS) == 0) {
13948 0 : WasteHeatLS = thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13949 : } else {
13950 1 : WasteHeatLS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumLS), OutdoorDryBulb, InletAirDryBulbTemp) *
13951 1 : thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13952 : }
13953 1 : if (thisDXCoil.MSWasteHeat(SpeedNumHS) == 0) {
13954 0 : WasteHeatHS = thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13955 : } else {
13956 1 : WasteHeatHS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumHS), OutdoorDryBulb, InletAirDryBulbTemp) *
13957 1 : thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13958 : }
13959 1 : thisDXCoil.MSFuelWasteHeat = (SpeedRatio * WasteHeatHS + (1.0 - SpeedRatio) * WasteHeatLS) * thisDXCoil.ElecCoolingPower;
13960 1 : if (thisDXCoil.MSHPHeatRecActive) {
13961 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
13962 : }
13963 : }
13964 28 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13965 :
13966 1 : thisDXCoil.FuelUsed = thisDXCoil.ElecHeatingPower;
13967 1 : thisDXCoil.ElecHeatingPower = 0.0;
13968 : }
13969 :
13970 : // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
13971 : // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
13972 28 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
13973 21 : if (!thisDXCoil.PLRImpact) {
13974 21 : thisDXCoil.DefrostPower = DefrostPowerHS * SpeedRatio + DefrostPowerLS * (1.0 - SpeedRatio);
13975 : } else {
13976 0 : thisDXCoil.DefrostPower =
13977 0 : DefrostPowerHS * thisDXCoil.HeatingCoilRuntimeFraction + DefrostPowerLS * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
13978 : }
13979 : }
13980 28 : thisDXCoil.OutletAirTemp = OutletAirTemp;
13981 28 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
13982 28 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
13983 28 : thisDXCoil.CrankcaseHeaterPower = 0.0;
13984 :
13985 : // Stage 1
13986 63 : } else if (CycRatio > 0.0 || (CycRatio > 0.0 && SingleMode == 1)) {
13987 :
13988 : // for cycling fan, reset mass flow to full on rate
13989 63 : if (fanOp == HVAC::FanOp::Cycling) {
13990 32 : AirMassFlow /= CycRatio;
13991 : }
13992 63 : if (fanOp == HVAC::FanOp::Continuous) {
13993 31 : AirMassFlow = MSHPMassFlowRateHigh;
13994 : }
13995 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton)
13996 63 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
13997 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
13998 : // AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
13999 63 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNum);
14000 :
14001 126 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
14002 63 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
14003 5 : if (thisDXCoil.ErrIndex1 == 0) {
14004 2 : ShowWarningMessage(state,
14005 2 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed 1.",
14006 1 : thisDXCoil.DXCoilType,
14007 1 : thisDXCoil.Name));
14008 2 : ShowContinueErrorTimeStamp(state, "");
14009 2 : ShowContinueError(state,
14010 2 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
14011 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
14012 1 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
14013 : VolFlowperRatedTotCap));
14014 2 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
14015 3 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
14016 : }
14017 40 : ShowRecurringWarningErrorAtEnd(
14018 : state,
14019 10 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
14020 : "\" - Air volume flow rate per watt of rated total heating capacity is out of range error continues at speed 1...",
14021 5 : thisDXCoil.ErrIndex1,
14022 : VolFlowperRatedTotCap,
14023 : VolFlowperRatedTotCap);
14024 : }
14025 :
14026 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
14027 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
14028 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
14029 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
14030 63 : if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNum))->numDims == 1) {
14031 32 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNum), OutdoorDryBulb);
14032 : } else {
14033 31 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNum), InletAirDryBulbTemp, OutdoorDryBulb);
14034 : }
14035 :
14036 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
14037 : // AirMassFlowRatio = AirMassFlow/DXCoil(DXCoilNum)%MSRatedAirMassFlowRate(SpeedNumLS)
14038 : // TotCapFlowModFac = CurveValue(state, DXCoil(DXCoilNum)%MSCCapFFlow(SpeedNumLS),AirMassFlowRatio)
14039 63 : TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNum), AirMassFlowRatioLS);
14040 : // Calculate total heating capacity for off-rated conditions
14041 63 : TotCap = thisDXCoil.MSRatedTotCap(SpeedNum) * TotCapFlowModFac * TotCapTempModFac;
14042 :
14043 : // Calculating adjustment factors for defrost
14044 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
14045 63 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
14046 63 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure, RoutineName)));
14047 :
14048 : // Initializing defrost adjustment factors
14049 63 : LoadDueToDefrost = 0.0;
14050 63 : HeatingCapacityMultiplier = 1.0;
14051 63 : FractionalDefrostTime = 0.0;
14052 63 : InputPowerMultiplier = 1.0;
14053 :
14054 : // Check outdoor temperature to determine of defrost is active
14055 63 : if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost) {
14056 : // Calculate defrost adjustment factors depending on defrost control type
14057 36 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
14058 36 : FractionalDefrostTime = thisDXCoil.DefrostTime;
14059 36 : if (FractionalDefrostTime > 0.0) {
14060 36 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
14061 2 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
14062 2 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
14063 : } else {
14064 34 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
14065 34 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
14066 34 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
14067 4 : ShowWarningMessage(
14068 : state,
14069 4 : format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
14070 : "actuator must be both provided for DX heating coil {}",
14071 2 : thisDXCoil.Name));
14072 6 : ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
14073 : }
14074 : }
14075 : }
14076 : } else { // else defrost control is on-demand
14077 0 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
14078 0 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
14079 0 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
14080 0 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
14081 : } else {
14082 0 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
14083 0 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
14084 0 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
14085 0 : ShowWarningMessage(state,
14086 0 : format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
14087 : "actuator must be both provided for DX heating coil {}",
14088 0 : thisDXCoil.Name));
14089 0 : ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
14090 : }
14091 : }
14092 : }
14093 :
14094 36 : if (FractionalDefrostTime > 0.0) {
14095 : // Calculate defrost adjustment factors depending on defrost control strategy
14096 36 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
14097 32 : LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(1) / 1.01667);
14098 32 : DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
14099 32 : thisDXCoil.DefrostPower = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(1) / 1.01667) * FractionalDefrostTime;
14100 : } else { // Defrost strategy is resistive
14101 4 : thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
14102 : }
14103 : } else { // Defrost is not active because (OutDryBulbTemp .GT. DXCoil(DXCoilNum)%MaxOATDefrost)
14104 0 : thisDXCoil.DefrostPower = 0.0;
14105 : }
14106 : }
14107 :
14108 : // Modify total heating capacity based on defrost heating capacity multiplier
14109 63 : TotCapAdj = TotCap * HeatingCapacityMultiplier;
14110 :
14111 : // Calculate full load outlet conditions
14112 63 : FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
14113 63 : FullLoadOutAirHumRat = InletAirHumRat;
14114 63 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
14115 63 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
14116 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
14117 : // FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
14118 63 : if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
14119 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure, RoutineName);
14120 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
14121 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
14122 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
14123 : }
14124 :
14125 : // Set outlet conditions from the full load calculation
14126 63 : OutletAirEnthalpy = FullLoadOutAirEnth;
14127 63 : OutletAirHumRat = FullLoadOutAirHumRat;
14128 63 : OutletAirTemp = FullLoadOutAirTemp;
14129 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
14130 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
14131 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
14132 : // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
14133 63 : if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(1))->numDims == 1) {
14134 32 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(1), OutdoorDryBulb);
14135 : } else {
14136 31 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(1), InletAirDryBulbTemp, OutdoorDryBulb);
14137 : }
14138 63 : EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(1), AirMassFlowRatioLS);
14139 63 : EIR = 1.0 / thisDXCoil.MSRatedCOP(1) * EIRTempModFac * EIRFlowModFac;
14140 : // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
14141 63 : PLRHeating = min(1.0, (CycRatio + LoadDueToDefrost / TotCapAdj));
14142 63 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(1), PLRHeating); // Calculate part-load factor
14143 63 : if (fanOp == HVAC::FanOp::Cycling && CycRatio == 1.0 && PLF != 1.0) {
14144 0 : if (thisDXCoil.PLFErrIndex == 0) {
14145 0 : ShowWarningMessage(state,
14146 0 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio = 1", thisDXCoil.Name, PLF));
14147 0 : ShowContinueError(state, "PLF curve value must be = 1.0 and has been reset to 1.0. Simulation is continuing.");
14148 0 : ShowContinueErrorTimeStamp(state, "");
14149 : }
14150 0 : ShowRecurringWarningErrorAtEnd(
14151 0 : state, thisDXCoil.Name + "\": DX heating coil PLF curve value <> 1.0 warning continues...", thisDXCoil.PLFErrIndex, PLF, PLF);
14152 0 : PLF = 1.0;
14153 : }
14154 :
14155 63 : if (PLF < 0.7) {
14156 0 : if (thisDXCoil.PLRErrIndex == 0) {
14157 0 : ShowWarningMessage(
14158 : state,
14159 0 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
14160 0 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
14161 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
14162 0 : ShowContinueErrorTimeStamp(state, "");
14163 : }
14164 0 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
14165 0 : PLF = 0.7;
14166 : }
14167 :
14168 63 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
14169 63 : if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
14170 0 : if (thisDXCoil.ErrIndex4 == 0) {
14171 0 : ShowWarningMessage(state,
14172 0 : format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
14173 0 : thisDXCoil.Name,
14174 0 : thisDXCoil.HeatingCoilRuntimeFraction));
14175 0 : ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
14176 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
14177 0 : ShowContinueErrorTimeStamp(state, "");
14178 : }
14179 0 : ShowRecurringWarningErrorAtEnd(state,
14180 0 : thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
14181 0 : thisDXCoil.ErrIndex4,
14182 0 : thisDXCoil.HeatingCoilRuntimeFraction,
14183 0 : thisDXCoil.HeatingCoilRuntimeFraction);
14184 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
14185 63 : } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
14186 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
14187 : }
14188 : // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
14189 63 : if (fanOp == HVAC::FanOp::Cycling) {
14190 32 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
14191 : }
14192 63 : thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
14193 :
14194 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
14195 : // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
14196 :
14197 63 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
14198 5 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
14199 : } else {
14200 58 : thisDXCoil.CrankcaseHeaterPower =
14201 58 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
14202 58 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
14203 : }
14204 :
14205 63 : thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (FullLoadOutAirEnth - InletAirEnthalpy) * CycRatio;
14206 63 : if (fanOp == HVAC::FanOp::Continuous) {
14207 31 : OutletAirEnthalpy = InletAirEnthalpy + thisDXCoil.TotalHeatingEnergyRate / thisDXCoil.InletAirMassFlowRate;
14208 31 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
14209 : }
14210 63 : if (thisDXCoil.MSHPHeatRecActive || thisDXCoil.FuelType != Constant::eFuel::Electricity) {
14211 32 : if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
14212 0 : thisDXCoil.MSFuelWasteHeat = thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecHeatingPower;
14213 : } else {
14214 32 : thisDXCoil.MSFuelWasteHeat = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNum), OutdoorDryBulb, InletAirDryBulbTemp) *
14215 32 : thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecHeatingPower;
14216 : }
14217 32 : if (thisDXCoil.MSHPHeatRecActive) {
14218 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
14219 : }
14220 : }
14221 63 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
14222 :
14223 32 : thisDXCoil.FuelUsed = thisDXCoil.ElecHeatingPower;
14224 32 : thisDXCoil.ElecHeatingPower = 0.0;
14225 : }
14226 : // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
14227 : // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
14228 63 : thisDXCoil.DefrostPower *= thisDXCoil.HeatingCoilRuntimeFraction;
14229 :
14230 63 : thisDXCoil.OutletAirTemp = OutletAirTemp;
14231 63 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
14232 63 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
14233 : }
14234 :
14235 : } else {
14236 :
14237 : // DX coil is off; just pass through conditions
14238 120 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
14239 120 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
14240 120 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
14241 :
14242 120 : thisDXCoil.ElecHeatingPower = 0.0;
14243 120 : thisDXCoil.FuelUsed = 0.0;
14244 120 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
14245 120 : thisDXCoil.DefrostPower = 0.0;
14246 :
14247 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
14248 : // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
14249 120 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
14250 10 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
14251 : } else {
14252 110 : thisDXCoil.CrankcaseHeaterPower =
14253 110 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
14254 : }
14255 :
14256 : } // end of on/off if - else
14257 :
14258 211 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
14259 211 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
14260 211 : thisDXCoil.PartLoadRatio = PLRHeating;
14261 211 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
14262 211 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
14263 211 : thisDXCoil.MSSpeedNumLS = SpeedNumLS;
14264 211 : thisDXCoil.MSSpeedNumHS = SpeedNumHS;
14265 211 : thisDXCoil.MSSpeedRatio = SpeedRatio;
14266 211 : thisDXCoil.MSCycRatio = CycRatio;
14267 :
14268 : // set outlet node conditions
14269 211 : int airOutletNode = thisDXCoil.AirOutNode;
14270 211 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
14271 211 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
14272 :
14273 : // calc secondary coil if specified
14274 211 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
14275 0 : CalcSecondaryDXCoils(state, DXCoilNum);
14276 : }
14277 211 : }
14278 :
14279 539062 : void UpdateDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current fan coil unit being simulated
14280 : {
14281 :
14282 : // SUBROUTINE INFORMATION:
14283 : // AUTHOR Fred Buhl
14284 : // DATE WRITTEN May 2000
14285 :
14286 : // PURPOSE OF THIS SUBROUTINE:
14287 : // This subroutine is for passing results to the outlet air node.
14288 :
14289 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14290 : int AirOutletNode; // air outlet node number
14291 : int AirInletNode; // air inlet node number
14292 :
14293 539062 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
14294 :
14295 539062 : AirOutletNode = thisDXCoil.AirOutNode;
14296 539062 : AirInletNode = thisDXCoil.AirInNode;
14297 : // changed outputs
14298 539062 : state.dataLoopNodes->Node(AirOutletNode).Enthalpy = thisDXCoil.OutletAirEnthalpy;
14299 539062 : state.dataLoopNodes->Node(AirOutletNode).Temp = thisDXCoil.OutletAirTemp;
14300 539062 : state.dataLoopNodes->Node(AirOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
14301 539062 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRate = thisDXCoil.InletAirMassFlowRate;
14302 : // pass through outputs
14303 539062 : state.dataLoopNodes->Node(AirOutletNode).Quality = state.dataLoopNodes->Node(AirInletNode).Quality;
14304 539062 : state.dataLoopNodes->Node(AirOutletNode).Press = state.dataLoopNodes->Node(AirInletNode).Press;
14305 539062 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMin = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMin;
14306 539062 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMax = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax;
14307 539062 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMinAvail;
14308 539062 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMaxAvail;
14309 :
14310 539062 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
14311 0 : state.dataLoopNodes->Node(AirOutletNode).CO2 = state.dataLoopNodes->Node(AirInletNode).CO2;
14312 : }
14313 539062 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
14314 0 : state.dataLoopNodes->Node(AirOutletNode).GenContam = state.dataLoopNodes->Node(AirInletNode).GenContam;
14315 : }
14316 539062 : }
14317 :
14318 539064 : void ReportDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current fan coil unit being simulated
14319 : {
14320 :
14321 : // SUBROUTINE INFORMATION:
14322 : // AUTHOR Fred Buhl
14323 : // DATE WRITTEN May 2000
14324 : // MODIFIED Richard Raustad/Don Shirey Oct 2001, Feb 2004
14325 : // Feb 2005 M. J. Witte, GARD Analytics, Inc.
14326 : // Always update evap value to support new coil type COIL:DX:MultiMode:CoolingEmpirical:
14327 : // Lixing Gu. Jan. 5, 2007, pass information to the AirflowNetwork model
14328 :
14329 : // PURPOSE OF THIS SUBROUTINE:
14330 : // Fills some of the report variables for the DX coils
14331 :
14332 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14333 :
14334 539064 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
14335 :
14336 539064 : if (thisDXCoil.reportCoilFinalSizes) {
14337 192897 : if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->DoingSizing) {
14338 104 : Real64 ratedSensCap(0.0);
14339 104 : ratedSensCap = thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1);
14340 104 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
14341 104 : state, thisDXCoil.Name, thisDXCoil.DXCoilType, thisDXCoil.RatedTotCap(1), ratedSensCap, thisDXCoil.RatedAirVolFlowRate(1), -999.0);
14342 104 : thisDXCoil.reportCoilFinalSizes = false;
14343 : }
14344 : }
14345 :
14346 539064 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
14347 :
14348 539064 : switch (thisDXCoil.DXCoilType_Num) {
14349 201111 : case HVAC::CoilDX_HeatingEmpirical:
14350 : case HVAC::CoilVRF_Heating:
14351 : case HVAC::CoilVRF_FluidTCtrl_Heating: {
14352 201111 : thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
14353 201111 : thisDXCoil.ElecHeatingConsumption = thisDXCoil.ElecHeatingPower * ReportingConstant;
14354 201111 : thisDXCoil.DefrostConsumption = thisDXCoil.DefrostPower * ReportingConstant;
14355 201111 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14356 201111 : state.dataHVACGlobal->DXElecHeatingPower = thisDXCoil.ElecHeatingPower + thisDXCoil.CrankcaseHeaterPower;
14357 201111 : state.dataHVACGlobal->DefrostElecPower = thisDXCoil.DefrostPower;
14358 201111 : } break;
14359 199 : case HVAC::CoilDX_MultiSpeedHeating: {
14360 199 : thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
14361 199 : if (thisDXCoil.FuelType == Constant::eFuel::Electricity) {
14362 116 : thisDXCoil.ElecHeatingConsumption = thisDXCoil.ElecHeatingPower * ReportingConstant;
14363 : } else {
14364 83 : thisDXCoil.FuelConsumed = thisDXCoil.FuelUsed * ReportingConstant;
14365 : }
14366 199 : thisDXCoil.DefrostConsumption = thisDXCoil.DefrostPower * ReportingConstant;
14367 199 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14368 199 : state.dataHVACGlobal->DXElecHeatingPower = thisDXCoil.ElecHeatingPower + thisDXCoil.CrankcaseHeaterPower;
14369 199 : state.dataHVACGlobal->DefrostElecPower = thisDXCoil.DefrostPower;
14370 199 : } break;
14371 251 : case HVAC::CoilDX_MultiSpeedCooling: {
14372 251 : thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
14373 251 : thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
14374 251 : thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
14375 251 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14376 251 : state.dataHVACGlobal->DXElecCoolingPower = thisDXCoil.ElecCoolingPower;
14377 251 : thisDXCoil.EvapCondPumpElecConsumption = thisDXCoil.EvapCondPumpElecPower * ReportingConstant;
14378 251 : thisDXCoil.EvapWaterConsump = thisDXCoil.EvapWaterConsumpRate * ReportingConstant;
14379 251 : if (thisDXCoil.FuelType == Constant::eFuel::Electricity) {
14380 179 : thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
14381 : } else {
14382 72 : thisDXCoil.FuelConsumed = thisDXCoil.FuelUsed * ReportingConstant;
14383 : }
14384 251 : if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
14385 0 : thisDXCoil.BasinHeaterConsumption = thisDXCoil.BasinHeaterPower * ReportingConstant;
14386 : }
14387 251 : } break;
14388 161 : case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
14389 : case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
14390 : // water heating energy for HP water heater DX Coil condenser
14391 161 : thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
14392 : // water heating power for HP water heater
14393 161 : thisDXCoil.ElecWaterHeatingConsumption = thisDXCoil.ElecWaterHeatingPower * ReportingConstant;
14394 : // other usual DX cooling coil outputs
14395 161 : thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
14396 161 : thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
14397 161 : thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
14398 161 : thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
14399 161 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14400 : // DXElecCoolingPower global is only used for air-to-air cooling and heating coils
14401 161 : state.dataHVACGlobal->DXElecCoolingPower = 0.0;
14402 161 : } break;
14403 337342 : default: {
14404 337342 : thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
14405 337342 : thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
14406 337342 : thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
14407 337342 : thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
14408 337342 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14409 337342 : state.dataHVACGlobal->DXElecCoolingPower = thisDXCoil.ElecCoolingPower;
14410 337342 : thisDXCoil.EvapCondPumpElecConsumption = thisDXCoil.EvapCondPumpElecPower * ReportingConstant;
14411 337342 : thisDXCoil.EvapWaterConsump = thisDXCoil.EvapWaterConsumpRate * ReportingConstant;
14412 337342 : if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
14413 33575 : thisDXCoil.BasinHeaterConsumption = thisDXCoil.BasinHeaterPower * ReportingConstant;
14414 : }
14415 337342 : } break;
14416 : }
14417 :
14418 539064 : if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
14419 : // calculate and report condensation rates (how much water extracted from the air stream)
14420 : // water flow of water in m3/s for water system interactions
14421 : // put here to catch all types of DX coils
14422 2 : Real64 Tavg = (thisDXCoil.InletAirTemp + thisDXCoil.OutletAirTemp) / 2.0;
14423 : // CR9155 Remove specific humidity calculations
14424 : // mdot * del HumRat / rho water
14425 2 : thisDXCoil.CondensateVdot =
14426 2 : max(0.0, (thisDXCoil.InletAirMassFlowRate * (thisDXCoil.InletAirHumRat - thisDXCoil.OutletAirHumRat) / Psychrometrics::RhoH2O(Tavg)));
14427 2 : thisDXCoil.CondensateVol = thisDXCoil.CondensateVdot * ReportingConstant;
14428 :
14429 2 : state.dataWaterData->WaterStorage(thisDXCoil.CondensateTankID).VdotAvailSupply(thisDXCoil.CondensateTankSupplyARRID) =
14430 2 : thisDXCoil.CondensateVdot;
14431 2 : state.dataWaterData->WaterStorage(thisDXCoil.CondensateTankID).TwaterSupply(thisDXCoil.CondensateTankSupplyARRID) = thisDXCoil.OutletAirTemp;
14432 : }
14433 :
14434 539064 : state.dataAirLoop->LoopDXCoilRTF = max(thisDXCoil.CoolingCoilRuntimeFraction, thisDXCoil.HeatingCoilRuntimeFraction);
14435 539064 : if (thisDXCoil.AirLoopNum > 0) {
14436 223282 : state.dataAirLoop->AirLoopAFNInfo(thisDXCoil.AirLoopNum).AFNLoopDXCoilRTF =
14437 223282 : max(thisDXCoil.CoolingCoilRuntimeFraction, thisDXCoil.HeatingCoilRuntimeFraction);
14438 : }
14439 539064 : }
14440 :
14441 6 : void CalcTwoSpeedDXCoilStandardRating(EnergyPlusData &state, int const DXCoilNum)
14442 : {
14443 : // SUBROUTINE INFORMATION:
14444 : // AUTHOR B. Griffith, (Derived from CalcDXCoilStandardRating by Bereket Nigusse & Chandan Sharma)
14445 : // DATE WRITTEN July 2012
14446 :
14447 : // PURPOSE OF THIS SUBROUTINE:
14448 : // Calculate the following
14449 : // (1) Standard Rated (net) Cooling Capacity
14450 : // (2) Energy Efficiency Ratio (EER),
14451 : // (3) Integrated Energy Efficiency Ratio (IEER)
14452 :
14453 : // REFERENCES:
14454 : // ANSI/AHRI Standard 340/360-2007, Performance Rating of Commercial and Industrial Unitary Air-Conditioning and
14455 : // Heat Pump Equipment, Air-Conditioning, Heating, and Refrigeration Institute, Arlington VA.
14456 :
14457 : // Using/Aliasing
14458 : using Curve::CurveValue;
14459 : using namespace OutputReportPredefined;
14460 :
14461 : // SUBROUTINE PARAMETER DEFINITIONS:
14462 : // AHRI Standard 340/360-2007 Performance Rating of Commercial and Industrial Unitary Air-Conditioning and Heat Pump Equipment
14463 6 : Real64 constexpr CoolingCoilInletAirWetBulbTempRated(19.4); // 19.44C (67F)
14464 6 : Real64 constexpr CoolingCoilInletAirDryBulbTempRated(26.7);
14465 6 : Real64 constexpr OutdoorUnitInletAirDryBulbTempRated(35.0); // 35.00C (95F)
14466 6 : static Array1D<Real64> const OutdoorUnitInletAirDryBulbTempPLTestPoint(3, {27.5, 20.0, 18.3});
14467 6 : static Array1D<Real64> const NetCapacityFactorPLTestPoint(3, {0.75, 0.50, 0.25});
14468 6 : Real64 constexpr ConvFromSIToIP(3.412141633); // Conversion from SI to IP [3.412 Btu/hr-W]
14469 :
14470 6 : Real64 constexpr AirMassFlowRatioRated(1.0); // AHRI test is at the design flow rate
14471 : // and hence AirMassFlowRatio is 1.0
14472 :
14473 6 : Real64 constexpr DefaultFanPowerPerEvapAirFlowRate(773.3); // 365 W/1000 scfm or 773.3 W/(m3/s). The AHRI standard
14474 6 : Real64 constexpr DefaultFanPowerPerEvapAirFlowRateSEER2(934.4); // 441 W/1000 scfm or 934.4 W/(m3/s). The AHRI standard
14475 : // specifies a nominal/default fan electric power consumption per rated air
14476 : // volume flow rate to account for indoor fan electric power consumption
14477 : // when the standard tests are conducted on units that do not have an
14478 : // indoor air circulating fan. Used if user doesn't enter a specific value.
14479 :
14480 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14481 : static constexpr std::string_view RoutineName("CalcTwoSpeedDXCoilStandardRating");
14482 :
14483 6 : auto &NetCoolingCapRated = state.dataDXCoils->NetCoolingCapRated;
14484 6 : auto &EER = state.dataDXCoils->EER;
14485 6 : auto &IEER = state.dataDXCoils->IEER;
14486 6 : auto &TotCapTempModFac = state.dataDXCoils->TotCapTempModFac;
14487 6 : auto &TotCapFlowModFac = state.dataDXCoils->TotCapFlowModFac;
14488 6 : auto &EIRTempModFac = state.dataDXCoils->EIRTempModFac;
14489 6 : auto &EIRFlowModFac = state.dataDXCoils->EIRFlowModFac;
14490 6 : auto &TempDryBulb_Leaving_Apoint = state.dataDXCoils->TempDryBulb_Leaving_Apoint;
14491 :
14492 6 : constexpr Real64 AccuracyTolerance(0.2); // tolerance in AHRI 340/360 Table 6 note 1
14493 6 : constexpr int MaximumIterations(1000);
14494 : Real64 EIR;
14495 : Real64 TotalElecPowerRated;
14496 6 : Array1D<Real64> EER_TestPoint_SI(4); // 1 = A, 2 = B, 3= C, 4= D
14497 6 : Array1D<Real64> EER_TestPoint_IP(4); // 1 = A, 2 = B, 3= C, 4= D
14498 6 : Array1D<Real64> NetCapacity_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
14499 6 : Array1D<Real64> NetPower_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
14500 6 : Array1D<Real64> SupAirMdot_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
14501 :
14502 : Real64 HighSpeedNetCoolingCap;
14503 : Real64 LowSpeedNetCoolingCap;
14504 :
14505 : Real64 PartLoadAirMassFlowRate;
14506 : Real64 AirMassFlowRatio;
14507 : int SolverFlag;
14508 : Real64 EIR_HighSpeed;
14509 : Real64 EIR_LowSpeed;
14510 : int FanInletNode;
14511 : int FanOutletNode;
14512 : int Iter;
14513 : Real64 ExternalStatic;
14514 : Real64 FanStaticPressureRise;
14515 : Real64 FanHeatCorrection;
14516 : Real64 FanPowerCorrection;
14517 6 : Real64 FanPowerPerEvapAirFlowRate = 0.0;
14518 : Real64 FanPowerPerEvapAirFlowRateSEER2;
14519 : Real64 SpeedRatio;
14520 : Real64 CycRatio;
14521 : Real64 TargetNetCapacity;
14522 : Real64 SupplyAirHumRat;
14523 : Real64 SupplyAirRho;
14524 : Real64 SupplyAirVolFlowRate;
14525 : Real64 HighSpeedTotCoolingCap;
14526 : Real64 LowSpeedTotCoolingCap;
14527 : Real64 TotCoolingCap;
14528 : Real64 NetCoolingCap;
14529 : Real64 PLF;
14530 : Real64 RunTimeFraction;
14531 : Real64 LowerBoundMassFlowRate;
14532 : int PartLoadTestPoint;
14533 : int countStaticInputs;
14534 : int index;
14535 :
14536 : // Formats
14537 : static constexpr std::string_view Header(
14538 : "! <VAV DX Cooling Coil Standard Rating Information>, DX Coil Type, DX Coil Name, Fan Type, Fan Name, Standard Net Cooling Capacity "
14539 : "{{W}}, Standard Net Cooling Capacity {{Btu/h}}, IEER {{Btu/W-h}}, COP 100% Capacity {{W/W}}, COP 75% Capacity {{W/W}}, COP 50% Capacity "
14540 : "{{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% "
14541 : "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% "
14542 : "{{kg/s}}\n");
14543 :
14544 : static constexpr std::string_view Format_891{
14545 : " VAV DX Cooling Coil Standard Rating Information, "
14546 : "{},{},{},{},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.4R},{:.4R},{:.4R},{:.4R},\n"};
14547 :
14548 6 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
14549 :
14550 : // Get fan index and name if not already available
14551 6 : if (thisDXCoil.SupplyFanIndex == 0) {
14552 2 : GetFanIndexForTwoSpeedCoil(state, DXCoilNum, thisDXCoil.SupplyFanIndex, thisDXCoil.SupplyFanName, thisDXCoil.supplyFanType);
14553 : }
14554 6 : if (thisDXCoil.SupplyFanIndex == 0) { // didn't find VAV fan, do not rate this coil
14555 0 : thisDXCoil.RateWithInternalStaticAndFanObject = false;
14556 0 : ShowWarningError(state,
14557 0 : format("CalcTwoSpeedDXCoilStandardRating: Did not find an appropriate fan associated with DX coil named = \"{}\". Standard "
14558 : "Ratings will not be calculated.",
14559 0 : thisDXCoil.Name));
14560 0 : return;
14561 : }
14562 6 : bool saveTurnFansOn = state.dataHVACGlobal->TurnFansOn;
14563 6 : bool saveTurnFansOff = state.dataHVACGlobal->TurnFansOff;
14564 6 : state.dataHVACGlobal->TurnFansOn = true; // enable fans, will override fan availability schedule if needed
14565 6 : state.dataHVACGlobal->TurnFansOff = false;
14566 :
14567 : // Calculate the Indoor fan electric power consumption. The electric power consumption is estimated
14568 : // using either user supplied or AHRI default value for fan power per air volume flow rate
14569 6 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14570 :
14571 3 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatioRated);
14572 3 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
14573 15 : for (Iter = 1; Iter <= 4; ++Iter) { // iterative solution in the event that net capacity is near a threshold for external static
14574 : // Obtain external static pressure from Table 5 in ANSI/AHRI Std. 340/360-2007
14575 12 : if (NetCoolingCapRated <= 21000.0) {
14576 12 : ExternalStatic = 50.0;
14577 0 : } else if (21000.0 < NetCoolingCapRated && NetCoolingCapRated <= 30800.0) {
14578 0 : ExternalStatic = 60.0;
14579 0 : } else if (30800.0 < NetCoolingCapRated && NetCoolingCapRated <= 39300.0) {
14580 0 : ExternalStatic = 70.0;
14581 0 : } else if (39300.0 < NetCoolingCapRated && NetCoolingCapRated <= 61500.0) {
14582 0 : ExternalStatic = 90.0;
14583 0 : } else if (61500.0 < NetCoolingCapRated && NetCoolingCapRated <= 82100.0) {
14584 0 : ExternalStatic = 100.0;
14585 0 : } else if (82100.0 < NetCoolingCapRated && NetCoolingCapRated <= 103000.0) {
14586 0 : ExternalStatic = 110.0;
14587 0 : } else if (103000.0 < NetCoolingCapRated && NetCoolingCapRated <= 117000.0) {
14588 0 : ExternalStatic = 140.0;
14589 0 : } else if (117000.0 < NetCoolingCapRated && NetCoolingCapRated <= 147000.0) {
14590 0 : ExternalStatic = 160.0;
14591 0 : } else if (147000.0 < NetCoolingCapRated) {
14592 0 : ExternalStatic = 190.0;
14593 : }
14594 12 : FanStaticPressureRise = ExternalStatic + thisDXCoil.InternalStaticPressureDrop;
14595 12 : FanInletNode = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->inletNodeNum;
14596 12 : FanOutletNode = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->outletNodeNum;
14597 :
14598 : // set node state variables in preparation for fan model.
14599 12 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
14600 12 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
14601 12 : state.dataLoopNodes->Node(FanInletNode).Temp = CoolingCoilInletAirDryBulbTempRated;
14602 12 : state.dataLoopNodes->Node(FanInletNode).HumRat = PsyWFnTdbTwbPb(
14603 12 : state, CoolingCoilInletAirDryBulbTempRated, CoolingCoilInletAirWetBulbTempRated, state.dataEnvrn->OutBaroPress, RoutineName);
14604 12 : state.dataLoopNodes->Node(FanInletNode).Enthalpy =
14605 12 : PsyHFnTdbW(CoolingCoilInletAirDryBulbTempRated, state.dataLoopNodes->Node(FanInletNode).HumRat);
14606 12 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
14607 12 : FanPowerCorrection = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->totalPower;
14608 :
14609 12 : FanHeatCorrection = state.dataLoopNodes->Node(FanInletNode).MassFlowRate *
14610 12 : (state.dataLoopNodes->Node(FanOutletNode).Enthalpy - state.dataLoopNodes->Node(FanInletNode).Enthalpy);
14611 :
14612 12 : NetCoolingCapRated = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14613 : }
14614 :
14615 : } else {
14616 3 : FanPowerPerEvapAirFlowRate = DefaultFanPowerPerEvapAirFlowRate;
14617 3 : FanPowerPerEvapAirFlowRateSEER2 = DefaultFanPowerPerEvapAirFlowRateSEER2;
14618 3 : FanPowerCorrection = DefaultFanPowerPerEvapAirFlowRate * thisDXCoil.RatedAirVolFlowRate(1);
14619 3 : FanHeatCorrection = DefaultFanPowerPerEvapAirFlowRate * thisDXCoil.RatedAirVolFlowRate(1);
14620 3 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatioRated);
14621 3 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
14622 3 : NetCoolingCapRated = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14623 : }
14624 :
14625 6 : SupAirMdot_TestPoint(1) = thisDXCoil.RatedAirMassFlowRate(1);
14626 :
14627 : // Calculate Energy Efficiency Ratio (EER) at (19.44C WB and 35.0C DB ), ANSI/AHRI Std. 340/360
14628 6 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
14629 6 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatioRated);
14630 6 : if (thisDXCoil.RatedCOP(1) > 0.0) {
14631 : // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
14632 6 : EIR = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP(1);
14633 : } else {
14634 0 : EIR = 0.0;
14635 : }
14636 6 : TotalElecPowerRated = EIR * (thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac) + FanPowerCorrection;
14637 :
14638 6 : if (TotalElecPowerRated > 0.0) {
14639 6 : EER = NetCoolingCapRated / TotalElecPowerRated;
14640 : } else {
14641 0 : EER = 0.0;
14642 : }
14643 :
14644 : // IEER - A point 100 % net capacity
14645 6 : EER_TestPoint_SI(1) = EER;
14646 6 : EER_TestPoint_IP(1) = EER * ConvFromSIToIP;
14647 :
14648 : // find coil leaving drybulb at point A, with full rated air flow rate.
14649 : // init coil
14650 6 : thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
14651 6 : thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(1);
14652 6 : thisDXCoil.InletAirTemp = 26.7;
14653 6 : thisDXCoil.InletAirHumRat = PsyWFnTdbTwbPb(state, 26.7, 19.4, state.dataEnvrn->OutBaroPress, RoutineName);
14654 6 : thisDXCoil.InletAirEnthalpy = PsyHFnTdbW(26.7, thisDXCoil.InletAirHumRat);
14655 :
14656 6 : Real64 const heldOutDryBulb = state.dataEnvrn->OutDryBulbTemp;
14657 6 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
14658 0 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = OutdoorUnitInletAirDryBulbTempRated;
14659 : } else {
14660 6 : state.dataEnvrn->OutDryBulbTemp = OutdoorUnitInletAirDryBulbTempRated;
14661 : }
14662 6 : SpeedRatio = 1.0;
14663 6 : CycRatio = 1.0;
14664 6 : CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio, true);
14665 6 : TempDryBulb_Leaving_Apoint = state.dataDXCoils->DXCoilOutletTemp(DXCoilNum); // store result
14666 :
14667 : // IEER - part load test points ***************************************************
14668 24 : for (PartLoadTestPoint = 1; PartLoadTestPoint <= 3; ++PartLoadTestPoint) {
14669 : // determine minimum unloading capacity fraction at point B conditions.
14670 18 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
14671 0 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
14672 : } else {
14673 18 : state.dataEnvrn->OutDryBulbTemp = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
14674 : }
14675 :
14676 18 : TargetNetCapacity = NetCapacityFactorPLTestPoint(PartLoadTestPoint) * NetCoolingCapRated;
14677 :
14678 : // set up parameters for the solver here
14679 18 : Real64 const par3 = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
14680 18 : Real64 par7 = FanPowerPerEvapAirFlowRate;
14681 18 : int fanInNode = 0;
14682 18 : int fanOutNode = 0;
14683 18 : Real64 externalStatic = 0.0;
14684 18 : int fanIndex = 0;
14685 18 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14686 9 : par7 = 0.0;
14687 9 : fanInNode = FanInletNode;
14688 9 : fanOutNode = FanOutletNode;
14689 9 : externalStatic = ExternalStatic;
14690 9 : fanIndex = thisDXCoil.SupplyFanIndex;
14691 : }
14692 :
14693 18 : LowerBoundMassFlowRate = 0.01 * thisDXCoil.RatedAirMassFlowRate(1);
14694 :
14695 : // OK, so there are two variables here which are const at compile time. The question is whether compile time data needs to be
14696 : // explicitly captured in the lambda capture block.
14697 : // For GCC it currently doesn't mind whether they are captured or not, no warnings.
14698 : // On Clang, if you list them, there is a compiler warning.
14699 : // 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.
14700 : // 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
14701 : // really simple, I'm just going to use two local variables and capture them instead of the original data.
14702 : // 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.
14703 18 : Real64 dbRated = CoolingCoilInletAirDryBulbTempRated;
14704 18 : Real64 wbRated = CoolingCoilInletAirWetBulbTempRated;
14705 : auto f = // (AUTO_OK_LAMBDA)
14706 3318 : [&state, DXCoilNum, TempDryBulb_Leaving_Apoint, TargetNetCapacity, par3, par7, fanInNode, fanOutNode, externalStatic, dbRated, wbRated](
14707 : Real64 SupplyAirMassFlowRate) {
14708 : static constexpr std::string_view RoutineName("CalcTwoSpeedDXCoilIEERResidual");
14709 3300 : auto &coil = state.dataDXCoils->DXCoil(DXCoilNum);
14710 3300 : Real64 AirMassFlowRatio = 0.0;
14711 3300 : if (coil.RatedAirMassFlowRate(1) > 0.0) {
14712 3300 : AirMassFlowRatio = SupplyAirMassFlowRate / coil.RatedAirMassFlowRate(1);
14713 : }
14714 3300 : Real64 SupplyAirHumRat = PsyWFnTdbTwbPb(state, dbRated, wbRated, state.dataEnvrn->OutBaroPress, RoutineName);
14715 3300 : Real64 SupplyAirRho = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, dbRated, SupplyAirHumRat, RoutineName);
14716 3300 : Real64 SupplyAirVolFlowRate = SupplyAirMassFlowRate / SupplyAirRho;
14717 :
14718 : Real64 FanHeatCorrection;
14719 3300 : if (coil.RateWithInternalStaticAndFanObject) {
14720 : // modify external static per AHRI 340/360, Table 6, note 1.
14721 1539 : Real64 FanStaticPressureRise = coil.InternalStaticPressureDrop + (externalStatic * pow_2(AirMassFlowRatio));
14722 1539 : auto &inletNode = state.dataLoopNodes->Node(fanInNode);
14723 1539 : auto &outletNode = state.dataLoopNodes->Node(fanOutNode);
14724 1539 : inletNode.MassFlowRate = SupplyAirMassFlowRate;
14725 1539 : outletNode.MassFlowRate = SupplyAirMassFlowRate;
14726 1539 : inletNode.Temp = dbRated;
14727 1539 : inletNode.HumRat = PsyWFnTdbTwbPb(state, dbRated, wbRated, state.dataEnvrn->OutBaroPress, RoutineName);
14728 1539 : inletNode.Enthalpy = PsyHFnTdbW(dbRated, inletNode.HumRat);
14729 1539 : state.dataFans->fans(coil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
14730 1539 : FanHeatCorrection = SupplyAirMassFlowRate * (outletNode.Enthalpy - inletNode.Enthalpy);
14731 : } else {
14732 1761 : FanHeatCorrection = par7 * SupplyAirVolFlowRate;
14733 : }
14734 :
14735 3300 : Real64 TotCapFlowModFac = Curve::CurveValue(state, coil.CCapFFlow(1), AirMassFlowRatio);
14736 3300 : Real64 TotCapTempModFac = Curve::CurveValue(state, coil.CCapFTemp(1), wbRated, par3);
14737 3300 : Real64 HighSpeedNetCoolingCap = coil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14738 :
14739 : // TotCapFlowModFac = CurveManager::CurveValue(state, coil.CCapFFlow(1), AirMassFlowRatio);
14740 3300 : TotCapTempModFac = Curve::CurveValue(state, coil.CCapFTemp2, wbRated, par3);
14741 3300 : Real64 LowSpeedNetCoolingCap = coil.RatedTotCap2 * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14742 :
14743 : Real64 SpeedRatio;
14744 : Real64 CycRatio;
14745 3300 : if (LowSpeedNetCoolingCap <= TargetNetCapacity) {
14746 1899 : CycRatio = 1.0;
14747 1899 : SpeedRatio = (TargetNetCapacity - LowSpeedNetCoolingCap) / (HighSpeedNetCoolingCap - LowSpeedNetCoolingCap);
14748 : } else { // minimum unloading limit exceeded for no cycling
14749 1401 : SpeedRatio = 0.0;
14750 1401 : CycRatio = TargetNetCapacity / LowSpeedNetCoolingCap;
14751 : }
14752 :
14753 3300 : coil.InletAirMassFlowRate = SupplyAirMassFlowRate;
14754 3300 : CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio, true);
14755 3300 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(DXCoilNum);
14756 3300 : return TempDryBulb_Leaving_Apoint - OutletAirTemp;
14757 18 : };
14758 18 : General::SolveRoot(state,
14759 : AccuracyTolerance,
14760 : MaximumIterations,
14761 : SolverFlag,
14762 : PartLoadAirMassFlowRate,
14763 : f,
14764 : LowerBoundMassFlowRate,
14765 18 : thisDXCoil.RatedAirMassFlowRate(1));
14766 :
14767 18 : if (SolverFlag == -1) {
14768 :
14769 0 : ShowWarningError(state, "CalcTwoSpeedDXCoilStandardRating: air flow rate solver failed. Iteration limit exceeded ");
14770 :
14771 0 : SupAirMdot_TestPoint(1 + PartLoadTestPoint) = -999.0;
14772 0 : EER_TestPoint_SI(1 + PartLoadTestPoint) = -999.0;
14773 0 : EER_TestPoint_IP(1 + PartLoadTestPoint) = -999.0;
14774 0 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = -999.0;
14775 0 : NetPower_TestPoint(1 + PartLoadTestPoint) = -999.0;
14776 :
14777 18 : } else if (SolverFlag == -2) {
14778 0 : ShowWarningError(state, "CalcTwoSpeedDXCoilStandardRating: air flow rate solver failed. root not bounded ");
14779 :
14780 0 : SupAirMdot_TestPoint(1 + PartLoadTestPoint) = -999.0;
14781 0 : EER_TestPoint_SI(1 + PartLoadTestPoint) = -999.0;
14782 0 : EER_TestPoint_IP(1 + PartLoadTestPoint) = -999.0;
14783 0 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = -999.0;
14784 0 : NetPower_TestPoint(1 + PartLoadTestPoint) = -999.0;
14785 : } else {
14786 : // now we have the supply air flow rate
14787 18 : SupAirMdot_TestPoint(1 + PartLoadTestPoint) = PartLoadAirMassFlowRate;
14788 18 : AirMassFlowRatio = PartLoadAirMassFlowRate / thisDXCoil.RatedAirMassFlowRate(1);
14789 18 : SupplyAirHumRat = PsyWFnTdbTwbPb(
14790 18 : state, CoolingCoilInletAirDryBulbTempRated, CoolingCoilInletAirWetBulbTempRated, state.dataEnvrn->OutBaroPress, RoutineName);
14791 18 : SupplyAirRho = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, CoolingCoilInletAirDryBulbTempRated, SupplyAirHumRat, RoutineName);
14792 18 : SupplyAirVolFlowRate = PartLoadAirMassFlowRate / SupplyAirRho;
14793 :
14794 18 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14795 9 : FanStaticPressureRise = thisDXCoil.InternalStaticPressureDrop + (ExternalStatic * pow_2(AirMassFlowRatio));
14796 9 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = PartLoadAirMassFlowRate;
14797 9 : state.dataLoopNodes->Node(FanInletNode).Temp = CoolingCoilInletAirDryBulbTempRated;
14798 9 : state.dataLoopNodes->Node(FanInletNode).HumRat = SupplyAirHumRat;
14799 9 : state.dataLoopNodes->Node(FanInletNode).Enthalpy = PsyHFnTdbW(CoolingCoilInletAirDryBulbTempRated, SupplyAirHumRat);
14800 :
14801 9 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
14802 9 : FanPowerCorrection = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->totalPower;
14803 :
14804 9 : FanHeatCorrection =
14805 9 : PartLoadAirMassFlowRate * (state.dataLoopNodes->Node(FanOutletNode).Enthalpy - state.dataLoopNodes->Node(FanInletNode).Enthalpy);
14806 :
14807 : } else {
14808 9 : FanPowerCorrection = FanPowerPerEvapAirFlowRate * PartLoadAirMassFlowRate;
14809 9 : FanHeatCorrection = FanPowerPerEvapAirFlowRate * PartLoadAirMassFlowRate;
14810 : }
14811 :
14812 18 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatio);
14813 : // Warn user if curve output goes negative
14814 18 : if (TotCapFlowModFac < 0.0) {
14815 0 : if (thisDXCoil.CCapFFlowErrorIndex == 0) {
14816 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
14817 0 : ShowContinueError(
14818 : state,
14819 0 : format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).", TotCapFlowModFac));
14820 0 : ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
14821 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
14822 : }
14823 0 : ShowRecurringWarningErrorAtEnd(
14824 : state,
14825 0 : format("{}{}\"{}\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
14826 : RoutineName,
14827 0 : thisDXCoil.DXCoilType,
14828 0 : thisDXCoil.Name),
14829 0 : thisDXCoil.CCapFFlowErrorIndex,
14830 : TotCapFlowModFac,
14831 : TotCapFlowModFac);
14832 0 : TotCapFlowModFac = 0.0;
14833 : }
14834 :
14835 54 : TotCapTempModFac = CurveValue(
14836 18 : state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14837 : // Warn user if curve output goes negative
14838 18 : if (TotCapTempModFac < 0.0) {
14839 0 : if (thisDXCoil.CCapFTempErrorIndex == 0) {
14840 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
14841 0 : ShowContinueError(
14842 : state,
14843 0 : format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
14844 0 : ShowContinueError(state,
14845 0 : format(" Negative value occurs using a coil inlet wet-bulb temperature of {:.1T} and an outdoor unit inlet air "
14846 : "dry-bulb temperature of {:.1T}.",
14847 : CoolingCoilInletAirWetBulbTempRated,
14848 : OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint)));
14849 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
14850 : }
14851 0 : ShowRecurringWarningErrorAtEnd(
14852 : state,
14853 0 : format("{}{} \"{}\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
14854 : RoutineName,
14855 0 : thisDXCoil.DXCoilType,
14856 0 : thisDXCoil.Name),
14857 0 : thisDXCoil.CCapFTempErrorIndex,
14858 : TotCapTempModFac,
14859 : TotCapTempModFac);
14860 0 : TotCapTempModFac = 0.0;
14861 : }
14862 :
14863 18 : HighSpeedTotCoolingCap = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac;
14864 18 : HighSpeedNetCoolingCap = HighSpeedTotCoolingCap - FanHeatCorrection;
14865 :
14866 54 : EIRTempModFac = CurveValue(
14867 18 : state, thisDXCoil.EIRFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14868 18 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatio);
14869 18 : if (thisDXCoil.RatedCOP(1) > 0.0) {
14870 : // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
14871 18 : EIR_HighSpeed = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP(1);
14872 : } else {
14873 0 : EIR = 0.0;
14874 : }
14875 :
14876 : // TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatio);
14877 36 : TotCapTempModFac = CurveValue(
14878 18 : state, thisDXCoil.CCapFTemp2, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14879 : // Warn user if curve output goes negative
14880 18 : if (TotCapTempModFac < 0.0) {
14881 0 : if (thisDXCoil.CCapFTempErrorIndex == 0) {
14882 0 : ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
14883 0 : ShowContinueError(
14884 : state,
14885 0 : format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
14886 0 : ShowContinueError(state,
14887 0 : format(" Negative value occurs using a coil inlet wet-bulb temperature of {:.1T} and an outdoor unit inlet air "
14888 : "dry-bulb temperature of {:.1T}.",
14889 : CoolingCoilInletAirWetBulbTempRated,
14890 : OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint)));
14891 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
14892 : }
14893 0 : ShowRecurringWarningErrorAtEnd(
14894 : state,
14895 0 : format("{}{} \"{}\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
14896 : RoutineName,
14897 0 : thisDXCoil.DXCoilType,
14898 0 : thisDXCoil.Name),
14899 0 : thisDXCoil.CCapFTempErrorIndex,
14900 : TotCapTempModFac,
14901 : TotCapTempModFac);
14902 0 : TotCapTempModFac = 0.0;
14903 : }
14904 :
14905 18 : LowSpeedTotCoolingCap = thisDXCoil.RatedTotCap2 * TotCapTempModFac * TotCapFlowModFac;
14906 18 : LowSpeedNetCoolingCap = LowSpeedTotCoolingCap - FanHeatCorrection;
14907 :
14908 36 : EIRTempModFac = CurveValue(
14909 18 : state, thisDXCoil.EIRFTemp2, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14910 18 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatio);
14911 18 : if (thisDXCoil.RatedCOP2 > 0.0) {
14912 : // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
14913 18 : EIR_LowSpeed = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP2;
14914 : } else {
14915 0 : EIR_LowSpeed = 0.0;
14916 : }
14917 :
14918 18 : if (LowSpeedNetCoolingCap <= TargetNetCapacity) {
14919 12 : CycRatio = 1.0;
14920 12 : SpeedRatio = (TargetNetCapacity - LowSpeedNetCoolingCap) / (HighSpeedNetCoolingCap - LowSpeedNetCoolingCap);
14921 12 : TotCoolingCap = HighSpeedTotCoolingCap * SpeedRatio + LowSpeedTotCoolingCap * (1.0 - SpeedRatio);
14922 12 : NetCoolingCap = TotCoolingCap - FanHeatCorrection;
14923 12 : EIR = EIR_HighSpeed * SpeedRatio + EIR_LowSpeed * (1.0 - SpeedRatio);
14924 12 : TotalElecPowerRated = TotCoolingCap * EIR + FanPowerCorrection;
14925 12 : EER_TestPoint_SI(1 + PartLoadTestPoint) = NetCoolingCap / TotalElecPowerRated;
14926 12 : EER_TestPoint_IP(1 + PartLoadTestPoint) = EER_TestPoint_SI(1 + PartLoadTestPoint) * ConvFromSIToIP;
14927 12 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = NetCoolingCap;
14928 12 : NetPower_TestPoint(1 + PartLoadTestPoint) = TotalElecPowerRated;
14929 : } else { // minimum unloading limit exceeded without cycling, so cycle
14930 6 : SpeedRatio = 0.0;
14931 6 : CycRatio = TargetNetCapacity / LowSpeedNetCoolingCap;
14932 6 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(1), CycRatio);
14933 6 : if (PLF < 0.7) {
14934 0 : PLF = 0.7;
14935 : }
14936 6 : RunTimeFraction = CycRatio / PLF;
14937 6 : RunTimeFraction = min(RunTimeFraction, 1.0);
14938 6 : TotCoolingCap = LowSpeedTotCoolingCap * RunTimeFraction;
14939 6 : NetCoolingCap = TotCoolingCap - FanHeatCorrection;
14940 6 : TotalElecPowerRated = LowSpeedTotCoolingCap * EIR_LowSpeed * RunTimeFraction + FanPowerCorrection;
14941 6 : EER_TestPoint_SI(1 + PartLoadTestPoint) = NetCoolingCap / TotalElecPowerRated;
14942 6 : EER_TestPoint_IP(1 + PartLoadTestPoint) = EER_TestPoint_SI(1 + PartLoadTestPoint) * ConvFromSIToIP;
14943 6 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = NetCoolingCap;
14944 6 : NetPower_TestPoint(1 + PartLoadTestPoint) = TotalElecPowerRated;
14945 : }
14946 : }
14947 : } // loop over 3 part load test points
14948 6 : state.dataHVACGlobal->TurnFansOn = saveTurnFansOn;
14949 6 : state.dataHVACGlobal->TurnFansOff = saveTurnFansOff;
14950 :
14951 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));
14952 : // CalcMultiSpeedDXCoilCooling() //??
14953 : // begin output
14954 6 : if (state.dataDXCoils->CalcTwoSpeedDXCoilStandardRatingOneTimeEIOHeaderWrite) {
14955 4 : print(state.files.eio, Header);
14956 4 : state.dataDXCoils->CalcTwoSpeedDXCoilStandardRatingOneTimeEIOHeaderWrite = false;
14957 8 : state.dataOutRptPredefined->pdstVAVDXCoolCoil =
14958 4 : newPreDefSubTable(state, state.dataOutRptPredefined->pdrEquip, "VAV DX Cooling Standard Rating Details");
14959 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilType =
14960 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "DX Cooling Coil Type");
14961 4 : state.dataOutRptPredefined->pdchVAVDXFanName = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Associated Fan");
14962 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilNetCapSI =
14963 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Net Cooling Capacity [W]");
14964 4 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP [W/W]");
14965 4 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEERIP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER [Btu/W-h]");
14966 4 : state.dataOutRptPredefined->pdchVAVDXCoolCoilIEERIP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "IEER [Btu/W-h]");
14967 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotA =
14968 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 100% [kg/s]");
14969 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_B =
14970 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 75% Capacity [W/W]");
14971 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_B_IP =
14972 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 75% Capacity [Btu/W-h]");
14973 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotB =
14974 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 75% [kg/s]");
14975 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_C =
14976 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 50% Capacity [W/W]");
14977 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_C_IP =
14978 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 50% Capacity [Btu/W-h]");
14979 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotC =
14980 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 50% [kg/s]");
14981 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_D =
14982 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 25% Capacity [W/W]");
14983 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_D_IP =
14984 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 25% Capacity [Btu/W-h]");
14985 8 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotD =
14986 4 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 25% [kg/s]");
14987 :
14988 : // determine footnote content
14989 4 : countStaticInputs = 0;
14990 8 : for (index = 1; index <= state.dataDXCoils->NumDXCoils; ++index) {
14991 :
14992 7 : if (state.dataDXCoils->DXCoil(index).RateWithInternalStaticAndFanObject &&
14993 3 : state.dataDXCoils->DXCoil(index).DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
14994 3 : ++countStaticInputs;
14995 : }
14996 : }
14997 :
14998 4 : if (countStaticInputs == state.dataDXCoils->NumDXMulSpeedCoils) {
14999 6 : addFootNoteSubTable(state,
15000 3 : state.dataOutRptPredefined->pdstVAVDXCoolCoil,
15001 : "Packaged VAV unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2");
15002 1 : } else if (countStaticInputs == 0) {
15003 2 : addFootNoteSubTable(state,
15004 1 : state.dataOutRptPredefined->pdstVAVDXCoolCoil,
15005 : "Indoor-coil-only unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2, with "
15006 : "supply fan specific power at 365 {{W/1000cfm}} (773.3 {{W/(m3/s)}})");
15007 : } else { // both
15008 0 : addFootNoteSubTable(state,
15009 0 : state.dataOutRptPredefined->pdstVAVDXCoolCoil,
15010 : "Packaged VAV unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2, "
15011 : "indoor-coil-only units with supply fan specific power at 365 {{W/1000cfm}} (773.3 {{W/(m3/s)}})");
15012 : }
15013 : }
15014 :
15015 0 : const auto &fan_type_name = [&]() -> std::pair<const char *, std::string> {
15016 6 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
15017 3 : return {"Fan:VariableVolume", thisDXCoil.SupplyFanName};
15018 : } else {
15019 3 : return {"N/A", "N/A"};
15020 : }
15021 6 : }();
15022 :
15023 6 : print(state.files.eio,
15024 : Format_891,
15025 : "Coil:Cooling:DX:TwoSpeed",
15026 6 : thisDXCoil.Name,
15027 6 : fan_type_name.first,
15028 6 : fan_type_name.second,
15029 : NetCoolingCapRated,
15030 6 : (NetCoolingCapRated * ConvFromSIToIP),
15031 : IEER,
15032 : EER_TestPoint_SI(1),
15033 : EER_TestPoint_SI(2),
15034 : EER_TestPoint_SI(3),
15035 : EER_TestPoint_SI(4),
15036 : EER_TestPoint_IP(1),
15037 : EER_TestPoint_IP(2),
15038 : EER_TestPoint_IP(3),
15039 : EER_TestPoint_IP(4),
15040 : SupAirMdot_TestPoint(1),
15041 : SupAirMdot_TestPoint(2),
15042 : SupAirMdot_TestPoint(3),
15043 : SupAirMdot_TestPoint(4));
15044 :
15045 6 : if (state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag) {
15046 : static constexpr std::string_view Format_994(
15047 : "! <DX Cooling Coil Standard Rating Information>, Component Type, Component Name, Standard Rating (Net) "
15048 : "Cooling Capacity {W}, Standard Rating Net COP {W/W}, EER {Btu/W-h}, SEER User {Btu/W-h}, SEER Standard {Btu/W-h}, "
15049 : "IEER "
15050 : "{Btu/W-h}");
15051 4 : print(state.files.eio, "{}\n", Format_994);
15052 4 : state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag = false;
15053 : }
15054 : static constexpr std::string_view Format_995(" DX Cooling Coil Standard Rating Information, {}, {}, {:.1R}, {}, {}, {}, {}, {}\n");
15055 6 : print(state.files.eio,
15056 : Format_995,
15057 : "Coil:Cooling:DX:TwoSpeed",
15058 6 : thisDXCoil.Name,
15059 : NetCoolingCapRated,
15060 : EER_TestPoint_SI(1),
15061 : EER_TestPoint_IP(1),
15062 : "N/A",
15063 : "N/A",
15064 : IEER);
15065 :
15066 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilType, thisDXCoil.Name, "Coil:Cooling:DX:TwoSpeed");
15067 : // W to tons
15068 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilNetCapSI, thisDXCoil.Name, NetCoolingCapRated, 1);
15069 :
15070 : // TODO: Commercial and industrial unitary air-conditioning condensing units with a capacity greater than 135,000 Btu/h (39564.59445 Watts)
15071 : // as defined in ANSI/AHRI Standard 365(I-P). | Scope 2.2.6 (ANSI/AHRI 340-360 2022)
15072 : //
15073 : // These will convert with a factor of 1 which is ok
15074 : // SEER | Capacity less than 65K Btu/h (19050 W) - calculated as per AHRI Standard 210/240-2023.
15075 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilCOP, thisDXCoil.Name, EER_TestPoint_SI(1), 2);
15076 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilEERIP, thisDXCoil.Name, EER_TestPoint_IP(1), 2);
15077 : // These will convert with a factor of 1 which is ok
15078 : // IEER | Capacity of 65K Btu/h (19050 W) to less than 135K Btu/h (39565 W) - calculated as per AHRI Standard 340/360-2022.
15079 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilIEERIP, thisDXCoil.Name, IEER, 1);
15080 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERUserIP, thisDXCoil.Name, "N/A");
15081 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERStandardIP, thisDXCoil.Name, "N/A");
15082 :
15083 6 : addFootNoteSubTable(state, state.dataOutRptPredefined->pdstDXCoolCoil, StandardRatings::AHRI2017FOOTNOTE);
15084 :
15085 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilType, thisDXCoil.Name, "Coil:Cooling:DX:TwoSpeed");
15086 6 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
15087 3 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXFanName, thisDXCoil.Name, thisDXCoil.SupplyFanName);
15088 : } else {
15089 3 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXFanName, thisDXCoil.Name, "None");
15090 : }
15091 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilNetCapSI, thisDXCoil.Name, NetCoolingCapRated, 2);
15092 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP, thisDXCoil.Name, EER_TestPoint_SI(1), 2);
15093 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilIEERIP, thisDXCoil.Name, IEER, 2);
15094 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEERIP, thisDXCoil.Name, EER_TestPoint_IP(1), 2);
15095 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotA, thisDXCoil.Name, SupAirMdot_TestPoint(1), 4);
15096 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_B, thisDXCoil.Name, EER_TestPoint_SI(2), 2);
15097 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_B_IP, thisDXCoil.Name, EER_TestPoint_IP(2), 2);
15098 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotB, thisDXCoil.Name, SupAirMdot_TestPoint(2), 4);
15099 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_C, thisDXCoil.Name, EER_TestPoint_SI(3), 2);
15100 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_C_IP, thisDXCoil.Name, EER_TestPoint_IP(3), 2);
15101 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotC, thisDXCoil.Name, SupAirMdot_TestPoint(3), 4);
15102 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_D, thisDXCoil.Name, EER_TestPoint_SI(4), 2);
15103 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_D_IP, thisDXCoil.Name, EER_TestPoint_IP(4), 2);
15104 6 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotD, thisDXCoil.Name, SupAirMdot_TestPoint(4), 4);
15105 :
15106 6 : state.dataEnvrn->OutDryBulbTemp = heldOutDryBulb; // reset the outdoor dry bulb when done with it
15107 6 : }
15108 :
15109 2 : void GetFanIndexForTwoSpeedCoil(
15110 : EnergyPlusData &state, int const CoolingCoilIndex, int &SupplyFanIndex, std::string &SupplyFanName, HVAC::FanType &supplyFanType)
15111 : {
15112 :
15113 : // SUBROUTINE INFORMATION:
15114 : // AUTHOR <author>
15115 : // DATE WRITTEN <date_written>
15116 :
15117 : // PURPOSE OF THIS SUBROUTINE:
15118 : // This routine looks up the given TwoSpeed DX coil and returns the companion supply fan index
15119 :
15120 : // Using/Aliasing
15121 2 : int NumPrimaryAirSys = state.dataHVACGlobal->NumPrimaryAirSys;
15122 :
15123 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
15124 : int FoundBranch;
15125 : int FoundAirSysNum;
15126 : int AirSysNum;
15127 : int BranchNum;
15128 : int CompNum;
15129 :
15130 2 : FoundBranch = 0;
15131 2 : FoundAirSysNum = 0;
15132 2 : SupplyFanIndex = 0;
15133 2 : SupplyFanName = "n/a";
15134 4 : for (AirSysNum = 1; AirSysNum <= NumPrimaryAirSys; ++AirSysNum) {
15135 :
15136 4 : for (BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).NumBranches; ++BranchNum) {
15137 :
15138 4 : for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).TotalComponents; ++CompNum) {
15139 :
15140 4 : if (state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num ==
15141 : SimAirServingZones::CompType::DXSystem) {
15142 :
15143 2 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name,
15144 2 : state.dataDXCoils->DXCoil(CoolingCoilIndex).CoilSystemName)) {
15145 2 : FoundBranch = BranchNum;
15146 2 : FoundAirSysNum = AirSysNum;
15147 2 : break;
15148 : }
15149 : // these are specified in SimAirServingZones and need to be moved to a Data* file. UnitarySystem=19
15150 2 : } else if (state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num ==
15151 : SimAirServingZones::CompType::UnitarySystemModel) {
15152 :
15153 0 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name,
15154 0 : state.dataDXCoils->DXCoil(CoolingCoilIndex).CoilSystemName)) {
15155 0 : FoundBranch = BranchNum;
15156 0 : FoundAirSysNum = AirSysNum;
15157 0 : break;
15158 : }
15159 : }
15160 : }
15161 :
15162 2 : if (FoundBranch > 0 && FoundAirSysNum > 0) {
15163 9 : for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).TotalComponents;
15164 : ++CompNum) {
15165 8 : if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
15166 : SimAirServingZones::CompType::Fan_Simple_VAV) {
15167 1 : SupplyFanName = state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).Name;
15168 1 : SupplyFanIndex = Fans::GetFanIndex(state, SupplyFanName);
15169 1 : supplyFanType = HVAC::FanType::VAV;
15170 1 : break;
15171 : // these are specified in SimAirServingZones and need to be moved to a Data* file. UnitarySystem=19
15172 7 : } else if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
15173 : SimAirServingZones::CompType::Fan_System_Object) {
15174 1 : SupplyFanName = state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).Name;
15175 1 : SupplyFanIndex = Fans::GetFanIndex(state, SupplyFanName);
15176 1 : supplyFanType = HVAC::FanType::SystemModel;
15177 :
15178 6 : } else if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
15179 : SimAirServingZones::CompType::UnitarySystemModel) {
15180 : // fan may not be specified in a unitary system object, keep looking
15181 : // Unitary System will "set" the fan index to the DX coil if contained within the HVAC system
15182 0 : if (state.dataDXCoils->DXCoil(CoolingCoilIndex).SupplyFanIndex > 0) {
15183 0 : break;
15184 : }
15185 : }
15186 : }
15187 : }
15188 : }
15189 : }
15190 2 : }
15191 :
15192 165 : void GetDXCoilIndex(EnergyPlusData &state,
15193 : std::string const &DXCoilName,
15194 : int &DXCoilIndex,
15195 : bool &ErrorsFound,
15196 : std::string_view const ThisObjectType,
15197 : bool const SuppressWarning)
15198 : {
15199 :
15200 : // SUBROUTINE INFORMATION:
15201 : // AUTHOR Richard Raustad
15202 : // DATE WRITTEN March 2005
15203 :
15204 : // PURPOSE OF THIS SUBROUTINE:
15205 : // This subroutine sets an index for a given DX Coil -- issues error message if that
15206 : // DX Coil is not a legal DX Coil.
15207 :
15208 165 : if (state.dataDXCoils->GetCoilsInputFlag) {
15209 58 : GetDXCoils(state);
15210 58 : state.dataDXCoils->GetCoilsInputFlag = false;
15211 : }
15212 :
15213 165 : DXCoilIndex = Util::FindItemInList(DXCoilName, state.dataDXCoils->DXCoil);
15214 165 : if (DXCoilIndex == 0) {
15215 0 : if (!SuppressWarning) {
15216 : // No warning printed if only searching for the existence of a DX Coil
15217 0 : if (!ThisObjectType.empty()) {
15218 0 : ShowSevereError(state, fmt::format("{}, GetDXCoilIndex: DX Coil not found={}", ThisObjectType, DXCoilName));
15219 : } else {
15220 0 : ShowSevereError(state, format("GetDXCoilIndex: DX Coil not found={}", DXCoilName));
15221 : }
15222 : }
15223 0 : ErrorsFound = true;
15224 : }
15225 165 : }
15226 :
15227 : std::string
15228 0 : GetDXCoilName(EnergyPlusData &state, int &DXCoilIndex, bool &ErrorsFound, std::string_view const ThisObjectType, bool const SuppressWarning)
15229 : {
15230 :
15231 : // SUBROUTINE INFORMATION:
15232 : // AUTHOR Richard Raustad
15233 : // DATE WRITTEN May 2017
15234 :
15235 : // PURPOSE OF THIS SUBROUTINE:
15236 : // This subroutine gets a name for a given DX Coil -- issues error message if that
15237 : // DX Coil is not a legal DX Coil.
15238 :
15239 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
15240 0 : GetDXCoils(state);
15241 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15242 : }
15243 :
15244 0 : if (DXCoilIndex == 0) {
15245 0 : if (!SuppressWarning) {
15246 : // No warning printed if only searching for the existence of a DX Coil
15247 0 : if (!ThisObjectType.empty()) {
15248 0 : ShowSevereError(state, fmt::format("{}, GetDXCoilIndex: DX Coil not found ", ThisObjectType));
15249 : } else {
15250 0 : ShowSevereError(state, "GetDXCoilIndex: DX Coil not found ");
15251 : }
15252 : }
15253 0 : ErrorsFound = true;
15254 0 : return " "; // This does not seem great
15255 :
15256 : } else {
15257 0 : return state.dataDXCoils->DXCoil(DXCoilIndex).Name;
15258 : }
15259 : }
15260 :
15261 6 : Real64 GetCoilCapacity(EnergyPlusData &state,
15262 : std::string const &CoilType, // must match coil types in this module
15263 : std::string const &CoilName, // must match coil names for the coil type
15264 : bool &ErrorsFound // set to true if problem
15265 : )
15266 : {
15267 :
15268 : // FUNCTION INFORMATION:
15269 : // AUTHOR Linda Lawrie
15270 : // DATE WRITTEN February 2006
15271 :
15272 : // PURPOSE OF THIS FUNCTION:
15273 : // This function looks up the coil capacity for the given coil and returns it. If
15274 : // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
15275 : // as negative.
15276 :
15277 : // Return value
15278 : Real64 CoilCapacity; // returned capacity of matched coil
15279 :
15280 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15281 : int WhichCoil;
15282 :
15283 : // Obtains and Allocates DXCoils
15284 6 : if (state.dataDXCoils->GetCoilsInputFlag) {
15285 0 : GetDXCoils(state);
15286 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15287 : }
15288 :
15289 6 : if (Util::SameString(CoilType, "Coil:Heating:DX:SingleSpeed") || Util::SameString(CoilType, "Coil:Cooling:DX:SingleSpeed")) {
15290 6 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15291 6 : if (WhichCoil != 0) {
15292 6 : CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(1);
15293 : }
15294 0 : } else if (Util::SameString(CoilType, "Coil:Cooling:DX:TwoStageWithHumidityControlMode")) {
15295 0 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15296 0 : if (WhichCoil != 0) {
15297 0 : CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(state.dataDXCoils->DXCoil(WhichCoil).NumCapacityStages);
15298 : }
15299 0 : } else if (Util::SameString(CoilType, "Coil:Cooling:DX:TwoSpeed")) {
15300 0 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15301 0 : if (WhichCoil != 0) {
15302 0 : CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(1);
15303 : }
15304 0 : } else if (Util::SameString(CoilType, "Coil:Cooling:DX:MultiSpeed") || Util::SameString(CoilType, "Coil:Heating:DX:MultiSpeed")) {
15305 0 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15306 0 : if (WhichCoil != 0) {
15307 0 : CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).MSRatedTotCap(state.dataDXCoils->DXCoil(WhichCoil).NumOfSpeeds);
15308 : }
15309 : } else {
15310 0 : WhichCoil = 0;
15311 : }
15312 :
15313 6 : if (WhichCoil == 0) {
15314 0 : ShowSevereError(state, format("GetCoilCapacity: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15315 0 : ShowContinueError(state, "... returning capacity as -1000.");
15316 0 : ErrorsFound = true;
15317 0 : CoilCapacity = -1000.0;
15318 : }
15319 :
15320 6 : return CoilCapacity;
15321 : }
15322 :
15323 39 : Real64 GetCoilCapacityByIndexType(EnergyPlusData &state,
15324 : int const CoilIndex, // must match coil index for the coil type
15325 : int const CoilType_Num, // must match coil types in this module
15326 : bool &ErrorsFound // set to true if problem
15327 : )
15328 : {
15329 :
15330 : // FUNCTION INFORMATION:
15331 : // AUTHOR Richard Raustad
15332 : // DATE WRITTEN October 2010
15333 :
15334 : // PURPOSE OF THIS FUNCTION:
15335 : // This function looks up the coil capacity for the given coil and returns it. If
15336 : // incorrect coil index or type is given, ErrorsFound is returned as true and capacity is returned
15337 : // as negative.
15338 :
15339 : // Return value
15340 : Real64 CoilCapacity; // returned capacity of matched coil
15341 :
15342 : // Obtains and Allocates DXCoils
15343 39 : if (state.dataDXCoils->GetCoilsInputFlag) {
15344 0 : GetDXCoils(state);
15345 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15346 : }
15347 :
15348 39 : if (CoilIndex == 0) {
15349 0 : ShowSevereError(state, "GetCoilCapacityByIndexType: Invalid index passed = 0");
15350 0 : ShowContinueError(state, "... returning capacity as -1000.");
15351 0 : ErrorsFound = true;
15352 0 : CoilCapacity = -1000.0;
15353 0 : return CoilCapacity;
15354 : }
15355 :
15356 39 : if (CoilType_Num != state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
15357 0 : ShowSevereError(state, "GetCoilCapacityByIndexType: Index passed does not match DX Coil type passed.");
15358 0 : ShowContinueError(state, "... returning capacity as -1000.");
15359 0 : ErrorsFound = true;
15360 0 : CoilCapacity = -1000.0;
15361 : } else {
15362 39 : switch (state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
15363 4 : case HVAC::CoilDX_MultiSpeedCooling:
15364 : case HVAC::CoilDX_MultiSpeedHeating: {
15365 4 : CoilCapacity = state.dataDXCoils->DXCoil(CoilIndex).MSRatedTotCap(state.dataDXCoils->DXCoil(CoilIndex).NumOfSpeeds);
15366 4 : } break;
15367 35 : default: {
15368 35 : CoilCapacity = state.dataDXCoils->DXCoil(CoilIndex).RatedTotCap(state.dataDXCoils->DXCoil(CoilIndex).NumCapacityStages);
15369 35 : } break;
15370 : }
15371 : }
15372 :
15373 39 : return CoilCapacity;
15374 : }
15375 :
15376 76 : int GetCoilTypeNum(EnergyPlusData &state,
15377 : std::string const &CoilType, // must match coil types in this module
15378 : std::string const &CoilName, // must match coil names for the coil type
15379 : bool &ErrorsFound, // set to true if problem
15380 : ObjexxFCL::Optional_bool_const PrintWarning // prints warning when true
15381 : )
15382 : {
15383 :
15384 : // FUNCTION INFORMATION:
15385 : // AUTHOR R. Raustad - FSEC
15386 : // DATE WRITTEN August 2008
15387 :
15388 : // PURPOSE OF THIS FUNCTION:
15389 : // This function looks up the integerized coil type for the given coil and returns it. If
15390 : // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
15391 : // as negative.
15392 :
15393 : // Return value
15394 : int TypeNum; // returned integerized type of matched coil
15395 :
15396 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15397 : int WhichCoil;
15398 : bool PrintMessage;
15399 :
15400 : // Obtains and Allocates DXCoils
15401 76 : if (state.dataDXCoils->GetCoilsInputFlag) {
15402 29 : GetDXCoils(state);
15403 29 : state.dataDXCoils->GetCoilsInputFlag = false;
15404 : }
15405 :
15406 76 : if (present(PrintWarning)) {
15407 74 : PrintMessage = PrintWarning;
15408 : } else {
15409 2 : PrintMessage = true;
15410 : }
15411 :
15412 76 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15413 76 : if (WhichCoil != 0) {
15414 76 : TypeNum = state.dataDXCoils->DXCoil(WhichCoil).DXCoilType_Num;
15415 : } else {
15416 0 : if (PrintMessage) {
15417 0 : ShowSevereError(state, format("GetCoilTypeNum: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15418 : }
15419 0 : ErrorsFound = true;
15420 0 : TypeNum = 0;
15421 : }
15422 :
15423 76 : return TypeNum;
15424 : }
15425 :
15426 76 : Real64 GetMinOATCompressor(EnergyPlusData &state,
15427 : int const CoilIndex, // index to cooling coil
15428 : bool &ErrorsFound // set to true if problem
15429 : )
15430 : {
15431 :
15432 : // Obtains and Allocates DXCoils
15433 76 : if (state.dataDXCoils->GetCoilsInputFlag) {
15434 0 : GetDXCoils(state);
15435 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15436 : }
15437 :
15438 76 : if (CoilIndex == 0) {
15439 0 : ShowSevereError(state, "GetMinOATCompressor: Index passed = 0");
15440 0 : ShowContinueError(state, "... returning Min OAT for compressor operation as -1000.");
15441 0 : ErrorsFound = true;
15442 0 : return -1000.0;
15443 : } else {
15444 76 : return state.dataDXCoils->DXCoil(CoilIndex).MinOATCompressor;
15445 : }
15446 : }
15447 :
15448 78 : int GetCoilInletNode(EnergyPlusData &state,
15449 : std::string const &CoilType, // must match coil types in this module
15450 : std::string const &CoilName, // must match coil names for the coil type
15451 : bool &ErrorsFound // set to true if problem
15452 : )
15453 : {
15454 :
15455 : // FUNCTION INFORMATION:
15456 : // AUTHOR Linda Lawrie
15457 : // DATE WRITTEN February 2006
15458 :
15459 : // PURPOSE OF THIS FUNCTION:
15460 : // This function looks up the given coil and returns the inlet node number. If
15461 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
15462 : // as zero.
15463 :
15464 : // Return value
15465 : int NodeNumber; // returned node number of matched coil
15466 :
15467 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15468 : int WhichCoil;
15469 :
15470 : // Obtains and Allocates DXCoils
15471 78 : if (state.dataDXCoils->GetCoilsInputFlag) {
15472 1 : GetDXCoils(state);
15473 1 : state.dataDXCoils->GetCoilsInputFlag = false;
15474 : }
15475 :
15476 78 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15477 78 : if (WhichCoil != 0) {
15478 78 : NodeNumber = state.dataDXCoils->DXCoil(WhichCoil).AirInNode;
15479 : } else {
15480 0 : ShowSevereError(state, format("GetCoilInletNode: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15481 0 : ErrorsFound = true;
15482 0 : NodeNumber = 0;
15483 : }
15484 :
15485 78 : return NodeNumber;
15486 : }
15487 :
15488 0 : int getCoilInNodeIndex(EnergyPlusData &state,
15489 : int const CoilIndex, // coil index
15490 : bool &ErrorsFound // set to true if problem
15491 : )
15492 : {
15493 :
15494 : int NodeNumber; // returned node number of matched coil
15495 :
15496 : // Obtains and Allocates DXCoils
15497 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
15498 0 : GetDXCoils(state);
15499 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15500 : }
15501 :
15502 0 : if (CoilIndex != 0) {
15503 0 : NodeNumber = state.dataDXCoils->DXCoil(CoilIndex).AirInNode;
15504 : } else {
15505 0 : ShowSevereError(state, "GetCoilInletNode: Could not find Coil Type");
15506 0 : ErrorsFound = true;
15507 0 : NodeNumber = 0;
15508 : }
15509 :
15510 0 : return NodeNumber;
15511 : }
15512 :
15513 83 : int GetCoilOutletNode(EnergyPlusData &state,
15514 : std::string const &CoilType, // must match coil types in this module
15515 : std::string const &CoilName, // must match coil names for the coil type
15516 : bool &ErrorsFound // set to true if problem
15517 : )
15518 : {
15519 :
15520 : // FUNCTION INFORMATION:
15521 : // AUTHOR Linda Lawrie
15522 : // DATE WRITTEN February 2006
15523 :
15524 : // PURPOSE OF THIS FUNCTION:
15525 : // This function looks up the given coil and returns the inlet node number. If
15526 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
15527 : // as zero.
15528 :
15529 : // Return value
15530 : int NodeNumber; // returned node number of matched coil
15531 :
15532 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15533 : int WhichCoil;
15534 :
15535 : // Obtains and Allocates DXCoils
15536 83 : if (state.dataDXCoils->GetCoilsInputFlag) {
15537 3 : GetDXCoils(state);
15538 3 : state.dataDXCoils->GetCoilsInputFlag = false;
15539 : }
15540 :
15541 83 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15542 83 : if (WhichCoil != 0) {
15543 83 : NodeNumber = state.dataDXCoils->DXCoil(WhichCoil).AirOutNode;
15544 : } else {
15545 0 : ShowSevereError(
15546 : state,
15547 0 : format("GetCoilOutletNode: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil outlet node number.", CoilType, CoilName));
15548 0 : ErrorsFound = true;
15549 0 : NodeNumber = 0;
15550 : }
15551 :
15552 83 : return NodeNumber;
15553 : }
15554 :
15555 0 : int getCoilOutNodeIndex(EnergyPlusData &state,
15556 : int const CoilIndex, // must match coil types in this module
15557 : bool &ErrorsFound // set to true if problem
15558 : )
15559 : {
15560 :
15561 : int NodeNumber; // returned node number of matched coil
15562 :
15563 : // Obtains and Allocates DXCoils
15564 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
15565 0 : GetDXCoils(state);
15566 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15567 : }
15568 :
15569 0 : if (CoilIndex != 0) {
15570 0 : NodeNumber = state.dataDXCoils->DXCoil(CoilIndex).AirOutNode;
15571 : } else {
15572 0 : ShowSevereError(state, "GetCoilOutletNode: Could not find Coil Type");
15573 0 : ErrorsFound = true;
15574 0 : NodeNumber = 0;
15575 : }
15576 :
15577 0 : return NodeNumber;
15578 : }
15579 :
15580 45 : int GetCoilCondenserInletNode(EnergyPlusData &state,
15581 : std::string const &CoilType, // must match coil types in this module
15582 : std::string const &CoilName, // must match coil names for the coil type
15583 : bool &ErrorsFound // set to true if problem
15584 : )
15585 : {
15586 :
15587 : // FUNCTION INFORMATION:
15588 : // AUTHOR R. Raustad
15589 : // DATE WRITTEN January 2007
15590 :
15591 : // PURPOSE OF THIS FUNCTION:
15592 : // This function looks up the given coil and returns the condenser inlet node. If
15593 : // incorrect coil type or name is given, ErrorsFound is returned as true.
15594 :
15595 : // Return value
15596 : int CondNode; // returned condenser node number of matched coil
15597 :
15598 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15599 : int WhichCoil;
15600 :
15601 : // Obtains and Allocates DXCoils
15602 45 : if (state.dataDXCoils->GetCoilsInputFlag) {
15603 0 : GetDXCoils(state);
15604 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15605 : }
15606 :
15607 45 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15608 45 : if (WhichCoil != 0) {
15609 45 : CondNode = state.dataDXCoils->DXCoil(WhichCoil).CondenserInletNodeNum(1);
15610 : } else {
15611 0 : ShowSevereError(state, format("GetCoilCondenserInletNode: Invalid DX Coil, Type= \"{}\" Name=\"{}\"", CoilType, CoilName));
15612 0 : ErrorsFound = true;
15613 0 : CondNode = 0;
15614 : }
15615 :
15616 45 : return CondNode;
15617 : }
15618 :
15619 2 : Real64 GetDXCoilBypassedFlowFrac(EnergyPlusData &state,
15620 : std::string const &CoilType, // must match coil types in this module
15621 : std::string const &CoilName, // must match coil names for the coil type
15622 : bool &ErrorsFound // set to true if problem
15623 : )
15624 : {
15625 :
15626 : // FUNCTION INFORMATION:
15627 : // AUTHOR R. Raustad
15628 : // DATE WRITTEN June 2007
15629 :
15630 : // PURPOSE OF THIS FUNCTION:
15631 : // This function looks up the given coil and returns the bypassed air flow fraction.
15632 : // Bypassed air flow fraction can only be greater than 0 for multimode DX cooling coils and is typical for 1st stage
15633 : // If incorrect coil type or name is given, ErrorsFound is returned as true.
15634 :
15635 : // Return value
15636 : Real64 BypassFraction; // returned bypass air fraction of matched coil
15637 :
15638 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15639 : int WhichCoil;
15640 :
15641 : // Obtains and Allocates DXCoils
15642 2 : if (state.dataDXCoils->GetCoilsInputFlag) {
15643 0 : GetDXCoils(state);
15644 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15645 : }
15646 :
15647 2 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15648 2 : if (WhichCoil != 0) {
15649 2 : BypassFraction = state.dataDXCoils->DXCoil(WhichCoil).BypassedFlowFrac(1);
15650 : } else {
15651 0 : ShowSevereError(state, format("GetDXCoilBypassedFlowFrac: Invalid DX Coil Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15652 0 : ErrorsFound = true;
15653 0 : BypassFraction = 0.0;
15654 : }
15655 :
15656 2 : return BypassFraction;
15657 : }
15658 :
15659 40 : int GetHPCoolingCoilIndex(EnergyPlusData &state,
15660 : std::string const &HeatingCoilType, // Type of DX heating coil used in HP
15661 : std::string const &HeatingCoilName, // Name of DX heating coil used in HP
15662 : int const HeatingCoilIndex // Index of DX heating coil used in HP
15663 : )
15664 : {
15665 :
15666 : // FUNCTION INFORMATION:
15667 : // AUTHOR R. Raustad
15668 : // DATE WRITTEN February 2007
15669 :
15670 : // PURPOSE OF THIS FUNCTION:
15671 : // This function looks up the given DX heating coil and returns the companion DX cooling coil.
15672 :
15673 : // Return value
15674 : int DXCoolingCoilIndex; // Index of HP DX cooling coil returned from this function
15675 :
15676 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15677 : int WhichComp; // DO loop counter to find correct comp set
15678 : int WhichCompanionComp; // DO loop counter to find companion coil comp set
15679 : int WhichHXAssistedComp; // DO loop counter when DX coil is used in a HX assisted cooling coil
15680 :
15681 40 : DXCoolingCoilIndex = 0;
15682 :
15683 : DataLoopNode::ConnectionObjectType HeatingCoilTypeNum = static_cast<DataLoopNode::ConnectionObjectType>(
15684 40 : getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC, Util::makeUPPER(HeatingCoilType)));
15685 :
15686 : DataLoopNode::ConnectionObjectType CompSetsParentType; // Parent object type which uses DX heating coil pass into this function
15687 40 : std::string CompSetsParentName;
15688 110 : for (WhichComp = 1; WhichComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichComp) {
15689 :
15690 151 : if (HeatingCoilTypeNum != state.dataBranchNodeConnections->CompSets(WhichComp).ComponentObjectType ||
15691 41 : !Util::SameString(HeatingCoilName, state.dataBranchNodeConnections->CompSets(WhichComp).CName)) {
15692 70 : continue;
15693 : }
15694 40 : CompSetsParentType = state.dataBranchNodeConnections->CompSets(WhichComp).ParentObjectType;
15695 40 : CompSetsParentName = state.dataBranchNodeConnections->CompSets(WhichComp).ParentCName;
15696 40 : if ((CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAir) ||
15697 14 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::ZoneHVACPackagedTerminalHeatPump) ||
15698 12 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed) ||
15699 12 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass) ||
15700 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitarySystem)) {
15701 : // Search for DX cooling coils
15702 104 : for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
15703 154 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, CompSetsParentName) ||
15704 64 : (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
15705 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed)) {
15706 64 : continue;
15707 : }
15708 : DXCoolingCoilIndex =
15709 26 : Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
15710 26 : break;
15711 : }
15712 152 : for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
15713 207 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, CompSetsParentName) ||
15714 91 : (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
15715 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed)) {
15716 112 : continue;
15717 : }
15718 : DXCoolingCoilIndex =
15719 4 : Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
15720 4 : break;
15721 : }
15722 : // Search for Heat Exchanger Assisted DX cooling coils
15723 40 : if (DXCoolingCoilIndex == 0) {
15724 93 : for (WhichHXAssistedComp = 1; WhichHXAssistedComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichHXAssistedComp) {
15725 124 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ParentCName, CompSetsParentName) ||
15726 62 : (state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ComponentObjectType !=
15727 : DataLoopNode::ConnectionObjectType::CoilSystemCoolingDXHeatExchangerAssisted)) {
15728 62 : continue;
15729 : }
15730 : DataLoopNode::ConnectionObjectType HXCompSetsParentType; // Used when DX cooling coil is a child of a HX assisted cooling coil
15731 0 : HXCompSetsParentType = state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ComponentObjectType;
15732 0 : std::string const &HXCompSetsParentName = state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).CName;
15733 0 : for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
15734 0 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, HXCompSetsParentName) ||
15735 0 : (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
15736 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed)) {
15737 0 : continue;
15738 : }
15739 : DXCoolingCoilIndex =
15740 0 : Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
15741 0 : break;
15742 : }
15743 0 : break;
15744 : }
15745 : }
15746 40 : } else {
15747 : // ErrorFound, Coil:Heating:DX:SingleSpeed is used in wrong type of parent object (should never get here)
15748 0 : ShowSevereError(state,
15749 0 : format("Configuration error in {}\"{}\"",
15750 0 : BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(CompSetsParentType)],
15751 : CompSetsParentName));
15752 0 : ShowContinueError(state, "DX heating coil not allowed in this configuration.");
15753 0 : ShowFatalError(state, "Preceding condition(s) causes termination.");
15754 : }
15755 40 : break;
15756 : }
15757 :
15758 : // Check and warn user is crankcase heater power or max OAT for crankcase heater differs in DX cooling and heating coils
15759 40 : if (DXCoolingCoilIndex > 0) {
15760 9 : if (state.dataDXCoils->DXCoil(DXCoolingCoilIndex).CrankcaseHeaterCapacity != 0.0) {
15761 1 : if (state.dataDXCoils->DXCoil(DXCoolingCoilIndex).CrankcaseHeaterCapacity !=
15762 2 : state.dataDXCoils->DXCoil(HeatingCoilIndex).CrankcaseHeaterCapacity ||
15763 1 : state.dataDXCoils->DXCoil(DXCoolingCoilIndex).MaxOATCrankcaseHeater !=
15764 1 : state.dataDXCoils->DXCoil(HeatingCoilIndex).MaxOATCrankcaseHeater) {
15765 0 : ShowWarningError(state, "Crankcase heater capacity or max outdoor temp for crankcase heater operation specified in");
15766 0 : ShowContinueError(state, format("Coil:Cooling:DX:SingleSpeed = {}", state.dataDXCoils->DXCoil(DXCoolingCoilIndex).Name));
15767 0 : ShowContinueError(state, format("is different than that specified in Coil:Heating:DX:SingleSpeed = {}.", HeatingCoilName));
15768 0 : ShowContinueError(state,
15769 0 : format("Both of these DX coils are part of {}={}.",
15770 0 : BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(CompSetsParentType)],
15771 : CompSetsParentName));
15772 0 : ShowContinueError(state, "The value specified in the DX heating coil will be used and the simulation continues...");
15773 : }
15774 : }
15775 : }
15776 :
15777 40 : return DXCoolingCoilIndex;
15778 40 : }
15779 :
15780 6 : int GetDXCoilNumberOfSpeeds(EnergyPlusData &state,
15781 : std::string const &CoilType, // must match coil types in this module
15782 : std::string const &CoilName, // must match coil names for the coil type
15783 : bool &ErrorsFound // set to true if problem
15784 : )
15785 : {
15786 :
15787 : // FUNCTION INFORMATION:
15788 : // AUTHOR L. Gu
15789 : // DATE WRITTEN July 2007
15790 :
15791 : // PURPOSE OF THIS FUNCTION:
15792 : // This function looks up the given coil and returns the number of speeds for multispeed coils.
15793 : // If incorrect coil type or name is given, ErrorsFound is returned as true.
15794 :
15795 : // Return value
15796 : int NumberOfSpeeds; // returned the number of speed of matched coil
15797 :
15798 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15799 : int WhichCoil;
15800 :
15801 : // Obtains and Allocates DXCoils
15802 6 : if (state.dataDXCoils->GetCoilsInputFlag) {
15803 0 : GetDXCoils(state);
15804 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15805 : }
15806 :
15807 6 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15808 6 : if (WhichCoil != 0) {
15809 6 : NumberOfSpeeds = state.dataDXCoils->DXCoil(WhichCoil).NumOfSpeeds;
15810 : } else {
15811 0 : ShowSevereError(state, format("GetDXCoilNumberOfSpeeds: Invalid DX Coil Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15812 0 : ErrorsFound = true;
15813 0 : NumberOfSpeeds = 0;
15814 : }
15815 :
15816 6 : return NumberOfSpeeds;
15817 : }
15818 :
15819 68 : Sched::Schedule *GetDXCoilAvailSched(EnergyPlusData &state,
15820 : std::string const &CoilType, // must match coil types in this module
15821 : std::string const &CoilName, // must match coil names for the coil type
15822 : bool &ErrorsFound, // set to true if problem
15823 : ObjexxFCL::Optional_int_const CoilIndex // Coil index number
15824 : )
15825 : {
15826 :
15827 : // FUNCTION INFORMATION:
15828 : // AUTHOR Richard Raustad
15829 : // DATE WRITTEN January 2013
15830 :
15831 : // PURPOSE OF THIS FUNCTION:
15832 : // This function looks up the given coil and returns the availability schedule index. If
15833 : // incorrect coil type or name is given, ErrorsFound is returned as true and schedule index is returned
15834 : // as -1.
15835 :
15836 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15837 : int WhichCoil;
15838 :
15839 : // Obtains and Allocates DXCoils
15840 68 : if (state.dataDXCoils->GetCoilsInputFlag) {
15841 0 : GetDXCoils(state);
15842 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15843 : }
15844 :
15845 68 : if (present(CoilIndex)) {
15846 2 : if (CoilIndex == 0) {
15847 0 : ShowSevereError(state, "GetDXCoilAvailSchPtr: Invalid index passed = 0");
15848 0 : ShowContinueError(state, "... returning DXCoilAvailSchPtr as -1.");
15849 0 : ErrorsFound = true;
15850 0 : return nullptr;
15851 : } else {
15852 2 : WhichCoil = CoilIndex;
15853 : }
15854 : } else {
15855 66 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15856 : }
15857 68 : if (WhichCoil != 0) {
15858 68 : return state.dataDXCoils->DXCoil(WhichCoil).availSched;
15859 : } else {
15860 0 : if (!present(CoilIndex)) {
15861 0 : ShowSevereError(state,
15862 0 : format("GetDXCoilAvailSch: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil availability schedule index.",
15863 : CoilType,
15864 : CoilName));
15865 : }
15866 0 : ErrorsFound = true;
15867 0 : return nullptr;
15868 : }
15869 : }
15870 :
15871 0 : Real64 GetDXCoilAirFlow(EnergyPlusData &state,
15872 : std::string const &CoilType, // must match coil types in this module
15873 : std::string const &CoilName, // must match coil names for the coil type
15874 : bool &ErrorsFound // set to true if problem
15875 : )
15876 : {
15877 :
15878 : // FUNCTION INFORMATION:
15879 : // AUTHOR Richard Raustad
15880 : // DATE WRITTEN January 2013
15881 :
15882 : // PURPOSE OF THIS FUNCTION:
15883 : // This function looks up the given coil and returns the availability schedule index. If
15884 : // incorrect coil type or name is given, ErrorsFound is returned as true and schedule index is returned
15885 : // as -1.
15886 :
15887 : // Return value
15888 : Real64 AirFlow; // returned coil air flow rate
15889 :
15890 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15891 : int WhichCoil;
15892 :
15893 : // Obtains and Allocates DXCoils
15894 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
15895 0 : GetDXCoils(state);
15896 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15897 : }
15898 :
15899 0 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15900 0 : if (WhichCoil != 0) {
15901 0 : switch (state.dataDXCoils->DXCoil(WhichCoil).DXCoilType_Num) {
15902 0 : case HVAC::CoilDX_CoolingSingleSpeed:
15903 : case HVAC::CoilDX_CoolingTwoSpeed:
15904 : case HVAC::CoilDX_HeatingEmpirical:
15905 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
15906 0 : AirFlow = state.dataDXCoils->DXCoil(WhichCoil).RatedAirVolFlowRate(1);
15907 0 : } break;
15908 0 : case HVAC::CoilDX_MultiSpeedCooling:
15909 : case HVAC::CoilDX_MultiSpeedHeating: {
15910 0 : AirFlow = state.dataDXCoils->DXCoil(WhichCoil).MSRatedAirVolFlowRate(1);
15911 0 : } break;
15912 0 : default: {
15913 0 : ShowSevereError(
15914 : state,
15915 0 : format("GetDXCoilAirFlow: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil air flow rate.", CoilType, CoilName));
15916 0 : ErrorsFound = true;
15917 0 : AirFlow = -1.0;
15918 0 : } break;
15919 : }
15920 : } else {
15921 0 : ShowSevereError(
15922 0 : state, format("GetDXCoilAirFlow: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil air flow rate.", CoilType, CoilName));
15923 0 : ErrorsFound = true;
15924 0 : AirFlow = -1.0;
15925 : }
15926 :
15927 0 : return AirFlow;
15928 : }
15929 :
15930 48 : int GetDXCoilCapFTCurveIndex(EnergyPlusData &state,
15931 : int const CoilIndex, // coil index pointer
15932 : bool &ErrorsFound // set to true if problem
15933 : )
15934 : {
15935 :
15936 : // FUNCTION INFORMATION:
15937 : // AUTHOR Richard Raustad
15938 : // DATE WRITTEN August 2013
15939 :
15940 : // PURPOSE OF THIS FUNCTION:
15941 : // This function looks up the given coil and returns the CapFT schedule index. If
15942 : // incorrect coil index is given, ErrorsFound is returned as true and schedule index is returned
15943 : // as -1.
15944 :
15945 : // Return value
15946 : int CapFTCurveIndex; // returned coil CapFT curve index
15947 :
15948 : // Obtains and Allocates DXCoils
15949 48 : if (state.dataDXCoils->GetCoilsInputFlag) {
15950 0 : GetDXCoils(state);
15951 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15952 : }
15953 :
15954 48 : if (CoilIndex != 0) {
15955 48 : switch (state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
15956 18 : case HVAC::CoilDX_CoolingSingleSpeed:
15957 : case HVAC::CoilDX_CoolingTwoSpeed:
15958 : case HVAC::CoilDX_HeatingEmpirical:
15959 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
15960 18 : CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).CCapFTemp(1);
15961 18 : } break;
15962 8 : case HVAC::CoilDX_MultiSpeedCooling:
15963 : case HVAC::CoilDX_MultiSpeedHeating: {
15964 8 : CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).MSCCapFTemp(state.dataDXCoils->DXCoil(CoilIndex).NumOfSpeeds);
15965 8 : } break;
15966 22 : case HVAC::CoilVRF_Heating: {
15967 22 : CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).CCapFTemp(1);
15968 22 : } break;
15969 0 : default: {
15970 : // CALL ShowSevereError(state, 'GetDXCoilCapFTCurveIndex: Could not find Coil, Type="'// &
15971 : // TRIM(cAllCoilTypes(DXCoil(CoilIndex)%DXCoilType_Num))//'" Name="'//TRIM(DXCoil(CoilIndex)%Name)// &
15972 : // '" when accessing coil capacity as a function of temperature curve.')
15973 0 : ErrorsFound = true;
15974 0 : CapFTCurveIndex = 0;
15975 0 : } break;
15976 : }
15977 : } else {
15978 : // CALL ShowSevereError(state, 'GetDXCoilCapFTCurveIndex: Could not find Coil, Index = 0'// &
15979 : // ' when accessing coil air flow rate.')
15980 0 : ErrorsFound = true;
15981 0 : CapFTCurveIndex = 0;
15982 : }
15983 :
15984 48 : return CapFTCurveIndex;
15985 : }
15986 :
15987 643 : void SetDXCoolingCoilData(
15988 : EnergyPlusData &state,
15989 : int const DXCoilNum, // Number of DX Cooling Coil
15990 : bool &ErrorsFound, // Set to true if certain errors found
15991 : ObjexxFCL::Optional_int HeatingCoilPLFCurvePTR, // Parameter equivalent of heating coil PLR curve index
15992 : ObjexxFCL::Optional<DataHeatBalance::RefrigCondenserType> CondenserType, // Parameter equivalent of condenser type parameter
15993 : ObjexxFCL::Optional_int CondenserInletNodeNum, // Parameter equivalent of condenser inlet node number
15994 : ObjexxFCL::Optional<Real64> MaxOATCrankcaseHeater, // Parameter equivalent of condenser Max OAT for Crank Case Heater temp
15995 : ObjexxFCL::Optional<Real64> MinOATCooling, // Parameter equivalent of condenser Min OAT for compressor cooling operation
15996 : ObjexxFCL::Optional<Real64> MaxOATCooling, // Parameter equivalent of condenser Max OAT for compressor cooling operation
15997 : ObjexxFCL::Optional<Real64> MinOATHeating, // Parameter equivalent of condenser Min OAT for compressor heating operation
15998 : ObjexxFCL::Optional<Real64> MaxOATHeating, // Parameter equivalent of condenser Max OAT for compressor heating operation
15999 : ObjexxFCL::Optional<HVAC::OATType> HeatingPerformanceOATType, // Parameter equivalent to condenser entering air temp type (1-db, 2=wb)
16000 : ObjexxFCL::Optional<StandardRatings::DefrostStrat> DefrostStrategy,
16001 : ObjexxFCL::Optional<StandardRatings::HPdefrostControl> DefrostControl,
16002 : ObjexxFCL::Optional_int DefrostEIRPtr,
16003 : ObjexxFCL::Optional<Real64> DefrostFraction,
16004 : ObjexxFCL::Optional<Real64> DefrostCapacity,
16005 : ObjexxFCL::Optional<Real64> MaxOATDefrost,
16006 : ObjexxFCL::Optional_bool CoolingCoilPresent,
16007 : ObjexxFCL::Optional_bool HeatingCoilPresent,
16008 : ObjexxFCL::Optional<Real64> HeatSizeRatio,
16009 : ObjexxFCL::Optional<Real64> TotCap,
16010 : ObjexxFCL::Optional_int SupplyFanIndex,
16011 : ObjexxFCL::Optional_string SupplyFanName,
16012 : ObjexxFCL::Optional<HVAC::FanType> supplyFanType)
16013 : {
16014 :
16015 : // SUBROUTINE INFORMATION:
16016 : // AUTHOR Richard Raustad, FSEC
16017 : // DATE WRITTEN December 2008
16018 :
16019 : // PURPOSE OF THIS SUBROUTINE:
16020 : // This routine was designed to allow the DX coil to access information from a gas or
16021 : // electric heating coil when these coils are each used in a parent object.
16022 : // Also, this is an illustration of setting Data from an outside source.
16023 :
16024 : // Using/Aliasing
16025 :
16026 : // Obtains and Allocates DXCoils
16027 643 : if (state.dataDXCoils->GetCoilsInputFlag) {
16028 0 : GetDXCoils(state);
16029 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16030 : }
16031 :
16032 643 : if (DXCoilNum <= 0 || DXCoilNum > state.dataDXCoils->NumDXCoils) {
16033 4 : ShowSevereError(state,
16034 4 : format("SetDXCoolingCoilData: called with DX Cooling Coil Number out of range={} should be >0 and <{}",
16035 : DXCoilNum,
16036 2 : state.dataDXCoils->NumDXCoils));
16037 2 : ErrorsFound = true;
16038 2 : return;
16039 : }
16040 :
16041 641 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
16042 641 : if (present(HeatingCoilPLFCurvePTR)) {
16043 0 : thisDXCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurvePTR;
16044 : }
16045 :
16046 641 : if (present(CondenserType)) {
16047 66 : thisDXCoil.CondenserType = CondenserType;
16048 : }
16049 :
16050 641 : if (present(CondenserInletNodeNum)) {
16051 66 : thisDXCoil.CondenserInletNodeNum(1) = CondenserInletNodeNum;
16052 : }
16053 :
16054 641 : if (present(MaxOATCrankcaseHeater)) {
16055 66 : thisDXCoil.MaxOATCrankcaseHeater = MaxOATCrankcaseHeater;
16056 : }
16057 :
16058 641 : if (present(MaxOATCooling)) {
16059 33 : thisDXCoil.MaxOATCompressor = MaxOATCooling;
16060 : }
16061 :
16062 641 : if (present(MaxOATHeating)) {
16063 11 : thisDXCoil.MaxOATCompressor = MaxOATHeating;
16064 : }
16065 :
16066 641 : if (present(MinOATCooling)) {
16067 33 : thisDXCoil.MinOATCompressor = MinOATCooling;
16068 : }
16069 :
16070 641 : if (present(MinOATHeating)) {
16071 33 : thisDXCoil.MinOATCompressor = MinOATHeating;
16072 : }
16073 :
16074 641 : if (present(HeatingPerformanceOATType)) {
16075 33 : thisDXCoil.HeatingPerformanceOATType = HeatingPerformanceOATType;
16076 : }
16077 :
16078 641 : if (present(DefrostStrategy)) {
16079 33 : thisDXCoil.DefrostStrategy = DefrostStrategy;
16080 : }
16081 :
16082 641 : if (present(DefrostControl)) {
16083 33 : thisDXCoil.DefrostControl = DefrostControl;
16084 : }
16085 :
16086 641 : if (present(DefrostEIRPtr)) {
16087 33 : thisDXCoil.DefrostEIRFT = DefrostEIRPtr;
16088 : }
16089 :
16090 641 : if (present(DefrostFraction)) {
16091 33 : thisDXCoil.DefrostTime = DefrostFraction;
16092 : }
16093 :
16094 641 : if (present(DefrostCapacity)) {
16095 33 : thisDXCoil.DefrostCapacity = DefrostCapacity;
16096 : }
16097 :
16098 641 : if (present(MaxOATDefrost)) {
16099 33 : thisDXCoil.MaxOATDefrost = MaxOATDefrost;
16100 : }
16101 :
16102 641 : if (present(CoolingCoilPresent)) {
16103 33 : thisDXCoil.CoolingCoilPresent = CoolingCoilPresent;
16104 : }
16105 :
16106 641 : if (present(HeatingCoilPresent)) {
16107 33 : thisDXCoil.HeatingCoilPresent = HeatingCoilPresent;
16108 : }
16109 :
16110 641 : if (present(HeatSizeRatio)) {
16111 0 : thisDXCoil.HeatSizeRatio = HeatSizeRatio;
16112 : }
16113 :
16114 641 : if (present(TotCap)) {
16115 0 : thisDXCoil.RatedTotCap(1) = TotCap;
16116 : }
16117 :
16118 641 : if (present(SupplyFanIndex)) {
16119 12 : thisDXCoil.SupplyFanIndex = SupplyFanIndex;
16120 : }
16121 :
16122 641 : if (present(SupplyFanName)) {
16123 12 : thisDXCoil.SupplyFanName = SupplyFanName;
16124 : }
16125 :
16126 641 : if (present(supplyFanType)) {
16127 12 : thisDXCoil.supplyFanType = supplyFanType;
16128 12 : if (thisDXCoil.SupplyFanIndex > 0) {
16129 12 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
16130 12 : thisDXCoil.Name,
16131 12 : thisDXCoil.DXCoilType,
16132 12 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->Name,
16133 12 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->type,
16134 : thisDXCoil.SupplyFanIndex);
16135 : }
16136 : }
16137 : }
16138 :
16139 1 : void SetCoilSystemHeatingDXFlag(EnergyPlusData &state,
16140 : std::string const &CoilType, // must match coil types in this module
16141 : std::string const &CoilName // must match coil names for the coil type
16142 : )
16143 : {
16144 :
16145 : // SUBROUTINE INFORMATION:
16146 : // AUTHOR B. Griffith
16147 : // DATE WRITTEN Jan. 2012
16148 :
16149 : // PURPOSE OF THIS SUBROUTINE:
16150 : // inform DX heating coil that is is part of a CoilSystem:Heating:DX
16151 : // and therefore it need not find its companion cooling coil
16152 :
16153 : // METHODOLOGY EMPLOYED:
16154 : // set value of logical flag FindCompanionUpStreamCoil to true
16155 :
16156 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16157 : int WhichCoil;
16158 :
16159 : // Obtains and Allocates DXCoils
16160 1 : if (state.dataDXCoils->GetCoilsInputFlag) {
16161 0 : GetDXCoils(state);
16162 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16163 : }
16164 :
16165 1 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
16166 1 : if (WhichCoil != 0) {
16167 1 : state.dataDXCoils->DXCoil(WhichCoil).FindCompanionUpStreamCoil = false;
16168 : } else {
16169 0 : ShowSevereError(state, format("SetCoilSystemHeatingDXFlag: Could not find Coil, Type=\"{}\"Name=\"{}\"", CoilType, CoilName));
16170 : }
16171 1 : }
16172 :
16173 2 : void SetCoilSystemCoolingData(EnergyPlusData &state,
16174 : std::string const &CoilName, // must match coil names for the coil type
16175 : std::string const &CoilSystemName)
16176 : {
16177 :
16178 : // SUBROUTINE INFORMATION:
16179 : // AUTHOR B. Griffith
16180 : // DATE WRITTEN July 2012
16181 :
16182 : // PURPOSE OF THIS SUBROUTINE:
16183 : // inform the child DX coil what the name of its parent is.
16184 :
16185 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16186 : int WhichCoil;
16187 :
16188 2 : if (state.dataDXCoils->GetCoilsInputFlag) {
16189 0 : GetDXCoils(state);
16190 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16191 : }
16192 :
16193 2 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
16194 2 : if (WhichCoil != 0) {
16195 2 : state.dataDXCoils->DXCoil(WhichCoil).CoilSystemName = CoilSystemName;
16196 : } else {
16197 0 : ShowSevereError(state, format("SetCoilSystemCoolingData: Could not find Coil \"Name=\"{}\"", CoilName));
16198 : }
16199 2 : }
16200 :
16201 3 : Real64 CalcSHRUserDefinedCurves(EnergyPlusData &state,
16202 : Real64 const InletDryBulb, // inlet air dry bulb temperature [C]
16203 : Real64 const InletWetBulb, // inlet air wet bulb temperature [C]
16204 : Real64 const AirMassFlowRatio, // ratio of actual air mass flow to rated air mass flow
16205 : int const SHRFTempCurveIndex, // SHR modifier curve index
16206 : int const SHRFFlowCurveIndex, // SHR modifier curve index
16207 : Real64 const SHRRated // rated sensible heat ratio, user input
16208 : )
16209 : {
16210 :
16211 : // SUBROUTINE INFORMATION:
16212 : // AUTHOR Bereket Nigusse, FSEC
16213 : // DATE WRITTEN December 2012
16214 :
16215 : // PURPOSE OF THIS FUNCTION:
16216 : // Returns the operating sensible heat ratio for a given Rated SHR and coil entering
16217 : // air DBT and WBT, and supply air mass flow fraction.
16218 :
16219 : // METHODOLOGY EMPLOYED:
16220 : // Model uses user specified rated SHR, and SHR modifying curves for temperature and flow
16221 : // fraction. The curves adjust the rated SHR based on biquadratic curve for temperatures
16222 : // and quadratic function for supply air mass flow ratio (actual vs rated).
16223 : // The biquadratic and quadratic curves are normalized curves generated from manufacturer's
16224 : // performance data
16225 :
16226 : // Using/Aliasing
16227 : using Curve::CurveValue;
16228 :
16229 : // Return value
16230 : Real64 SHRopr; // operating SHR, corrected for Temp and Flow Fraction
16231 :
16232 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16233 : Real64 SHRTempModFac; // Sensible Heat Ratio modifier (function of entering wetbulb, entering drybulb)
16234 : Real64 SHRFlowModFac; // Sensible Heat Ratio modifier (function of actual vs rated flow)
16235 :
16236 : // Get SHR modifying factor (function of inlet wetbulb & drybulb) for off-rated conditions
16237 3 : if (SHRFTempCurveIndex == 0) {
16238 3 : SHRTempModFac = 1.0;
16239 : } else {
16240 0 : SHRTempModFac = CurveValue(state, SHRFTempCurveIndex, InletWetBulb, InletDryBulb);
16241 0 : if (SHRTempModFac < 0.0) {
16242 0 : SHRTempModFac = 0.0;
16243 : }
16244 : }
16245 : // Get SHR modifying factor (function of mass flow ratio) for off-rated conditions
16246 3 : if (SHRFFlowCurveIndex == 0) {
16247 3 : SHRFlowModFac = 1.0;
16248 : } else {
16249 0 : SHRFlowModFac = CurveValue(state, SHRFFlowCurveIndex, AirMassFlowRatio);
16250 0 : if (SHRFlowModFac < 0.0) {
16251 0 : SHRFlowModFac = 0.0;
16252 : }
16253 : }
16254 : // Calculate "operating" sensible heat ratio
16255 3 : SHRopr = SHRRated * SHRTempModFac * SHRFlowModFac;
16256 :
16257 3 : if (SHRopr < 0.0) {
16258 0 : SHRopr = 0.0; // SHR cannot be less than zero
16259 : }
16260 3 : if (SHRopr > 1.0) {
16261 0 : SHRopr = 1.0; // SHR cannot be greater than 1.0
16262 : }
16263 :
16264 3 : return SHRopr;
16265 : }
16266 :
16267 0 : void SetDXCoilTypeData(EnergyPlusData &state, std::string const &CoilName) // must match coil names for the coil type
16268 : {
16269 :
16270 : // SUBROUTINE INFORMATION:
16271 : // AUTHOR B. Nigusse
16272 : // DATE WRITTEN January 2013
16273 :
16274 : // PURPOSE OF THIS SUBROUTINE:
16275 : // inform the child DX coil if the DX cooling coil is for 100% DOAS application.
16276 :
16277 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16278 : int WhichCoil;
16279 :
16280 0 : if (state.dataDXCoils->GetCoilsInputFlag) {
16281 0 : GetDXCoils(state);
16282 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16283 : }
16284 :
16285 0 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
16286 0 : if (WhichCoil != 0) {
16287 0 : state.dataDXCoils->DXCoil(WhichCoil).ISHundredPercentDOASDXCoil = true;
16288 : } else {
16289 : // DXCoil(WhichCoil)%ISHundredPercentDOASDXCoil = .FALSE. //Autodesk:BoundsViolation DXCoil(0): DXCoil is not allocated with a 0
16290 : // element: Commented out
16291 0 : ShowSevereError(state, format("SetDXCoilTypeData: Could not find Coil \"Name=\"{}\"", CoilName));
16292 : }
16293 0 : }
16294 :
16295 5 : void CalcSecondaryDXCoils(EnergyPlusData &state, int const DXCoilNum)
16296 : {
16297 :
16298 : // SUBROUTINE INFORMATION:
16299 : // AUTHOR B. Nigusse
16300 : // DATE WRITTEN February 2015
16301 :
16302 : // PURPOSE OF THIS SUBROUTINE:
16303 : // Calculates secondary zone heat gain from secondary DX coils placed in a zone.
16304 :
16305 : // METHODOLOGY EMPLOYED:
16306 : // Energy balance:
16307 : // (1) Condenser placed in a zone, the zone total (sensible) heat
16308 : // gain rate is given Qcond = QEvap + WcompPluscondFanPower
16309 : // (2) Evaporator placed in a zone, the zone total heat removal
16310 : // rate is given Qevap = Qcond - WcompPluscondFanPower
16311 : // Furthermore, the evaporator total heat removal is split into
16312 : // latent and sensible components using user specified SHR
16313 :
16314 : // Using/Aliasing
16315 : using Curve::CurveValue;
16316 :
16317 : // SUBROUTINE PARAMETER DEFINITIONS:
16318 : static constexpr std::string_view RoutineName("CalcSecondaryDXCoils");
16319 :
16320 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16321 : Real64 CondInletDryBulb; // condenser entering air dry-bulb temperature (C)
16322 : Real64 EvapAirMassFlow; // Condenser air mass flow rate [kg/s]
16323 : Real64 EvapInletDryBulb; // evaporator inlet air drybulb [C]
16324 : Real64 EvapInletHumRat; // evaporator inlet air humidity ratio [kg/kg]
16325 : Real64 EvapInletWetBulb; // evaporator inlet air wetbulb [C]
16326 : Real64 EvapInletEnthalpy; // evaporator inlet air enthalpy [J/kg]
16327 : Real64 FullLoadOutAirEnth; // evaporator outlet full load enthalpy [J/kg]
16328 : Real64 FullLoadOutAirHumRat; // evaporator outlet humidity ratio at full load
16329 : Real64 FullLoadOutAirTemp; // evaporator outlet air temperature at full load [C]
16330 : Real64 hTinwout; // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
16331 5 : Real64 SHR(0); // sensible heat ratio
16332 : Real64 RhoAir; // secondary coil entering air density [kg/m3]
16333 5 : Real64 PartLoadRatio(0); // primary coil part-load ratio [-]
16334 : Real64 SecCoilRatedSHR; // secondary DX coil nominal or rated sensible heat ratio
16335 : Real64 SecCoilFlowFraction; // secondary coil flow fraction, is 1.0 for single speed machine
16336 : Real64 TotalHeatRemovalRate; // secondary coil total heat removal rate
16337 : Real64 TotalHeatRejectionRate; // secondary coil total heat rejection rate
16338 : int SecCoilSHRFT; // index of the SHR modifier curve for temperature of a secondary DX coil
16339 : int SecCoilSHRFF; // index of the sHR modifier curve for flow fraction of a secondary DX coil
16340 : int MSSpeedNumLS; // current low speed number of multispeed HP
16341 : int MSSpeedNumHS; // current high speed number of multispeed HP
16342 : Real64 MSSpeedRatio; // current speed ratio of multispeed HP
16343 : Real64 MSCycRatio; // current cycling ratio of multispeed HP
16344 : Real64 SHRHighSpeed; // sensible heat ratio at high speed
16345 : Real64 SHRLowSpeed; // sensible heat ratio at low speed
16346 :
16347 5 : EvapAirMassFlow = 0.0;
16348 :
16349 5 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
16350 :
16351 5 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
16352 5 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
16353 : // Select the correct unit type
16354 5 : switch (thisDXCoil.DXCoilType_Num) {
16355 3 : case HVAC::CoilDX_CoolingSingleSpeed:
16356 : case HVAC::CoilDX_CoolingTwoSpeed:
16357 : case HVAC::CoilDX_MultiSpeedCooling: {
16358 : // total sensible heat gain of the secondary zone from the secondary coil (condenser)
16359 3 : if (thisDXCoil.ElecCoolingPower > 0.0) {
16360 3 : TotalHeatRejectionRate = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
16361 : } else {
16362 0 : TotalHeatRejectionRate = 0.0;
16363 0 : return;
16364 : }
16365 3 : thisDXCoil.SecCoilSensibleHeatGainRate = TotalHeatRejectionRate;
16366 3 : } break;
16367 1 : case HVAC::CoilDX_HeatingEmpirical: {
16368 : // evaporator coil in the secondary zone
16369 1 : if (thisDXCoil.ElecHeatingPower > 0.0) {
16370 1 : TotalHeatRemovalRate = max(0.0, thisDXCoil.TotalHeatingEnergyRate - thisDXCoil.ElecHeatingPower);
16371 : } else {
16372 0 : TotalHeatRemovalRate = 0.0;
16373 0 : thisDXCoil.SecCoilSHR = 0.0;
16374 0 : return;
16375 : }
16376 1 : thisDXCoil.SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower;
16377 1 : EvapInletDryBulb = secZoneHB.ZT;
16378 1 : EvapInletHumRat = secZoneHB.airHumRat;
16379 1 : RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat);
16380 1 : EvapAirMassFlow = RhoAir * thisDXCoil.SecCoilAirFlow;
16381 : ;
16382 1 : PartLoadRatio = thisDXCoil.CompressorPartLoadRatio;
16383 1 : SecCoilRatedSHR = thisDXCoil.SecCoilRatedSHR;
16384 1 : if ((EvapAirMassFlow > HVAC::SmallMassFlow) && (PartLoadRatio > 0.0) &&
16385 1 : (EvapInletDryBulb > thisDXCoil.MinOATCompressor)) { // coil is running
16386 1 : SecCoilFlowFraction = 1.0; // for single speed DX coil the secondary coil (condenser) flow fraction is 1.0
16387 1 : CondInletDryBulb = state.dataLoopNodes->Node(thisDXCoil.AirInNode).Temp;
16388 1 : EvapInletWetBulb = PsyTwbFnTdbWPb(state, EvapInletDryBulb, EvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
16389 1 : EvapInletEnthalpy = PsyHFnTdbW(EvapInletDryBulb, EvapInletHumRat);
16390 1 : SecCoilSHRFT = thisDXCoil.SecCoilSHRFT;
16391 1 : SecCoilSHRFF = thisDXCoil.SecCoilSHRFF;
16392 : // determine the current SHR
16393 1 : SHR = CalcSecondaryDXCoilsSHR(state,
16394 : DXCoilNum,
16395 : EvapAirMassFlow,
16396 : TotalHeatRemovalRate,
16397 : PartLoadRatio,
16398 : SecCoilRatedSHR,
16399 : EvapInletDryBulb,
16400 : EvapInletHumRat,
16401 : EvapInletWetBulb,
16402 : EvapInletEnthalpy,
16403 : CondInletDryBulb,
16404 : SecCoilFlowFraction,
16405 : SecCoilSHRFT,
16406 : SecCoilSHRFF);
16407 : // Calculate full load output conditions
16408 1 : FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16409 1 : hTinwout = EvapInletEnthalpy - (1.0 - SHR) * ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
16410 1 : FullLoadOutAirHumRat = PsyWFnTdbH(state, EvapInletDryBulb, hTinwout, RoutineName, true);
16411 1 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
16412 : // when the air outlet temperature falls below the saturation temperature, it is reset to saturation temperature
16413 1 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
16414 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName);
16415 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
16416 : // Adjust SHR for the new outlet condition that balances energy
16417 0 : hTinwout = PsyHFnTdbW(EvapInletDryBulb, FullLoadOutAirHumRat);
16418 0 : SHR = 1.0 - (EvapInletEnthalpy - hTinwout) / ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
16419 0 : SHR = min(SHR, 1.0);
16420 : }
16421 : // calculate the sensible and latent zone heat removal (extraction) rate by the secondary coil
16422 1 : thisDXCoil.SecCoilSensibleHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate * SHR;
16423 1 : thisDXCoil.SecCoilLatentHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate - thisDXCoil.SecCoilSensibleHeatRemovalRate;
16424 : } else {
16425 : // DX coil is off;
16426 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
16427 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
16428 0 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
16429 0 : SHR = 0.0; // SHR is set to zero if the coil is off
16430 : }
16431 1 : thisDXCoil.SecCoilSHR = SHR;
16432 1 : } break;
16433 1 : case HVAC::CoilDX_MultiSpeedHeating: {
16434 1 : EvapInletDryBulb = secZoneHB.ZT;
16435 1 : EvapInletHumRat = secZoneHB.airHumRat;
16436 1 : RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat);
16437 1 : MSSpeedRatio = thisDXCoil.MSSpeedRatio;
16438 1 : MSCycRatio = thisDXCoil.MSCycRatio;
16439 1 : MSSpeedNumHS = thisDXCoil.MSSpeedNumHS;
16440 1 : MSSpeedNumLS = thisDXCoil.MSSpeedNumLS;
16441 1 : if (MSSpeedRatio > 0.0) {
16442 0 : EvapAirMassFlow = RhoAir * (thisDXCoil.MSSecCoilAirFlow(MSSpeedNumHS) * MSSpeedRatio +
16443 0 : thisDXCoil.MSSecCoilAirFlow(MSSpeedNumLS) * (1.0 - MSSpeedRatio));
16444 1 : } else if (MSCycRatio > 0.0) {
16445 1 : EvapAirMassFlow = RhoAir * thisDXCoil.MSSecCoilAirFlow(MSSpeedNumLS);
16446 : }
16447 1 : if (thisDXCoil.ElecHeatingPower > 0.0) {
16448 1 : TotalHeatRemovalRate = max(0.0, thisDXCoil.TotalHeatingEnergyRate - thisDXCoil.ElecHeatingPower);
16449 : } else {
16450 0 : TotalHeatRemovalRate = 0.0;
16451 0 : return;
16452 : }
16453 1 : thisDXCoil.SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower;
16454 1 : if ((EvapAirMassFlow > HVAC::SmallMassFlow) && (MSSpeedRatio > 0.0 || MSCycRatio > 0.0) &&
16455 1 : (EvapInletDryBulb > thisDXCoil.MinOATCompressor)) { // coil is running
16456 1 : SecCoilFlowFraction = 1.0; // for single speed DX coil the secondary coil (condenser) flow fraction is 1.0
16457 1 : CondInletDryBulb = state.dataLoopNodes->Node(thisDXCoil.AirInNode).Temp;
16458 1 : EvapInletWetBulb = PsyTwbFnTdbWPb(state, EvapInletDryBulb, EvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
16459 1 : EvapInletEnthalpy = PsyHFnTdbW(EvapInletDryBulb, EvapInletHumRat);
16460 : // determine the current SHR
16461 1 : if (MSSpeedRatio > 0.0) {
16462 : // calculate SHR for the higher speed
16463 0 : PartLoadRatio = 1.0;
16464 0 : SecCoilFlowFraction = 1.0;
16465 0 : SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumHS);
16466 0 : SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumHS);
16467 0 : SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumHS);
16468 0 : SHRHighSpeed = CalcSecondaryDXCoilsSHR(state,
16469 : DXCoilNum,
16470 : EvapAirMassFlow,
16471 : TotalHeatRemovalRate,
16472 : PartLoadRatio,
16473 : SecCoilRatedSHR,
16474 : EvapInletDryBulb,
16475 : EvapInletHumRat,
16476 : EvapInletWetBulb,
16477 : EvapInletEnthalpy,
16478 : CondInletDryBulb,
16479 : SecCoilFlowFraction,
16480 : SecCoilSHRFT,
16481 : SecCoilSHRFF);
16482 : // calculate SHR for the lower speed
16483 0 : SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumLS);
16484 0 : SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumLS);
16485 0 : SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumLS);
16486 0 : SHRLowSpeed = CalcSecondaryDXCoilsSHR(state,
16487 : DXCoilNum,
16488 : EvapAirMassFlow,
16489 : TotalHeatRemovalRate,
16490 : PartLoadRatio,
16491 : SecCoilRatedSHR,
16492 : EvapInletDryBulb,
16493 : EvapInletHumRat,
16494 : EvapInletWetBulb,
16495 : EvapInletEnthalpy,
16496 : CondInletDryBulb,
16497 : SecCoilFlowFraction,
16498 : SecCoilSHRFT,
16499 : SecCoilSHRFF);
16500 0 : SHR = SHRHighSpeed * MSSpeedRatio + SHRLowSpeed * (1.0 - MSSpeedRatio);
16501 :
16502 1 : } else if (MSCycRatio > 0.0) {
16503 : // calculate SHR for the lower speed
16504 1 : PartLoadRatio = MSCycRatio;
16505 1 : SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumLS);
16506 1 : SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumLS);
16507 1 : SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumLS);
16508 1 : SecCoilFlowFraction = 1.0;
16509 1 : SHRLowSpeed = CalcSecondaryDXCoilsSHR(state,
16510 : DXCoilNum,
16511 : EvapAirMassFlow,
16512 : TotalHeatRemovalRate,
16513 : MSCycRatio,
16514 : SecCoilRatedSHR,
16515 : EvapInletDryBulb,
16516 : EvapInletHumRat,
16517 : EvapInletWetBulb,
16518 : EvapInletEnthalpy,
16519 : CondInletDryBulb,
16520 : SecCoilFlowFraction,
16521 : SecCoilSHRFT,
16522 : SecCoilSHRFF);
16523 1 : SHR = SHRLowSpeed;
16524 : }
16525 : // Calculate full load output conditions
16526 1 : FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16527 1 : hTinwout = EvapInletEnthalpy - (1.0 - SHR) * ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
16528 1 : FullLoadOutAirHumRat = PsyWFnTdbH(state, EvapInletDryBulb, hTinwout, RoutineName, true);
16529 1 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
16530 : // when the air outlet temperature falls below the saturation temperature, it is reset to saturation temperature
16531 1 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
16532 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName);
16533 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
16534 : // Adjust SHR for the new outlet condition that balances energy
16535 0 : hTinwout = PsyHFnTdbW(EvapInletDryBulb, FullLoadOutAirHumRat);
16536 0 : SHR = 1.0 - (EvapInletEnthalpy - hTinwout) / (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16537 0 : SHR = min(SHR, 1.0);
16538 : }
16539 : // calculate the sensible and latent zone heat removal (extraction) rate by the secondary coil
16540 1 : thisDXCoil.SecCoilSensibleHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate * SHR;
16541 1 : thisDXCoil.SecCoilLatentHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate - thisDXCoil.SecCoilSensibleHeatRemovalRate;
16542 : } else {
16543 : // DX coil is off;
16544 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
16545 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
16546 0 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
16547 0 : SHR = 0.0; // SHR is set to rated value if the coil is off
16548 : }
16549 1 : thisDXCoil.SecCoilSHR = SHR;
16550 1 : } break;
16551 0 : default:
16552 0 : break;
16553 : }
16554 :
16555 : } else {
16556 0 : thisDXCoil.SecCoilSensibleHeatGainRate = 0.0;
16557 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
16558 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
16559 0 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
16560 : }
16561 : }
16562 :
16563 3 : Real64 CalcSecondaryDXCoilsSHR(EnergyPlusData &state,
16564 : [[maybe_unused]] int const DXCoilNum,
16565 : Real64 const EvapAirMassFlow,
16566 : Real64 const TotalHeatRemovalRate,
16567 : Real64 const PartLoadRatio,
16568 : Real64 const SecCoilRatedSHR,
16569 : Real64 const EvapInletDryBulb,
16570 : Real64 const EvapInletHumRat,
16571 : Real64 const EvapInletWetBulb,
16572 : Real64 const EvapInletEnthalpy,
16573 : Real64 const CondInletDryBulb,
16574 : Real64 const SecCoilFlowFraction,
16575 : int const SecCoilSHRFT,
16576 : int const SecCoilSHRFF)
16577 : {
16578 :
16579 : // SUBROUTINE INFORMATION:
16580 : // AUTHOR B. Nigusse
16581 : // DATE WRITTEN February 2015
16582 :
16583 : // PURPOSE OF THIS SUBROUTINE:
16584 : // Calculates secondary coil (evaporator) sensible heat ratio.
16585 :
16586 : // METHODOLOGY EMPLOYED:
16587 : // Energy balance:
16588 : // (1) checks if the secondary coil operation is dry and calculates applicable SHR.
16589 : // (2) determines SHR from user specified rated SHR values and SHR modifier curves for
16590 : // temperature and flow fraction.
16591 : // (3) if secondary coil operates dry then the larger of the user SHR value and dry
16592 : // coil operation SHR is selected.
16593 :
16594 : // Using/Aliasing
16595 : using Curve::CurveValue;
16596 :
16597 : // SUBROUTINE PARAMETER DEFINITIONS:
16598 3 : int constexpr MaxIter(30);
16599 3 : Real64 constexpr RelaxationFactor(0.4);
16600 3 : Real64 constexpr Tolerance(0.1);
16601 3 : Real64 constexpr DryCoilTestEvapInletHumRatReset(0.00001);
16602 : static constexpr std::string_view RoutineName("CalcSecondaryDXCoilsSHR");
16603 :
16604 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16605 : Real64 DryCoilTestEvapInletHumRat; // evaporator coil inlet humidity ratio test for dry coil
16606 : Real64 DryCoilTestEvapInletWetBulb; // evaporator coil inlet dry bulb temperature test for dry coil
16607 : Real64 FullLoadOutAirEnth; // evaporator outlet full load enthalpy [J/kg]
16608 : Real64 FullLoadOutAirTemp; // evaporator outlet air temperature at full load [C]
16609 : Real64 hTinwADP; // enthalpy of air at secondary coil entering temperature and Humidity ratio at ADP
16610 : Real64 SHRadp; // Sensible heat ratio
16611 : Real64 hADP; // enthalpy of air at secondary coil at ADP
16612 : Real64 tADP; // dry bulb temperature of air at secondary coil at ADP
16613 : Real64 wADP; // humidity ratio of air at secondary coil at ADP
16614 : Real64 HumRatError; // humidity ratio error
16615 : bool CoilMightBeDry; // TRUE means the secondary DX coil runs dry
16616 : int Counter; // iteration counter
16617 : bool Converged; // convergence flag
16618 : Real64 SHR; // current time step sensible heat ratio of secondary coil
16619 :
16620 3 : CoilMightBeDry = false;
16621 3 : FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16622 3 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, EvapInletHumRat);
16623 3 : if (FullLoadOutAirTemp > PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
16624 3 : CoilMightBeDry = true;
16625 : // find wADP, humidity ratio at apparatus dewpoint and inlet hum rat that would have dry coil
16626 3 : DryCoilTestEvapInletHumRat = EvapInletHumRat;
16627 3 : DryCoilTestEvapInletWetBulb = EvapInletWetBulb;
16628 3 : Counter = 0;
16629 3 : Converged = false;
16630 6 : while (!Converged) {
16631 : // assumes coil bypass factor (CBF) = 0.0
16632 3 : hADP = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16633 3 : tADP = PsyTsatFnHPb(state, hADP, state.dataEnvrn->OutBaroPress, RoutineName);
16634 3 : wADP = min(EvapInletHumRat, PsyWFnTdbH(state, tADP, hADP, RoutineName));
16635 3 : hTinwADP = PsyHFnTdbW(EvapInletDryBulb, wADP);
16636 3 : if ((EvapInletEnthalpy - hADP) > 1.e-10) {
16637 3 : SHRadp = min((hTinwADP - hADP) / (EvapInletEnthalpy - hADP), 1.0);
16638 : } else {
16639 0 : SHRadp = 1.0;
16640 : }
16641 3 : if ((wADP > DryCoilTestEvapInletHumRat) || (Counter >= 1 && Counter < MaxIter)) {
16642 0 : if (DryCoilTestEvapInletHumRat <= 0.0) {
16643 0 : DryCoilTestEvapInletHumRat = DryCoilTestEvapInletHumRatReset;
16644 : }
16645 0 : HumRatError = (DryCoilTestEvapInletHumRat - wADP) / DryCoilTestEvapInletHumRat;
16646 0 : DryCoilTestEvapInletHumRat = RelaxationFactor * wADP + (1.0 - RelaxationFactor) * DryCoilTestEvapInletHumRat;
16647 : DryCoilTestEvapInletWetBulb =
16648 0 : PsyTwbFnTdbWPb(state, EvapInletDryBulb, DryCoilTestEvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
16649 0 : ++Counter;
16650 0 : if (std::abs(HumRatError) <= Tolerance) {
16651 0 : Converged = true;
16652 : } else {
16653 0 : Converged = false;
16654 : }
16655 : } else {
16656 3 : Converged = true;
16657 : }
16658 : }
16659 : }
16660 : // determine SHR from user specified nominal value and SHR modifier curves
16661 3 : SHR = CalcSHRUserDefinedCurves(state, CondInletDryBulb, EvapInletWetBulb, SecCoilFlowFraction, SecCoilSHRFT, SecCoilSHRFF, SecCoilRatedSHR);
16662 3 : if (CoilMightBeDry) {
16663 3 : if ((EvapInletHumRat < DryCoilTestEvapInletHumRat) && (SHRadp > SHR)) { // coil is dry for sure
16664 0 : SHR = 1.0;
16665 3 : } else if (SHRadp > SHR) {
16666 0 : SHR = SHRadp;
16667 : }
16668 : }
16669 3 : return SHR;
16670 : }
16671 :
16672 23659 : void CalcVRFCoolingCoil_FluidTCtrl(EnergyPlusData &state,
16673 : int const DXCoilNum, // the number of the DX coil to be simulated
16674 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
16675 : bool const FirstHVACIteration, // true if this is the first iteration of HVAC
16676 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
16677 : HVAC::FanOp const fanOp, // Allows parent object to control fan operation
16678 : Real64 const CompCycRatio, // cycling ratio of VRF condenser
16679 : ObjexxFCL::Optional_int_const PerfMode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
16680 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
16681 : Real64 MaxCoolCap // maximum allowed cooling capacity
16682 : )
16683 : {
16684 : // SUBROUTINE INFORMATION:
16685 : // AUTHOR Xiufeng Pang, LBNL
16686 : // DATE WRITTEN Jan 2013
16687 : // MODIFIED Nov 2015, RP Zhang, LBNL
16688 :
16689 : // PURPOSE OF THIS SUBROUTINE:
16690 : // Calculates the air-side performance of a direct-expansion, air-cooled
16691 : // VRF terminal unit cooling coil, for the VRF_FluidTCtrl model.
16692 :
16693 : // METHODOLOGY EMPLOYED:
16694 : // This subroutine is derived from CalcVRFCoolingCoil, and implements the new VRF model for FluidTCtrl.
16695 :
16696 : // Using/Aliasing
16697 : using Curve::CurveValue;
16698 23659 : Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
16699 23659 : Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
16700 : using General::CreateSysTimeIntervalString;
16701 :
16702 : using namespace HVACVariableRefrigerantFlow;
16703 :
16704 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16705 :
16706 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
16707 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
16708 : // (average flow if cycling fan, full flow if constant fan)
16709 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
16710 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
16711 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
16712 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
16713 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
16714 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
16715 : Real64 RatedCBF; // coil bypass factor at rated conditions
16716 : Real64 CBF; // coil bypass factor at off rated conditions
16717 : Real64 A0; // NTU * air mass flow rate, used in CBF calculation
16718 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
16719 : Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
16720 : // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
16721 : Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
16722 : // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
16723 : Real64 CondAirMassFlow; // Condenser air mass flow rate [kg/s]
16724 : Real64 RhoAir; // Density of air [kg/m3]
16725 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
16726 23659 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
16727 : Real64 AirFlowRatio; // ratio of compressor on airflow to average timestep airflow
16728 : // used when constant fan mode yields different air flow rates when compressor is ON and OFF
16729 : // (e.g. Packaged Terminal Heat Pump)
16730 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
16731 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
16732 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
16733 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
16734 :
16735 : int Mode; // Performance mode for Multimode DX coil; Always 1 for other coil types
16736 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
16737 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
16738 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
16739 : Real64 ADiff; // Used for exponential
16740 :
16741 : // Followings for VRF FluidTCtrl Only
16742 : Real64 QCoilReq; // Coil load (W)
16743 : Real64 FanSpdRatio; // Fan speed ratio
16744 : Real64 AirMassFlowMin; // Min air mass flow rate due to OA requirement [kg/s]
16745 : Real64 ActualSH; // Super heating degrees (C)
16746 : Real64 ActualSC; // Sub cooling degrees (C)
16747 :
16748 : // If Performance mode not present, then set to 1. Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
16749 23659 : if (present(PerfMode)) {
16750 0 : Mode = PerfMode;
16751 : } else {
16752 23659 : Mode = 1;
16753 : }
16754 :
16755 : // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
16756 : // during cooling and when no cooling is required (constant fan, fan speed changes)
16757 23659 : if (present(OnOffAirFlowRatio)) {
16758 0 : AirFlowRatio = OnOffAirFlowRatio;
16759 : } else {
16760 23659 : AirFlowRatio = 1.0;
16761 : }
16762 :
16763 23659 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
16764 :
16765 : // Initialize coil air side parameters
16766 23659 : CondInletTemp = 0.0;
16767 23659 : CondInletHumRat = 0.0;
16768 23659 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
16769 23659 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
16770 23659 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
16771 23659 : InletAirHumRat = thisDXCoil.InletAirHumRat;
16772 23659 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
16773 23659 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
16774 23659 : thisDXCoil.PartLoadRatio = 0.0;
16775 23659 : thisDXCoil.BasinHeaterPower = 0.0;
16776 23659 : thisDXCoil.EvaporatingTemp = state.dataHVACVarRefFlow->VRF(thisDXCoil.VRFOUPtr).IUEvaporatingTemp;
16777 :
16778 23659 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
16779 0 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
16780 0 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
16781 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
16782 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
16783 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
16784 : } else {
16785 0 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
16786 : // If node is not connected to anything, pressure = default, use weather data
16787 0 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
16788 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
16789 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
16790 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
16791 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
16792 : } else {
16793 0 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
16794 0 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
16795 : }
16796 : }
16797 : } else {
16798 23659 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
16799 23659 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
16800 23659 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
16801 23659 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
16802 : }
16803 :
16804 23659 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
16805 0 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
16806 0 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
16807 : // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
16808 0 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
16809 0 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
16810 0 : CompAmbTemp = OutdoorDryBulb;
16811 : } else { // for air or water-cooled, inlet temp is stored in OutdoorDryBulb temp
16812 23659 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp or water inlet temp
16813 23659 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
16814 0 : CompAmbTemp = state.dataEnvrn->OutDryBulbTemp; // for crankcase heater use actual outdoor temp for water-cooled
16815 : } else {
16816 23659 : CompAmbTemp = OutdoorDryBulb;
16817 : }
16818 : }
16819 :
16820 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
16821 : // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
16822 23659 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
16823 32 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
16824 32 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
16825 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
16826 : }
16827 : } else {
16828 23627 : CrankcaseHeatingPower = 0.0;
16829 : }
16830 :
16831 : // calculate end time of current time step to determine if error messages should be printed
16832 23659 : state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
16833 :
16834 : // The following checks are not necessary for VRF-FluidTCtrl model. (1) OAT check is already performed in the VRF OU routines (2)
16835 : // VRF-FluidTCtrl model is physics based, not system curve based, and thus doesn't require special performance curves for operations at
16836 : // low inlet temperatures
16837 : // Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
16838 : // Wait for next time step to print warnings. If simulation iterates, print out
16839 : // the warning for the last iteration only. Must wait for next time step to accomplish this.
16840 : // If a warning occurs and the simulation down shifts, the warning is not valid.
16841 : // if ( DXCoil( DXCoilNum ).PrintLowAmbMessage ) { // .AND. &
16842 : // if ( CurrentEndTime > DXCoil( DXCoilNum ).CurrentEndTimeLast && TimeStepSys >= DXCoil( DXCoilNum ).TimeStepSysLast ) {
16843 : // if ( DXCoil( DXCoilNum ).LowAmbErrIndex == 0 ) {
16844 : // ShowWarningMessage(state, DXCoil( DXCoilNum ).LowAmbBuffer1 );
16845 : // ShowContinueError(state, DXCoil( DXCoilNum ).LowAmbBuffer2 );
16846 : // ShowContinueError(state, "... Operation at low inlet temperatures may require special performance curves." );
16847 : // }
16848 : // ShowRecurringWarningErrorAtEnd(state, DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Low condenser inlet
16849 : // temperature error continues...", DXCoil( DXCoilNum ).LowAmbErrIndex, DXCoil( DXCoilNum ).LowTempLast, DXCoil( DXCoilNum ).LowTempLast,
16850 : // _,
16851 : // "[C]", "[C]" );
16852 : // }
16853 : // }
16854 : //
16855 : // if ( DXCoil( DXCoilNum ).PrintHighAmbMessage ) { // .AND. &
16856 : // if ( CurrentEndTime > DXCoil( DXCoilNum ).CurrentEndTimeLast && TimeStepSys >= DXCoil( DXCoilNum ).TimeStepSysLast ) {
16857 : // if ( DXCoil( DXCoilNum ).HighAmbErrIndex == 0 ) {
16858 : // ShowWarningMessage(state, DXCoil( DXCoilNum ).HighAmbBuffer1 );
16859 : // ShowContinueError(state, DXCoil( DXCoilNum ).HighAmbBuffer2 );
16860 : // ShowContinueError(state, "... Operation at high inlet temperatures may require special performance curves." );
16861 : // }
16862 : // ShowRecurringWarningErrorAtEnd(state, DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - High condenser inlet
16863 : // temperature error continues...", DXCoil( DXCoilNum ).HighAmbErrIndex, DXCoil( DXCoilNum ).HighTempLast, DXCoil( DXCoilNum
16864 : // ).HighTempLast,
16865 : // _, "[C]", "[C]" );
16866 : // }
16867 : // }
16868 :
16869 23659 : if (thisDXCoil.PrintLowOutTempMessage) {
16870 0 : if ((state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime > thisDXCoil.CurrentEndTimeLast) &&
16871 0 : (TimeStepSys >= thisDXCoil.TimeStepSysLast)) {
16872 0 : if (thisDXCoil.LowOutletTempIndex == 0) {
16873 0 : ShowWarningMessage(state, thisDXCoil.LowOutTempBuffer1);
16874 0 : ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
16875 0 : ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
16876 0 : ShowContinueError(state,
16877 0 : format(" 1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
16878 0 : thisDXCoil.FullLoadInletAirTempLast));
16879 0 : ShowContinueError(state, " 2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
16880 0 : ShowContinueError(state,
16881 : " 3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
16882 : }
16883 0 : ShowRecurringWarningErrorAtEnd(state,
16884 0 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
16885 : "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
16886 : "Outlet air temperature statistics follow:",
16887 0 : thisDXCoil.LowOutletTempIndex,
16888 0 : thisDXCoil.FullLoadOutAirTempLast,
16889 0 : thisDXCoil.FullLoadOutAirTempLast);
16890 : }
16891 : }
16892 :
16893 : // save last system time step and last end time of current time step (used to determine if warning is valid)
16894 23659 : thisDXCoil.TimeStepSysLast = TimeStepSys;
16895 23659 : thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime;
16896 23659 : thisDXCoil.PrintLowAmbMessage = false;
16897 23659 : thisDXCoil.PrintLowOutTempMessage = false;
16898 :
16899 23659 : if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
16900 : (compressorOp == HVAC::CompressorOp::On)) { // for cycling fan, reset mass flow to full on rate
16901 :
16902 10299 : if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
16903 0 : ShowFatalError(state, format("{} \"{}\" - Rated total cooling capacity is zero or less.", thisDXCoil.DXCoilType, thisDXCoil.Name));
16904 : }
16905 :
16906 10299 : TotCap = min(MaxCoolCap, thisDXCoil.RatedTotCap(Mode));
16907 :
16908 10299 : QCoilReq = -PartLoadRatio * TotCap;
16909 10299 : if (PartLoadRatio == 0.0) {
16910 0 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
16911 : } else {
16912 10299 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
16913 : }
16914 :
16915 : // Call ControlVRFIUCoil to calculate: (1) FanSpdRatio, (2) coil inlet/outlet conditions, and (3) SH/SC
16916 10299 : ControlVRFIUCoil(state,
16917 : DXCoilNum,
16918 : QCoilReq,
16919 : thisDXCoil.InletAirTemp,
16920 : thisDXCoil.InletAirHumRat,
16921 : thisDXCoil.EvaporatingTemp,
16922 : AirMassFlowMin,
16923 : FanSpdRatio,
16924 : OutletAirHumRat,
16925 : OutletAirTemp,
16926 : OutletAirEnthalpy,
16927 : ActualSH,
16928 : ActualSC);
16929 10299 : AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
16930 :
16931 10299 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
16932 10299 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
16933 : // VolFlowperRatedTotCap was checked at the initialization step
16934 : // No need to check VolFlowperRatedTotCap at the simulation
16935 : // New VRF_FluidTCtrl model implements VAV fan which can vary air flow rate during simulation
16936 :
16937 10299 : RatedCBF = thisDXCoil.RatedCBF(Mode);
16938 10299 : if (RatedCBF > 0.0) {
16939 10299 : A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
16940 : } else {
16941 0 : A0 = 0.0;
16942 : }
16943 10299 : ADiff = -A0 / AirMassFlow;
16944 10299 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
16945 7714 : CBF = std::exp(ADiff);
16946 : } else {
16947 2585 : CBF = 0.0;
16948 : }
16949 :
16950 : // The following checks are not necessary for VRF-FluidTCtrl model. (1) OAT check is already performed in the VRF OU routines (2)
16951 : // VRF-FluidTCtrl model is physics based, not system curve based, and thus doesn't require special performance curves for operations
16952 : // at low inlet temperatures
16953 : // // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
16954 : // if ( OutdoorDryBulb < DXCoil( DXCoilNum ).MinOATCompressor && ! WarmupFlag ) {
16955 : // DXCoil( DXCoilNum ).PrintLowAmbMessage = true;
16956 : // DXCoil( DXCoilNum ).LowTempLast = OutdoorDryBulb;
16957 : // if ( DXCoil( DXCoilNum ).LowAmbErrIndex == 0 ) {
16958 : // DXCoil( DXCoilNum ).LowAmbBuffer1 = DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Condenser
16959 : // inlet temperature below " + RoundSigDigits( DXCoil( DXCoilNum ).MinOATCompressor, 2 ) + " C. Condenser inlet temperature = " +
16960 : // RoundSigDigits( OutdoorDryBulb, 2 );
16961 : // DXCoil( DXCoilNum ).LowAmbBuffer2 = " ... Occurrence info = " + EnvironmentName + ", " + CurMnDy + " " +
16962 : // CreateSysTimeIntervalString();
16963 : // }
16964 : // }
16965 : //
16966 : // // check boundary for high ambient temperature and post warnings to individual DX coil buffers to print at end of time step
16967 : // if ( OutdoorDryBulb > DXCoil( DXCoilNum ).MaxOATCompressor && ! WarmupFlag ) {
16968 : // DXCoil( DXCoilNum ).PrintHighAmbMessage = true;
16969 : // DXCoil( DXCoilNum ).HighTempLast = OutdoorDryBulb;
16970 : // if ( DXCoil( DXCoilNum ).HighAmbErrIndex == 0 ) {
16971 : // DXCoil( DXCoilNum ).HighAmbBuffer1 = DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Condenser
16972 : // inlet temperature above " + RoundSigDigits( DXCoil( DXCoilNum ).MaxOATCompressor, 2 ) + " C. Condenser temperature = " +
16973 : // RoundSigDigits( OutdoorDryBulb, 2 ); DXCoil( DXCoilNum ).HighAmbBuffer2 = " ... Occurrence info = " + EnvironmentName + ",
16974 : // "
16975 : // + CurMnDy + " " + CreateSysTimeIntervalString();
16976 : // }
16977 : // }
16978 :
16979 : // Get total capacity modifying factor (function of temperature) for off-rated conditions
16980 : // InletAirHumRat may be modified in this ADP/BF loop, use temporary varible for calculations
16981 :
16982 : // commented, not used issue #6950
16983 : // InletAirHumRatTemp = InletAirHumRat;
16984 :
16985 : //// Calculate apparatus dew point conditions using TotCap and CBF
16986 : // hDelta = TotCap / AirMassFlow;
16987 : //// there is an issue here with using CBF to calculate the ADP enthalpy.
16988 : //// at low loads the bypass factor increases significantly.
16989 : // hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
16990 : // tADP = PsyTsatFnHPb(hADP, OutdoorPressure, RoutineName);
16991 : //// Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
16992 : //// tADP = PsyTsatFnHPb(hADP,InletAirPressure)
16993 : // wADP = min(InletAirHumRat, PsyWFnTdbH(tADP, hADP, RoutineName));
16994 : // hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
16995 : // if ((InletAirEnthalpy - hADP) > 1.e-10) {
16996 : // SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
16997 : //} else {
16998 : // SHR = 1.0;
16999 : //}
17000 : // commented, not used issue #6950 ends here
17001 :
17002 10299 : if (thisDXCoil.PLFFPLR(Mode) > 0 && CompCycRatio < 1.0) {
17003 0 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CompCycRatio); // Calculate part-load factor
17004 : } else {
17005 10299 : PLF = 1.0;
17006 : }
17007 :
17008 10299 : if (PLF < 0.7) {
17009 0 : if (thisDXCoil.ErrIndex2 == 0) {
17010 0 : ShowWarningMessage(
17011 : state,
17012 0 : format(
17013 0 : "The PLF curve value for the DX cooling coil {} ={:.3R} for part-load ratio ={:.3R}", thisDXCoil.Name, PLF, PartLoadRatio));
17014 0 : ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
17015 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
17016 : }
17017 0 : ShowRecurringWarningErrorAtEnd(
17018 0 : state, thisDXCoil.Name + ", DX cooling coil PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
17019 0 : PLF = 0.7;
17020 : }
17021 :
17022 10299 : thisDXCoil.PartLoadRatio = PartLoadRatio;
17023 10299 : thisDXCoil.CoolingCoilRuntimeFraction = CompCycRatio / PLF;
17024 10299 : if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
17025 0 : if (thisDXCoil.ErrIndex3 == 0) {
17026 0 : ShowWarningMessage(state,
17027 0 : format("The runtime fraction for DX cooling coil {} exceeded 1.0. [{:.4R}].",
17028 0 : thisDXCoil.Name,
17029 0 : thisDXCoil.CoolingCoilRuntimeFraction));
17030 0 : ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
17031 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
17032 0 : ShowContinueErrorTimeStamp(state, "");
17033 : }
17034 0 : ShowRecurringWarningErrorAtEnd(state,
17035 0 : thisDXCoil.Name + ", DX cooling coil runtime fraction > 1.0 warning continues...",
17036 0 : thisDXCoil.ErrIndex3,
17037 0 : thisDXCoil.CoolingCoilRuntimeFraction,
17038 0 : thisDXCoil.CoolingCoilRuntimeFraction);
17039 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
17040 10299 : } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
17041 0 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
17042 : }
17043 :
17044 : // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
17045 10299 : if (fanOp == HVAC::FanOp::Cycling) {
17046 10299 : state.dataHVACGlobal->OnOffFanPartLoadFraction = thisDXCoil.CoolingCoilRuntimeFraction;
17047 : }
17048 :
17049 : // Check for saturation error and modify temperature at constant enthalpy
17050 10299 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) {
17051 18 : OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
17052 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17053 : // IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
17054 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
17055 18 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
17056 : }
17057 :
17058 : // Store actual outlet conditions when DX coil is ON for use in heat recovery module
17059 10299 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = OutletAirTemp;
17060 10299 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = OutletAirHumRat;
17061 :
17062 : // Add warning message for cold cooling coil (OutletAirTemp < 2 C)
17063 10299 : if (OutletAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
17064 0 : thisDXCoil.PrintLowOutTempMessage = true;
17065 0 : thisDXCoil.FullLoadOutAirTempLast = OutletAirTemp;
17066 0 : if (thisDXCoil.LowOutletTempIndex == 0) {
17067 0 : thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
17068 0 : thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
17069 : "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
17070 0 : thisDXCoil.DXCoilType,
17071 0 : thisDXCoil.Name,
17072 0 : OutletAirTemp);
17073 0 : thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + " " +
17074 0 : CreateSysTimeIntervalString(state);
17075 : }
17076 : }
17077 :
17078 : // Coil total/sensible/latent cooling rates
17079 10299 : CalcComponentSensibleLatentOutput(AirMassFlow * PartLoadRatio,
17080 : InletAirDryBulbTemp,
17081 : InletAirHumRat,
17082 : OutletAirTemp,
17083 : OutletAirHumRat,
17084 10299 : thisDXCoil.SensCoolingEnergyRate,
17085 10299 : thisDXCoil.LatCoolingEnergyRate,
17086 10299 : thisDXCoil.TotalCoolingEnergyRate);
17087 :
17088 : // Coil outlet conditions
17089 10299 : thisDXCoil.OutletAirTemp = OutletAirTemp;
17090 10299 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
17091 10299 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
17092 :
17093 : // Coil SH/SC
17094 10299 : thisDXCoil.ActualSH = ActualSH;
17095 10299 : thisDXCoil.ActualSC = ActualSC;
17096 :
17097 : } else {
17098 : // DX coil is off; just pass through conditions
17099 :
17100 13360 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
17101 13360 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
17102 13360 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
17103 :
17104 13360 : thisDXCoil.ElecCoolingPower = 0.0;
17105 13360 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
17106 13360 : thisDXCoil.SensCoolingEnergyRate = 0.0;
17107 13360 : thisDXCoil.LatCoolingEnergyRate = 0.0;
17108 13360 : thisDXCoil.EvapCondPumpElecPower = 0.0;
17109 13360 : thisDXCoil.EvapWaterConsumpRate = 0.0;
17110 :
17111 13360 : thisDXCoil.ActualSH = 999.0;
17112 13360 : thisDXCoil.ActualSC = 999.0;
17113 :
17114 : // Reset globals when DX coil is OFF for use in heat recovery module
17115 13360 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
17116 13360 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
17117 :
17118 : } // end of on/off
17119 :
17120 : // set water system demand request (if needed)
17121 23659 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
17122 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
17123 0 : thisDXCoil.EvapWaterConsumpRate;
17124 : }
17125 :
17126 23659 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
17127 23659 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
17128 23659 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
17129 23659 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
17130 23659 : thisDXCoil.CondInletTemp = CondInletTemp;
17131 23659 : state.dataDXCoils->DXCoilTotalCooling(DXCoilNum) = thisDXCoil.TotalCoolingEnergyRate;
17132 23659 : state.dataDXCoils->DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
17133 23659 : }
17134 :
17135 23659 : void CalcVRFHeatingCoil_FluidTCtrl(EnergyPlusData &state,
17136 : HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
17137 : int const DXCoilNum, // the number of the DX heating coil to be simulated
17138 : Real64 const PartLoadRatio, // sensible cooling load / full load sensible cooling capacity
17139 : HVAC::FanOp const fanOp, // Allows parent object to control fan mode
17140 : ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
17141 : ObjexxFCL::Optional<Real64 const> MaxHeatCap // maximum allowed heating capacity
17142 : )
17143 : {
17144 : // SUBROUTINE INFORMATION:
17145 : // AUTHOR Xiufeng Pang (XP), LBNL
17146 : // DATE WRITTEN Mar 2013
17147 : // MODIFIED Nov 2015, RP Zhang, LBNL
17148 :
17149 : // PURPOSE OF THIS SUBROUTINE:
17150 : // Calculates the air-side performance of a direct-expansion, air-cooled
17151 : // VRF terminal unit heating coil, for the new VRF model.
17152 :
17153 : // METHODOLOGY EMPLOYED:
17154 : // This subroutine is derived from CalcVRFCoolingCoil, and implements the new VRF model for FluidTCtrl.
17155 :
17156 : // Using/Aliasing
17157 : using Curve::CurveValue;
17158 :
17159 : using namespace HVACVariableRefrigerantFlow;
17160 :
17161 : // INTERFACE BLOCK SPECIFICATIONS
17162 : static constexpr std::string_view RoutineNameFullLoad("CalcVRFHeatingCoil_FluidTCtrl:fullload");
17163 :
17164 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
17165 : Real64 AirMassFlow; // dry air mass flow rate through coil [kg/s]
17166 : Real64 AirMassFlowRatio; // Ratio of actual air mass flow to rated air mass flow
17167 : Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s]
17168 : Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W]
17169 : Real64 TotCap; // gross total cooling capacity at off-rated conditions [W]
17170 : Real64 TotCapAdj; // adjusted total cooling capacity at off-rated conditions [W]
17171 : // on the type of curve
17172 : Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
17173 : Real64 InletAirWetBulbC; // wetbulb temperature of inlet air [C]
17174 : Real64 InletAirEnthalpy; // inlet air enthalpy [J/kg]
17175 : Real64 InletAirHumRat; // inlet air humidity ratio [kg/kg]
17176 : Real64 FullLoadOutAirEnth; // outlet full load enthalpy [J/kg]
17177 : Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
17178 : Real64 FullLoadOutAirTemp; // outlet air temperature at full load [C]
17179 : Real64 FullLoadOutAirRH; // outlet air relative humidity at full load
17180 23659 : Real64 EIRTempModFac(0.0); // EIR modifier (function of entering drybulb, outside drybulb) depending on the
17181 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17182 : // type of curve
17183 : // Real64 DefrostEIRTempModFac; // EIR modifier for defrost (function of entering wetbulb, outside drybulb)
17184 : Real64 EIRFlowModFac; // EIR modifier (function of actual supply air flow vs rated flow)
17185 : Real64 EIR; // EIR at part load and off rated conditions
17186 : Real64 PLF; // Part load factor, accounts for thermal lag at compressor startup
17187 : Real64 PLRHeating; // PartLoadRatio in heating
17188 : Real64 OutdoorCoilT; // Outdoor coil temperature (C)
17189 : Real64 OutdoorCoildw; // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
17190 : Real64 FractionalDefrostTime; // Fraction of time step system is in defrost
17191 : Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
17192 : Real64 InputPowerMultiplier; // Multiplier for power when system is in defrost
17193 : Real64 LoadDueToDefrost; // Additional load due to defrost
17194 : Real64 CrankcaseHeatingPower; // power due to crankcase heater
17195 : Real64 OutdoorDryBulb; // Outdoor dry-bulb temperature at condenser (C)
17196 : Real64 OutdoorWetBulb; // Outdoor wet-bulb temperature at condenser (C)
17197 : Real64 OutdoorHumRat; // Outdoor humidity ratio at condenser (kg/kg)
17198 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
17199 23659 : constexpr int Mode(1); // Performance mode for MultiMode DX coil. Always 1 for other coil types
17200 : Real64 AirFlowRatio; // Ratio of compressor on airflow to average timestep airflow
17201 : Real64 OutletAirTemp; // Supply air temperature (average value if constant fan, full output if cycling fan)
17202 : Real64 OutletAirHumRat; // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
17203 : Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
17204 :
17205 : // Followings for VRF FluidTCtrl Only
17206 : Real64 QCoilReq; // Coil load (W)
17207 : Real64 FanSpdRatio; // Fan Speed Ratio
17208 : Real64 AirMassFlowMin; // Min air mass flow rate due to OA requirement [kg/s]
17209 : Real64 ActualSH; // Actual Super Heating
17210 : Real64 ActualSC; // Actual Sub Cooling
17211 :
17212 23659 : if (present(OnOffAirFlowRatio)) {
17213 0 : AirFlowRatio = OnOffAirFlowRatio;
17214 : } else {
17215 23659 : AirFlowRatio = 1.0;
17216 : }
17217 :
17218 : // Air cooled condenser
17219 23659 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
17220 23659 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
17221 23659 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
17222 23659 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
17223 :
17224 23659 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
17225 :
17226 23659 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
17227 23659 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
17228 23659 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
17229 23659 : InletAirHumRat = thisDXCoil.InletAirHumRat;
17230 23659 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
17231 23659 : PLRHeating = 0.0;
17232 23659 : thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
17233 23659 : thisDXCoil.CondensingTemp = state.dataHVACVarRefFlow->VRF(thisDXCoil.VRFOUPtr).IUCondensingTemp;
17234 :
17235 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
17236 23659 : if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
17237 32 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
17238 32 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
17239 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
17240 : }
17241 : } else {
17242 23627 : CrankcaseHeatingPower = 0.0;
17243 : }
17244 :
17245 32212 : if ((AirMassFlow > 0.0) && (compressorOp == HVAC::CompressorOp::On) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
17246 8553 : (OutdoorDryBulb > thisDXCoil.MinOATCompressor)) {
17247 :
17248 8553 : TotCap = thisDXCoil.RatedTotCap(Mode);
17249 8553 : HeatingCapacityMultiplier = 1.0;
17250 : // Modify total heating capacity based on defrost heating capacity multiplier
17251 : // MaxHeatCap passed from parent object VRF Condenser and is used to limit capacity of TU's to that available from condenser
17252 8553 : if (present(MaxHeatCap)) {
17253 8547 : TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
17254 8547 : TotCap = min(MaxHeatCap, TotCap);
17255 : } else {
17256 6 : TotCapAdj = TotCap * HeatingCapacityMultiplier;
17257 : }
17258 :
17259 8553 : QCoilReq = PartLoadRatio * TotCap;
17260 8553 : if (PartLoadRatio == 0.0) {
17261 0 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
17262 : } else {
17263 8553 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
17264 : }
17265 :
17266 : // Call ControlVRFIUCoil to calculate: (1) FanSpdRatio, (2) coil inlet/outlet conditions, and (3) SH/SC
17267 8553 : ControlVRFIUCoil(state,
17268 : DXCoilNum,
17269 : QCoilReq,
17270 : thisDXCoil.InletAirTemp,
17271 : thisDXCoil.InletAirHumRat,
17272 : thisDXCoil.CondensingTemp,
17273 : AirMassFlowMin,
17274 : FanSpdRatio,
17275 : OutletAirHumRat,
17276 : OutletAirTemp,
17277 : OutletAirEnthalpy,
17278 : ActualSH,
17279 : ActualSC);
17280 8553 : AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
17281 :
17282 8553 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
17283 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17284 8553 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
17285 : // VolFlowperRatedTotCap was checked at the initialization step
17286 : // No need to check VolFlowperRatedTotCap at the simulation
17287 : // New VRF_FluidTCtrl model implements VAV fan which can vary air flow rate during simulation
17288 :
17289 8553 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
17290 :
17291 : // Calculating adjustment factors for defrost
17292 : // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
17293 8553 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
17294 8553 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
17295 :
17296 : // Initializing defrost adjustment factors
17297 8553 : LoadDueToDefrost = 0.0;
17298 8553 : FractionalDefrostTime = 0.0;
17299 8553 : InputPowerMultiplier = 1.0;
17300 :
17301 : // Calculate full load outlet conditions
17302 8553 : FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
17303 8553 : FullLoadOutAirHumRat = InletAirHumRat;
17304 8553 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
17305 8553 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
17306 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17307 : // FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
17308 8553 : if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
17309 0 : FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
17310 : // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
17311 : // FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
17312 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
17313 : }
17314 :
17315 : // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
17316 : // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
17317 : // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
17318 : // advised to use the bi-quaratic curve if sufficient manufacturer data is available.
17319 8553 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
17320 0 : if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 1) {
17321 0 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), OutdoorDryBulb);
17322 : } else {
17323 0 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
17324 : }
17325 0 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
17326 : } else {
17327 8553 : EIRTempModFac = 1.0;
17328 8553 : EIRFlowModFac = 1.0;
17329 : }
17330 8553 : EIR = thisDXCoil.RatedEIR(Mode) * EIRTempModFac * EIRFlowModFac;
17331 :
17332 : // Calculate PLRHeating: modified PartLoadRatio due to defrost ( reverse-cycle defrost only )
17333 8553 : if (TotCap > 0.0) {
17334 8553 : PLRHeating = min(1.0, (PartLoadRatio + LoadDueToDefrost / TotCap));
17335 : } else {
17336 0 : PLRHeating = min(1.0, PartLoadRatio);
17337 : }
17338 :
17339 8553 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
17340 0 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PLRHeating); // Calculate part-load factor
17341 : } else {
17342 8553 : PLF = 1.0;
17343 : }
17344 :
17345 8553 : if (PLF < 0.7) {
17346 0 : if (thisDXCoil.PLRErrIndex == 0) {
17347 0 : ShowWarningMessage(
17348 : state,
17349 0 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
17350 0 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
17351 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
17352 0 : ShowContinueErrorTimeStamp(state, "");
17353 : }
17354 0 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
17355 0 : PLF = 0.7;
17356 : }
17357 :
17358 8553 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
17359 8553 : if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
17360 0 : if (thisDXCoil.ErrIndex4 == 0) {
17361 0 : ShowWarningMessage(state,
17362 0 : format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
17363 0 : thisDXCoil.Name,
17364 0 : thisDXCoil.HeatingCoilRuntimeFraction));
17365 0 : ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
17366 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
17367 0 : ShowContinueErrorTimeStamp(state, "");
17368 : }
17369 0 : ShowRecurringWarningErrorAtEnd(state,
17370 0 : thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
17371 0 : thisDXCoil.ErrIndex4,
17372 0 : thisDXCoil.HeatingCoilRuntimeFraction,
17373 0 : thisDXCoil.HeatingCoilRuntimeFraction);
17374 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
17375 8553 : } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
17376 0 : thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
17377 : }
17378 :
17379 : // if cycling fan, send coil part-load fraction to on / off fan via HVACDataGlobals
17380 8553 : if (fanOp == HVAC::FanOp::Cycling) {
17381 8553 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
17382 : }
17383 8553 : thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
17384 :
17385 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
17386 : // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
17387 8553 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
17388 8553 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
17389 : } else {
17390 0 : thisDXCoil.CrankcaseHeaterPower =
17391 0 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
17392 0 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
17393 : }
17394 :
17395 8553 : thisDXCoil.OutletAirTemp = OutletAirTemp;
17396 8553 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
17397 8553 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
17398 8553 : thisDXCoil.CompressorPartLoadRatio = PartLoadRatio;
17399 8553 : thisDXCoil.ActualSH = ActualSH;
17400 8553 : thisDXCoil.ActualSC = ActualSC;
17401 8553 : thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy) * PartLoadRatio;
17402 8553 : thisDXCoil.DefrostPower = thisDXCoil.DefrostPower * thisDXCoil.HeatingCoilRuntimeFraction;
17403 :
17404 : } else {
17405 : // DX coil is off; just pass through conditions
17406 :
17407 15106 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
17408 15106 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
17409 15106 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
17410 :
17411 15106 : thisDXCoil.ElecHeatingPower = 0.0;
17412 15106 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
17413 15106 : thisDXCoil.DefrostPower = 0.0;
17414 :
17415 : // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
17416 : // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
17417 15106 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
17418 15106 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
17419 : } else {
17420 0 : thisDXCoil.CrankcaseHeaterPower =
17421 0 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
17422 : }
17423 15106 : thisDXCoil.CompressorPartLoadRatio = 0.0;
17424 :
17425 15106 : thisDXCoil.ActualSH = 999.0;
17426 15106 : thisDXCoil.ActualSC = 999.0;
17427 : } // end of on/off if - else
17428 :
17429 23659 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
17430 23659 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
17431 23659 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
17432 23659 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
17433 23659 : state.dataDXCoils->DXCoilTotalHeating(DXCoilNum) = thisDXCoil.TotalHeatingEnergyRate;
17434 23659 : state.dataDXCoils->DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
17435 23659 : state.dataDXCoils->DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;
17436 :
17437 : // calc secondary coil if specified
17438 23659 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
17439 0 : CalcSecondaryDXCoils(state, DXCoilNum);
17440 : }
17441 23659 : }
17442 :
17443 90388 : void ControlVRFIUCoil(EnergyPlusData &state,
17444 : int const CoilIndex, // index to VRFTU coil
17445 : Real64 const QCoil, // coil load
17446 : Real64 const Tin, // inlet air temperature
17447 : Real64 const Win, // inlet air humidity ratio
17448 : Real64 const TeTc, // evaporating or condensing temperature
17449 : Real64 const OAMassFlow, // mass flow rate of outdoor air
17450 : Real64 &FanSpdRatio, // fan speed ratio: actual flow rate / rated flow rate
17451 : Real64 &Wout, // outlet air humidity ratio
17452 : Real64 &Tout, // outlet air temperature
17453 : Real64 &Hout, // outlet air enthalpy
17454 : Real64 &SHact, // actual SH
17455 : Real64 &SCact // actual SC
17456 : )
17457 : {
17458 : // SUBROUTINE INFORMATION:
17459 : // AUTHOR Xiufeng Pang, LBNL
17460 : // DATE WRITTEN Feb 2013
17461 : // MODIFIED Nov 2015, RP Zhang, LBNL
17462 : //
17463 : // PURPOSE OF THIS SUBROUTINE:
17464 : // Analyze the VRF Indoor Unit operations given coil loads.
17465 : // Calculated parameters include: (1) Fan Speed Ratio (2) SH/SC, (3) Coil Outlet conditions
17466 : //
17467 : // METHODOLOGY EMPLOYED:
17468 : // A new physics based VRF model applicable for Fluid Temperature Control.
17469 : //
17470 : // USE STATEMENTS:
17471 : using Psychrometrics::PsyHFnTdbW;
17472 :
17473 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
17474 90388 : int MaxIter(500); // Max iteration numbers (-)
17475 : int SolFla; // Solving flag for SolveRoot (-)
17476 90388 : int constexpr FlagCoolMode(0); // Flag for cooling mode
17477 90388 : int constexpr FlagHeatMode(1); // Flag for heating mode
17478 : Real64 BF; // Bypass factor (-)
17479 : Real64 C1Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17480 : Real64 C2Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17481 : Real64 C3Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17482 : Real64 C1Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17483 : Real64 C2Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17484 : Real64 C3Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17485 : Real64 CoilOnOffRatio; // coil on/off ratio: time coil is on divided by total time
17486 : Real64 deltaT; // Difference between evaporating/condensing temperature and coil surface temperature (C)
17487 : Real64 FanSpdRatioMin; // Min fan speed ratio, below which the cycling will be activated (-)
17488 : Real64 FanSpdRatioMax; // Max fan speed ratio (-)
17489 : Real64 Garate; // Nominal air mass flow rate (m3/s)
17490 : Real64 MaxSH; // Max super heating degrees (C)
17491 : Real64 MaxSC; // Max subcooling degrees (C)
17492 : Real64 QinSenMin1; // Coil capacity at minimum fan speed, corresponding to real SH (W)
17493 : Real64 QinSenMin2; // Coil capacity at minimum fan speed, corresponding to corresponds maximum SH (W)
17494 : Real64 QinSenPerFlowRate; // Coil capacity per air mass flow rate(W-s/kg)
17495 : Real64 QCoilSenCoolingLoad; // Coil sensible cooling load (W)
17496 : Real64 QCoilSenHeatingLoad; // Coil sensible heating load (W)
17497 : Real64 Ratio1; // Fan speed ratio (-)
17498 : Real64 RHsat; // Relative humidity of the air at saturated condition(-)
17499 : Real64 SH; // Super heating degrees (C)
17500 : Real64 SC; // Subcooling degrees (C)
17501 : Real64 Ts_1; // Air temperature at the coil surface, corresponding to SH (C)
17502 : Real64 Ts_2; // Air temperature at the coil surface, corresponding to MaxSH (C)
17503 : Real64 To_1; // Air temperature at the coil outlet, corresponding to SH (C)
17504 : Real64 To_2; // Air temperature at the coil outlet, corresponding to MaxSH (C)
17505 : Real64 Ts; // Air temperature at the coil surface (C)
17506 : Real64 Ws; // Air humidity ratio at the coil surface (kg/kg)
17507 :
17508 90388 : RHsat = 0.98; // Saturated RH
17509 90388 : MaxSH = 15;
17510 90388 : MaxSC = 20;
17511 90388 : Garate = state.dataDXCoils->DXCoil(CoilIndex).RatedAirMassFlowRate(1);
17512 90388 : FanSpdRatioMin = min(OAMassFlow / Garate, 1.0); // ensure that coil flow rate is higher than OA flow rate
17513 :
17514 90388 : if (QCoil == 0) {
17515 : // No Heating or Cooling
17516 0 : FanSpdRatio = OAMassFlow / Garate;
17517 0 : CoilOnOffRatio = 0.0;
17518 :
17519 0 : SHact = 999.0;
17520 0 : SCact = 999.0;
17521 0 : Tout = Tin;
17522 0 : Hout = PsyHFnTdbW(Tin, Win);
17523 0 : Wout = Win;
17524 :
17525 90388 : } else if (QCoil < 0) {
17526 : // Cooling Mode
17527 :
17528 : // Obtain coil cooling loads
17529 47821 : QCoilSenCoolingLoad = -QCoil;
17530 :
17531 : // Coefficients describing coil performance
17532 47821 : SH = state.dataDXCoils->DXCoil(CoilIndex).SH;
17533 47821 : C1Tevap = state.dataDXCoils->DXCoil(CoilIndex).C1Te;
17534 47821 : C2Tevap = state.dataDXCoils->DXCoil(CoilIndex).C2Te;
17535 47821 : C3Tevap = state.dataDXCoils->DXCoil(CoilIndex).C3Te;
17536 47821 : BF = state.dataDXCoils->DXCoil(CoilIndex).RateBFVRFIUEvap;
17537 :
17538 : // Coil sensible heat transfer_minimum value
17539 47821 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilIndex, Tin, TeTc, SH, BF, QinSenPerFlowRate, Ts_1);
17540 47821 : To_1 = Tin - QinSenPerFlowRate / 1005;
17541 47821 : QinSenMin1 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds real SH
17542 :
17543 47821 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilIndex, Tin, TeTc, MaxSH, BF, QinSenPerFlowRate, Ts_2);
17544 47821 : To_2 = Tin - QinSenPerFlowRate / 1005;
17545 47821 : QinSenMin2 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds maximum SH
17546 :
17547 47821 : if (QCoilSenCoolingLoad > QinSenMin1) {
17548 : // Increase fan speed to meet room sensible load; SH is not updated
17549 45830 : FanSpdRatioMax = 1.0;
17550 130189 : auto f = [QCoilSenCoolingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
17551 130189 : return FanSpdResidualCool(FanSpdRto, QCoilSenCoolingLoad, Ts_1, Tin, Garate, BF);
17552 45830 : };
17553 45830 : General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, Ratio1, f, FanSpdRatioMin, FanSpdRatioMax);
17554 45830 : if (SolFla < 0) {
17555 7301 : Ratio1 = FanSpdRatioMax; // over capacity
17556 : }
17557 45830 : FanSpdRatio = Ratio1;
17558 45830 : CoilOnOffRatio = 1.0;
17559 :
17560 45830 : Tout = To_1; // Since SH is not updated
17561 45830 : Ws = PsyWFnTdbRhPb(state, Ts_1, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
17562 45830 : if (Ws < Win) {
17563 45829 : Wout = Win - (Win - Ws) * (1 - BF);
17564 : } else {
17565 1 : Wout = Win;
17566 : }
17567 45830 : Hout = PsyHFnTdbW(Tout, Wout);
17568 45830 : SCact = 999.0;
17569 45830 : SHact = SH;
17570 :
17571 : } else {
17572 : // Low load modification algorithm
17573 : // Need to increase SH to further reduce coil capacity
17574 : // May further implement coil cycling control if SC modification is not enough
17575 :
17576 1991 : FanSpdRatio = FanSpdRatioMin;
17577 :
17578 1991 : CoilOnOffRatio = 1.0;
17579 :
17580 1991 : Tout = Tin - QCoilSenCoolingLoad / 1005.0 / FanSpdRatioMin / Garate;
17581 1991 : Ts = Tin - (Tin - Tout) / (1 - BF);
17582 1991 : deltaT = Ts - TeTc;
17583 :
17584 : // Update SH
17585 1991 : if (C3Tevap <= 0.0) {
17586 1991 : if (C2Tevap > 0.0) {
17587 1991 : SHact = (deltaT - C1Tevap) / C2Tevap;
17588 : } else {
17589 0 : SHact = 998.0;
17590 : }
17591 : } else {
17592 0 : SHact = (-C2Tevap + sqrt(pow_2(C2Tevap) - 4 * C3Tevap * (C1Tevap - deltaT))) / 2 / C3Tevap;
17593 : }
17594 :
17595 1991 : Ws = PsyWFnTdbRhPb(state, Ts, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
17596 1991 : if (Ws < Win) {
17597 1776 : Wout = Win - (Win - Ws) * (1 - BF);
17598 : } else {
17599 215 : Wout = Win;
17600 : }
17601 :
17602 1991 : if (SHact > MaxSH) {
17603 : // Further implement On/Off Control
17604 791 : SHact = MaxSH;
17605 791 : CoilOnOffRatio = QCoilSenCoolingLoad / QinSenMin2;
17606 :
17607 791 : Ts = Ts_2;
17608 791 : Ws = PsyWFnTdbRhPb(state, Ts, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
17609 791 : if (Ws < Win) {
17610 791 : Wout = Win - (Win - Ws) * (1 - BF);
17611 : } else {
17612 0 : Wout = Win;
17613 : }
17614 :
17615 : // outlet air temperature and humidity ratio is time-weighted
17616 791 : Tout = CoilOnOffRatio * To_2 + (1 - CoilOnOffRatio) * Tin;
17617 791 : Wout = CoilOnOffRatio * Wout + (1 - CoilOnOffRatio) * Win;
17618 : }
17619 :
17620 1991 : Hout = PsyHFnTdbW(Tout, Wout);
17621 1991 : SCact = 999.0;
17622 : }
17623 :
17624 42567 : } else if (QCoil > 0) {
17625 : // Heating Mode
17626 :
17627 : // Obtain zonal heating loads
17628 42567 : QCoilSenHeatingLoad = QCoil;
17629 :
17630 : // Coefficients describing coil performance
17631 42567 : SC = state.dataDXCoils->DXCoil(CoilIndex).SC;
17632 42567 : C1Tcond = state.dataDXCoils->DXCoil(CoilIndex).C1Tc;
17633 42567 : C2Tcond = state.dataDXCoils->DXCoil(CoilIndex).C2Tc;
17634 42567 : C3Tcond = state.dataDXCoils->DXCoil(CoilIndex).C3Tc;
17635 42567 : BF = state.dataDXCoils->DXCoil(CoilIndex).RateBFVRFIUCond;
17636 :
17637 : // Coil sensible heat transfer_minimum value
17638 42567 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilIndex, Tin, TeTc, SC, BF, QinSenPerFlowRate, Ts_1);
17639 42567 : To_1 = QinSenPerFlowRate / 1005 + Tin;
17640 42567 : QinSenMin1 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds real SH
17641 :
17642 42567 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilIndex, Tin, TeTc, MaxSC, BF, QinSenPerFlowRate, Ts_2);
17643 42567 : To_2 = QinSenPerFlowRate / 1005 + Tin;
17644 42567 : QinSenMin2 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds maximum SH
17645 :
17646 42567 : if (QCoilSenHeatingLoad > QinSenMin1) {
17647 : // Modulate fan speed to meet room sensible load; SC is not updated
17648 42271 : FanSpdRatioMax = 1.0;
17649 126812 : auto f = [QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
17650 126812 : return FanSpdResidualHeat(FanSpdRto, QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF);
17651 42271 : };
17652 42271 : General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, Ratio1, f, FanSpdRatioMin, FanSpdRatioMax);
17653 : // this will likely cause problems eventually, -1 and -2 mean different things
17654 42271 : if (SolFla < 0) {
17655 1 : Ratio1 = FanSpdRatioMax; // over capacity
17656 : }
17657 42271 : FanSpdRatio = Ratio1;
17658 42271 : CoilOnOffRatio = 1.0;
17659 :
17660 42271 : Tout = Tin + (Ts_1 - Tin) * (1 - BF);
17661 42271 : Wout = Win;
17662 42271 : Hout = PsyHFnTdbW(Tout, Wout);
17663 42271 : SHact = 999.0;
17664 42271 : SCact = SC;
17665 :
17666 : } else {
17667 : // Low load modification algorithm
17668 : // Need to increase SC to further reduce coil heating capacity
17669 : // May further implement coil cycling control if SC modification is not enough
17670 :
17671 296 : FanSpdRatio = FanSpdRatioMin;
17672 296 : CoilOnOffRatio = 1.0;
17673 :
17674 296 : Tout = Tin + QCoilSenHeatingLoad / 1005.0 / FanSpdRatio / Garate;
17675 296 : Ts = Tin + (Tout - Tin) / (1 - BF);
17676 296 : deltaT = TeTc - Ts;
17677 :
17678 : // Update SC
17679 296 : if (C3Tcond <= 0.0) {
17680 0 : if (C2Tcond > 0.0) {
17681 0 : SCact = (deltaT - C1Tcond) / C2Tcond;
17682 : } else {
17683 0 : SCact = 998.0;
17684 : }
17685 : } else {
17686 296 : SCact = (-C2Tcond + sqrt(pow_2(C2Tcond) - 4 * C3Tcond * (C1Tcond - deltaT))) / 2 / C3Tcond;
17687 : }
17688 :
17689 296 : if (SCact > MaxSC) {
17690 : // Implement On/Off Control
17691 77 : SCact = MaxSC;
17692 77 : CoilOnOffRatio = QCoilSenHeatingLoad / QinSenMin2;
17693 : // outlet air temperature is time-weighted
17694 77 : Tout = CoilOnOffRatio * To_2 + (1 - CoilOnOffRatio) * Tin;
17695 : }
17696 296 : Wout = Win;
17697 296 : Hout = PsyHFnTdbW(Tout, Wout);
17698 296 : SHact = 999.0;
17699 : }
17700 : }
17701 90388 : }
17702 :
17703 180788 : void CalcVRFCoilSenCap(EnergyPlusData &state,
17704 : int const OperationMode, // mode 0 for cooling, 1 for heating
17705 : int const CoilNum, // index to VRFTU cooling or heating coil
17706 : Real64 const Tinlet, // dry bulb temperature of air entering the coil
17707 : Real64 const TeTc, // evaporating or condensing temperature
17708 : Real64 const SHSC, // SH at cooling /SC at heating
17709 : Real64 const BF, // Bypass factor
17710 : Real64 &Q_sen, // VRF coil sensible capacity per air mass flow rate
17711 : Real64 &T_coil_surf // Air temperature at coil surface
17712 : )
17713 : {
17714 : // SUBROUTINE INFORMATION:
17715 : // AUTHOR Rongpeng Zhang, LBNL
17716 : // DATE WRITTEN Jul 2015
17717 : //
17718 : // PURPOSE OF THIS SUBROUTINE:
17719 : // Calculate the VRF coil sensible capacity per air mass flow rate, given:
17720 : // (1) refrigerant temperature (Te or Tc), (2) SH or SC, and (3) inlet air temperature.
17721 : //
17722 : // METHODOLOGY EMPLOYED:
17723 : // A new physics based VRF model appliable for Fluid Temperature Control.
17724 : //
17725 :
17726 180788 : int constexpr FlagCoolMode(0); // Flag for cooling mode
17727 180788 : int constexpr FlagHeatMode(1); // Flag for heating mode
17728 : Real64 C1Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17729 : Real64 C2Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17730 : Real64 C3Tevap; // Coefficient for indoor unit coil evaporating temperature curve (-)
17731 : Real64 C1Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17732 : Real64 C2Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17733 : Real64 C3Tcond; // Coefficient for indoor unit coil condensing temperature curve (-)
17734 : Real64 deltaT; // Difference between Te/Tc and coil surface temperature (C)
17735 : Real64 SH; // Super heating at cooling mode(C)
17736 : Real64 SC; // Subcooling at heating mode (C)
17737 : Real64 T_coil_in; // Air temperature at coil inlet (C)
17738 : Real64 T_coil_out; // Air temperature at coil outlet (C)
17739 :
17740 180788 : if (OperationMode == FlagCoolMode) {
17741 : // Cooling: OperationMode 0
17742 :
17743 95654 : C1Tevap = state.dataDXCoils->DXCoil(CoilNum).C1Te;
17744 95654 : C2Tevap = state.dataDXCoils->DXCoil(CoilNum).C2Te;
17745 95654 : C3Tevap = state.dataDXCoils->DXCoil(CoilNum).C3Te;
17746 95654 : SH = SHSC;
17747 95654 : T_coil_in = Tinlet;
17748 :
17749 : // Coil surface temperature
17750 95654 : deltaT = C3Tevap * SH * SH + C2Tevap * SH + C1Tevap;
17751 95654 : T_coil_surf = TeTc + deltaT;
17752 :
17753 : // Outlet air temperature
17754 95654 : T_coil_out = T_coil_in - (T_coil_in - T_coil_surf) * (1 - BF);
17755 :
17756 : // Coil sensilbe heat transfer per mass flow rate
17757 95654 : Q_sen = max(1005 * (T_coil_in - T_coil_out), 0.0);
17758 :
17759 85134 : } else if (OperationMode == FlagHeatMode) {
17760 : // Heating: OperationMode 1
17761 :
17762 85134 : C1Tcond = state.dataDXCoils->DXCoil(CoilNum).C1Tc;
17763 85134 : C2Tcond = state.dataDXCoils->DXCoil(CoilNum).C2Tc;
17764 85134 : C3Tcond = state.dataDXCoils->DXCoil(CoilNum).C3Tc;
17765 85134 : SC = SHSC;
17766 85134 : T_coil_in = Tinlet;
17767 :
17768 : // Coil surface temperature
17769 85134 : deltaT = C3Tcond * SC * SC + C2Tcond * SC + C1Tcond;
17770 85134 : T_coil_surf = TeTc - deltaT;
17771 :
17772 : // Coil outlet air temperature
17773 85134 : T_coil_out = T_coil_in + (T_coil_surf - T_coil_in) * (1 - BF);
17774 :
17775 : // Coil sensilbe heat transfer_minimum value
17776 85134 : Q_sen = max(1005 * (T_coil_out - T_coil_in), 0.0);
17777 : }
17778 180788 : }
17779 :
17780 6 : void CalcVRFCoilCapModFac(EnergyPlusData &state,
17781 : int const OperationMode, // mode 0 for cooling, 1 for heating
17782 : ObjexxFCL::Optional<int const> CoilIndex, // index to VRFTU cooling or heating coil
17783 : ObjexxFCL::Optional<std::string> CoilName, // name of VRFTU cooling or heating coil
17784 : Real64 const Tinlet, // dry bulb temperature of air entering the coil
17785 : ObjexxFCL::Optional<Real64 const> TeTc, // evaporating or condensing temperature
17786 : ObjexxFCL::Optional<Real64 const> SHSC, // SH at cooling /SC at heating
17787 : ObjexxFCL::Optional<Real64 const> BF, // Bypass factor
17788 : Real64 &CapModFac // Coil capacity modification factor
17789 : )
17790 : {
17791 : // SUBROUTINE INFORMATION:
17792 : // AUTHOR Rongpeng Zhang, LBNL
17793 : // DATE WRITTEN Jul 2015
17794 : //
17795 : // PURPOSE OF THIS SUBROUTINE:
17796 : // Calculate the VRF coil capacity modification factor, which is the ratio of
17797 : // the capacity at real conditions and that at rated conditions.
17798 : // This is used for the coil sizing subroutine.
17799 : //
17800 : // METHODOLOGY EMPLOYED:
17801 : // A new physics based VRF model applicable for Fluid Temperature Control.
17802 : //
17803 :
17804 6 : bool ErrorsFound(false); // Flag for errors
17805 6 : int constexpr FlagCoolMode(0); // Flag for cooling mode
17806 6 : int constexpr FlagHeatMode(1); // Flag for heating mode
17807 6 : Real64 constexpr SH_rate(3); // Super heating at cooling mode, default 3(C)
17808 6 : Real64 constexpr SC_rate(5); // Subcooling at heating mode, default 5 (C)
17809 6 : Real64 constexpr Te_rate(6); // Evaporating temperature at cooling mode, default 6 (C)
17810 6 : Real64 constexpr Tc_rate(44); // Condensing temperature at heating mode, default 44 (C)
17811 : int CoilNum; // index to VRFTU cooling or heating coil
17812 : Real64 BF_real; // Bypass factor (-)
17813 : Real64 BFC_rate; // Bypass factor at cooling mode (-)
17814 : Real64 BFH_rate; // Bypass factor at heating mode (-)
17815 : Real64 SHSC_real; // Super heating or Subcooling (C)
17816 : Real64 TeTc_real; // Evaporating temperature or condensing temperature (C)
17817 : Real64 Ts; // Air temperature at coil surface (C)
17818 : Real64 Q_real; // Coil capacity at given condition (W)
17819 : Real64 Q_rate; // Coil capacity at rated condition (W)
17820 :
17821 6 : if (present(CoilIndex)) {
17822 0 : CoilNum = CoilIndex;
17823 : } else {
17824 6 : GetDXCoilIndex(state, CoilName, CoilNum, ErrorsFound, "", true);
17825 : }
17826 :
17827 6 : BFC_rate = state.dataDXCoils->DXCoil(CoilNum).RateBFVRFIUEvap;
17828 6 : BFH_rate = state.dataDXCoils->DXCoil(CoilNum).RateBFVRFIUCond;
17829 :
17830 6 : if (OperationMode == FlagCoolMode) {
17831 : // Cooling: OperationMode 0
17832 :
17833 6 : if (present(BF)) {
17834 0 : BF_real = BF;
17835 : } else {
17836 6 : BF_real = BFC_rate;
17837 : }
17838 6 : if (present(TeTc)) {
17839 0 : TeTc_real = TeTc;
17840 : } else {
17841 6 : TeTc_real = Te_rate;
17842 : }
17843 6 : if (present(SHSC)) {
17844 0 : SHSC_real = SHSC;
17845 : } else {
17846 6 : SHSC_real = SH_rate;
17847 : }
17848 :
17849 : // Coil capacity at rated conditions
17850 6 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilNum, 26, Te_rate, SH_rate, BFC_rate, Q_rate, Ts);
17851 :
17852 : // Coil capacity at given conditions
17853 6 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilNum, Tinlet, TeTc_real, SHSC_real, BF_real, Q_real, Ts);
17854 :
17855 6 : if (Q_rate > 0) {
17856 6 : CapModFac = Q_real / Q_rate;
17857 : } else {
17858 0 : CapModFac = 1.0;
17859 : }
17860 :
17861 0 : } else if (OperationMode == FlagHeatMode) {
17862 : // Heating: OperationMode 1
17863 :
17864 0 : if (present(BF)) {
17865 0 : BF_real = BF;
17866 : } else {
17867 0 : BF_real = BFH_rate;
17868 : }
17869 0 : if (present(TeTc)) {
17870 0 : TeTc_real = TeTc;
17871 : } else {
17872 0 : TeTc_real = Tc_rate;
17873 : }
17874 0 : if (present(SHSC)) {
17875 0 : SHSC_real = SHSC;
17876 : } else {
17877 0 : SHSC_real = SC_rate;
17878 : }
17879 :
17880 : // Coil capacity at rated conditions
17881 0 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilNum, 20, Tc_rate, SC_rate, BFH_rate, Q_rate, Ts);
17882 :
17883 : // Coil capacity at given conditions
17884 0 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilNum, Tinlet, TeTc_real, SHSC_real, BF_real, Q_real, Ts);
17885 :
17886 0 : if (Q_rate > 0) {
17887 0 : CapModFac = Q_real / Q_rate;
17888 : } else {
17889 0 : CapModFac = 1.0;
17890 : }
17891 : }
17892 6 : }
17893 :
17894 130190 : Real64 FanSpdResidualCool(
17895 : Real64 const FanSpdRto, Real64 const QCoilSenCoolingLoad, Real64 const Ts_1, Real64 const Tin, Real64 const Garate, Real64 const BF)
17896 : {
17897 : // FUNCTION INFORMATION:
17898 : // AUTHOR Xiufeng Pang (XP)
17899 : // DATE WRITTEN Mar 2013
17900 : // MODIFIED Nov 2015, RP Zhang, LBNL
17901 : //
17902 : // PURPOSE OF THIS FUNCTION:
17903 : // Calculates residual function (desired zone cooling load - actual coil cooling capacity)
17904 : // This is used to modify the fan speed to adjust the coil cooling capacity to match
17905 : // the zone cooling load.
17906 : //
17907 130190 : Real64 ZnSenLoad = QCoilSenCoolingLoad;
17908 : // +-100 W minimum zone load?
17909 130190 : if (std::abs(ZnSenLoad) < 100.0) {
17910 0 : ZnSenLoad = sign(100.0, ZnSenLoad);
17911 : }
17912 130190 : Real64 Tout = Tin - (Tin - Ts_1) * (1 - BF);
17913 130190 : Real64 TotCap = FanSpdRto * Garate * 1005.0 * (Tin - Tout);
17914 130190 : return (TotCap - ZnSenLoad) / ZnSenLoad;
17915 : }
17916 :
17917 126813 : Real64 FanSpdResidualHeat(Real64 FanSpdRto, Real64 QCoilSenHeatingLoad, Real64 Ts_1, Real64 Tin, Real64 Garate, Real64 BF)
17918 : {
17919 :
17920 : // FUNCTION INFORMATION:
17921 : // AUTHOR Xiufeng Pang (XP)
17922 : // DATE WRITTEN Mar 2013
17923 : // MODIFIED Nov 2015, RP Zhang, LBNL
17924 : //
17925 : // PURPOSE OF THIS FUNCTION:
17926 : // Calculates residual function (desired zone heating load - actual heating coil capacity)
17927 : // This is used to modify the fan speed to adjust the coil heating capacity to match
17928 : // the zone heating load.
17929 : //
17930 :
17931 126813 : Real64 ZnSenLoad = QCoilSenHeatingLoad;
17932 : // +-100 W minimum zone load?
17933 126813 : if (std::abs(ZnSenLoad) < 100.0) {
17934 0 : ZnSenLoad = sign(100.0, ZnSenLoad);
17935 : }
17936 126813 : Real64 Tout = Tin + (Ts_1 - Tin) * (1 - BF);
17937 126813 : Real64 TotCap = FanSpdRto * Garate * 1005.0 * (Tout - Tin);
17938 126813 : return (TotCap - ZnSenLoad) / ZnSenLoad;
17939 : }
17940 :
17941 4 : void SetMSHPDXCoilHeatRecoveryFlag(EnergyPlusData &state, int const DXCoilNum)
17942 : {
17943 :
17944 : // SUBROUTINE INFORMATION:
17945 : // AUTHOR L. Gu
17946 : // DATE WRITTEN Sep. 2015
17947 :
17948 : // PURPOSE OF THIS SUBROUTINE:
17949 : // Set the heat recovery flag true when the parent object requests heat recovery.
17950 :
17951 4 : if (state.dataDXCoils->DXCoil(DXCoilNum).FuelType != Constant::eFuel::Electricity) {
17952 2 : state.dataDXCoils->DXCoil(DXCoilNum).MSHPHeatRecActive = true;
17953 : }
17954 4 : }
17955 :
17956 4 : void SetDXCoilAirLoopNumber(EnergyPlusData &state, std::string const &CoilName, int const AirLoopNum)
17957 : {
17958 : // SUBROUTINE INFORMATION:
17959 : // AUTHOR L. Gu
17960 : // DATE WRITTEN March, 2018
17961 :
17962 : // PURPOSE OF THIS SUBROUTINE:
17963 : // Set AirLoopNum for AFN model with multiple AirLoops
17964 :
17965 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
17966 : int WhichCoil;
17967 :
17968 4 : if (state.dataDXCoils->GetCoilsInputFlag) {
17969 1 : GetDXCoils(state);
17970 1 : state.dataDXCoils->GetCoilsInputFlag = false;
17971 : }
17972 :
17973 4 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
17974 4 : if (WhichCoil != 0) {
17975 2 : state.dataDXCoils->DXCoil(WhichCoil).AirLoopNum = AirLoopNum;
17976 : } else {
17977 2 : ShowSevereError(state, format("SetDXCoilAirLoopNumber: Could not find Coil \"Name=\"{}\"", CoilName));
17978 : }
17979 4 : } // must match coil names for the coil type
17980 :
17981 1 : void DisableLatentDegradation(EnergyPlusData &state, int const DXCoilNum)
17982 : {
17983 : // SUBROUTINE INFORMATION:
17984 : // AUTHOR L. Gu
17985 : // DATE WRITTEN JUne, 2019
17986 :
17987 : // PURPOSE OF THIS SUBROUTINE:
17988 : // Disable latent degradation when direct solution is used.
17989 :
17990 1 : state.dataDXCoils->DXCoil(DXCoilNum).Twet_Rated(1) = 0.0;
17991 1 : }
17992 :
17993 : } // namespace EnergyPlus::DXCoils
|