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 47484304 : 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 47484304 : 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 47484304 : if (CompIndex == 0) {
164 22 : DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
165 22 : if (DXCoilNum == 0) {
166 0 : ShowFatalError(state, format("DX Coil not found={}", CompName));
167 : }
168 22 : CompIndex = DXCoilNum;
169 : } else {
170 47484282 : DXCoilNum = CompIndex;
171 47484282 : 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 47484282 : if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
179 840 : 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 840 : state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
187 : }
188 : }
189 :
190 47484304 : if (present(OnOffAFR)) {
191 43901932 : AirFlowRatio = OnOffAFR;
192 : } else {
193 3582372 : AirFlowRatio = 1.0;
194 : }
195 :
196 47484304 : if (present(CompCyclingRatio)) {
197 1368572 : CompCycRatio = CompCyclingRatio;
198 : } else {
199 46115732 : CompCycRatio = 1.0;
200 : }
201 :
202 : // Initialize the DX coil unit
203 47484304 : InitDXCoil(state, DXCoilNum);
204 :
205 : // Select the correct unit type
206 47484304 : switch (state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType_Num) { // Autodesk:OPTIONAL PartLoadRatio, MaxCap used in this block without PRESENT check
207 36505721 : case HVAC::CoilDX_CoolingSingleSpeed: {
208 36505721 : if (present(CoilCoolingHeatingPLRRatio)) {
209 30498184 : CalcDoe2DXCoil(state, DXCoilNum, compressorOp, FirstHVACIteration, PartLoadRatio, fanOp, _, AirFlowRatio, CoilCoolingHeatingPLRRatio);
210 : } else {
211 6007537 : CalcDoe2DXCoil(state, DXCoilNum, compressorOp, FirstHVACIteration, PartLoadRatio, fanOp, _, AirFlowRatio);
212 : }
213 36505721 : } break;
214 5885051 : case HVAC::CoilDX_HeatingEmpirical: {
215 5885051 : CalcDXHeatingCoil(state, DXCoilNum, PartLoadRatio, fanOp, AirFlowRatio);
216 5885051 : } break;
217 636362 : 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 636362 : CalcHPWHDXCoil(state, DXCoilNum, PartLoadRatio);
221 : // CALL CalcDoe2DXCoil(state, DXCoilNum, compressorOp, FirstHVACIteration,PartLoadRatio), perform air-side calculations
222 636362 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp);
223 636362 : } break;
224 1701118 : case HVAC::CoilVRF_Cooling: {
225 1701118 : CalcVRFCoolingCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, CompCycRatio, _, AirFlowRatio, MaxCap);
226 1701118 : } break;
227 1701118 : case HVAC::CoilVRF_Heating: {
228 1701118 : CalcDXHeatingCoil(state, DXCoilNum, PartLoadRatio, fanOp, AirFlowRatio, MaxCap);
229 1701118 : } break;
230 527467 : case HVAC::CoilVRF_FluidTCtrl_Cooling: {
231 527467 : CalcVRFCoolingCoil_FluidTCtrl(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, CompCycRatio, _, _, MaxCap);
232 527467 : } break;
233 527467 : case HVAC::CoilVRF_FluidTCtrl_Heating: {
234 527467 : CalcVRFHeatingCoil_FluidTCtrl(state, compressorOp, DXCoilNum, PartLoadRatio, fanOp, _, MaxCap);
235 527467 : } 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 47484304 : UpdateDXCoil(state, DXCoilNum);
245 :
246 : // Report the result of the simulation
247 47484304 : ReportDXCoil(state, DXCoilNum);
248 47484304 : }
249 :
250 15939507 : 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 15939507 : 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 15939507 : 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 15939507 : DXCoilNum = CompIndex;
298 15939507 : 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 15939507 : if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
306 138 : 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 138 : state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
314 : }
315 : }
316 :
317 15939507 : if (present(SingleMode)) {
318 9012251 : SingleModeOper = SingleMode;
319 : } else {
320 6927256 : SingleModeOper = 0;
321 : }
322 :
323 : // Initialize the DX coil unit
324 15939507 : InitDXCoil(state, DXCoilNum);
325 :
326 : // Select the correct unit type
327 15939507 : switch (state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType_Num) {
328 2226306 : case HVAC::CoilDX_CoolingTwoSpeed: {
329 2226306 : CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio);
330 2226306 : } break;
331 6865266 : case HVAC::CoilDX_MultiSpeedCooling: {
332 6865266 : if (present(SpeedNum)) {
333 6865266 : 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 6865266 : } break;
344 6847935 : case HVAC::CoilDX_MultiSpeedHeating: {
345 6847935 : if (present(SpeedNum)) {
346 6847935 : CalcMultiSpeedDXCoilHeating(state,
347 : DXCoilNum,
348 : SpeedRatio,
349 : CycRatio,
350 : SpeedNum,
351 : fanOp,
352 : SingleModeOper); // Autodesk:OPTIONAL fanOp used without PRESENT check
353 : }
354 :
355 6847935 : } 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 15939507 : UpdateDXCoil(state, DXCoilNum);
365 :
366 : // Report the result of the simulation
367 15939507 : ReportDXCoil(state, DXCoilNum);
368 15939507 : }
369 :
370 130449 : 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 130449 : 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 130449 : 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 130449 : 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 130449 : if (CompIndex == 0) {
444 2 : DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
445 2 : if (DXCoilNum == 0) {
446 0 : ShowFatalError(state, format("DX Coil not found={}", CompName));
447 : }
448 2 : CompIndex = DXCoilNum;
449 : } else {
450 130447 : DXCoilNum = CompIndex;
451 130447 : 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 130447 : if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
459 11 : 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 11 : state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
467 : }
468 : }
469 :
470 : // Initialize the DX coil unit
471 130449 : InitDXCoil(state, DXCoilNum);
472 :
473 130449 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
474 : // Select the correct unit type
475 130449 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
476 : // Initialize local variables
477 130449 : S1RuntimeFraction = 0.0;
478 130449 : S1OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
479 130449 : S1OutletAirHumRat = thisDXCoil.InletAirHumRat;
480 130449 : S1OutletAirTemp = thisDXCoil.InletAirTemp;
481 130449 : S1ElecCoolingPower = 0.0;
482 130449 : S1TotalCoolingEnergyRate = 0.0;
483 130449 : S1SensCoolingEnergyRate = 0.0;
484 130449 : S1LatCoolingEnergyRate = 0.0;
485 130449 : S1CrankcaseHeaterPower = 0.0;
486 130449 : S1EvapWaterConsumpRate = 0.0;
487 130449 : S1EvapCondPumpElecPower = 0.0;
488 :
489 130449 : S12RuntimeFraction = 0.0;
490 130449 : S12OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
491 130449 : S12OutletAirHumRat = thisDXCoil.InletAirHumRat;
492 130449 : S12OutletAirTemp = thisDXCoil.InletAirTemp;
493 130449 : S12ElecCoolingPower = 0.0;
494 130449 : S12TotalCoolingEnergyRate = 0.0;
495 130449 : S12SensCoolingEnergyRate = 0.0;
496 130449 : S12LatCoolingEnergyRate = 0.0;
497 130449 : S12CrankcaseHeaterPower = 0.0;
498 130449 : S12EvapWaterConsumpRate = 0.0;
499 130449 : S12EvapCondPumpElecPower = 0.0;
500 :
501 130449 : thisDXCoil.DehumidificationMode = DehumidMode;
502 130449 : 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 130449 : if ((thisDXCoil.NumCapacityStages == 1) || (PartLoadRatio <= 0.0)) {
510 : // Run stage 1 at its part load
511 78555 : PerfMode = (int)DehumidMode * 2 + 1; // This. This is not good. Don't do math on enums.
512 78555 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, PerfMode);
513 78555 : S1PLR = PartLoadRatio;
514 78555 : S2PLR = 0.0;
515 : } else {
516 : // If a two-stage coil
517 : // Run stage 1 at full load
518 51894 : PerfMode = (int)DehumidMode * 2 + 1;
519 51894 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, 1.0, fanOp, PerfMode);
520 51894 : S1SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
521 51894 : if (S1SensCoolingEnergyRate > 0.0) {
522 51894 : S1PLR = PartLoadRatio;
523 : } else {
524 0 : S1PLR = 0.0;
525 : }
526 : // Run stage 1+2 at full load
527 51894 : if (thisDXCoil.NumCapacityStages >= 2) {
528 51894 : PerfMode = (int)DehumidMode * 2 + 2;
529 51894 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, 1.0, fanOp, PerfMode);
530 51894 : S12SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
531 51894 : 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 51894 : if (S1SensCoolingEnergyRate > 0.0) {
545 51894 : S1PLR = PartLoadRatio * S12SensCoolingEnergyRate / S1SensCoolingEnergyRate;
546 : } else {
547 0 : S1PLR = 0.0;
548 : }
549 51894 : S1PLR = min(1.0, S1PLR);
550 51894 : S1PLR = max(0.0, S1PLR);
551 51894 : if ((S12SensCoolingEnergyRate - S1SensCoolingEnergyRate) > 0.0) {
552 51894 : S2PLR = (PartLoadRatio * S12SensCoolingEnergyRate - S1SensCoolingEnergyRate) / (S12SensCoolingEnergyRate - S1SensCoolingEnergyRate);
553 : } else {
554 0 : S2PLR = 0.0;
555 : }
556 51894 : S2PLR = min(1.0, S2PLR);
557 51894 : S2PLR = max(0.0, S2PLR);
558 :
559 : // Run stage 1 at its part load
560 51894 : PerfMode = (int)DehumidMode * 2 + 1;
561 51894 : 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 130449 : if ((S2PLR > 0.0) && (thisDXCoil.NumCapacityStages >= 2)) {
568 : // Store stage 1 outputs
569 46420 : S1RuntimeFraction = thisDXCoil.CoolingCoilRuntimeFraction;
570 46420 : S1OutletAirEnthalpy = thisDXCoil.OutletAirEnthalpy;
571 46420 : S1OutletAirHumRat = thisDXCoil.OutletAirHumRat;
572 46420 : S1OutletAirTemp = thisDXCoil.OutletAirTemp;
573 46420 : S1ElecCoolingPower = thisDXCoil.ElecCoolingPower;
574 46420 : S1TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate;
575 46420 : S1SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
576 46420 : S1LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate;
577 46420 : S1CrankcaseHeaterPower = thisDXCoil.CrankcaseHeaterPower;
578 46420 : S1EvapWaterConsumpRate = thisDXCoil.EvapWaterConsumpRate;
579 46420 : S1EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecPower;
580 :
581 : // Save first stage full load outlet conditions to pass to heat recovery
582 46420 : S1FFullLoadOutAirTemp = state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum);
583 46420 : S1FullLoadOutAirHumRat = state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum);
584 :
585 : // Run stage 1+2 at its part load
586 46420 : PerfMode = (int)DehumidMode * 2 + 2;
587 46420 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, S2PLR, fanOp, PerfMode);
588 46420 : S12RuntimeFraction = thisDXCoil.CoolingCoilRuntimeFraction;
589 46420 : S12OutletAirEnthalpy = thisDXCoil.OutletAirEnthalpy;
590 46420 : S12OutletAirHumRat = thisDXCoil.OutletAirHumRat;
591 46420 : S12OutletAirTemp = thisDXCoil.OutletAirTemp;
592 46420 : S12ElecCoolingPower = thisDXCoil.ElecCoolingPower;
593 46420 : S12TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate;
594 46420 : S12SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
595 46420 : S12LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate;
596 46420 : S12CrankcaseHeaterPower = thisDXCoil.CrankcaseHeaterPower;
597 46420 : S12EvapWaterConsumpRate = thisDXCoil.EvapWaterConsumpRate;
598 46420 : S12EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecPower;
599 :
600 : // Determine combined performance
601 46420 : thisDXCoil.OutletAirEnthalpy = (1.0 - S2PLR) * S1OutletAirEnthalpy + S2PLR * S12OutletAirEnthalpy;
602 46420 : thisDXCoil.OutletAirHumRat = (1.0 - S2PLR) * S1OutletAirHumRat + S2PLR * S12OutletAirHumRat;
603 46420 : thisDXCoil.OutletAirTemp = PsyTdbFnHW(thisDXCoil.OutletAirEnthalpy, thisDXCoil.OutletAirHumRat);
604 : // Check for saturation error and modify temperature at constant enthalpy
605 46420 : 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 46420 : TSat = PsyTsatFnHPb(state, thisDXCoil.OutletAirEnthalpy, state.dataEnvrn->OutBaroPress, RoutineName);
618 46420 : 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 46420 : 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 46420 : if (S12ElecCoolFullLoadPower > 0.0) {
635 46420 : thisDXCoil.ElecCoolingPower =
636 46420 : S1RuntimeFraction * S1ElecCoolingPower +
637 46420 : S12RuntimeFraction * (S12ElecCoolingPower - S1ElecCoolingPower * S12ElecCoolingPower / S12ElecCoolFullLoadPower);
638 : } else {
639 0 : thisDXCoil.ElecCoolingPower = 0.0;
640 : }
641 :
642 46420 : thisDXCoil.CoolingCoilRuntimeFraction = S1RuntimeFraction;
643 :
644 46420 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
645 46420 : CalcComponentSensibleLatentOutput(AirMassFlow,
646 : thisDXCoil.InletAirTemp,
647 : thisDXCoil.InletAirHumRat,
648 : thisDXCoil.OutletAirTemp,
649 : thisDXCoil.OutletAirHumRat,
650 46420 : thisDXCoil.SensCoolingEnergyRate,
651 46420 : thisDXCoil.LatCoolingEnergyRate,
652 46420 : thisDXCoil.TotalCoolingEnergyRate);
653 :
654 46420 : thisDXCoil.EvapWaterConsumpRate = (1.0 - S12RuntimeFraction) * S1EvapWaterConsumpRate + S12RuntimeFraction * S12EvapWaterConsumpRate;
655 46420 : thisDXCoil.EvapCondPumpElecPower = (1.0 - S12RuntimeFraction) * S1EvapCondPumpElecPower + S12RuntimeFraction * S12EvapCondPumpElecPower;
656 :
657 : // Stage 1 runtime sets the crankcase heater power
658 46420 : thisDXCoil.CrankcaseHeaterPower = S1CrankcaseHeaterPower;
659 :
660 46420 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
661 46420 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
662 :
663 : // calculate average full load outlet conditions for second stage operation
664 46420 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) =
665 46420 : (1.0 - S2PLR) * S1FFullLoadOutAirTemp + S2PLR * state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum);
666 46420 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) =
667 46420 : (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 130449 : thisDXCoil.PartLoadRatio = S1PLR;
673 130449 : 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 130449 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
677 :
678 130449 : thisDXCoil.CoolingCoilStg2RuntimeFrac = S12RuntimeFraction;
679 :
680 : // Calculate basin heater power
681 130449 : 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 130449 : UpdateDXCoil(state, DXCoilNum);
690 :
691 : // Report the result of the simulation
692 130449 : ReportDXCoil(state, DXCoilNum);
693 130449 : }
694 :
695 251 : 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 251 : 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 251 : Array1D_string Alphas2; // Alpha input items for object
740 251 : Array1D<Real64> Numbers2; // Numeric input items for object
741 251 : Array1D_string cAlphaFields2; // Alpha field names
742 251 : Array1D_string cNumericFields2; // Numeric field names
743 251 : Array1D_bool lAlphaBlanks2; // Logical array, alpha field input BLANK = .TRUE.
744 251 : 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 251 : 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 251 : std::string CurrentModuleObject; // Object type for getting and error messages
756 251 : std::string PerfObjectType; // Performance object type for getting and error messages
757 251 : 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 251 : Array1D_string Alphas; // Alpha input items for object
763 251 : Array1D_string cAlphaFields; // Alpha field names
764 251 : Array1D_string cNumericFields; // Numeric field names
765 251 : Array1D<Real64> Numbers; // Numeric input items for object
766 251 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
767 251 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
768 251 : int MaxNumbers(0); // Maximum number of numeric input fields
769 251 : int MaxAlphas(0); // Maximum number of alpha input fields
770 251 : 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 251 : state.dataDXCoils->NumDoe2DXCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:SingleSpeed");
780 251 : state.dataDXCoils->NumDXHeatingCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:DX:SingleSpeed");
781 251 : state.dataDXCoils->NumDXMulSpeedCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:TwoSpeed");
782 502 : state.dataDXCoils->NumDXMulModeCoils =
783 251 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:TwoStageWithHumidityControlMode");
784 502 : state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils =
785 251 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped));
786 502 : state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils =
787 251 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped));
788 251 : state.dataDXCoils->NumDXMulSpeedCoolCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:MultiSpeed");
789 251 : state.dataDXCoils->NumDXMulSpeedHeatCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:DX:MultiSpeed");
790 502 : state.dataDXCoils->NumVRFCoolingCoils =
791 251 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling));
792 502 : state.dataDXCoils->NumVRFHeatingCoils =
793 251 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating));
794 502 : state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils =
795 251 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling));
796 502 : state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils =
797 251 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating));
798 :
799 251 : state.dataDXCoils->NumDXCoils = state.dataDXCoils->NumDoe2DXCoils + state.dataDXCoils->NumDXHeatingCoils + state.dataDXCoils->NumDXMulSpeedCoils +
800 251 : state.dataDXCoils->NumDXMulModeCoils + state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils +
801 251 : state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils + state.dataDXCoils->NumDXMulSpeedCoolCoils +
802 251 : state.dataDXCoils->NumDXMulSpeedHeatCoils + state.dataDXCoils->NumVRFCoolingCoils +
803 251 : state.dataDXCoils->NumVRFHeatingCoils + state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils +
804 251 : 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 251 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:SingleSpeed", TotalArgs, NumAlphas, NumNumbers);
808 251 : MaxNumbers = NumNumbers;
809 251 : MaxAlphas = NumAlphas;
810 251 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:DX:SingleSpeed", TotalArgs, NumAlphas, NumNumbers);
811 251 : MaxNumbers = max(MaxNumbers, NumNumbers);
812 251 : MaxAlphas = max(MaxAlphas, NumAlphas);
813 251 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:TwoSpeed", TotalArgs, NumAlphas, NumNumbers);
814 251 : MaxNumbers = max(MaxNumbers, NumNumbers);
815 251 : MaxAlphas = max(MaxAlphas, NumAlphas);
816 251 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
817 : state, "Coil:Cooling:DX:TwoStageWithHumidityControlMode", TotalArgs, NumAlphas, NumNumbers);
818 251 : MaxNumbers = max(MaxNumbers, NumNumbers);
819 251 : MaxAlphas = max(MaxAlphas, NumAlphas);
820 502 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
821 251 : state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped), TotalArgs, NumAlphas, NumNumbers);
822 251 : MaxNumbers = max(MaxNumbers, NumNumbers);
823 251 : MaxAlphas = max(MaxAlphas, NumAlphas);
824 502 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
825 251 : state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped), TotalArgs, NumAlphas, NumNumbers);
826 251 : MaxNumbers = max(MaxNumbers, NumNumbers);
827 251 : MaxAlphas = max(MaxAlphas, NumAlphas);
828 251 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:MultiSpeed", TotalArgs, NumAlphas, NumNumbers);
829 251 : MaxNumbers = max(MaxNumbers, NumNumbers);
830 251 : MaxAlphas = max(MaxAlphas, NumAlphas);
831 251 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:DX:MultiSpeed", TotalArgs, NumAlphas, NumNumbers);
832 251 : MaxNumbers = max(MaxNumbers, NumNumbers);
833 251 : MaxAlphas = max(MaxAlphas, NumAlphas);
834 502 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
835 251 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling), TotalArgs, NumAlphas, NumNumbers);
836 251 : MaxNumbers = max(MaxNumbers, NumNumbers);
837 251 : MaxAlphas = max(MaxAlphas, NumAlphas);
838 502 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
839 251 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating), TotalArgs, NumAlphas, NumNumbers);
840 251 : MaxNumbers = max(MaxNumbers, NumNumbers);
841 251 : MaxAlphas = max(MaxAlphas, NumAlphas);
842 502 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
843 251 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling), TotalArgs, NumAlphas, NumNumbers);
844 251 : MaxNumbers = max(MaxNumbers, NumNumbers);
845 251 : MaxAlphas = max(MaxAlphas, NumAlphas);
846 502 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
847 251 : state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating), TotalArgs, NumAlphas, NumNumbers);
848 251 : MaxNumbers = max(MaxNumbers, NumNumbers);
849 251 : MaxAlphas = max(MaxAlphas, NumAlphas);
850 251 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "CoilPerformance:DX:Cooling", TotalArgs, NumAlphas, NumNumbers);
851 251 : MaxNumbers = max(MaxNumbers, NumNumbers);
852 251 : MaxAlphas = max(MaxAlphas, NumAlphas);
853 :
854 251 : Alphas.allocate(MaxAlphas);
855 251 : cAlphaFields.allocate(MaxAlphas);
856 251 : cNumericFields.allocate(MaxNumbers);
857 251 : Numbers.dimension(MaxNumbers, 0.0);
858 251 : lAlphaBlanks.dimension(MaxAlphas, true);
859 251 : lNumericBlanks.dimension(MaxNumbers, true);
860 :
861 251 : Alphas2.allocate(MaxAlphas);
862 251 : cAlphaFields2.allocate(MaxAlphas);
863 251 : cNumericFields2.allocate(MaxNumbers);
864 251 : Numbers2.dimension(MaxNumbers, 0.0);
865 251 : lAlphaBlanks2.dimension(MaxAlphas, true);
866 251 : lNumericBlanks2.dimension(MaxNumbers, true);
867 :
868 : // allocate the data structure
869 :
870 : // Derived types
871 251 : state.dataDXCoils->DXCoil.allocate(state.dataDXCoils->NumDXCoils);
872 251 : state.dataDXCoils->DXCoilNumericFields.allocate(state.dataDXCoils->NumDXCoils);
873 251 : state.dataHeatBal->HeatReclaimDXCoil.allocate(state.dataDXCoils->NumDXCoils);
874 251 : state.dataDXCoils->CheckEquipName.dimension(state.dataDXCoils->NumDXCoils, true);
875 :
876 : // Module level variable arrays
877 251 : state.dataDXCoils->DXCoilOutletTemp.allocate(state.dataDXCoils->NumDXCoils);
878 251 : state.dataDXCoils->DXCoilOutletHumRat.allocate(state.dataDXCoils->NumDXCoils);
879 251 : state.dataDXCoils->DXCoilPartLoadRatio.allocate(state.dataDXCoils->NumDXCoils);
880 251 : state.dataDXCoils->DXCoilFanOp.allocate(state.dataDXCoils->NumDXCoils);
881 251 : state.dataDXCoils->DXCoilFullLoadOutAirTemp.allocate(state.dataDXCoils->NumDXCoils);
882 251 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat.allocate(state.dataDXCoils->NumDXCoils);
883 251 : state.dataDXCoils->DXCoilTotalCooling.allocate(state.dataDXCoils->NumDXCoils);
884 251 : state.dataDXCoils->DXCoilTotalHeating.allocate(state.dataDXCoils->NumDXCoils);
885 251 : state.dataDXCoils->DXCoilCoolInletAirWBTemp.allocate(state.dataDXCoils->NumDXCoils);
886 251 : state.dataDXCoils->DXCoilHeatInletAirDBTemp.allocate(state.dataDXCoils->NumDXCoils);
887 251 : state.dataDXCoils->DXCoilHeatInletAirWBTemp.allocate(state.dataDXCoils->NumDXCoils);
888 :
889 : // initialize the module level arrays
890 251 : state.dataDXCoils->DXCoilOutletTemp = 0.0;
891 251 : state.dataDXCoils->DXCoilOutletHumRat = 0.0;
892 251 : state.dataDXCoils->DXCoilPartLoadRatio = 0.0;
893 251 : state.dataDXCoils->DXCoilFanOp = HVAC::FanOp::Invalid;
894 251 : state.dataDXCoils->DXCoilFullLoadOutAirTemp = 0.0;
895 251 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat = 0.0;
896 :
897 : // initialize the coil counter
898 251 : DXCoilNum = 0;
899 :
900 : // Loop over the Doe2 DX Coils and get & load the data
901 251 : CurrentModuleObject = "Coil:Cooling:DX:SingleSpeed";
902 876 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDoe2DXCoils; ++DXCoilIndex) {
903 :
904 625 : 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 625 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
918 :
919 625 : ++DXCoilNum;
920 : // allocate single performance mode for numeric field strings used for sizing routine
921 625 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
922 625 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
923 625 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
924 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
925 625 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
926 :
927 625 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
928 625 : thisDXCoil.Name = Alphas(1);
929 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
930 625 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
931 625 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
932 625 : thisDXCoil.DXCoilType = CurrentModuleObject;
933 625 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingSingleSpeed;
934 625 : if (lAlphaBlanks(2)) {
935 87 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
936 538 : } 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 625 : thisDXCoil.RatedTotCap(1) = Numbers(1);
941 625 : thisDXCoil.RatedSHR(1) = Numbers(2);
942 625 : thisDXCoil.RatedCOP(1) = Numbers(3);
943 625 : 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 625 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(4);
950 625 : thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(5);
951 625 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(6);
952 :
953 625 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
954 625 : Alphas(3),
955 : ErrorsFound,
956 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
957 625 : Alphas(1),
958 : DataLoopNode::NodeFluidType::Air,
959 : DataLoopNode::ConnectionType::Inlet,
960 : NodeInputManager::CompFluidStream::Primary,
961 : ObjectIsNotParent);
962 :
963 1250 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
964 625 : Alphas(4),
965 : ErrorsFound,
966 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
967 625 : Alphas(1),
968 : DataLoopNode::NodeFluidType::Air,
969 : DataLoopNode::ConnectionType::Outlet,
970 : NodeInputManager::CompFluidStream::Primary,
971 : ObjectIsNotParent);
972 :
973 625 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
974 :
975 625 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
976 625 : 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 1875 : ErrorsFound |= Curve::CheckCurveDims(state,
988 625 : thisDXCoil.CCapFTemp(1), // Curve index
989 : {2}, // Valid dimensions
990 : RoutineName, // Routine name
991 : CurrentModuleObject, // Object Type
992 : thisDXCoil.Name, // Object Name
993 625 : cAlphaFields(5)); // Field Name
994 :
995 625 : if (!ErrorsFound) {
996 625 : checkCurveIsNormalizedToOne(state,
997 1875 : std::string{RoutineName} + CurrentModuleObject,
998 625 : thisDXCoil.Name,
999 625 : thisDXCoil.CCapFTemp(1),
1000 625 : cAlphaFields(5),
1001 625 : Alphas(5),
1002 : RatedInletWetBulbTemp,
1003 : RatedOutdoorAirTemp);
1004 : }
1005 : }
1006 :
1007 625 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
1008 625 : 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 1875 : ErrorsFound |= Curve::CheckCurveDims(state,
1020 625 : thisDXCoil.CCapFFlow(1), // Curve index
1021 : {1}, // Valid dimensions
1022 : RoutineName, // Routine name
1023 : CurrentModuleObject, // Object Type
1024 : thisDXCoil.Name, // Object Name
1025 625 : cAlphaFields(6)); // Field Name
1026 :
1027 625 : if (!ErrorsFound) {
1028 625 : checkCurveIsNormalizedToOne(
1029 2500 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
1030 : }
1031 : }
1032 :
1033 625 : thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
1034 625 : 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 1875 : ErrorsFound |= Curve::CheckCurveDims(state,
1046 625 : thisDXCoil.EIRFTemp(1), // Curve index
1047 : {2}, // Valid dimensions
1048 : RoutineName, // Routine name
1049 : CurrentModuleObject, // Object Type
1050 : thisDXCoil.Name, // Object Name
1051 625 : cAlphaFields(7)); // Field Name
1052 :
1053 625 : if (!ErrorsFound) {
1054 625 : checkCurveIsNormalizedToOne(state,
1055 1875 : std::string{RoutineName} + CurrentModuleObject,
1056 625 : thisDXCoil.Name,
1057 625 : thisDXCoil.EIRFTemp(1),
1058 625 : cAlphaFields(7),
1059 625 : Alphas(7),
1060 : RatedInletWetBulbTemp,
1061 : RatedOutdoorAirTemp);
1062 : }
1063 : }
1064 :
1065 625 : thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
1066 625 : 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 1875 : ErrorsFound |= Curve::CheckCurveDims(state,
1078 625 : thisDXCoil.EIRFFlow(1), // Curve index
1079 : {1}, // Valid dimensions
1080 : RoutineName, // Routine name
1081 : CurrentModuleObject, // Object Type
1082 : thisDXCoil.Name, // Object Name
1083 625 : cAlphaFields(8)); // Field Name
1084 :
1085 625 : if (!ErrorsFound) {
1086 625 : checkCurveIsNormalizedToOne(
1087 2500 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
1088 : }
1089 : }
1090 :
1091 625 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
1092 625 : 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 1875 : ErrorsFound |= Curve::CheckCurveDims(state,
1104 625 : thisDXCoil.PLFFPLR(1), // Curve index
1105 : {1}, // Valid dimensions
1106 : RoutineName, // Routine name
1107 : CurrentModuleObject, // Object Type
1108 : thisDXCoil.Name, // Object Name
1109 625 : cAlphaFields(9)); // Field Name
1110 :
1111 625 : if (!ErrorsFound) {
1112 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
1113 625 : MinCurveVal = 999.0;
1114 625 : MaxCurveVal = -999.0;
1115 625 : CurveInput = 0.0;
1116 63125 : while (CurveInput <= 1.0) {
1117 62500 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
1118 62500 : if (CurveVal < MinCurveVal) {
1119 625 : MinCurveVal = CurveVal;
1120 625 : MinCurvePLR = CurveInput;
1121 : }
1122 62500 : if (CurveVal > MaxCurveVal) {
1123 61708 : MaxCurveVal = CurveVal;
1124 61708 : MaxCurvePLR = CurveInput;
1125 : }
1126 62500 : CurveInput += 0.01;
1127 : }
1128 625 : 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 625 : if (MaxCurveVal > 1.0) {
1138 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1139 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
1140 0 : ShowContinueError(state,
1141 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
1142 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
1143 0 : Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
1144 : }
1145 : }
1146 : }
1147 :
1148 : // Set minimum OAT for compressor operation
1149 625 : thisDXCoil.MinOATCompressor = Numbers(7);
1150 625 : 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 625 : thisDXCoil.Twet_Rated(1) = Numbers(8);
1155 625 : thisDXCoil.Gamma_Rated(1) = Numbers(9);
1156 625 : thisDXCoil.MaxONOFFCyclesperHour(1) = Numbers(10);
1157 625 : 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 654 : if ((Numbers(8) > 0.0 || Numbers(9) > 0.0 || Numbers(10) > 0.0 || Numbers(11) > 0.0) &&
1161 29 : (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 625 : if (lAlphaBlanks(10)) {
1169 512 : thisDXCoil.CondenserInletNodeNum(1) = 0;
1170 : } else {
1171 226 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
1172 113 : Alphas(10),
1173 : ErrorsFound,
1174 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
1175 113 : thisDXCoil.Name,
1176 : DataLoopNode::NodeFluidType::Air,
1177 : DataLoopNode::ConnectionType::OutsideAirReference,
1178 : NodeInputManager::CompFluidStream::Primary,
1179 : ObjectIsNotParent);
1180 :
1181 113 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
1182 0 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1183 0 : ShowContinueError(
1184 : state,
1185 0 : format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(10), Alphas(10)));
1186 0 : ShowContinueError(
1187 : state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
1188 : }
1189 : }
1190 :
1191 625 : if ((Util::SameString(Alphas(11), "AirCooled")) || lAlphaBlanks(11)) {
1192 623 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
1193 2 : } else if (Util::SameString(Alphas(11), "EvaporativelyCooled")) {
1194 2 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
1195 2 : thisDXCoil.ReportEvapCondVars = true;
1196 : } else {
1197 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1198 0 : ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(11), Alphas(11)));
1199 0 : ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
1200 0 : ErrorsFound = true;
1201 : }
1202 :
1203 625 : thisDXCoil.EvapCondEffect(1) = Numbers(12);
1204 625 : 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 625 : thisDXCoil.EvapCondAirFlow(1) = Numbers(13);
1212 625 : 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 625 : thisDXCoil.EvapCondPumpElecNomPower(1) = Numbers(14);
1220 625 : 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 625 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(15);
1229 625 : 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 625 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(16);
1238 :
1239 625 : if (thisDXCoil.RatedCOP(1) > 0.0) {
1240 625 : thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
1241 : }
1242 :
1243 : // A12, \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
1244 625 : if (!lAlphaBlanks(12)) {
1245 1 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(12));
1246 1 : 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 3 : 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 1 : cAlphaFields(12)); // Field Name
1257 : }
1258 : }
1259 :
1260 : // Get Water System tank connections
1261 : // A13, \field Name of Water Storage Tank for Supply
1262 625 : thisDXCoil.EvapWaterSupplyName = Alphas(13);
1263 625 : if (lAlphaBlanks(13)) {
1264 625 : 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 625 : thisDXCoil.CondensateCollectName = Alphas(14);
1278 625 : if (lAlphaBlanks(14)) {
1279 625 : 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 625 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(17);
1293 625 : 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 625 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(18);
1301 625 : 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 625 : 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 625 : 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 625 : if (!lAlphaBlanks(17) && NumAlphas > 16) {
1337 0 : thisDXCoil.SHRFFlow(1) = GetCurveIndex(state, Alphas(17)); // convert curve name to number
1338 0 : if (thisDXCoil.SHRFTemp(1) == 0) {
1339 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
1340 0 : 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 625 : 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 625 : if (lAlphaBlanks(18)) {
1358 617 : thisDXCoil.ASHRAE127StdRprt = false;
1359 : } else {
1360 8 : if (Alphas(18) == "YES" || Alphas(18) == "Yes") {
1361 8 : thisDXCoil.ASHRAE127StdRprt = true;
1362 : } else {
1363 0 : thisDXCoil.ASHRAE127StdRprt = false;
1364 : }
1365 : }
1366 : // A19; \field Zone Name for Condenser Placement
1367 625 : if (!lAlphaBlanks(19) && NumAlphas > 18) {
1368 1 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(19), state.dataHeatBal->Zone);
1369 :
1370 1 : if (thisDXCoil.SecZonePtr > 0) {
1371 1 : SetupZoneInternalGain(state,
1372 : thisDXCoil.SecZonePtr,
1373 : thisDXCoil.Name,
1374 : DataHeatBalance::IntGainType::SecCoolingDXCoilSingleSpeed,
1375 : &thisDXCoil.SecCoilSensibleHeatGainRate);
1376 1 : 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 251 : 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 251 : CurrentModuleObject = "Coil:Cooling:DX:TwoStageWithHumidityControlMode";
1392 262 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulModeCoils; ++DXCoilIndex) {
1393 :
1394 11 : 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 11 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
1408 11 : ++DXCoilNum;
1409 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
1410 11 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
1411 :
1412 11 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
1413 11 : thisDXCoil.Name = Alphas(1);
1414 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
1415 11 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
1416 11 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
1417 11 : thisDXCoil.DXCoilType = CurrentModuleObject;
1418 11 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingTwoStageWHumControl;
1419 11 : if (lAlphaBlanks(2)) {
1420 4 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
1421 7 : } 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 11 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
1427 11 : Alphas(3),
1428 : ErrorsFound,
1429 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoStageWithHumidityControlMode,
1430 11 : Alphas(1),
1431 : DataLoopNode::NodeFluidType::Air,
1432 : DataLoopNode::ConnectionType::Inlet,
1433 : NodeInputManager::CompFluidStream::Primary,
1434 : ObjectIsNotParent);
1435 :
1436 22 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
1437 11 : Alphas(4),
1438 : ErrorsFound,
1439 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoStageWithHumidityControlMode,
1440 11 : Alphas(1),
1441 : DataLoopNode::NodeFluidType::Air,
1442 : DataLoopNode::ConnectionType::Outlet,
1443 : NodeInputManager::CompFluidStream::Primary,
1444 : ObjectIsNotParent);
1445 :
1446 11 : 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 11 : if (!lAlphaBlanks(5)) {
1450 0 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
1451 0 : 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 0 : 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 0 : cAlphaFields(5)); // Field Name
1462 : }
1463 : }
1464 :
1465 : // Set crankcase heater capacity
1466 11 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(1);
1467 11 : 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 11 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(2);
1475 :
1476 : // Number of capacity stages
1477 11 : thisDXCoil.NumCapacityStages = Numbers(3);
1478 : // Check if requested number of capacity stages exceeds limits
1479 11 : 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 11 : thisDXCoil.NumDehumidModes = Numbers(4);
1488 : // Check if requested number of enhanced dehumidification modes exceeds limits
1489 11 : 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 11 : AlphaIndex = 6;
1498 : // allocate performance modes for numeric field strings used for sizing routine
1499 22 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(
1500 11 : thisDXCoil.NumDehumidModes * 2 + thisDXCoil.NumCapacityStages * 2); // not sure this math is correct, ask MW
1501 :
1502 : // Loop through capacity stages and dehumidification modes
1503 29 : for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
1504 53 : for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
1505 : // Check if sufficient number of fields entered
1506 35 : 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 35 : PerfObjectType = Alphas(AlphaIndex);
1513 35 : PerfObjectName = Alphas(AlphaIndex + 1);
1514 35 : PerfModeNum = DehumidModeNum * 2 + CapacityStageNum;
1515 35 : thisDXCoil.CoilPerformanceType(PerfModeNum) = PerfObjectType;
1516 35 : if (Util::SameString(PerfObjectType, "CoilPerformance:DX:Cooling")) {
1517 35 : 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 35 : thisDXCoil.CoilPerformanceName(PerfModeNum) = PerfObjectName;
1525 : // Get for CoilPerformance object
1526 35 : PerfObjectNum = state.dataInputProcessing->inputProcessor->getObjectItemNum(state, PerfObjectType, PerfObjectName);
1527 35 : if (PerfObjectNum > 0) {
1528 :
1529 35 : 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 35 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum)
1544 35 : .PerfMode(PerfModeNum)
1545 35 : .FieldNames.allocate(NumNumbers2); // use MaxNumbers here??
1546 35 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(PerfModeNum).FieldNames = cNumericFields2;
1547 :
1548 35 : thisDXCoil.RatedTotCap(PerfModeNum) = Numbers2(1);
1549 35 : thisDXCoil.RatedSHR(PerfModeNum) = Numbers2(2);
1550 35 : thisDXCoil.RatedCOP(PerfModeNum) = Numbers2(3);
1551 : // Rated flow is immediately adjusted for bypass fraction if not autosized
1552 35 : thisDXCoil.BypassedFlowFrac(PerfModeNum) = Numbers2(5);
1553 35 : thisDXCoil.RatedAirVolFlowRate(PerfModeNum) = Numbers2(4);
1554 35 : if (thisDXCoil.RatedAirVolFlowRate(PerfModeNum) != AutoSize) {
1555 7 : thisDXCoil.RatedAirVolFlowRate(PerfModeNum) *= (1.0 - thisDXCoil.BypassedFlowFrac(PerfModeNum));
1556 : }
1557 :
1558 35 : thisDXCoil.CCapFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(2)); // convert curve name to number
1559 35 : 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 105 : ErrorsFound |= Curve::CheckCurveDims(state,
1571 35 : thisDXCoil.CCapFTemp(PerfModeNum), // Curve index
1572 : {2}, // Valid dimensions
1573 : RoutineName, // Routine name
1574 : CurrentModuleObject, // Object Type
1575 : thisDXCoil.Name, // Object Name
1576 35 : cAlphaFields2(2)); // Field Name
1577 :
1578 35 : if (!ErrorsFound) {
1579 35 : checkCurveIsNormalizedToOne(state,
1580 105 : std::string{RoutineName} + CurrentModuleObject,
1581 35 : thisDXCoil.Name,
1582 35 : thisDXCoil.CCapFTemp(PerfModeNum),
1583 35 : cAlphaFields2(2),
1584 35 : Alphas2(2),
1585 : RatedInletWetBulbTemp,
1586 : RatedOutdoorAirTemp);
1587 : }
1588 : }
1589 :
1590 35 : thisDXCoil.CCapFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(3)); // convert curve name to number
1591 35 : 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 105 : ErrorsFound |= Curve::CheckCurveDims(state,
1603 35 : thisDXCoil.CCapFFlow(PerfModeNum), // Curve index
1604 : {1}, // Valid dimensions
1605 : RoutineName, // Routine name
1606 : CurrentModuleObject, // Object Type
1607 : thisDXCoil.Name, // Object Name
1608 35 : cAlphaFields2(3)); // Field Name
1609 :
1610 35 : if (!ErrorsFound) {
1611 35 : checkCurveIsNormalizedToOne(state,
1612 105 : std::string{RoutineName} + CurrentModuleObject,
1613 35 : thisDXCoil.Name,
1614 35 : thisDXCoil.CCapFFlow(PerfModeNum),
1615 35 : cAlphaFields2(3),
1616 35 : Alphas2(3),
1617 : 1.0);
1618 : }
1619 : }
1620 :
1621 35 : thisDXCoil.EIRFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(4)); // convert curve name to number
1622 35 : 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 105 : ErrorsFound |= Curve::CheckCurveDims(state,
1634 35 : thisDXCoil.EIRFTemp(PerfModeNum), // Curve index
1635 : {2}, // Valid dimensions
1636 : RoutineName, // Routine name
1637 : CurrentModuleObject, // Object Type
1638 : thisDXCoil.Name, // Object Name
1639 35 : cAlphaFields2(4)); // Field Name
1640 :
1641 35 : if (!ErrorsFound) {
1642 35 : checkCurveIsNormalizedToOne(state,
1643 105 : std::string{RoutineName} + CurrentModuleObject,
1644 35 : thisDXCoil.Name,
1645 35 : thisDXCoil.EIRFTemp(PerfModeNum),
1646 35 : cAlphaFields2(4),
1647 35 : Alphas2(4),
1648 : RatedInletWetBulbTemp,
1649 : RatedOutdoorAirTemp);
1650 : }
1651 : }
1652 :
1653 35 : thisDXCoil.EIRFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(5)); // convert curve name to number
1654 35 : 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 105 : ErrorsFound |= Curve::CheckCurveDims(state,
1666 35 : thisDXCoil.EIRFFlow(PerfModeNum), // Curve index
1667 : {1}, // Valid dimensions
1668 : RoutineName, // Routine name
1669 : CurrentModuleObject, // Object Type
1670 : thisDXCoil.Name, // Object Name
1671 35 : cAlphaFields2(5)); // Field Name
1672 :
1673 35 : if (!ErrorsFound) {
1674 35 : checkCurveIsNormalizedToOne(state,
1675 105 : std::string{RoutineName} + CurrentModuleObject,
1676 35 : thisDXCoil.Name,
1677 35 : thisDXCoil.EIRFFlow(PerfModeNum),
1678 35 : cAlphaFields2(5),
1679 35 : Alphas2(5),
1680 : 1.0);
1681 : }
1682 : }
1683 :
1684 35 : thisDXCoil.PLFFPLR(PerfModeNum) = GetCurveIndex(state, Alphas2(6)); // convert curve name to number
1685 35 : 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 105 : ErrorsFound |= Curve::CheckCurveDims(state,
1697 35 : thisDXCoil.PLFFPLR(PerfModeNum), // Curve index
1698 : {1}, // Valid dimensions
1699 : RoutineName, // Routine name
1700 : CurrentModuleObject, // Object Type
1701 : thisDXCoil.Name, // Object Name
1702 35 : cAlphaFields2(6)); // Field Name
1703 :
1704 35 : if (!ErrorsFound) {
1705 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
1706 35 : MinCurveVal = 999.0;
1707 35 : MaxCurveVal = -999.0;
1708 35 : CurveInput = 0.0;
1709 3535 : while (CurveInput <= 1.0) {
1710 3500 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(PerfModeNum), CurveInput);
1711 3500 : if (CurveVal < MinCurveVal) {
1712 35 : MinCurveVal = CurveVal;
1713 35 : MinCurvePLR = CurveInput;
1714 : }
1715 3500 : if (CurveVal > MaxCurveVal) {
1716 3500 : MaxCurveVal = CurveVal;
1717 3500 : MaxCurvePLR = CurveInput;
1718 : }
1719 3500 : CurveInput += 0.01;
1720 : }
1721 35 : 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 35 : 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 35 : thisDXCoil.Twet_Rated(PerfModeNum) = Numbers2(6);
1744 35 : thisDXCoil.Gamma_Rated(PerfModeNum) = Numbers2(7);
1745 35 : thisDXCoil.MaxONOFFCyclesperHour(PerfModeNum) = Numbers2(8);
1746 35 : thisDXCoil.LatentCapacityTimeConstant(PerfModeNum) = Numbers2(9);
1747 : // Numbers2 (6) through (9) must all be greater than zero to use the latent capacity degradation model
1748 35 : 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 35 : if (lAlphaBlanks2(7)) {
1758 35 : 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 35 : if ((Util::SameString(Alphas2(8), "AirCooled")) || lAlphaBlanks2(8)) {
1781 35 : 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 35 : thisDXCoil.EvapCondEffect(PerfModeNum) = Numbers2(10);
1793 35 : 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 35 : thisDXCoil.EvapCondAirFlow(PerfModeNum) = Numbers2(11);
1801 35 : 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 35 : thisDXCoil.EvapCondPumpElecNomPower(PerfModeNum) = Numbers2(12);
1809 35 : 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 35 : thisDXCoil.RatedEIR(PerfModeNum) = 1.0 / thisDXCoil.RatedCOP(PerfModeNum);
1817 :
1818 : // read in user specified SHR modifier curves
1819 35 : 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 35 : 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 35 : if (thisDXCoil.SHRFTemp(PerfModeNum) > 0 && thisDXCoil.SHRFFlow(PerfModeNum) > 0) {
1853 0 : thisDXCoil.UserSHRCurveExists = true;
1854 : } else {
1855 35 : 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 35 : 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 19 : for (CapacityStageNum = (thisDXCoil.NumCapacityStages + 1); CapacityStageNum <= MaxCapacityStages; ++CapacityStageNum) {
1868 1 : 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 1 : 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 11 : thisDXCoil.EvapWaterSupplyName = Alphas(14);
1880 11 : if (lAlphaBlanks(14)) {
1881 11 : 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 11 : thisDXCoil.CondensateCollectName = Alphas(15);
1895 11 : if (lAlphaBlanks(15)) {
1896 11 : 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 11 : thisDXCoil.MinOATCompressor = Numbers(5);
1910 11 : if (NumNumbers < 5) {
1911 8 : 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 11 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(6);
1916 11 : 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 11 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(7);
1924 11 : 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 11 : 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 251 : 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 251 : CurrentModuleObject = "Coil:Heating:DX:SingleSpeed";
1951 326 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXHeatingCoils; ++DXCoilIndex) {
1952 :
1953 75 : ++DXCoilNum;
1954 :
1955 75 : 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 75 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
1969 : // allocate single performance mode for numeric field strings used for sizing routine
1970 75 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
1971 75 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
1972 75 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
1973 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
1974 75 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
1975 :
1976 75 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
1977 75 : thisDXCoil.Name = Alphas(1);
1978 75 : thisDXCoil.DXCoilType = CurrentModuleObject;
1979 75 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatingEmpirical;
1980 75 : if (lAlphaBlanks(2)) {
1981 22 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
1982 53 : } 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 75 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
1988 75 : Alphas(3),
1989 : ErrorsFound,
1990 : DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
1991 75 : Alphas(1),
1992 : DataLoopNode::NodeFluidType::Air,
1993 : DataLoopNode::ConnectionType::Inlet,
1994 : NodeInputManager::CompFluidStream::Primary,
1995 : ObjectIsNotParent);
1996 :
1997 150 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
1998 75 : Alphas(4),
1999 : ErrorsFound,
2000 : DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
2001 75 : Alphas(1),
2002 : DataLoopNode::NodeFluidType::Air,
2003 : DataLoopNode::ConnectionType::Outlet,
2004 : NodeInputManager::CompFluidStream::Primary,
2005 : ObjectIsNotParent);
2006 :
2007 75 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
2008 :
2009 75 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
2010 75 : 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 225 : ErrorsFound |= Curve::CheckCurveDims(state,
2022 75 : 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 75 : cAlphaFields(5)); // Field Name
2028 :
2029 75 : if (!ErrorsFound) {
2030 75 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
2031 74 : checkCurveIsNormalizedToOne(state,
2032 222 : std::string{RoutineName} + CurrentModuleObject,
2033 74 : thisDXCoil.Name,
2034 74 : thisDXCoil.CCapFTemp(1),
2035 74 : cAlphaFields(5),
2036 74 : Alphas(5),
2037 : RatedOutdoorAirTempHeat);
2038 : } else {
2039 1 : checkCurveIsNormalizedToOne(state,
2040 3 : std::string{RoutineName} + CurrentModuleObject,
2041 1 : thisDXCoil.Name,
2042 1 : thisDXCoil.CCapFTemp(1),
2043 1 : cAlphaFields(5),
2044 1 : Alphas(5),
2045 : RatedInletAirTempHeat,
2046 : RatedOutdoorAirTempHeat);
2047 : }
2048 : }
2049 : }
2050 :
2051 75 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
2052 75 : 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 225 : ErrorsFound |= Curve::CheckCurveDims(state,
2064 75 : thisDXCoil.CCapFFlow(1), // Curve index
2065 : {1}, // Valid dimensions
2066 : RoutineName, // Routine name
2067 : CurrentModuleObject, // Object Type
2068 : thisDXCoil.Name, // Object Name
2069 75 : cAlphaFields(6)); // Field Name
2070 :
2071 75 : if (!ErrorsFound) {
2072 75 : checkCurveIsNormalizedToOne(
2073 300 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
2074 : }
2075 : }
2076 :
2077 75 : thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
2078 75 : 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 225 : ErrorsFound |= Curve::CheckCurveDims(state,
2090 75 : 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 75 : cAlphaFields(7)); // Field Name
2096 :
2097 75 : if (!ErrorsFound) {
2098 75 : if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(1))->numDims == 1) {
2099 74 : checkCurveIsNormalizedToOne(state,
2100 222 : std::string{RoutineName} + CurrentModuleObject,
2101 74 : thisDXCoil.Name,
2102 74 : thisDXCoil.EIRFTemp(1),
2103 74 : cAlphaFields(7),
2104 74 : Alphas(7),
2105 : RatedOutdoorAirTempHeat);
2106 : } else {
2107 1 : checkCurveIsNormalizedToOne(state,
2108 3 : std::string{RoutineName} + CurrentModuleObject,
2109 1 : thisDXCoil.Name,
2110 1 : thisDXCoil.EIRFTemp(1),
2111 1 : cAlphaFields(7),
2112 1 : Alphas(7),
2113 : RatedInletAirTempHeat,
2114 : RatedOutdoorAirTempHeat);
2115 : }
2116 : }
2117 : }
2118 :
2119 75 : thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
2120 75 : 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 225 : ErrorsFound |= Curve::CheckCurveDims(state,
2132 75 : thisDXCoil.EIRFFlow(1), // Curve index
2133 : {1}, // Valid dimensions
2134 : RoutineName, // Routine name
2135 : CurrentModuleObject, // Object Type
2136 : thisDXCoil.Name, // Object Name
2137 75 : cAlphaFields(8)); // Field Name
2138 :
2139 75 : if (!ErrorsFound) {
2140 75 : checkCurveIsNormalizedToOne(
2141 300 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
2142 : }
2143 : }
2144 :
2145 75 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
2146 75 : 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 225 : ErrorsFound |= Curve::CheckCurveDims(state,
2158 75 : thisDXCoil.PLFFPLR(1), // Curve index
2159 : {1}, // Valid dimensions
2160 : RoutineName, // Routine name
2161 : CurrentModuleObject, // Object Type
2162 : thisDXCoil.Name, // Object Name
2163 75 : cAlphaFields(9)); // Field Name
2164 :
2165 75 : if (!ErrorsFound) {
2166 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
2167 75 : MinCurveVal = 999.0;
2168 75 : MaxCurveVal = -999.0;
2169 75 : CurveInput = 0.0;
2170 7575 : while (CurveInput <= 1.0) {
2171 7500 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
2172 7500 : if (CurveVal < MinCurveVal) {
2173 75 : MinCurveVal = CurveVal;
2174 75 : MinCurvePLR = CurveInput;
2175 : }
2176 7500 : if (CurveVal > MaxCurveVal) {
2177 7500 : MaxCurveVal = CurveVal;
2178 7500 : MaxCurvePLR = CurveInput;
2179 : }
2180 7500 : CurveInput += 0.01;
2181 : }
2182 75 : 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 75 : 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 75 : thisDXCoil.DefrostEIRFT = GetCurveIndex(state, Alphas(10)); // convert curve name to number
2204 : // A11; \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
2205 75 : if (!lAlphaBlanks(11)) {
2206 1 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(11));
2207 1 : 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 3 : 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 1 : cAlphaFields(11)); // Field Name
2218 : }
2219 : }
2220 :
2221 75 : if (Util::SameString(Alphas(12), "ReverseCycle")) {
2222 :
2223 27 : 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 54 : 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 27 : cAlphaFields(10)); // Field Name
2242 :
2243 27 : if (!ErrorsFound) {
2244 27 : checkCurveIsNormalizedToOne(state,
2245 81 : std::string{RoutineName} + CurrentModuleObject,
2246 27 : thisDXCoil.Name,
2247 : thisDXCoil.DefrostEIRFT,
2248 27 : cAlphaFields(10),
2249 27 : Alphas(10),
2250 : RatedInletAirTempHeat,
2251 : RatedOutdoorAirTempHeat);
2252 : }
2253 : }
2254 : }
2255 :
2256 75 : if (Util::SameString(Alphas(12), "ReverseCycle")) {
2257 27 : thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
2258 : }
2259 75 : if (Util::SameString(Alphas(12), "Resistive")) {
2260 48 : thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
2261 : }
2262 :
2263 75 : 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 75 : if (Util::SameString(Alphas(13), "Timed")) {
2271 66 : thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::Timed;
2272 : }
2273 75 : if (Util::SameString(Alphas(13), "OnDemand")) {
2274 9 : thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
2275 : }
2276 75 : 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 75 : thisDXCoil.RatedSHR(1) = 1.0;
2284 75 : thisDXCoil.RatedTotCap(1) = Numbers(1);
2285 75 : thisDXCoil.RatedCOP(1) = Numbers(2);
2286 75 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(3);
2287 75 : thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(4);
2288 75 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(5);
2289 :
2290 : // Set minimum OAT for heat pump compressor operation
2291 75 : thisDXCoil.MinOATCompressor = Numbers(6);
2292 :
2293 75 : thisDXCoil.OATempCompressorOn = Numbers(7);
2294 :
2295 75 : if (lNumericBlanks(7) || lNumericBlanks(6)) { //??TBD:BPS 6 or 5 | 7 or 6
2296 74 : thisDXCoil.OATempCompressorOnOffBlank = true;
2297 : } else {
2298 1 : thisDXCoil.OATempCompressorOnOffBlank = false;
2299 : }
2300 :
2301 75 : if (thisDXCoil.OATempCompressorOn < thisDXCoil.MinOATCompressor) {
2302 15 : thisDXCoil.OATempCompressorOn = thisDXCoil.MinOATCompressor;
2303 : }
2304 :
2305 : // Set maximum outdoor temp for defrost to occur
2306 75 : thisDXCoil.MaxOATDefrost = Numbers(8);
2307 :
2308 : // Set crankcase heater capacity
2309 75 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(9);
2310 75 : 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 75 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(10);
2319 :
2320 : // Set defrost time period
2321 75 : thisDXCoil.DefrostTime = Numbers(11);
2322 75 : 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 75 : thisDXCoil.DefrostCapacity = Numbers(12);
2329 75 : 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 75 : thisDXCoil.RegionNum = Numbers(13);
2336 :
2337 75 : if (lNumericBlanks(13)) {
2338 74 : thisDXCoil.RegionNum = 4;
2339 : }
2340 :
2341 75 : thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
2342 :
2343 : // A14 is optional evaporator node name
2344 75 : if (lAlphaBlanks(14)) {
2345 72 : thisDXCoil.CondenserInletNodeNum(1) = 0;
2346 : } else {
2347 6 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
2348 3 : Alphas(14),
2349 : ErrorsFound,
2350 : DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
2351 3 : 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 3 : 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 75 : if (!lAlphaBlanks(15) && NumAlphas > 14) {
2369 1 : thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(15), state.dataHeatBal->Zone);
2370 1 : if (thisDXCoil.SecZonePtr > 0) {
2371 1 : SetupZoneInternalGain(state,
2372 : thisDXCoil.SecZonePtr,
2373 : thisDXCoil.Name,
2374 : DataHeatBalance::IntGainType::SecHeatingDXCoilSingleSpeed,
2375 : &thisDXCoil.SecCoilSensibleHeatRemovalRate,
2376 : nullptr,
2377 : nullptr,
2378 : &thisDXCoil.SecCoilLatentHeatRemovalRate);
2379 1 : 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 75 : if (thisDXCoil.SecZonePtr > 0) {
2386 : // N14, \field Secondary Coil Air Flow Rate
2387 1 : if (!lNumericBlanks(13)) {
2388 1 : thisDXCoil.SecCoilAirFlow = Numbers(14);
2389 : }
2390 : // N15, \field Secondary Coil Fan Flow Scaling Factor
2391 1 : if (!lNumericBlanks(15)) {
2392 1 : thisDXCoil.SecCoilAirFlowScalingFactor = Numbers(15);
2393 : }
2394 : // N16, \field Nominal Sensible Heat Ratio of Secondary Coil
2395 1 : if (!lNumericBlanks(16)) {
2396 1 : 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 1 : if (!lAlphaBlanks(16)) {
2402 1 : thisDXCoil.SecCoilSHRFT = GetCurveIndex(state, Alphas(16));
2403 1 : 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 1 : if (!lAlphaBlanks(17)) {
2410 1 : thisDXCoil.SecCoilSHRFF = GetCurveIndex(state, Alphas(17));
2411 1 : 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 251 : if (ErrorsFound) {
2421 0 : ShowFatalError(state,
2422 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
2423 : }
2424 :
2425 251 : CurrentModuleObject = "Coil:Cooling:DX:TwoSpeed";
2426 318 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedCoils; ++DXCoilIndex) {
2427 :
2428 67 : ++DXCoilNum;
2429 :
2430 67 : 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 67 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
2444 :
2445 : // allocate single performance mode for numeric field strings used for sizing routine
2446 67 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
2447 67 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
2448 67 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
2449 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
2450 67 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
2451 :
2452 67 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
2453 67 : thisDXCoil.Name = Alphas(1);
2454 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
2455 67 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
2456 67 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
2457 67 : thisDXCoil.DXCoilType = CurrentModuleObject;
2458 67 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingTwoSpeed;
2459 67 : if (lAlphaBlanks(2)) {
2460 2 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
2461 65 : } 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 67 : thisDXCoil.RatedTotCap(1) = Numbers(1);
2466 67 : thisDXCoil.RatedSHR(1) = Numbers(2);
2467 67 : thisDXCoil.RatedCOP(1) = Numbers(3);
2468 67 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(4);
2469 :
2470 67 : thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(5);
2471 67 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(6);
2472 :
2473 67 : if (!lNumericBlanks(7)) {
2474 32 : thisDXCoil.InternalStaticPressureDrop = Numbers(7);
2475 32 : thisDXCoil.RateWithInternalStaticAndFanObject = true;
2476 : } else {
2477 35 : thisDXCoil.InternalStaticPressureDrop = -999.0;
2478 35 : thisDXCoil.RateWithInternalStaticAndFanObject = false;
2479 : }
2480 :
2481 67 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
2482 67 : Alphas(3),
2483 : ErrorsFound,
2484 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
2485 67 : Alphas(1),
2486 : DataLoopNode::NodeFluidType::Air,
2487 : DataLoopNode::ConnectionType::Inlet,
2488 : NodeInputManager::CompFluidStream::Primary,
2489 : ObjectIsNotParent);
2490 :
2491 134 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
2492 67 : Alphas(4),
2493 : ErrorsFound,
2494 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
2495 67 : Alphas(1),
2496 : DataLoopNode::NodeFluidType::Air,
2497 : DataLoopNode::ConnectionType::Outlet,
2498 : NodeInputManager::CompFluidStream::Primary,
2499 : ObjectIsNotParent);
2500 :
2501 67 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
2502 :
2503 67 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
2504 67 : 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 201 : ErrorsFound |= Curve::CheckCurveDims(state,
2516 67 : thisDXCoil.CCapFTemp(1), // Curve index
2517 : {2}, // Valid dimensions
2518 : RoutineName, // Routine name
2519 : CurrentModuleObject, // Object Type
2520 : thisDXCoil.Name, // Object Name
2521 67 : cAlphaFields(5)); // Field Name
2522 :
2523 67 : if (!ErrorsFound) {
2524 67 : checkCurveIsNormalizedToOne(state,
2525 201 : std::string{RoutineName} + CurrentModuleObject,
2526 67 : thisDXCoil.Name,
2527 67 : thisDXCoil.CCapFTemp(1),
2528 67 : cAlphaFields(5),
2529 67 : Alphas(5),
2530 : RatedInletWetBulbTemp,
2531 : RatedOutdoorAirTemp);
2532 : }
2533 : }
2534 :
2535 67 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
2536 67 : 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 201 : ErrorsFound |= Curve::CheckCurveDims(state,
2548 67 : thisDXCoil.CCapFFlow(1), // Curve index
2549 : {1}, // Valid dimensions
2550 : RoutineName, // Routine name
2551 : CurrentModuleObject, // Object Type
2552 : thisDXCoil.Name, // Object Name
2553 67 : cAlphaFields(6)); // Field Name
2554 :
2555 67 : if (!ErrorsFound) {
2556 67 : checkCurveIsNormalizedToOne(
2557 268 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
2558 : }
2559 : }
2560 :
2561 67 : thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
2562 67 : 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 201 : ErrorsFound |= Curve::CheckCurveDims(state,
2574 67 : thisDXCoil.EIRFTemp(1), // Curve index
2575 : {2}, // Valid dimensions
2576 : RoutineName, // Routine name
2577 : CurrentModuleObject, // Object Type
2578 : thisDXCoil.Name, // Object Name
2579 67 : cAlphaFields(7)); // Field Name
2580 :
2581 67 : if (!ErrorsFound) {
2582 67 : checkCurveIsNormalizedToOne(state,
2583 201 : std::string{RoutineName} + CurrentModuleObject,
2584 67 : thisDXCoil.Name,
2585 67 : thisDXCoil.EIRFTemp(1),
2586 67 : cAlphaFields(7),
2587 67 : Alphas(7),
2588 : RatedInletWetBulbTemp,
2589 : RatedOutdoorAirTemp);
2590 : }
2591 : }
2592 :
2593 67 : thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
2594 67 : 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 201 : ErrorsFound |= Curve::CheckCurveDims(state,
2606 67 : thisDXCoil.EIRFFlow(1), // Curve index
2607 : {1}, // Valid dimensions
2608 : RoutineName, // Routine name
2609 : CurrentModuleObject, // Object Type
2610 : thisDXCoil.Name, // Object Name
2611 67 : cAlphaFields(8)); // Field Name
2612 :
2613 67 : if (!ErrorsFound) {
2614 67 : checkCurveIsNormalizedToOne(
2615 268 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
2616 : }
2617 : }
2618 :
2619 67 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
2620 67 : 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 201 : ErrorsFound |= Curve::CheckCurveDims(state,
2632 67 : thisDXCoil.PLFFPLR(1), // Curve index
2633 : {1}, // Valid dimensions
2634 : RoutineName, // Routine name
2635 : CurrentModuleObject, // Object Type
2636 : thisDXCoil.Name, // Object Name
2637 67 : cAlphaFields(9)); // Field Name
2638 :
2639 67 : if (!ErrorsFound) {
2640 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
2641 67 : MinCurveVal = 999.0;
2642 67 : MaxCurveVal = -999.0;
2643 67 : CurveInput = 0.0;
2644 6767 : while (CurveInput <= 1.0) {
2645 6700 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
2646 6700 : if (CurveVal < MinCurveVal) {
2647 67 : MinCurveVal = CurveVal;
2648 67 : MinCurvePLR = CurveInput;
2649 : }
2650 6700 : if (CurveVal > MaxCurveVal) {
2651 2542 : MaxCurveVal = CurveVal;
2652 2542 : MaxCurvePLR = CurveInput;
2653 : }
2654 6700 : CurveInput += 0.01;
2655 : }
2656 67 : 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 67 : 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 67 : thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
2677 :
2678 67 : thisDXCoil.RatedTotCap2 = Numbers(8);
2679 67 : thisDXCoil.RatedSHR2 = Numbers(9);
2680 67 : thisDXCoil.RatedCOP2 = Numbers(10);
2681 67 : thisDXCoil.RatedAirVolFlowRate2 = Numbers(11);
2682 :
2683 67 : thisDXCoil.FanPowerPerEvapAirFlowRate_LowSpeed(1) = Numbers(12);
2684 67 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023_LowSpeed(1) = Numbers(13);
2685 :
2686 67 : if (lNumericBlanks(14)) {
2687 67 : thisDXCoil.MinOATCompressor = -25.0;
2688 : } else {
2689 0 : thisDXCoil.MinOATCompressor = Numbers(14);
2690 : }
2691 :
2692 67 : thisDXCoil.CCapFTemp2 = GetCurveIndex(state, Alphas(10)); // convert curve name to number
2693 67 : 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 134 : 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 67 : cAlphaFields(10)); // Field Name
2711 :
2712 67 : if (!ErrorsFound) {
2713 67 : checkCurveIsNormalizedToOne(state,
2714 201 : std::string{RoutineName} + CurrentModuleObject,
2715 67 : thisDXCoil.Name,
2716 : thisDXCoil.CCapFTemp2,
2717 67 : cAlphaFields(10),
2718 67 : Alphas(10),
2719 : RatedInletWetBulbTemp,
2720 : RatedOutdoorAirTemp);
2721 : }
2722 : }
2723 :
2724 67 : thisDXCoil.EIRFTemp2 = GetCurveIndex(state, Alphas(11)); // convert curve name to number
2725 67 : 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 134 : 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 67 : cAlphaFields(11)); // Field Name
2743 :
2744 67 : if (!ErrorsFound) {
2745 67 : checkCurveIsNormalizedToOne(state,
2746 201 : std::string{RoutineName} + CurrentModuleObject,
2747 67 : thisDXCoil.Name,
2748 : thisDXCoil.EIRFTemp2,
2749 67 : cAlphaFields(11),
2750 67 : Alphas(11),
2751 : RatedInletWetBulbTemp,
2752 : RatedOutdoorAirTemp);
2753 : }
2754 : }
2755 :
2756 : // outdoor condenser node
2757 67 : if (lAlphaBlanks(12)) {
2758 58 : thisDXCoil.CondenserInletNodeNum(1) = 0;
2759 : } else {
2760 18 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
2761 9 : Alphas(12),
2762 : ErrorsFound,
2763 : DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
2764 9 : thisDXCoil.Name,
2765 : DataLoopNode::NodeFluidType::Air,
2766 : DataLoopNode::ConnectionType::OutsideAirReference,
2767 : NodeInputManager::CompFluidStream::Primary,
2768 : ObjectIsNotParent);
2769 9 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
2770 0 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
2771 0 : ShowContinueError(
2772 : state,
2773 0 : format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(12), Alphas(12)));
2774 0 : 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 67 : if ((Util::SameString(Alphas(13), "AirCooled")) || lAlphaBlanks(13)) {
2780 66 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
2781 1 : } else if (Util::SameString(Alphas(13), "EvaporativelyCooled")) {
2782 1 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
2783 1 : 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 67 : thisDXCoil.EvapCondEffect(1) = Numbers(15);
2792 67 : 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 67 : thisDXCoil.EvapCondAirFlow(1) = Numbers(16);
2800 67 : 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 67 : thisDXCoil.EvapCondPumpElecNomPower(1) = Numbers(17);
2808 67 : 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 67 : thisDXCoil.EvapCondEffect2 = Numbers(18);
2816 67 : 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 67 : thisDXCoil.EvapCondAirFlow2 = Numbers(19);
2824 67 : 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 67 : thisDXCoil.EvapCondPumpElecNomPower2 = Numbers(20);
2832 67 : 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 67 : thisDXCoil.RatedEIR2 = 1.0 / thisDXCoil.RatedCOP2;
2840 :
2841 : // Get Water System tank connections
2842 : // A14, \field Name of Water Storage Tank for Supply
2843 67 : thisDXCoil.EvapWaterSupplyName = Alphas(14);
2844 67 : if (lAlphaBlanks(14)) {
2845 67 : 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 67 : thisDXCoil.CondensateCollectName = Alphas(15);
2859 67 : if (lAlphaBlanks(15)) {
2860 67 : 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 67 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(21);
2874 67 : 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 67 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(22);
2882 67 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
2883 1 : if (NumNumbers < 22) {
2884 0 : thisDXCoil.BasinHeaterSetPointTemp = 2.0;
2885 : }
2886 1 : 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 67 : if (!lAlphaBlanks(16)) {
2894 1 : if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(16))) == nullptr) {
2895 0 : ShowWarningItemNotFound(
2896 0 : state, eoh, cAlphaFields(16), Alphas(16), "Basin heater will be available to operate throughout the simulation.");
2897 : }
2898 : }
2899 :
2900 67 : if (!lAlphaBlanks(17) && NumAlphas > 16) {
2901 1 : thisDXCoil.SHRFTemp(1) = GetCurveIndex(state, Alphas(17)); // convert curve name to number
2902 : // DXCoil(DXCoilNum)%SHRFTemp2 = DXCoil(DXCoilNum)%SHRFTemp(1)
2903 1 : 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 4 : ErrorsFound |= Curve::CheckCurveDims(state,
2909 1 : thisDXCoil.SHRFTemp(1), // Curve index
2910 : {2}, // Valid dimensions
2911 : RoutineName, // Routine name
2912 : CurrentModuleObject, // Object Type
2913 : thisDXCoil.Name, // Object Name
2914 1 : cAlphaFields(17)); // Field Name
2915 : }
2916 : }
2917 :
2918 67 : if (!lAlphaBlanks(18) && NumAlphas > 17) {
2919 1 : thisDXCoil.SHRFFlow(1) = GetCurveIndex(state, Alphas(18)); // convert curve name to number
2920 : // DXCoil(DXCoilNum)%SHRFFlow2 = DXCoil(DXCoilNum)%SHRFFlow(1)
2921 1 : 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 4 : ErrorsFound |= Curve::CheckCurveDims(state,
2927 1 : thisDXCoil.SHRFFlow(1), // Curve index
2928 : {1}, // Valid dimensions
2929 : RoutineName, // Routine name
2930 : CurrentModuleObject, // Object Type
2931 : thisDXCoil.Name, // Object Name
2932 1 : cAlphaFields(18)); // Field Name
2933 : }
2934 : }
2935 :
2936 67 : if (!lAlphaBlanks(19) && NumAlphas > 18) {
2937 1 : thisDXCoil.SHRFTemp2 = GetCurveIndex(state, Alphas(19)); // convert curve name to number
2938 1 : 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 3 : 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 1 : cAlphaFields(19)); // Field Name
2950 : }
2951 : }
2952 :
2953 67 : if (!lAlphaBlanks(20) && NumAlphas > 19) {
2954 1 : thisDXCoil.SHRFFlow2 = GetCurveIndex(state, Alphas(20)); // convert curve name to number
2955 1 : 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 3 : 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 1 : cAlphaFields(20)); // Field Name
2967 : }
2968 : }
2969 67 : if (thisDXCoil.SHRFTemp(1) > 0 && thisDXCoil.SHRFFlow(1) > 0 && thisDXCoil.SHRFTemp2 > 0 && thisDXCoil.SHRFFlow2 > 0) {
2970 1 : thisDXCoil.UserSHRCurveExists = true;
2971 : } else {
2972 66 : thisDXCoil.UserSHRCurveExists = false;
2973 : }
2974 : // A21; \field Zone Name for Condenser Placement
2975 67 : 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 251 : 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 251 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped);
2998 264 : for (DXHPWaterHeaterCoilNum = 1; DXHPWaterHeaterCoilNum <= state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils; ++DXHPWaterHeaterCoilNum) {
2999 :
3000 13 : 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 13 : ++DXCoilNum;
3014 :
3015 : // allocate single performance mode for numeric field strings used for sizing routine
3016 13 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
3017 13 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
3018 13 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
3019 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
3020 13 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
3021 :
3022 13 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
3023 13 : thisDXCoil.Name = Alphas(1);
3024 13 : thisDXCoil.DXCoilType = CurrentModuleObject;
3025 13 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatPumpWaterHeaterPumped;
3026 13 : 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 13 : thisDXCoil.RatedTotCap2 = Numbers(1);
3031 13 : 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 13 : thisDXCoil.RatedCOP(1) = Numbers(2);
3038 13 : 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 13 : thisDXCoil.RatedSHR(1) = Numbers(3);
3045 13 : 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 13 : thisDXCoil.RatedInletDBTemp = Numbers(4);
3053 13 : 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 13 : thisDXCoil.RatedInletWBTemp = Numbers(5);
3060 13 : 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 13 : thisDXCoil.RatedInletWaterTemp = Numbers(6);
3067 13 : 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 13 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(7);
3074 13 : if (thisDXCoil.RatedAirVolFlowRate(1) != Constant::AutoCalculate) {
3075 7 : 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 13 : thisDXCoil.RatedHPWHCondWaterFlow = Numbers(8);
3083 : // move to init
3084 13 : if (thisDXCoil.RatedHPWHCondWaterFlow != Constant::AutoCalculate) {
3085 7 : 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 7 : if (thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2 < 1.79405e-8 ||
3092 7 : 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 13 : if (Util::SameString(Alphas(2), "Yes") || Util::SameString(Alphas(2), "No")) {
3105 : // initialized to TRUE on allocate
3106 13 : if (Util::SameString(Alphas(2), "No")) {
3107 11 : 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 13 : if (Util::SameString(Alphas(3), "Yes") || Util::SameString(Alphas(3), "No")) {
3117 : // initialized to FALSE on allocate
3118 13 : 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 13 : if (Util::SameString(Alphas(4), "Yes") || Util::SameString(Alphas(4), "No")) {
3129 : // initialized to FALSE on allocate
3130 13 : 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 13 : thisDXCoil.HPWHCondPumpElecNomPower = Numbers(9);
3141 13 : 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 13 : thisDXCoil.HPWHCondPumpFracToWater = Numbers(10);
3148 13 : 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 13 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
3156 13 : Alphas(5),
3157 : ErrorsFound,
3158 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3159 13 : Alphas(1),
3160 : DataLoopNode::NodeFluidType::Air,
3161 : DataLoopNode::ConnectionType::Inlet,
3162 : NodeInputManager::CompFluidStream::Primary,
3163 : ObjectIsNotParent);
3164 :
3165 26 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
3166 13 : Alphas(6),
3167 : ErrorsFound,
3168 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3169 13 : Alphas(1),
3170 : DataLoopNode::NodeFluidType::Air,
3171 : DataLoopNode::ConnectionType::Outlet,
3172 : NodeInputManager::CompFluidStream::Primary,
3173 : ObjectIsNotParent);
3174 :
3175 13 : 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 13 : thisDXCoil.IsDXCoilInZone = !CheckOutAirNodeNumber(state, thisDXCoil.AirInNode);
3179 :
3180 : // Water nodes
3181 13 : thisDXCoil.WaterInNode = GetOnlySingleNode(state,
3182 13 : Alphas(7),
3183 : ErrorsFound,
3184 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3185 13 : Alphas(1),
3186 : DataLoopNode::NodeFluidType::Water,
3187 : DataLoopNode::ConnectionType::Inlet,
3188 : NodeInputManager::CompFluidStream::Secondary,
3189 : ObjectIsNotParent);
3190 :
3191 26 : thisDXCoil.WaterOutNode = GetOnlySingleNode(state,
3192 13 : Alphas(8),
3193 : ErrorsFound,
3194 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
3195 13 : Alphas(1),
3196 : DataLoopNode::NodeFluidType::Water,
3197 : DataLoopNode::ConnectionType::Outlet,
3198 : NodeInputManager::CompFluidStream::Secondary,
3199 : ObjectIsNotParent);
3200 :
3201 13 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(7), Alphas(8), "Water Nodes");
3202 :
3203 13 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(11);
3204 13 : 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 13 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(12);
3211 13 : 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 13 : if (!lAlphaBlanks(9)) {
3218 0 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(9));
3219 0 : 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 0 : 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 0 : cAlphaFields(9)); // Field Name
3230 : }
3231 : }
3232 :
3233 13 : thisDXCoil.InletAirTemperatureType = static_cast<HVAC::OATType>(getEnumValue(HVAC::oatTypeNamesUC, Alphas(10)));
3234 :
3235 : // set rated inlet air temperature for curve object verification
3236 13 : if (thisDXCoil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
3237 13 : InletAirTemp = thisDXCoil.RatedInletWBTemp;
3238 : } else {
3239 0 : InletAirTemp = thisDXCoil.RatedInletDBTemp;
3240 : }
3241 : // set rated water temperature for curve object verification
3242 13 : InletWaterTemp = thisDXCoil.RatedInletWaterTemp;
3243 :
3244 13 : if (!lAlphaBlanks(11)) {
3245 13 : thisDXCoil.HCapFTemp = GetCurveIndex(state, Alphas(11));
3246 13 : 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 26 : 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 13 : cAlphaFields(11)); // Field Name
3259 :
3260 13 : if (!ErrorsFound) {
3261 13 : if (state.dataCurveManager->curves(thisDXCoil.HCapFTemp)->numDims == 1) {
3262 0 : checkCurveIsNormalizedToOne(state,
3263 0 : std::string{RoutineName} + CurrentModuleObject,
3264 0 : thisDXCoil.Name,
3265 : thisDXCoil.HCapFTemp,
3266 0 : cAlphaFields(11),
3267 0 : Alphas(11),
3268 : InletAirTemp);
3269 : } else {
3270 13 : checkCurveIsNormalizedToOne(state,
3271 39 : std::string{RoutineName} + CurrentModuleObject,
3272 13 : thisDXCoil.Name,
3273 : thisDXCoil.HCapFTemp,
3274 13 : cAlphaFields(11),
3275 13 : Alphas(11),
3276 : InletAirTemp,
3277 : InletWaterTemp);
3278 : }
3279 : }
3280 : }
3281 : }
3282 :
3283 13 : if (!lAlphaBlanks(12)) {
3284 0 : thisDXCoil.HCapFAirFlow = GetCurveIndex(state, Alphas(12));
3285 0 : 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 0 : 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 0 : cAlphaFields(12)); // Field Name
3298 :
3299 0 : if (!ErrorsFound) {
3300 0 : checkCurveIsNormalizedToOne(state,
3301 0 : std::string{RoutineName} + CurrentModuleObject,
3302 0 : thisDXCoil.Name,
3303 : thisDXCoil.HCapFAirFlow,
3304 0 : cAlphaFields(12),
3305 0 : Alphas(12),
3306 : 1.0);
3307 : }
3308 : }
3309 : }
3310 :
3311 13 : if (!lAlphaBlanks(13)) {
3312 0 : thisDXCoil.HCapFWaterFlow = GetCurveIndex(state, Alphas(13));
3313 0 : 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 0 : 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 0 : cAlphaFields(13)); // Field Name
3326 :
3327 0 : if (!ErrorsFound) {
3328 0 : checkCurveIsNormalizedToOne(state,
3329 0 : std::string{RoutineName} + CurrentModuleObject,
3330 0 : thisDXCoil.Name,
3331 : thisDXCoil.HCapFWaterFlow,
3332 0 : cAlphaFields(13),
3333 0 : Alphas(13),
3334 : 1.0);
3335 : }
3336 : }
3337 : }
3338 :
3339 13 : if (!lAlphaBlanks(14)) {
3340 13 : thisDXCoil.HCOPFTemp = GetCurveIndex(state, Alphas(14));
3341 13 : 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 26 : 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 13 : cAlphaFields(14)); // Field Name
3354 :
3355 13 : if (!ErrorsFound) {
3356 13 : 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 13 : checkCurveIsNormalizedToOne(state,
3366 39 : std::string{RoutineName} + CurrentModuleObject,
3367 13 : thisDXCoil.Name,
3368 : thisDXCoil.HCOPFTemp,
3369 13 : cAlphaFields(14),
3370 13 : Alphas(14),
3371 : InletAirTemp,
3372 : InletWaterTemp);
3373 : }
3374 : }
3375 : }
3376 : }
3377 :
3378 13 : if (!lAlphaBlanks(15)) {
3379 0 : thisDXCoil.HCOPFAirFlow = GetCurveIndex(state, Alphas(15));
3380 0 : 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 0 : 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 0 : cAlphaFields(15)); // Field Name
3393 :
3394 0 : if (!ErrorsFound) {
3395 0 : checkCurveIsNormalizedToOne(state,
3396 0 : std::string{RoutineName} + CurrentModuleObject,
3397 0 : thisDXCoil.Name,
3398 : thisDXCoil.HCOPFAirFlow,
3399 0 : cAlphaFields(15),
3400 0 : Alphas(15),
3401 : 1.0);
3402 : }
3403 : }
3404 : }
3405 :
3406 13 : if (!lAlphaBlanks(16)) {
3407 0 : thisDXCoil.HCOPFWaterFlow = GetCurveIndex(state, Alphas(16));
3408 0 : 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 0 : 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 0 : cAlphaFields(16)); // Field Name
3421 :
3422 0 : if (!ErrorsFound) {
3423 0 : checkCurveIsNormalizedToOne(state,
3424 0 : std::string{RoutineName} + CurrentModuleObject,
3425 0 : thisDXCoil.Name,
3426 : thisDXCoil.HCOPFWaterFlow,
3427 0 : cAlphaFields(16),
3428 0 : Alphas(16),
3429 : 1.0);
3430 : }
3431 : }
3432 : }
3433 :
3434 13 : if (!lAlphaBlanks(17)) {
3435 13 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(17));
3436 13 : 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 39 : ErrorsFound |= Curve::CheckCurveDims(state,
3443 13 : thisDXCoil.PLFFPLR(1), // Curve index
3444 : {1}, // Valid dimensions
3445 : RoutineName, // Routine name
3446 : CurrentModuleObject, // Object Type
3447 : thisDXCoil.Name, // Object Name
3448 13 : cAlphaFields(17)); // Field Name
3449 :
3450 13 : if (!ErrorsFound) {
3451 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
3452 13 : MinCurveVal = 999.0;
3453 13 : MaxCurveVal = -999.0;
3454 13 : CurveInput = 0.0;
3455 1313 : while (CurveInput <= 1.0) {
3456 1300 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
3457 1300 : if (CurveVal < MinCurveVal) {
3458 13 : MinCurveVal = CurveVal;
3459 13 : MinCurvePLR = CurveInput;
3460 : }
3461 1300 : if (CurveVal > MaxCurveVal) {
3462 1300 : MaxCurveVal = CurveVal;
3463 1300 : MaxCurvePLR = CurveInput;
3464 : }
3465 1300 : CurveInput += 0.01;
3466 : }
3467 13 : 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 13 : 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 13 : thisDXCoil.CondenserInletNodeNum(1) = thisDXCoil.AirInNode;
3490 :
3491 : // set condenser type as HPWH
3492 13 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::WaterHeater;
3493 :
3494 : } // end of the DX water heater coil loop
3495 :
3496 251 : 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 251 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped);
3502 254 : for (DXHPWaterHeaterCoilNum = 1; DXHPWaterHeaterCoilNum <= state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils; ++DXHPWaterHeaterCoilNum) {
3503 :
3504 3 : 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 3 : ++DXCoilNum;
3518 :
3519 : // allocate single performance mode for numeric field strings used for sizing routine
3520 3 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
3521 3 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
3522 3 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
3523 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
3524 3 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
3525 :
3526 3 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
3527 3 : thisDXCoil.Name = Alphas(1);
3528 3 : thisDXCoil.DXCoilType = CurrentModuleObject;
3529 3 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatPumpWaterHeaterWrapped;
3530 3 : 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 3 : thisDXCoil.RatedTotCap2 = Numbers(1);
3535 3 : 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 3 : thisDXCoil.RatedCOP(1) = Numbers(2);
3542 3 : 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 3 : thisDXCoil.RatedSHR(1) = Numbers(3);
3549 3 : 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 3 : thisDXCoil.RatedInletDBTemp = Numbers(4);
3557 3 : 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 3 : thisDXCoil.RatedInletWBTemp = Numbers(5);
3564 3 : 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 3 : thisDXCoil.RatedInletWaterTemp = Numbers(6);
3571 3 : 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 3 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(7);
3578 3 : if (thisDXCoil.RatedAirVolFlowRate(1) != Constant::AutoCalculate) {
3579 3 : 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 3 : if (Util::SameString(Alphas(2), "Yes") || Util::SameString(Alphas(2), "No")) {
3587 : // initialized to TRUE on allocate
3588 3 : 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 3 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
3600 3 : Alphas(3),
3601 : ErrorsFound,
3602 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3603 3 : Alphas(1),
3604 : DataLoopNode::NodeFluidType::Air,
3605 : DataLoopNode::ConnectionType::Inlet,
3606 : NodeInputManager::CompFluidStream::Primary,
3607 : ObjectIsNotParent);
3608 :
3609 6 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
3610 3 : Alphas(4),
3611 : ErrorsFound,
3612 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3613 3 : Alphas(1),
3614 : DataLoopNode::NodeFluidType::Air,
3615 : DataLoopNode::ConnectionType::Outlet,
3616 : NodeInputManager::CompFluidStream::Primary,
3617 : ObjectIsNotParent);
3618 :
3619 3 : 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 3 : thisDXCoil.IsDXCoilInZone = !CheckOutAirNodeNumber(state, thisDXCoil.AirInNode);
3623 :
3624 3 : std::string const DummyCondenserInletName("DUMMY CONDENSER INLET " + thisDXCoil.Name);
3625 3 : std::string const DummyCondenserOutletName("DUMMY CONDENSER OUTLET " + thisDXCoil.Name);
3626 3 : thisDXCoil.WaterInNode = GetOnlySingleNode(state,
3627 : DummyCondenserInletName,
3628 : ErrorsFound,
3629 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3630 3 : Alphas(1),
3631 : DataLoopNode::NodeFluidType::Water,
3632 : DataLoopNode::ConnectionType::Inlet,
3633 : NodeInputManager::CompFluidStream::Secondary,
3634 : ObjectIsNotParent);
3635 :
3636 6 : thisDXCoil.WaterOutNode = GetOnlySingleNode(state,
3637 : DummyCondenserOutletName,
3638 : ErrorsFound,
3639 : DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
3640 3 : Alphas(1),
3641 : DataLoopNode::NodeFluidType::Water,
3642 : DataLoopNode::ConnectionType::Outlet,
3643 : NodeInputManager::CompFluidStream::Secondary,
3644 : ObjectIsNotParent);
3645 :
3646 3 : TestCompSet(state, CurrentModuleObject, Alphas(1), DummyCondenserInletName, DummyCondenserOutletName, "Water Nodes");
3647 :
3648 3 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(8);
3649 3 : 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 3 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(9);
3656 3 : 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 3 : if (!lAlphaBlanks(5)) {
3664 0 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
3665 0 : 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 0 : 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 0 : cAlphaFields(5)); // Field Name
3676 : }
3677 : }
3678 :
3679 3 : if (Util::SameString(Alphas(6), "DryBulbTemperature")) {
3680 0 : thisDXCoil.InletAirTemperatureType = HVAC::OATType::DryBulb;
3681 3 : } else if (Util::SameString(Alphas(6), "WetBulbTemperature")) {
3682 3 : 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 3 : if (thisDXCoil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
3693 3 : InletAirTemp = thisDXCoil.RatedInletWBTemp;
3694 : } else {
3695 0 : InletAirTemp = thisDXCoil.RatedInletDBTemp;
3696 : }
3697 : // set rated water temperature for curve object verification
3698 3 : InletWaterTemp = thisDXCoil.RatedInletWaterTemp;
3699 :
3700 3 : if (!lAlphaBlanks(7)) {
3701 3 : thisDXCoil.HCapFTemp = GetCurveIndex(state, Alphas(7));
3702 3 : 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 6 : 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 3 : cAlphaFields(7)); // Field Name
3715 :
3716 3 : if (!ErrorsFound) {
3717 3 : 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 3 : checkCurveIsNormalizedToOne(state,
3727 9 : std::string{RoutineName} + CurrentModuleObject,
3728 3 : thisDXCoil.Name,
3729 : thisDXCoil.HCapFTemp,
3730 3 : cAlphaFields(7),
3731 3 : Alphas(7),
3732 : InletAirTemp,
3733 : InletWaterTemp);
3734 : }
3735 : }
3736 : }
3737 : }
3738 :
3739 3 : if (!lAlphaBlanks(8)) {
3740 0 : thisDXCoil.HCapFAirFlow = GetCurveIndex(state, Alphas(8));
3741 0 : 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 0 : 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 0 : cAlphaFields(8)); // Field Name
3754 :
3755 0 : if (!ErrorsFound) {
3756 0 : checkCurveIsNormalizedToOne(state,
3757 0 : std::string{RoutineName} + CurrentModuleObject,
3758 0 : thisDXCoil.Name,
3759 : thisDXCoil.HCapFAirFlow,
3760 0 : cAlphaFields(8),
3761 0 : Alphas(8),
3762 : 1.0);
3763 : }
3764 : }
3765 : }
3766 :
3767 3 : if (!lAlphaBlanks(9)) {
3768 3 : thisDXCoil.HCOPFTemp = GetCurveIndex(state, Alphas(9));
3769 3 : 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 6 : 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 3 : cAlphaFields(9)); // Field Name
3782 :
3783 3 : if (!ErrorsFound) {
3784 3 : 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 3 : checkCurveIsNormalizedToOne(state,
3794 9 : std::string{RoutineName} + CurrentModuleObject,
3795 3 : thisDXCoil.Name,
3796 : thisDXCoil.HCOPFTemp,
3797 3 : cAlphaFields(9),
3798 3 : Alphas(9),
3799 : InletAirTemp,
3800 : InletWaterTemp);
3801 : }
3802 : }
3803 : }
3804 : }
3805 :
3806 3 : if (!lAlphaBlanks(10)) {
3807 0 : thisDXCoil.HCOPFAirFlow = GetCurveIndex(state, Alphas(10));
3808 0 : 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 0 : 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 0 : cAlphaFields(10)); // Field Name
3821 :
3822 0 : if (!ErrorsFound) {
3823 0 : checkCurveIsNormalizedToOne(state,
3824 0 : std::string{RoutineName} + CurrentModuleObject,
3825 0 : thisDXCoil.Name,
3826 : thisDXCoil.HCOPFAirFlow,
3827 0 : cAlphaFields(10),
3828 0 : Alphas(10),
3829 : 1.0);
3830 : }
3831 : }
3832 : }
3833 :
3834 3 : if (!lAlphaBlanks(11)) {
3835 3 : thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(11));
3836 3 : 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 9 : ErrorsFound |= Curve::CheckCurveDims(state,
3843 3 : thisDXCoil.PLFFPLR(1), // Curve index
3844 : {1}, // Valid dimensions
3845 : RoutineName, // Routine name
3846 : CurrentModuleObject, // Object Type
3847 : thisDXCoil.Name, // Object Name
3848 3 : cAlphaFields(11)); // Field Name
3849 :
3850 3 : if (!ErrorsFound) {
3851 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
3852 3 : MinCurveVal = 999.0;
3853 3 : MaxCurveVal = -999.0;
3854 3 : CurveInput = 0.0;
3855 303 : while (CurveInput <= 1.0) {
3856 300 : CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
3857 300 : if (CurveVal < MinCurveVal) {
3858 3 : MinCurveVal = CurveVal;
3859 3 : MinCurvePLR = CurveInput;
3860 : }
3861 300 : if (CurveVal > MaxCurveVal) {
3862 3 : MaxCurveVal = CurveVal;
3863 3 : MaxCurvePLR = CurveInput;
3864 : }
3865 300 : CurveInput += 0.01;
3866 : }
3867 3 : 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 3 : 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 3 : thisDXCoil.CondenserInletNodeNum(1) = thisDXCoil.AirInNode;
3890 :
3891 : // set condenser type as HPWH
3892 3 : thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::WaterHeater;
3893 :
3894 3 : } // end of the DX water heater wrapped coil loop
3895 :
3896 251 : 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 251 : CurrentModuleObject = "Coil:Cooling:DX:MultiSpeed";
3903 300 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedCoolCoils; ++DXCoilIndex) {
3904 :
3905 49 : ++DXCoilNum;
3906 :
3907 49 : 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 49 : 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 49 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
3923 49 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
3924 49 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
3925 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
3926 49 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
3927 :
3928 49 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
3929 49 : thisDXCoil.Name = Alphas(1);
3930 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
3931 49 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
3932 49 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
3933 49 : thisDXCoil.DXCoilType = CurrentModuleObject;
3934 49 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_MultiSpeedCooling;
3935 49 : if (lAlphaBlanks(2)) {
3936 2 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
3937 47 : } 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 49 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
3943 49 : Alphas(3),
3944 : ErrorsFound,
3945 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
3946 49 : Alphas(1),
3947 : DataLoopNode::NodeFluidType::Air,
3948 : DataLoopNode::ConnectionType::Inlet,
3949 : NodeInputManager::CompFluidStream::Primary,
3950 : ObjectIsNotParent);
3951 :
3952 98 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
3953 49 : Alphas(4),
3954 : ErrorsFound,
3955 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
3956 49 : Alphas(1),
3957 : DataLoopNode::NodeFluidType::Air,
3958 : DataLoopNode::ConnectionType::Outlet,
3959 : NodeInputManager::CompFluidStream::Primary,
3960 : ObjectIsNotParent);
3961 :
3962 49 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
3963 :
3964 : // outdoor condenser node
3965 49 : if (lAlphaBlanks(5)) {
3966 33 : thisDXCoil.CondenserInletNodeNum(1) = 0;
3967 : } else {
3968 32 : thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
3969 16 : Alphas(5),
3970 : ErrorsFound,
3971 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
3972 16 : thisDXCoil.Name,
3973 : DataLoopNode::NodeFluidType::Air,
3974 : DataLoopNode::ConnectionType::OutsideAirReference,
3975 : NodeInputManager::CompFluidStream::Primary,
3976 : ObjectIsNotParent);
3977 16 : if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
3978 0 : ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
3979 0 : ShowContinueError(
3980 0 : state, format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(5), Alphas(5)));
3981 0 : 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 49 : if ((Util::SameString(Alphas(6), "AirCooled")) || lAlphaBlanks(6)) {
3987 49 : 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 49 : thisDXCoil.EvapWaterSupplyName = Alphas(7);
4001 49 : if (lAlphaBlanks(7)) {
4002 49 : 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 49 : thisDXCoil.CondensateCollectName = Alphas(8);
4016 49 : if (lAlphaBlanks(8)) {
4017 49 : 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 49 : thisDXCoil.MinOATCompressor = Numbers(1);
4031 :
4032 : // Set crankcase heater capacity
4033 49 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(2);
4034 49 : 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 49 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(3);
4043 :
4044 49 : if (Util::SameString(Alphas(9), "Yes")) {
4045 0 : thisDXCoil.PLRImpact = true;
4046 49 : } else if (Util::SameString(Alphas(9), "No")) {
4047 49 : 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 49 : if (Util::SameString(Alphas(10), "Yes")) {
4056 0 : thisDXCoil.LatentImpact = true;
4057 49 : } else if (Util::SameString(Alphas(10), "No")) {
4058 49 : 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 49 : thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(4);
4068 49 : 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 49 : thisDXCoil.BasinHeaterSetPointTemp = Numbers(5);
4075 49 : 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 49 : if (!lAlphaBlanks(11)) {
4087 0 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(11));
4088 0 : 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 0 : 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 0 : cAlphaFields(11)); // Field Name
4099 : }
4100 : }
4101 :
4102 49 : 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 49 : thisDXCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(13)));
4111 :
4112 49 : thisDXCoil.NumOfSpeeds = Numbers(6); // Number of speeds
4113 49 : 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 49 : thisDXCoil.MSErrIndex.allocate(thisDXCoil.NumOfSpeeds);
4121 49 : thisDXCoil.MSErrIndex = 0;
4122 49 : thisDXCoil.MSRatedTotCap.allocate(thisDXCoil.NumOfSpeeds);
4123 49 : thisDXCoil.MSRatedTotCapDes.allocate(thisDXCoil.NumOfSpeeds);
4124 49 : thisDXCoil.MSRatedSHR.allocate(thisDXCoil.NumOfSpeeds);
4125 49 : thisDXCoil.MSRatedCOP.allocate(thisDXCoil.NumOfSpeeds);
4126 49 : thisDXCoil.MSRatedAirVolFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4127 49 : thisDXCoil.MSRatedAirMassFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4128 49 : thisDXCoil.MSRatedAirMassFlowRate = 1.0; // avoid divide by 0, will get overwritten in InitDXCoil
4129 49 : thisDXCoil.MSCCapFTemp.allocate(thisDXCoil.NumOfSpeeds);
4130 49 : thisDXCoil.MSCCapFFlow.allocate(thisDXCoil.NumOfSpeeds);
4131 49 : thisDXCoil.MSEIRFTemp.allocate(thisDXCoil.NumOfSpeeds);
4132 49 : thisDXCoil.MSEIRFFlow.allocate(thisDXCoil.NumOfSpeeds);
4133 49 : thisDXCoil.MSWasteHeat.allocate(thisDXCoil.NumOfSpeeds);
4134 49 : thisDXCoil.MSEvapCondEffect.allocate(thisDXCoil.NumOfSpeeds);
4135 49 : thisDXCoil.MSEvapCondAirFlow.allocate(thisDXCoil.NumOfSpeeds);
4136 49 : thisDXCoil.MSEvapCondPumpElecNomPower.allocate(thisDXCoil.NumOfSpeeds);
4137 49 : thisDXCoil.MSRatedCBF.allocate(thisDXCoil.NumOfSpeeds);
4138 49 : thisDXCoil.MSWasteHeatFrac.allocate(thisDXCoil.NumOfSpeeds);
4139 49 : thisDXCoil.MSPLFFPLR.allocate(thisDXCoil.NumOfSpeeds);
4140 49 : thisDXCoil.MSTwet_Rated.allocate(thisDXCoil.NumOfSpeeds);
4141 49 : thisDXCoil.MSGamma_Rated.allocate(thisDXCoil.NumOfSpeeds);
4142 49 : thisDXCoil.MSMaxONOFFCyclesperHour.allocate(thisDXCoil.NumOfSpeeds);
4143 49 : thisDXCoil.MSLatentCapacityTimeConstant.allocate(thisDXCoil.NumOfSpeeds);
4144 49 : thisDXCoil.MSFanPowerPerEvapAirFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4145 49 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023.allocate(thisDXCoil.NumOfSpeeds);
4146 :
4147 162 : for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
4148 113 : thisDXCoil.MSRatedTotCap(I) = Numbers(7 + (I - 1) * 14);
4149 113 : thisDXCoil.MSRatedSHR(I) = Numbers(8 + (I - 1) * 14);
4150 113 : thisDXCoil.MSRatedCOP(I) = Numbers(9 + (I - 1) * 14);
4151 113 : thisDXCoil.MSRatedAirVolFlowRate(I) = Numbers(10 + (I - 1) * 14);
4152 113 : thisDXCoil.MSFanPowerPerEvapAirFlowRate(I) = Numbers(11 + (I - 1) * 14);
4153 113 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023(I) = Numbers(12 + (I - 1) * 14);
4154 :
4155 113 : thisDXCoil.MSCCapFTemp(I) = GetCurveIndex(state, Alphas(14 + (I - 1) * 6)); // convert curve name to number
4156 113 : 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 339 : ErrorsFound |= Curve::CheckCurveDims(state,
4168 113 : thisDXCoil.MSCCapFTemp(I), // Curve index
4169 : {2}, // Valid dimensions
4170 : RoutineName, // Routine name
4171 : CurrentModuleObject, // Object Type
4172 : thisDXCoil.Name, // Object Name
4173 113 : cAlphaFields(14 + (I - 1) * 6)); // Field Name
4174 :
4175 113 : if (!ErrorsFound) {
4176 113 : checkCurveIsNormalizedToOne(state,
4177 339 : std::string{RoutineName} + CurrentModuleObject,
4178 113 : thisDXCoil.Name,
4179 113 : thisDXCoil.MSCCapFTemp(I),
4180 113 : cAlphaFields(14 + (I - 1) * 6),
4181 113 : Alphas(14 + (I - 1) * 6),
4182 : RatedInletWetBulbTemp,
4183 : RatedOutdoorAirTemp);
4184 : }
4185 : }
4186 :
4187 113 : thisDXCoil.MSCCapFFlow(I) = GetCurveIndex(state, Alphas(15 + (I - 1) * 6)); // convert curve name to number
4188 113 : 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 339 : ErrorsFound |= Curve::CheckCurveDims(state,
4200 113 : thisDXCoil.MSCCapFFlow(I), // Curve index
4201 : {1}, // Valid dimensions
4202 : RoutineName, // Routine name
4203 : CurrentModuleObject, // Object Type
4204 : thisDXCoil.Name, // Object Name
4205 113 : cAlphaFields(15 + (I - 1) * 6)); // Field Name
4206 :
4207 113 : if (!ErrorsFound) {
4208 113 : checkCurveIsNormalizedToOne(state,
4209 339 : std::string{RoutineName} + CurrentModuleObject,
4210 113 : thisDXCoil.Name,
4211 113 : thisDXCoil.MSCCapFFlow(I),
4212 113 : cAlphaFields(15 + (I - 1) * 6),
4213 113 : Alphas(15 + (I - 1) * 6),
4214 : 1.0);
4215 : }
4216 : }
4217 :
4218 113 : thisDXCoil.MSEIRFTemp(I) = GetCurveIndex(state, Alphas(16 + (I - 1) * 6)); // convert curve name to number
4219 113 : 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 339 : ErrorsFound |= Curve::CheckCurveDims(state,
4231 113 : thisDXCoil.MSEIRFTemp(I), // Curve index
4232 : {2}, // Valid dimensions
4233 : RoutineName, // Routine name
4234 : CurrentModuleObject, // Object Type
4235 : thisDXCoil.Name, // Object Name
4236 113 : cAlphaFields(16 + (I - 1) * 6)); // Field Name
4237 :
4238 113 : if (!ErrorsFound) {
4239 113 : checkCurveIsNormalizedToOne(state,
4240 339 : std::string{RoutineName} + CurrentModuleObject,
4241 113 : thisDXCoil.Name,
4242 113 : thisDXCoil.MSEIRFTemp(I),
4243 113 : cAlphaFields(16 + (I - 1) * 6),
4244 113 : Alphas(16 + (I - 1) * 6),
4245 : RatedInletWetBulbTemp,
4246 : RatedOutdoorAirTemp);
4247 : }
4248 : }
4249 :
4250 113 : thisDXCoil.MSEIRFFlow(I) = GetCurveIndex(state, Alphas(17 + (I - 1) * 6)); // convert curve name to number
4251 113 : 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 339 : ErrorsFound |= Curve::CheckCurveDims(state,
4263 113 : thisDXCoil.MSEIRFFlow(I), // Curve index
4264 : {1}, // Valid dimensions
4265 : RoutineName, // Routine name
4266 : CurrentModuleObject, // Object Type
4267 : thisDXCoil.Name, // Object Name
4268 113 : cAlphaFields(17 + (I - 1) * 6)); // Field Name
4269 :
4270 113 : if (!ErrorsFound) {
4271 113 : checkCurveIsNormalizedToOne(state,
4272 339 : std::string{RoutineName} + CurrentModuleObject,
4273 113 : thisDXCoil.Name,
4274 113 : thisDXCoil.MSEIRFFlow(I),
4275 113 : cAlphaFields(17 + (I - 1) * 6),
4276 113 : Alphas(17 + (I - 1) * 6),
4277 : 1.0);
4278 : }
4279 : }
4280 :
4281 113 : thisDXCoil.MSPLFFPLR(I) = GetCurveIndex(state, Alphas(18 + (I - 1) * 6)); // convert curve name to number
4282 113 : if (thisDXCoil.MSPLFFPLR(I) == 0) {
4283 0 : 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 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
4288 0 : ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(18 + (I - 1) * 6), Alphas(18 + (I - 1) * 6)));
4289 : }
4290 0 : ErrorsFound = true;
4291 : } else {
4292 : // Verify Curve Object, only legal types are Quadratic or Cubic
4293 339 : ErrorsFound |= Curve::CheckCurveDims(state,
4294 113 : thisDXCoil.MSPLFFPLR(I), // Curve index
4295 : {1}, // Valid dimensions
4296 : RoutineName, // Routine name
4297 : CurrentModuleObject, // Object Type
4298 : thisDXCoil.Name, // Object Name
4299 113 : cAlphaFields(18 + (I - 1) * 6)); // Field Name
4300 :
4301 113 : if (!ErrorsFound) {
4302 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
4303 113 : MinCurveVal = 999.0;
4304 113 : MaxCurveVal = -999.0;
4305 113 : CurveInput = 0.0;
4306 11413 : while (CurveInput <= 1.0) {
4307 11300 : CurveVal = CurveValue(state, thisDXCoil.MSPLFFPLR(I), CurveInput);
4308 11300 : if (CurveVal < MinCurveVal) {
4309 113 : MinCurveVal = CurveVal;
4310 113 : MinCurvePLR = CurveInput;
4311 : }
4312 11300 : if (CurveVal > MaxCurveVal) {
4313 11300 : MaxCurveVal = CurveVal;
4314 11300 : MaxCurvePLR = CurveInput;
4315 : }
4316 11300 : CurveInput += 0.01;
4317 : }
4318 113 : 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 113 : 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 113 : thisDXCoil.MSTwet_Rated(I) = Numbers(13 + (I - 1) * 14);
4342 113 : 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 113 : thisDXCoil.MSGamma_Rated(I) = Numbers(14 + (I - 1) * 14);
4349 113 : 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 113 : thisDXCoil.MSMaxONOFFCyclesperHour(I) = Numbers(15 + (I - 1) * 14);
4356 113 : 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 113 : thisDXCoil.MSLatentCapacityTimeConstant(I) = Numbers(16 + (I - 1) * 14);
4365 113 : 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 113 : thisDXCoil.MSWasteHeatFrac(I) = Numbers(17 + (I - 1) * 14);
4375 :
4376 : // Read waste heat modifier curve name
4377 113 : thisDXCoil.MSWasteHeat(I) = GetCurveIndex(state, Alphas(19 + (I - 1) * 6)); // convert curve name to number
4378 113 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
4379 24 : if (thisDXCoil.MSWasteHeat(I) > 0) {
4380 : // Verify Curve Object, only legal types are BiQuadratic
4381 72 : ErrorsFound |= Curve::CheckCurveDims(state,
4382 24 : thisDXCoil.MSWasteHeat(I), // Curve index
4383 : {2}, // Valid dimensions
4384 : RoutineName, // Routine name
4385 : CurrentModuleObject, // Object Type
4386 : thisDXCoil.Name, // Object Name
4387 24 : cAlphaFields(19 + (I - 1) * 6)); // Field Name
4388 :
4389 24 : if (!ErrorsFound) {
4390 24 : CurveVal = CurveValue(state, thisDXCoil.MSWasteHeat(I), RatedOutdoorAirTemp, RatedInletAirTemp);
4391 24 : 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 113 : thisDXCoil.MSEvapCondEffect(I) = Numbers(18 + (I - 1) * 14);
4403 113 : 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 113 : thisDXCoil.MSEvapCondAirFlow(I) = Numbers(19 + (I - 1) * 14);
4412 113 : 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 113 : thisDXCoil.MSEvapCondPumpElecNomPower(I) = Numbers(20 + (I - 1) * 14);
4420 113 : 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 49 : 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 251 : if (ErrorsFound) {
4445 0 : ShowFatalError(state,
4446 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
4447 : }
4448 :
4449 : // DX multispeed heating coil
4450 251 : CurrentModuleObject = "Coil:Heating:DX:MultiSpeed";
4451 273 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedHeatCoils; ++DXCoilIndex) {
4452 :
4453 22 : ++DXCoilNum;
4454 :
4455 22 : 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 22 : 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 22 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
4473 22 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
4474 22 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
4475 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
4476 22 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
4477 :
4478 22 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
4479 22 : thisDXCoil.Name = Alphas(1);
4480 : // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
4481 22 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
4482 22 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
4483 22 : thisDXCoil.DXCoilType = CurrentModuleObject;
4484 22 : thisDXCoil.DXCoilType_Num = HVAC::CoilDX_MultiSpeedHeating;
4485 22 : if (lAlphaBlanks(2)) {
4486 8 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
4487 14 : } 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 22 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
4493 22 : Alphas(3),
4494 : ErrorsFound,
4495 : DataLoopNode::ConnectionObjectType::CoilHeatingDXMultiSpeed,
4496 22 : Alphas(1),
4497 : DataLoopNode::NodeFluidType::Air,
4498 : DataLoopNode::ConnectionType::Inlet,
4499 : NodeInputManager::CompFluidStream::Primary,
4500 : ObjectIsNotParent);
4501 :
4502 44 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
4503 22 : Alphas(4),
4504 : ErrorsFound,
4505 : DataLoopNode::ConnectionObjectType::CoilHeatingDXMultiSpeed,
4506 22 : Alphas(1),
4507 : DataLoopNode::NodeFluidType::Air,
4508 : DataLoopNode::ConnectionType::Outlet,
4509 : NodeInputManager::CompFluidStream::Primary,
4510 : ObjectIsNotParent);
4511 :
4512 22 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
4513 :
4514 : // Set minimum OAT for heat pump compressor operation
4515 22 : thisDXCoil.MinOATCompressor = Numbers(1);
4516 :
4517 : // set Minimum Outdoor Dry-Bulb Temperature for Compressor Operation
4518 22 : thisDXCoil.OATempCompressorOn = Numbers(2);
4519 : // Set crankcase heater capacity
4520 22 : thisDXCoil.CrankcaseHeaterCapacity = Numbers(3);
4521 22 : 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 22 : thisDXCoil.MaxOATCrankcaseHeater = Numbers(4);
4529 :
4530 22 : if (!lAlphaBlanks(5)) {
4531 0 : thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
4532 0 : 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 0 : 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 0 : cAlphaFields(5)); // Field Name
4543 : }
4544 : }
4545 :
4546 : // Only required for reverse cycle heat pumps
4547 22 : thisDXCoil.DefrostEIRFT = GetCurveIndex(state, Alphas(6)); // convert curve name to number
4548 22 : if (Util::SameString(Alphas(7), "ReverseCycle")) {
4549 22 : 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 44 : 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 22 : cAlphaFields(6)); // Field Name
4567 :
4568 22 : if (!ErrorsFound) {
4569 22 : checkCurveIsNormalizedToOne(state,
4570 66 : std::string{RoutineName} + CurrentModuleObject,
4571 22 : thisDXCoil.Name,
4572 : thisDXCoil.DefrostEIRFT,
4573 22 : cAlphaFields(6),
4574 22 : Alphas(6),
4575 : RatedInletWetBulbTempHeat,
4576 : RatedOutdoorAirTempHeat);
4577 : }
4578 : }
4579 : }
4580 :
4581 22 : if (Util::SameString(Alphas(7), "ReverseCycle")) {
4582 22 : thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
4583 : }
4584 22 : if (Util::SameString(Alphas(7), "Resistive")) {
4585 0 : thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
4586 : }
4587 22 : 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 22 : if (Util::SameString(Alphas(8), "Timed")) {
4595 22 : thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::Timed;
4596 : }
4597 22 : if (Util::SameString(Alphas(8), "OnDemand")) {
4598 0 : thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
4599 : }
4600 22 : 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 22 : thisDXCoil.MaxOATDefrost = Numbers(5);
4609 :
4610 : // Set defrost time period
4611 22 : thisDXCoil.DefrostTime = Numbers(6);
4612 22 : 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 22 : thisDXCoil.DefrostCapacity = Numbers(7);
4619 22 : 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 22 : if (Util::SameString(Alphas(9), "Yes")) {
4625 0 : thisDXCoil.PLRImpact = true;
4626 22 : } else if (Util::SameString(Alphas(9), "No")) {
4627 22 : 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 22 : thisDXCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(10)));
4637 :
4638 22 : thisDXCoil.RegionNum = Numbers(8); // Region Number for HSPF Calc
4639 22 : thisDXCoil.NumOfSpeeds = Numbers(9); // Number of speeds
4640 22 : 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 22 : thisDXCoil.MSErrIndex.allocate(thisDXCoil.NumOfSpeeds);
4648 22 : thisDXCoil.MSErrIndex = 0;
4649 22 : thisDXCoil.MSRatedTotCap.allocate(thisDXCoil.NumOfSpeeds);
4650 22 : thisDXCoil.MSRatedCOP.allocate(thisDXCoil.NumOfSpeeds);
4651 22 : thisDXCoil.MSRatedAirVolFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4652 22 : thisDXCoil.MSRatedAirMassFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4653 22 : thisDXCoil.MSRatedAirMassFlowRate = 1.0; // avoid divide by 0, will get overwritten in InitDXCoil
4654 22 : thisDXCoil.MSCCapFTemp.allocate(thisDXCoil.NumOfSpeeds);
4655 22 : thisDXCoil.MSCCapFFlow.allocate(thisDXCoil.NumOfSpeeds);
4656 22 : thisDXCoil.MSEIRFTemp.allocate(thisDXCoil.NumOfSpeeds);
4657 22 : thisDXCoil.MSEIRFFlow.allocate(thisDXCoil.NumOfSpeeds);
4658 22 : thisDXCoil.MSWasteHeat.allocate(thisDXCoil.NumOfSpeeds);
4659 22 : thisDXCoil.MSPLFFPLR.allocate(thisDXCoil.NumOfSpeeds);
4660 22 : thisDXCoil.MSRatedCBF.allocate(thisDXCoil.NumOfSpeeds);
4661 22 : thisDXCoil.MSWasteHeatFrac.allocate(thisDXCoil.NumOfSpeeds);
4662 22 : thisDXCoil.MSFanPowerPerEvapAirFlowRate.allocate(thisDXCoil.NumOfSpeeds);
4663 22 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023.allocate(thisDXCoil.NumOfSpeeds);
4664 22 : thisDXCoil.MSSecCoilSHRFT.allocate(thisDXCoil.NumOfSpeeds);
4665 22 : thisDXCoil.MSSecCoilSHRFF.allocate(thisDXCoil.NumOfSpeeds);
4666 22 : thisDXCoil.MSSecCoilAirFlow.allocate(thisDXCoil.NumOfSpeeds);
4667 22 : thisDXCoil.MSSecCoilAirFlowScalingFactor.allocate(thisDXCoil.NumOfSpeeds);
4668 22 : thisDXCoil.MSSecCoilRatedSHR.allocate(thisDXCoil.NumOfSpeeds);
4669 :
4670 22 : thisDXCoil.RatedSHR(1) = 1.0;
4671 :
4672 92 : for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
4673 70 : thisDXCoil.MSRatedTotCap(I) = Numbers(10 + (I - 1) * 6);
4674 70 : thisDXCoil.MSRatedCOP(I) = Numbers(11 + (I - 1) * 6);
4675 70 : thisDXCoil.MSRatedAirVolFlowRate(I) = Numbers(12 + (I - 1) * 6);
4676 70 : thisDXCoil.MSFanPowerPerEvapAirFlowRate(I) = Numbers(13 + (I - 1) * 6);
4677 70 : thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023(I) = Numbers(14 + (I - 1) * 6);
4678 70 : thisDXCoil.MSWasteHeatFrac(I) = Numbers(15 + (I - 1) * 6);
4679 :
4680 70 : thisDXCoil.MSCCapFTemp(I) = GetCurveIndex(state, Alphas(11 + (I - 1) * 6)); // convert curve name to number
4681 70 : 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 210 : ErrorsFound |= Curve::CheckCurveDims(state,
4692 70 : 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 70 : cAlphaFields(11 + (I - 1) * 6)); // Field Name
4698 :
4699 70 : if (!ErrorsFound) {
4700 70 : if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(I))->numDims == 1) {
4701 52 : checkCurveIsNormalizedToOne(state,
4702 156 : std::string{RoutineName} + CurrentModuleObject,
4703 52 : thisDXCoil.Name,
4704 52 : thisDXCoil.MSCCapFTemp(I),
4705 52 : cAlphaFields(11 + (I - 1) * 6),
4706 52 : Alphas(11 + (I - 1) * 6),
4707 : RatedOutdoorAirTempHeat);
4708 : } else {
4709 18 : checkCurveIsNormalizedToOne(state,
4710 54 : std::string{RoutineName} + CurrentModuleObject,
4711 18 : thisDXCoil.Name,
4712 18 : thisDXCoil.MSCCapFTemp(I),
4713 18 : cAlphaFields(11 + (I - 1) * 6),
4714 18 : Alphas(11 + (I - 1) * 6),
4715 : RatedInletAirTempHeat,
4716 : RatedOutdoorAirTempHeat);
4717 : }
4718 : }
4719 : }
4720 :
4721 70 : thisDXCoil.MSCCapFFlow(I) = GetCurveIndex(state, Alphas(12 + (I - 1) * 6)); // convert curve name to number
4722 70 : 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 210 : ErrorsFound |= Curve::CheckCurveDims(state,
4734 70 : thisDXCoil.MSCCapFFlow(I), // Curve index
4735 : {1}, // Valid dimensions
4736 : RoutineName, // Routine name
4737 : CurrentModuleObject, // Object Type
4738 : thisDXCoil.Name, // Object Name
4739 70 : cAlphaFields(12 + (I - 1) * 6)); // Field Name
4740 :
4741 70 : if (!ErrorsFound) {
4742 70 : checkCurveIsNormalizedToOne(state,
4743 210 : std::string{RoutineName} + CurrentModuleObject,
4744 70 : thisDXCoil.Name,
4745 70 : thisDXCoil.MSCCapFFlow(I),
4746 70 : cAlphaFields(12 + (I - 1) * 6),
4747 70 : Alphas(12 + (I - 1) * 6),
4748 : 1.0);
4749 : }
4750 : }
4751 :
4752 70 : thisDXCoil.MSEIRFTemp(I) = GetCurveIndex(state, Alphas(13 + (I - 1) * 6)); // convert curve name to number
4753 70 : 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 210 : ErrorsFound |= Curve::CheckCurveDims(state,
4765 70 : 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 70 : cAlphaFields(13 + (I - 1) * 6)); // Field Name
4771 :
4772 70 : if (!ErrorsFound) {
4773 70 : if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(I))->numDims == 1) {
4774 52 : checkCurveIsNormalizedToOne(state,
4775 156 : std::string{RoutineName} + CurrentModuleObject,
4776 52 : thisDXCoil.Name,
4777 52 : thisDXCoil.MSEIRFTemp(I),
4778 52 : cAlphaFields(13 + (I - 1) * 6),
4779 52 : Alphas(13 + (I - 1) * 6),
4780 : RatedOutdoorAirTempHeat);
4781 : } else {
4782 18 : checkCurveIsNormalizedToOne(state,
4783 54 : std::string{RoutineName} + CurrentModuleObject,
4784 18 : thisDXCoil.Name,
4785 18 : thisDXCoil.MSEIRFTemp(I),
4786 18 : cAlphaFields(13 + (I - 1) * 6),
4787 18 : Alphas(13 + (I - 1) * 6),
4788 : RatedInletAirTempHeat,
4789 : RatedOutdoorAirTempHeat);
4790 : }
4791 : }
4792 : }
4793 :
4794 70 : thisDXCoil.MSEIRFFlow(I) = GetCurveIndex(state, Alphas(14 + (I - 1) * 6)); // convert curve name to number
4795 70 : 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 210 : ErrorsFound |= Curve::CheckCurveDims(state,
4807 70 : thisDXCoil.MSEIRFFlow(I), // Curve index
4808 : {1}, // Valid dimensions
4809 : RoutineName, // Routine name
4810 : CurrentModuleObject, // Object Type
4811 : thisDXCoil.Name, // Object Name
4812 70 : cAlphaFields(14 + (I - 1) * 6)); // Field Name
4813 :
4814 70 : if (!ErrorsFound) {
4815 70 : checkCurveIsNormalizedToOne(state,
4816 210 : std::string{RoutineName} + CurrentModuleObject,
4817 70 : thisDXCoil.Name,
4818 70 : thisDXCoil.MSEIRFFlow(I),
4819 70 : cAlphaFields(14 + (I - 1) * 6),
4820 70 : Alphas(14 + (I - 1) * 6),
4821 : 1.0);
4822 : }
4823 : }
4824 :
4825 70 : thisDXCoil.MSPLFFPLR(I) = GetCurveIndex(state, Alphas(15 + (I - 1) * 6)); // convert curve name to number
4826 70 : 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 210 : ErrorsFound |= Curve::CheckCurveDims(state,
4838 70 : thisDXCoil.MSPLFFPLR(I), // Curve index
4839 : {1}, // Valid dimensions
4840 : RoutineName, // Routine name
4841 : CurrentModuleObject, // Object Type
4842 : thisDXCoil.Name, // Object Name
4843 70 : cAlphaFields(15 + (I - 1) * 6)); // Field Name
4844 :
4845 70 : if (!ErrorsFound) {
4846 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
4847 70 : MinCurveVal = 999.0;
4848 70 : MaxCurveVal = -999.0;
4849 70 : CurveInput = 0.0;
4850 7070 : while (CurveInput <= 1.0) {
4851 7000 : CurveVal = CurveValue(state, thisDXCoil.MSPLFFPLR(I), CurveInput);
4852 7000 : if (CurveVal < MinCurveVal) {
4853 70 : MinCurveVal = CurveVal;
4854 70 : MinCurvePLR = CurveInput;
4855 : }
4856 7000 : if (CurveVal > MaxCurveVal) {
4857 7000 : MaxCurveVal = CurveVal;
4858 7000 : MaxCurvePLR = CurveInput;
4859 : }
4860 7000 : CurveInput += 0.01;
4861 : }
4862 70 : 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 70 : 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 70 : thisDXCoil.MSWasteHeat(I) = GetCurveIndex(state, Alphas(16 + (I - 1) * 6)); // convert curve name to number
4886 70 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
4887 16 : if (thisDXCoil.MSWasteHeat(I) > 0) {
4888 : // Verify Curve Object, only legal types are BiQuadratic
4889 48 : ErrorsFound |= Curve::CheckCurveDims(state,
4890 16 : thisDXCoil.MSWasteHeat(I), // Curve index
4891 : {2}, // Valid dimensions
4892 : RoutineName, // Routine name
4893 : CurrentModuleObject, // Object Type
4894 : thisDXCoil.Name, // Object Name
4895 16 : cAlphaFields(16 + (I - 1) * 6)); // Field Name
4896 :
4897 16 : if (!ErrorsFound) {
4898 16 : checkCurveIsNormalizedToOne(state,
4899 48 : std::string{RoutineName} + CurrentModuleObject,
4900 16 : thisDXCoil.Name,
4901 16 : thisDXCoil.MSWasteHeat(I),
4902 16 : cAlphaFields(16 + (I - 1) * 6),
4903 16 : Alphas(16 + (I - 1) * 6),
4904 : RatedOutdoorAirTempHeat,
4905 : RatedInletAirTempHeat);
4906 : }
4907 : }
4908 : }
4909 : }
4910 : // A35; \field Zone Name for Condenser Placement
4911 22 : 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 22 : 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 251 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling);
4955 297 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFCoolingCoils; ++DXCoilIndex) {
4956 :
4957 46 : 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 46 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
4971 :
4972 46 : ++DXCoilNum;
4973 :
4974 : // allocate single performance mode for numeric field strings used for sizing routine
4975 46 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
4976 46 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
4977 46 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
4978 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
4979 46 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
4980 :
4981 46 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
4982 46 : thisDXCoil.Name = Alphas(1);
4983 46 : thisDXCoil.DXCoilType = CurrentModuleObject;
4984 46 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_Cooling;
4985 :
4986 46 : if (lAlphaBlanks(2)) {
4987 5 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
4988 41 : } 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 46 : thisDXCoil.RatedTotCap(1) = Numbers(1);
4993 46 : thisDXCoil.RatedSHR(1) = Numbers(2);
4994 46 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(3);
4995 :
4996 46 : thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(3));
4997 : // Verify Curve Object, only legal type is Linear, Quadratic, Cubic, or BiQuadratic
4998 138 : ErrorsFound |= Curve::CheckCurveDims(state,
4999 46 : 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 46 : cAlphaFields(3)); // Field Name
5005 :
5006 46 : if (!ErrorsFound) {
5007 46 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
5008 31 : checkCurveIsNormalizedToOne(state,
5009 93 : std::string{RoutineName} + CurrentModuleObject,
5010 31 : thisDXCoil.Name,
5011 31 : thisDXCoil.CCapFTemp(1),
5012 31 : cAlphaFields(3),
5013 31 : Alphas(3),
5014 : RatedInletWetBulbTemp);
5015 : } else {
5016 15 : checkCurveIsNormalizedToOne(state,
5017 45 : std::string{RoutineName} + CurrentModuleObject,
5018 15 : thisDXCoil.Name,
5019 15 : thisDXCoil.CCapFTemp(1),
5020 15 : cAlphaFields(3),
5021 15 : Alphas(3),
5022 : RatedInletWetBulbTemp,
5023 : RatedOutdoorAirTemp);
5024 : }
5025 : }
5026 :
5027 46 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(4)); // convert curve name to number
5028 46 : 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 138 : ErrorsFound |= Curve::CheckCurveDims(state,
5040 46 : thisDXCoil.CCapFFlow(1), // Curve index
5041 : {1}, // Valid dimensions
5042 : RoutineName, // Routine name
5043 : CurrentModuleObject, // Object Type
5044 : thisDXCoil.Name, // Object Name
5045 46 : cAlphaFields(4)); // Field Name
5046 :
5047 46 : if (!ErrorsFound) {
5048 46 : checkCurveIsNormalizedToOne(
5049 184 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(4), Alphas(4), 1.0);
5050 : }
5051 : }
5052 :
5053 46 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5054 46 : Alphas(5),
5055 : ErrorsFound,
5056 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlow,
5057 46 : Alphas(1),
5058 : DataLoopNode::NodeFluidType::Air,
5059 : DataLoopNode::ConnectionType::Inlet,
5060 : NodeInputManager::CompFluidStream::Primary,
5061 : ObjectIsNotParent);
5062 :
5063 92 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5064 46 : Alphas(6),
5065 : ErrorsFound,
5066 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlow,
5067 46 : Alphas(1),
5068 : DataLoopNode::NodeFluidType::Air,
5069 : DataLoopNode::ConnectionType::Outlet,
5070 : NodeInputManager::CompFluidStream::Primary,
5071 : ObjectIsNotParent);
5072 :
5073 46 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(5), Alphas(6), "Air Nodes");
5074 :
5075 46 : thisDXCoil.CondensateCollectName = Alphas(7);
5076 46 : if (lAlphaBlanks(7)) {
5077 46 : 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 251 : 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 251 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating);
5097 297 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFHeatingCoils; ++DXCoilIndex) {
5098 :
5099 46 : 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 46 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
5113 46 : ++DXCoilNum;
5114 :
5115 : // allocate single performance mode for numeric field strings used for sizing routine
5116 46 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
5117 46 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
5118 46 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
5119 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
5120 46 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
5121 :
5122 46 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5123 46 : thisDXCoil.Name = Alphas(1);
5124 46 : thisDXCoil.DXCoilType = CurrentModuleObject;
5125 46 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_Heating;
5126 46 : if (lAlphaBlanks(2)) {
5127 5 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
5128 41 : } 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 46 : thisDXCoil.RatedTotCap(1) = Numbers(1);
5133 46 : thisDXCoil.RatedAirVolFlowRate(1) = Numbers(2);
5134 :
5135 46 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5136 46 : Alphas(3),
5137 : ErrorsFound,
5138 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlow,
5139 46 : Alphas(1),
5140 : DataLoopNode::NodeFluidType::Air,
5141 : DataLoopNode::ConnectionType::Inlet,
5142 : NodeInputManager::CompFluidStream::Primary,
5143 : ObjectIsNotParent);
5144 :
5145 92 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5146 46 : Alphas(4),
5147 : ErrorsFound,
5148 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlow,
5149 46 : Alphas(1),
5150 : DataLoopNode::NodeFluidType::Air,
5151 : DataLoopNode::ConnectionType::Outlet,
5152 : NodeInputManager::CompFluidStream::Primary,
5153 : ObjectIsNotParent);
5154 :
5155 46 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
5156 :
5157 46 : thisDXCoil.CCapFTemp = GetCurveIndex(state, Alphas(5));
5158 46 : 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 138 : ErrorsFound |= Curve::CheckCurveDims(state,
5169 46 : 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 46 : cAlphaFields(5)); // Field Name
5175 :
5176 46 : if (!ErrorsFound) {
5177 46 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
5178 31 : checkCurveIsNormalizedToOne(state,
5179 93 : std::string{RoutineName} + CurrentModuleObject,
5180 31 : thisDXCoil.Name,
5181 31 : thisDXCoil.CCapFTemp(1),
5182 31 : cAlphaFields(5),
5183 31 : 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 46 : thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
5193 46 : 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 138 : ErrorsFound |= Curve::CheckCurveDims(state,
5205 46 : thisDXCoil.CCapFFlow(1), // Curve index
5206 : {1}, // Valid dimensions
5207 : RoutineName, // Routine name
5208 : CurrentModuleObject, // Object Type
5209 : thisDXCoil.Name, // Object Name
5210 46 : cAlphaFields(6)); // Field Name
5211 :
5212 46 : if (!ErrorsFound) {
5213 46 : checkCurveIsNormalizedToOne(
5214 184 : state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
5215 : }
5216 : }
5217 : }
5218 :
5219 251 : 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 251 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling);
5226 267 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils; ++DXCoilIndex) {
5227 :
5228 16 : 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 16 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
5242 16 : ++DXCoilNum;
5243 :
5244 : // allocate single performance mode for numeric field strings used for sizing routine
5245 16 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
5246 16 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
5247 16 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
5248 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
5249 16 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
5250 :
5251 16 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5252 16 : thisDXCoil.Name = Alphas(1);
5253 16 : thisDXCoil.DXCoilType = CurrentModuleObject;
5254 16 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_FluidTCtrl_Cooling;
5255 16 : if (lAlphaBlanks(2)) {
5256 0 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
5257 16 : } 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 16 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5263 16 : Alphas(3),
5264 : ErrorsFound,
5265 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl,
5266 16 : Alphas(1),
5267 : DataLoopNode::NodeFluidType::Air,
5268 : DataLoopNode::ConnectionType::Inlet,
5269 : NodeInputManager::CompFluidStream::Primary,
5270 : ObjectIsNotParent);
5271 32 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5272 16 : Alphas(4),
5273 : ErrorsFound,
5274 : DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl,
5275 16 : Alphas(1),
5276 : DataLoopNode::NodeFluidType::Air,
5277 : DataLoopNode::ConnectionType::Outlet,
5278 : NodeInputManager::CompFluidStream::Primary,
5279 : ObjectIsNotParent);
5280 16 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
5281 :
5282 16 : thisDXCoil.RatedTotCap(1) = Numbers(1);
5283 16 : thisDXCoil.RatedSHR(1) = Numbers(2);
5284 16 : 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 16 : int indexSHCurve = GetCurveIndex(state, Alphas(5)); // convert curve name to index number
5289 : // Verify curve name and type
5290 16 : 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 16 : if (state.dataCurveManager->curves(indexSHCurve)->curveType == Curve::CurveType::Quadratic) {
5302 16 : thisDXCoil.C1Te = state.dataCurveManager->curves(indexSHCurve)->coeff[0];
5303 16 : thisDXCoil.C2Te = state.dataCurveManager->curves(indexSHCurve)->coeff[1];
5304 16 : 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 16 : thisDXCoil.CondensateCollectName = Alphas(6);
5319 16 : if (lAlphaBlanks(6)) {
5320 16 : 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 251 : 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 251 : CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating);
5340 267 : for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils; ++DXCoilIndex) {
5341 :
5342 16 : 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 16 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
5356 16 : ++DXCoilNum;
5357 :
5358 : // allocate single performance mode for numeric field strings used for sizing routine
5359 16 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
5360 16 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
5361 16 : state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
5362 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
5363 16 : VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
5364 :
5365 16 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5366 16 : thisDXCoil.Name = Alphas(1);
5367 16 : thisDXCoil.DXCoilType = CurrentModuleObject;
5368 16 : thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_FluidTCtrl_Heating;
5369 16 : if (lAlphaBlanks(2)) {
5370 0 : thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
5371 16 : } 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 16 : thisDXCoil.AirInNode = GetOnlySingleNode(state,
5377 16 : Alphas(3),
5378 : ErrorsFound,
5379 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl,
5380 16 : Alphas(1),
5381 : DataLoopNode::NodeFluidType::Air,
5382 : DataLoopNode::ConnectionType::Inlet,
5383 : NodeInputManager::CompFluidStream::Primary,
5384 : ObjectIsNotParent);
5385 32 : thisDXCoil.AirOutNode = GetOnlySingleNode(state,
5386 16 : Alphas(4),
5387 : ErrorsFound,
5388 : DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl,
5389 16 : Alphas(1),
5390 : DataLoopNode::NodeFluidType::Air,
5391 : DataLoopNode::ConnectionType::Outlet,
5392 : NodeInputManager::CompFluidStream::Primary,
5393 : ObjectIsNotParent);
5394 16 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
5395 :
5396 16 : thisDXCoil.RatedTotCap(1) = Numbers(1);
5397 16 : thisDXCoil.SC = Numbers(2);
5398 : //@@ DXCoil( DXCoilNum ).RateBFVRFIUCond = 0.136;
5399 :
5400 16 : int indexSCCurve = GetCurveIndex(state, Alphas(5)); // convert curve name to index number
5401 : // Verify curve name and type
5402 16 : 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 16 : if (state.dataCurveManager->curves(indexSCCurve)->curveType == Curve::CurveType::Quadratic) {
5414 16 : thisDXCoil.C1Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[0];
5415 16 : thisDXCoil.C2Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[1];
5416 16 : 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 251 : if (ErrorsFound) {
5432 0 : ShowFatalError(state,
5433 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
5434 : }
5435 :
5436 1240 : for (DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDXCoils; ++DXCoilNum) {
5437 :
5438 989 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
5439 :
5440 989 : 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 1272 : SetupOutputVariable(state,
5444 : "Cooling Coil Total Cooling Rate",
5445 : Constant::Units::W,
5446 636 : thisDXCoil.TotalCoolingEnergyRate,
5447 : OutputProcessor::TimeStepType::System,
5448 : OutputProcessor::StoreType::Average,
5449 636 : thisDXCoil.Name);
5450 1272 : SetupOutputVariable(state,
5451 : "Cooling Coil Total Cooling Energy",
5452 : Constant::Units::J,
5453 636 : thisDXCoil.TotalCoolingEnergy,
5454 : OutputProcessor::TimeStepType::System,
5455 : OutputProcessor::StoreType::Sum,
5456 636 : thisDXCoil.Name,
5457 : Constant::eResource::EnergyTransfer,
5458 : OutputProcessor::Group::HVAC,
5459 : OutputProcessor::EndUseCat::CoolingCoils);
5460 1272 : SetupOutputVariable(state,
5461 : "Cooling Coil Sensible Cooling Rate",
5462 : Constant::Units::W,
5463 636 : thisDXCoil.SensCoolingEnergyRate,
5464 : OutputProcessor::TimeStepType::System,
5465 : OutputProcessor::StoreType::Average,
5466 636 : thisDXCoil.Name);
5467 1272 : SetupOutputVariable(state,
5468 : "Cooling Coil Sensible Cooling Energy",
5469 : Constant::Units::J,
5470 636 : thisDXCoil.SensCoolingEnergy,
5471 : OutputProcessor::TimeStepType::System,
5472 : OutputProcessor::StoreType::Sum,
5473 636 : thisDXCoil.Name);
5474 1272 : SetupOutputVariable(state,
5475 : "Cooling Coil Latent Cooling Rate",
5476 : Constant::Units::W,
5477 636 : thisDXCoil.LatCoolingEnergyRate,
5478 : OutputProcessor::TimeStepType::System,
5479 : OutputProcessor::StoreType::Average,
5480 636 : thisDXCoil.Name);
5481 1272 : SetupOutputVariable(state,
5482 : "Cooling Coil Latent Cooling Energy",
5483 : Constant::Units::J,
5484 636 : thisDXCoil.LatCoolingEnergy,
5485 : OutputProcessor::TimeStepType::System,
5486 : OutputProcessor::StoreType::Sum,
5487 636 : thisDXCoil.Name);
5488 1272 : SetupOutputVariable(state,
5489 : "Cooling Coil Electricity Rate",
5490 : Constant::Units::W,
5491 636 : thisDXCoil.ElecCoolingPower,
5492 : OutputProcessor::TimeStepType::System,
5493 : OutputProcessor::StoreType::Average,
5494 636 : thisDXCoil.Name);
5495 1272 : SetupOutputVariable(state,
5496 : "Cooling Coil Electricity Energy",
5497 : Constant::Units::J,
5498 636 : thisDXCoil.ElecCoolingConsumption,
5499 : OutputProcessor::TimeStepType::System,
5500 : OutputProcessor::StoreType::Sum,
5501 636 : thisDXCoil.Name,
5502 : Constant::eResource::Electricity,
5503 : OutputProcessor::Group::HVAC,
5504 : OutputProcessor::EndUseCat::Cooling);
5505 1272 : SetupOutputVariable(state,
5506 : "Cooling Coil Runtime Fraction",
5507 : Constant::Units::None,
5508 636 : thisDXCoil.CoolingCoilRuntimeFraction,
5509 : OutputProcessor::TimeStepType::System,
5510 : OutputProcessor::StoreType::Average,
5511 636 : thisDXCoil.Name);
5512 636 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
5513 2 : SetupOutputVariable(state,
5514 : "Secondary Coil Heat Rejection Rate",
5515 : Constant::Units::W,
5516 1 : thisDXCoil.SecCoilSensibleHeatGainRate,
5517 : OutputProcessor::TimeStepType::System,
5518 : OutputProcessor::StoreType::Average,
5519 1 : thisDXCoil.Name);
5520 : }
5521 :
5522 : // do we report these even if no storage tank?
5523 636 : 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 636 : if (thisDXCoil.ReportEvapCondVars) {
5544 4 : SetupOutputVariable(state,
5545 : "Cooling Coil Condenser Inlet Temperature",
5546 : Constant::Units::C,
5547 2 : thisDXCoil.CondInletTemp,
5548 : OutputProcessor::TimeStepType::System,
5549 : OutputProcessor::StoreType::Average,
5550 2 : thisDXCoil.Name);
5551 4 : SetupOutputVariable(state,
5552 : "Cooling Coil Evaporative Condenser Water Volume",
5553 : Constant::Units::m3,
5554 2 : thisDXCoil.EvapWaterConsump,
5555 : OutputProcessor::TimeStepType::System,
5556 : OutputProcessor::StoreType::Sum,
5557 2 : thisDXCoil.Name,
5558 : Constant::eResource::Water,
5559 : OutputProcessor::Group::HVAC,
5560 : OutputProcessor::EndUseCat::Cooling);
5561 4 : SetupOutputVariable(state,
5562 : "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
5563 : Constant::Units::m3,
5564 2 : thisDXCoil.EvapWaterConsump,
5565 : OutputProcessor::TimeStepType::System,
5566 : OutputProcessor::StoreType::Sum,
5567 2 : thisDXCoil.Name,
5568 : Constant::eResource::MainsWater,
5569 : OutputProcessor::Group::HVAC,
5570 : OutputProcessor::EndUseCat::Cooling);
5571 4 : SetupOutputVariable(state,
5572 : "Cooling Coil Evaporative Condenser Pump Electricity Rate",
5573 : Constant::Units::W,
5574 2 : thisDXCoil.EvapCondPumpElecPower,
5575 : OutputProcessor::TimeStepType::System,
5576 : OutputProcessor::StoreType::Average,
5577 2 : thisDXCoil.Name);
5578 4 : SetupOutputVariable(state,
5579 : "Cooling Coil Evaporative Condenser Pump Electricity Energy",
5580 : Constant::Units::J,
5581 2 : thisDXCoil.EvapCondPumpElecConsumption,
5582 : OutputProcessor::TimeStepType::System,
5583 : OutputProcessor::StoreType::Sum,
5584 2 : thisDXCoil.Name,
5585 : Constant::eResource::Electricity,
5586 : OutputProcessor::Group::HVAC,
5587 : OutputProcessor::EndUseCat::Cooling);
5588 2 : if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
5589 4 : SetupOutputVariable(state,
5590 : "Cooling Coil Basin Heater Electricity Rate",
5591 : Constant::Units::W,
5592 2 : thisDXCoil.BasinHeaterPower,
5593 : OutputProcessor::TimeStepType::System,
5594 : OutputProcessor::StoreType::Average,
5595 2 : thisDXCoil.Name);
5596 4 : SetupOutputVariable(state,
5597 : "Cooling Coil Basin Heater Electricity Energy",
5598 : Constant::Units::J,
5599 2 : thisDXCoil.BasinHeaterConsumption,
5600 : OutputProcessor::TimeStepType::System,
5601 : OutputProcessor::StoreType::Sum,
5602 2 : thisDXCoil.Name,
5603 : Constant::eResource::Electricity,
5604 : OutputProcessor::Group::HVAC,
5605 : OutputProcessor::EndUseCat::Cooling);
5606 : }
5607 : }
5608 :
5609 636 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
5610 : // Setup Report Variables for Cooling Equipment
5611 : // CurrentModuleObject='Cooling:DX:TwoStageWithHumidityControlMode'
5612 22 : SetupOutputVariable(state,
5613 : "Cooling Coil Stage 2 Runtime Fraction",
5614 : Constant::Units::None,
5615 11 : thisDXCoil.CoolingCoilStg2RuntimeFrac,
5616 : OutputProcessor::TimeStepType::System,
5617 : OutputProcessor::StoreType::Average,
5618 11 : thisDXCoil.Name);
5619 11 : SetupOutputVariable(state,
5620 : "Cooling Coil Dehumidification Mode",
5621 : Constant::Units::None,
5622 11 : (int &)thisDXCoil.DehumidificationMode,
5623 : OutputProcessor::TimeStepType::System,
5624 : OutputProcessor::StoreType::Average,
5625 11 : thisDXCoil.Name);
5626 : }
5627 :
5628 : }
5629 :
5630 353 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5631 : // Setup Report Variables for Heating Equipment
5632 : // CurrentModuleObject='Coil:Heating:DX:SingleSpeed'
5633 150 : SetupOutputVariable(state,
5634 : "Heating Coil Heating Rate",
5635 : Constant::Units::W,
5636 75 : thisDXCoil.TotalHeatingEnergyRate,
5637 : OutputProcessor::TimeStepType::System,
5638 : OutputProcessor::StoreType::Average,
5639 75 : thisDXCoil.Name);
5640 150 : SetupOutputVariable(state,
5641 : "Heating Coil Heating Energy",
5642 : Constant::Units::J,
5643 75 : thisDXCoil.TotalHeatingEnergy,
5644 : OutputProcessor::TimeStepType::System,
5645 : OutputProcessor::StoreType::Sum,
5646 75 : thisDXCoil.Name,
5647 : Constant::eResource::EnergyTransfer,
5648 : OutputProcessor::Group::HVAC,
5649 : OutputProcessor::EndUseCat::HeatingCoils);
5650 150 : SetupOutputVariable(state,
5651 : "Heating Coil Electricity Rate",
5652 : Constant::Units::W,
5653 75 : thisDXCoil.ElecHeatingPower,
5654 : OutputProcessor::TimeStepType::System,
5655 : OutputProcessor::StoreType::Average,
5656 75 : thisDXCoil.Name);
5657 150 : SetupOutputVariable(state,
5658 : "Heating Coil Electricity Energy",
5659 : Constant::Units::J,
5660 75 : thisDXCoil.ElecHeatingConsumption,
5661 : OutputProcessor::TimeStepType::System,
5662 : OutputProcessor::StoreType::Sum,
5663 75 : thisDXCoil.Name,
5664 : Constant::eResource::Electricity,
5665 : OutputProcessor::Group::HVAC,
5666 : OutputProcessor::EndUseCat::Heating);
5667 150 : SetupOutputVariable(state,
5668 : "Heating Coil Defrost Electricity Rate",
5669 : Constant::Units::W,
5670 75 : thisDXCoil.DefrostPower,
5671 : OutputProcessor::TimeStepType::System,
5672 : OutputProcessor::StoreType::Average,
5673 75 : thisDXCoil.Name);
5674 150 : SetupOutputVariable(state,
5675 : "Heating Coil Defrost Electricity Energy",
5676 : Constant::Units::J,
5677 75 : thisDXCoil.DefrostConsumption,
5678 : OutputProcessor::TimeStepType::System,
5679 : OutputProcessor::StoreType::Sum,
5680 75 : thisDXCoil.Name,
5681 : Constant::eResource::Electricity,
5682 : OutputProcessor::Group::HVAC,
5683 : OutputProcessor::EndUseCat::Heating);
5684 150 : SetupOutputVariable(state,
5685 : "Heating Coil Crankcase Heater Electricity Rate",
5686 : Constant::Units::W,
5687 75 : thisDXCoil.CrankcaseHeaterPower,
5688 : OutputProcessor::TimeStepType::System,
5689 : OutputProcessor::StoreType::Average,
5690 75 : thisDXCoil.Name);
5691 150 : SetupOutputVariable(state,
5692 : "Heating Coil Crankcase Heater Electricity Energy",
5693 : Constant::Units::J,
5694 75 : thisDXCoil.CrankcaseHeaterConsumption,
5695 : OutputProcessor::TimeStepType::System,
5696 : OutputProcessor::StoreType::Sum,
5697 75 : thisDXCoil.Name,
5698 : Constant::eResource::Electricity,
5699 : OutputProcessor::Group::HVAC,
5700 : OutputProcessor::EndUseCat::Heating);
5701 150 : SetupOutputVariable(state,
5702 : "Heating Coil Runtime Fraction",
5703 : Constant::Units::None,
5704 75 : thisDXCoil.HeatingCoilRuntimeFraction,
5705 : OutputProcessor::TimeStepType::System,
5706 : OutputProcessor::StoreType::Average,
5707 75 : thisDXCoil.Name);
5708 75 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
5709 2 : SetupOutputVariable(state,
5710 : "Secondary Coil Total Heat Removal Rate",
5711 : Constant::Units::W,
5712 1 : thisDXCoil.SecCoilTotalHeatRemovalRate,
5713 : OutputProcessor::TimeStepType::System,
5714 : OutputProcessor::StoreType::Average,
5715 1 : thisDXCoil.Name);
5716 2 : SetupOutputVariable(state,
5717 : "Secondary Coil Sensible Heat Removal Rate",
5718 : Constant::Units::W,
5719 1 : thisDXCoil.SecCoilSensibleHeatRemovalRate,
5720 : OutputProcessor::TimeStepType::System,
5721 : OutputProcessor::StoreType::Average,
5722 1 : thisDXCoil.Name);
5723 2 : SetupOutputVariable(state,
5724 : "Secondary Coil Latent Heat Removal Rate",
5725 : Constant::Units::W,
5726 1 : thisDXCoil.SecCoilLatentHeatRemovalRate,
5727 : OutputProcessor::TimeStepType::System,
5728 : OutputProcessor::StoreType::Average,
5729 1 : thisDXCoil.Name);
5730 2 : SetupOutputVariable(state,
5731 : "Secondary Coil Sensible Heat Ratio",
5732 : Constant::Units::None,
5733 1 : thisDXCoil.SecCoilSHR,
5734 : OutputProcessor::TimeStepType::System,
5735 : OutputProcessor::StoreType::Average,
5736 1 : thisDXCoil.Name);
5737 2 : SetupOutputVariable(state,
5738 : "Secondary Coil Compressor Part Load Ratio",
5739 : Constant::Units::None,
5740 1 : thisDXCoil.CompressorPartLoadRatio,
5741 : OutputProcessor::TimeStepType::System,
5742 : OutputProcessor::StoreType::Average,
5743 1 : thisDXCoil.Name);
5744 : }
5745 75 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
5746 11 : SetupEMSActuator(state,
5747 : thisDXCoil.DXCoilType,
5748 : thisDXCoil.Name,
5749 : "Frost Heating Capacity Multiplier",
5750 : "[]",
5751 11 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
5752 11 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
5753 :
5754 11 : SetupEMSActuator(state,
5755 : thisDXCoil.DXCoilType,
5756 : thisDXCoil.Name,
5757 : "Frost Heating Input Power Multiplier",
5758 : "[]",
5759 11 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
5760 11 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
5761 : }
5762 : }
5763 :
5764 278 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
5765 : // Setup Report Variables for Cooling Equipment
5766 : // CurrentModuleObject='Coil:Cooling:DX:TwoSpeed'
5767 134 : SetupOutputVariable(state,
5768 : "Cooling Coil Total Cooling Rate",
5769 : Constant::Units::W,
5770 67 : thisDXCoil.TotalCoolingEnergyRate,
5771 : OutputProcessor::TimeStepType::System,
5772 : OutputProcessor::StoreType::Average,
5773 67 : thisDXCoil.Name);
5774 134 : SetupOutputVariable(state,
5775 : "Cooling Coil Total Cooling Energy",
5776 : Constant::Units::J,
5777 67 : thisDXCoil.TotalCoolingEnergy,
5778 : OutputProcessor::TimeStepType::System,
5779 : OutputProcessor::StoreType::Sum,
5780 67 : thisDXCoil.Name,
5781 : Constant::eResource::EnergyTransfer,
5782 : OutputProcessor::Group::HVAC,
5783 : OutputProcessor::EndUseCat::CoolingCoils);
5784 134 : SetupOutputVariable(state,
5785 : "Cooling Coil Sensible Cooling Rate",
5786 : Constant::Units::W,
5787 67 : thisDXCoil.SensCoolingEnergyRate,
5788 : OutputProcessor::TimeStepType::System,
5789 : OutputProcessor::StoreType::Average,
5790 67 : thisDXCoil.Name);
5791 134 : SetupOutputVariable(state,
5792 : "Cooling Coil Sensible Cooling Energy",
5793 : Constant::Units::J,
5794 67 : thisDXCoil.SensCoolingEnergy,
5795 : OutputProcessor::TimeStepType::System,
5796 : OutputProcessor::StoreType::Sum,
5797 67 : thisDXCoil.Name);
5798 134 : SetupOutputVariable(state,
5799 : "Cooling Coil Latent Cooling Rate",
5800 : Constant::Units::W,
5801 67 : thisDXCoil.LatCoolingEnergyRate,
5802 : OutputProcessor::TimeStepType::System,
5803 : OutputProcessor::StoreType::Average,
5804 67 : thisDXCoil.Name);
5805 134 : SetupOutputVariable(state,
5806 : "Cooling Coil Latent Cooling Energy",
5807 : Constant::Units::J,
5808 67 : thisDXCoil.LatCoolingEnergy,
5809 : OutputProcessor::TimeStepType::System,
5810 : OutputProcessor::StoreType::Sum,
5811 67 : thisDXCoil.Name);
5812 134 : SetupOutputVariable(state,
5813 : "Cooling Coil Electricity Rate",
5814 : Constant::Units::W,
5815 67 : thisDXCoil.ElecCoolingPower,
5816 : OutputProcessor::TimeStepType::System,
5817 : OutputProcessor::StoreType::Average,
5818 67 : thisDXCoil.Name);
5819 134 : SetupOutputVariable(state,
5820 : "Cooling Coil Electricity Energy",
5821 : Constant::Units::J,
5822 67 : thisDXCoil.ElecCoolingConsumption,
5823 : OutputProcessor::TimeStepType::System,
5824 : OutputProcessor::StoreType::Sum,
5825 67 : thisDXCoil.Name,
5826 : Constant::eResource::Electricity,
5827 : OutputProcessor::Group::HVAC,
5828 : OutputProcessor::EndUseCat::Cooling);
5829 134 : SetupOutputVariable(state,
5830 : "Cooling Coil Runtime Fraction",
5831 : Constant::Units::None,
5832 67 : thisDXCoil.CoolingCoilRuntimeFraction,
5833 : OutputProcessor::TimeStepType::System,
5834 : OutputProcessor::StoreType::Average,
5835 67 : thisDXCoil.Name);
5836 67 : 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 67 : if (thisDXCoil.ReportEvapCondVars) {
5847 2 : SetupOutputVariable(state,
5848 : "Cooling Coil Condenser Inlet Temperature",
5849 : Constant::Units::C,
5850 1 : thisDXCoil.CondInletTemp,
5851 : OutputProcessor::TimeStepType::System,
5852 : OutputProcessor::StoreType::Average,
5853 1 : thisDXCoil.Name);
5854 2 : SetupOutputVariable(state,
5855 : "Cooling Coil Evaporative Condenser Water Volume",
5856 : Constant::Units::m3,
5857 1 : thisDXCoil.EvapWaterConsump,
5858 : OutputProcessor::TimeStepType::System,
5859 : OutputProcessor::StoreType::Sum,
5860 1 : thisDXCoil.Name,
5861 : Constant::eResource::Water,
5862 : OutputProcessor::Group::HVAC,
5863 : OutputProcessor::EndUseCat::Cooling);
5864 2 : SetupOutputVariable(state,
5865 : "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
5866 : Constant::Units::m3,
5867 1 : thisDXCoil.EvapWaterConsump,
5868 : OutputProcessor::TimeStepType::System,
5869 : OutputProcessor::StoreType::Sum,
5870 1 : thisDXCoil.Name,
5871 : Constant::eResource::MainsWater,
5872 : OutputProcessor::Group::HVAC,
5873 : OutputProcessor::EndUseCat::Cooling);
5874 2 : SetupOutputVariable(state,
5875 : "Cooling Coil Evaporative Condenser Pump Electricity Rate",
5876 : Constant::Units::W,
5877 1 : thisDXCoil.EvapCondPumpElecPower,
5878 : OutputProcessor::TimeStepType::System,
5879 : OutputProcessor::StoreType::Average,
5880 1 : thisDXCoil.Name);
5881 2 : SetupOutputVariable(state,
5882 : "Cooling Coil Evaporative Condenser Pump Electricity Energy",
5883 : Constant::Units::J,
5884 1 : thisDXCoil.EvapCondPumpElecConsumption,
5885 : OutputProcessor::TimeStepType::System,
5886 : OutputProcessor::StoreType::Sum,
5887 1 : thisDXCoil.Name,
5888 : Constant::eResource::Electricity,
5889 : OutputProcessor::Group::HVAC,
5890 : OutputProcessor::EndUseCat::Cooling);
5891 1 : 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 211 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
5915 198 : 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 30 : SetupOutputVariable(state,
5929 : "Cooling Coil Total Cooling Energy",
5930 : Constant::Units::J,
5931 15 : thisDXCoil.TotalCoolingEnergy,
5932 : OutputProcessor::TimeStepType::System,
5933 : OutputProcessor::StoreType::Sum,
5934 15 : thisDXCoil.Name,
5935 : Constant::eResource::EnergyTransfer,
5936 : OutputProcessor::Group::HVAC,
5937 : OutputProcessor::EndUseCat::CoolingCoils);
5938 : } else {
5939 2 : SetupOutputVariable(state,
5940 : "Cooling Coil Total Cooling Energy",
5941 : Constant::Units::J,
5942 1 : thisDXCoil.TotalCoolingEnergy,
5943 : OutputProcessor::TimeStepType::System,
5944 : OutputProcessor::StoreType::Sum,
5945 1 : 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 195 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6040 : // Setup Report Variables for Cooling Equipment:
6041 : // CurrentModuleObject='Coil:Cooling:DX:MultiSpeed'
6042 98 : SetupOutputVariable(state,
6043 : "Cooling Coil Total Cooling Rate",
6044 : Constant::Units::W,
6045 49 : thisDXCoil.TotalCoolingEnergyRate,
6046 : OutputProcessor::TimeStepType::System,
6047 : OutputProcessor::StoreType::Average,
6048 49 : thisDXCoil.Name);
6049 98 : SetupOutputVariable(state,
6050 : "Cooling Coil Total Cooling Energy",
6051 : Constant::Units::J,
6052 49 : thisDXCoil.TotalCoolingEnergy,
6053 : OutputProcessor::TimeStepType::System,
6054 : OutputProcessor::StoreType::Sum,
6055 49 : thisDXCoil.Name,
6056 : Constant::eResource::EnergyTransfer,
6057 : OutputProcessor::Group::HVAC,
6058 : OutputProcessor::EndUseCat::CoolingCoils);
6059 98 : SetupOutputVariable(state,
6060 : "Cooling Coil Sensible Cooling Rate",
6061 : Constant::Units::W,
6062 49 : thisDXCoil.SensCoolingEnergyRate,
6063 : OutputProcessor::TimeStepType::System,
6064 : OutputProcessor::StoreType::Average,
6065 49 : thisDXCoil.Name);
6066 98 : SetupOutputVariable(state,
6067 : "Cooling Coil Sensible Cooling Energy",
6068 : Constant::Units::J,
6069 49 : thisDXCoil.SensCoolingEnergy,
6070 : OutputProcessor::TimeStepType::System,
6071 : OutputProcessor::StoreType::Sum,
6072 49 : thisDXCoil.Name);
6073 98 : SetupOutputVariable(state,
6074 : "Cooling Coil Latent Cooling Rate",
6075 : Constant::Units::W,
6076 49 : thisDXCoil.LatCoolingEnergyRate,
6077 : OutputProcessor::TimeStepType::System,
6078 : OutputProcessor::StoreType::Average,
6079 49 : thisDXCoil.Name);
6080 98 : SetupOutputVariable(state,
6081 : "Cooling Coil Latent Cooling Energy",
6082 : Constant::Units::J,
6083 49 : thisDXCoil.LatCoolingEnergy,
6084 : OutputProcessor::TimeStepType::System,
6085 : OutputProcessor::StoreType::Sum,
6086 49 : thisDXCoil.Name);
6087 98 : SetupOutputVariable(state,
6088 : "Cooling Coil Electricity Rate",
6089 : Constant::Units::W,
6090 49 : thisDXCoil.ElecCoolingPower,
6091 : OutputProcessor::TimeStepType::System,
6092 : OutputProcessor::StoreType::Average,
6093 49 : thisDXCoil.Name);
6094 98 : SetupOutputVariable(state,
6095 : "Cooling Coil Electricity Energy",
6096 : Constant::Units::J,
6097 49 : thisDXCoil.ElecCoolingConsumption,
6098 : OutputProcessor::TimeStepType::System,
6099 : OutputProcessor::StoreType::Sum,
6100 49 : thisDXCoil.Name,
6101 : Constant::eResource::Electricity,
6102 : OutputProcessor::Group::HVAC,
6103 : OutputProcessor::EndUseCat::Cooling);
6104 :
6105 49 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
6106 6 : std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
6107 18 : SetupOutputVariable(state,
6108 12 : format("Cooling Coil {} Rate", sFuelType),
6109 : Constant::Units::W,
6110 6 : thisDXCoil.FuelUsed,
6111 : OutputProcessor::TimeStepType::System,
6112 : OutputProcessor::StoreType::Average,
6113 6 : thisDXCoil.Name);
6114 18 : SetupOutputVariable(state,
6115 12 : format("Cooling Coil {} Energy", sFuelType),
6116 : Constant::Units::J,
6117 6 : thisDXCoil.FuelConsumed,
6118 : OutputProcessor::TimeStepType::System,
6119 : OutputProcessor::StoreType::Sum,
6120 6 : thisDXCoil.Name,
6121 6 : Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
6122 : OutputProcessor::Group::HVAC,
6123 : OutputProcessor::EndUseCat::Cooling);
6124 : }
6125 :
6126 98 : SetupOutputVariable(state,
6127 : "Cooling Coil Runtime Fraction",
6128 : Constant::Units::None,
6129 49 : thisDXCoil.CoolingCoilRuntimeFraction,
6130 : OutputProcessor::TimeStepType::System,
6131 : OutputProcessor::StoreType::Average,
6132 49 : thisDXCoil.Name);
6133 :
6134 49 : 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 49 : 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 146 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6212 : // Setup Report Variables for Heating Equipment:
6213 : // CurrentModuleObject='Coil:Heating:DX:MultiSpeed'
6214 44 : SetupOutputVariable(state,
6215 : "Heating Coil Heating Rate",
6216 : Constant::Units::W,
6217 22 : thisDXCoil.TotalHeatingEnergyRate,
6218 : OutputProcessor::TimeStepType::System,
6219 : OutputProcessor::StoreType::Average,
6220 22 : thisDXCoil.Name);
6221 44 : SetupOutputVariable(state,
6222 : "Heating Coil Heating Energy",
6223 : Constant::Units::J,
6224 22 : thisDXCoil.TotalHeatingEnergy,
6225 : OutputProcessor::TimeStepType::System,
6226 : OutputProcessor::StoreType::Sum,
6227 22 : thisDXCoil.Name,
6228 : Constant::eResource::EnergyTransfer,
6229 : OutputProcessor::Group::HVAC,
6230 : OutputProcessor::EndUseCat::HeatingCoils);
6231 44 : SetupOutputVariable(state,
6232 : "Heating Coil Electricity Rate",
6233 : Constant::Units::W,
6234 22 : thisDXCoil.ElecHeatingPower,
6235 : OutputProcessor::TimeStepType::System,
6236 : OutputProcessor::StoreType::Average,
6237 22 : thisDXCoil.Name);
6238 44 : SetupOutputVariable(state,
6239 : "Heating Coil Electricity Energy",
6240 : Constant::Units::J,
6241 22 : thisDXCoil.ElecHeatingConsumption,
6242 : OutputProcessor::TimeStepType::System,
6243 : OutputProcessor::StoreType::Sum,
6244 22 : thisDXCoil.Name,
6245 : Constant::eResource::Electricity,
6246 : OutputProcessor::Group::HVAC,
6247 : OutputProcessor::EndUseCat::Heating);
6248 :
6249 22 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
6250 4 : std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
6251 12 : SetupOutputVariable(state,
6252 8 : format("Heating Coil {} Rate", sFuelType),
6253 : Constant::Units::W,
6254 4 : thisDXCoil.FuelUsed,
6255 : OutputProcessor::TimeStepType::System,
6256 : OutputProcessor::StoreType::Average,
6257 4 : thisDXCoil.Name);
6258 12 : SetupOutputVariable(state,
6259 8 : format("Heating Coil {} Energy", sFuelType),
6260 : Constant::Units::J,
6261 4 : thisDXCoil.FuelConsumed,
6262 : OutputProcessor::TimeStepType::System,
6263 : OutputProcessor::StoreType::Sum,
6264 4 : thisDXCoil.Name,
6265 4 : Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
6266 : OutputProcessor::Group::HVAC,
6267 : OutputProcessor::EndUseCat::HeatingCoils);
6268 : }
6269 :
6270 22 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
6271 4 : std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
6272 12 : SetupOutputVariable(state,
6273 8 : format("Heating Coil Defrost {} Rate", sFuelType),
6274 : Constant::Units::W,
6275 4 : thisDXCoil.DefrostPower,
6276 : OutputProcessor::TimeStepType::System,
6277 : OutputProcessor::StoreType::Average,
6278 4 : thisDXCoil.Name);
6279 12 : SetupOutputVariable(state,
6280 8 : format("Heating Coil Defrost {} Energy", sFuelType),
6281 : Constant::Units::J,
6282 4 : thisDXCoil.DefrostConsumption,
6283 : OutputProcessor::TimeStepType::System,
6284 : OutputProcessor::StoreType::Sum,
6285 4 : thisDXCoil.Name,
6286 4 : Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
6287 : OutputProcessor::Group::HVAC,
6288 : OutputProcessor::EndUseCat::Heating);
6289 4 : } else {
6290 36 : SetupOutputVariable(state,
6291 : "Heating Coil Defrost Electricity Rate",
6292 : Constant::Units::W,
6293 18 : thisDXCoil.DefrostPower,
6294 : OutputProcessor::TimeStepType::System,
6295 : OutputProcessor::StoreType::Average,
6296 18 : thisDXCoil.Name);
6297 36 : SetupOutputVariable(state,
6298 : "Heating Coil Defrost Electricity Energy",
6299 : Constant::Units::J,
6300 18 : thisDXCoil.DefrostConsumption,
6301 : OutputProcessor::TimeStepType::System,
6302 : OutputProcessor::StoreType::Sum,
6303 18 : thisDXCoil.Name,
6304 : Constant::eResource::Electricity,
6305 : OutputProcessor::Group::HVAC,
6306 : OutputProcessor::EndUseCat::Heating);
6307 : }
6308 :
6309 44 : SetupOutputVariable(state,
6310 : "Heating Coil Crankcase Heater Electricity Rate",
6311 : Constant::Units::W,
6312 22 : thisDXCoil.CrankcaseHeaterPower,
6313 : OutputProcessor::TimeStepType::System,
6314 : OutputProcessor::StoreType::Average,
6315 22 : thisDXCoil.Name);
6316 44 : SetupOutputVariable(state,
6317 : "Heating Coil Crankcase Heater Electricity Energy",
6318 : Constant::Units::J,
6319 22 : thisDXCoil.CrankcaseHeaterConsumption,
6320 : OutputProcessor::TimeStepType::System,
6321 : OutputProcessor::StoreType::Sum,
6322 22 : thisDXCoil.Name,
6323 : Constant::eResource::Electricity,
6324 : OutputProcessor::Group::HVAC,
6325 : OutputProcessor::EndUseCat::Heating);
6326 44 : SetupOutputVariable(state,
6327 : "Heating Coil Runtime Fraction",
6328 : Constant::Units::None,
6329 22 : thisDXCoil.HeatingCoilRuntimeFraction,
6330 : OutputProcessor::TimeStepType::System,
6331 : OutputProcessor::StoreType::Average,
6332 22 : thisDXCoil.Name);
6333 :
6334 22 : 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 22 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
6366 8 : SetupEMSActuator(state,
6367 : thisDXCoil.DXCoilType,
6368 : thisDXCoil.Name,
6369 : "Frost Heating Capacity Multiplier",
6370 : "[]",
6371 8 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
6372 8 : thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
6373 :
6374 8 : SetupEMSActuator(state,
6375 : thisDXCoil.DXCoilType,
6376 : thisDXCoil.Name,
6377 : "Frost Heating Input Power Multiplier",
6378 : "[]",
6379 8 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
6380 8 : thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
6381 : }
6382 : }
6383 :
6384 : // VRF cooling coil report variables
6385 124 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
6386 : // Setup Report Variables for Cooling Equipment:
6387 : // CurrentModuleObject='Coil:Cooling:DX:VariableRefrigerantFlow
6388 92 : SetupOutputVariable(state,
6389 : "Cooling Coil Total Cooling Rate",
6390 : Constant::Units::W,
6391 46 : thisDXCoil.TotalCoolingEnergyRate,
6392 : OutputProcessor::TimeStepType::System,
6393 : OutputProcessor::StoreType::Average,
6394 46 : thisDXCoil.Name);
6395 92 : SetupOutputVariable(state,
6396 : "Cooling Coil Total Cooling Energy",
6397 : Constant::Units::J,
6398 46 : thisDXCoil.TotalCoolingEnergy,
6399 : OutputProcessor::TimeStepType::System,
6400 : OutputProcessor::StoreType::Sum,
6401 46 : thisDXCoil.Name,
6402 : Constant::eResource::EnergyTransfer,
6403 : OutputProcessor::Group::HVAC,
6404 : OutputProcessor::EndUseCat::CoolingCoils);
6405 92 : SetupOutputVariable(state,
6406 : "Cooling Coil Sensible Cooling Rate",
6407 : Constant::Units::W,
6408 46 : thisDXCoil.SensCoolingEnergyRate,
6409 : OutputProcessor::TimeStepType::System,
6410 : OutputProcessor::StoreType::Average,
6411 46 : thisDXCoil.Name);
6412 92 : SetupOutputVariable(state,
6413 : "Cooling Coil Sensible Cooling Energy",
6414 : Constant::Units::J,
6415 46 : thisDXCoil.SensCoolingEnergy,
6416 : OutputProcessor::TimeStepType::System,
6417 : OutputProcessor::StoreType::Sum,
6418 46 : thisDXCoil.Name);
6419 92 : SetupOutputVariable(state,
6420 : "Cooling Coil Latent Cooling Rate",
6421 : Constant::Units::W,
6422 46 : thisDXCoil.LatCoolingEnergyRate,
6423 : OutputProcessor::TimeStepType::System,
6424 : OutputProcessor::StoreType::Average,
6425 46 : thisDXCoil.Name);
6426 92 : SetupOutputVariable(state,
6427 : "Cooling Coil Latent Cooling Energy",
6428 : Constant::Units::J,
6429 46 : thisDXCoil.LatCoolingEnergy,
6430 : OutputProcessor::TimeStepType::System,
6431 : OutputProcessor::StoreType::Sum,
6432 46 : thisDXCoil.Name);
6433 92 : SetupOutputVariable(state,
6434 : "Cooling Coil Runtime Fraction",
6435 : Constant::Units::None,
6436 46 : thisDXCoil.CoolingCoilRuntimeFraction,
6437 : OutputProcessor::TimeStepType::System,
6438 : OutputProcessor::StoreType::Average,
6439 46 : thisDXCoil.Name);
6440 46 : 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 78 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
6463 : // Setup Report Variables for Heating Equipment:
6464 : // CurrentModuleObject='Coil:Heating:DX:VariableRefrigerantFlow
6465 92 : SetupOutputVariable(state,
6466 : "Heating Coil Heating Rate",
6467 : Constant::Units::W,
6468 46 : thisDXCoil.TotalHeatingEnergyRate,
6469 : OutputProcessor::TimeStepType::System,
6470 : OutputProcessor::StoreType::Average,
6471 46 : thisDXCoil.Name);
6472 92 : SetupOutputVariable(state,
6473 : "Heating Coil Heating Energy",
6474 : Constant::Units::J,
6475 46 : thisDXCoil.TotalHeatingEnergy,
6476 : OutputProcessor::TimeStepType::System,
6477 : OutputProcessor::StoreType::Sum,
6478 46 : thisDXCoil.Name,
6479 : Constant::eResource::EnergyTransfer,
6480 : OutputProcessor::Group::HVAC,
6481 : OutputProcessor::EndUseCat::HeatingCoils);
6482 92 : SetupOutputVariable(state,
6483 : "Heating Coil Runtime Fraction",
6484 : Constant::Units::None,
6485 46 : thisDXCoil.HeatingCoilRuntimeFraction,
6486 : OutputProcessor::TimeStepType::System,
6487 : OutputProcessor::StoreType::Average,
6488 46 : thisDXCoil.Name);
6489 :
6490 46 : 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 32 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
6511 : // Setup Report Variables for Cooling Equipment:
6512 : // CurrentModuleObject='Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl
6513 32 : SetupOutputVariable(state,
6514 : "Cooling Coil Total Cooling Rate",
6515 : Constant::Units::W,
6516 16 : thisDXCoil.TotalCoolingEnergyRate,
6517 : OutputProcessor::TimeStepType::System,
6518 : OutputProcessor::StoreType::Average,
6519 16 : thisDXCoil.Name);
6520 32 : SetupOutputVariable(state,
6521 : "Cooling Coil Total Cooling Energy",
6522 : Constant::Units::J,
6523 16 : thisDXCoil.TotalCoolingEnergy,
6524 : OutputProcessor::TimeStepType::System,
6525 : OutputProcessor::StoreType::Sum,
6526 16 : thisDXCoil.Name,
6527 : Constant::eResource::EnergyTransfer,
6528 : OutputProcessor::Group::HVAC,
6529 : OutputProcessor::EndUseCat::CoolingCoils);
6530 32 : SetupOutputVariable(state,
6531 : "Cooling Coil Sensible Cooling Rate",
6532 : Constant::Units::W,
6533 16 : thisDXCoil.SensCoolingEnergyRate,
6534 : OutputProcessor::TimeStepType::System,
6535 : OutputProcessor::StoreType::Average,
6536 16 : thisDXCoil.Name);
6537 32 : SetupOutputVariable(state,
6538 : "Cooling Coil Sensible Cooling Energy",
6539 : Constant::Units::J,
6540 16 : thisDXCoil.SensCoolingEnergy,
6541 : OutputProcessor::TimeStepType::System,
6542 : OutputProcessor::StoreType::Sum,
6543 16 : thisDXCoil.Name);
6544 32 : SetupOutputVariable(state,
6545 : "Cooling Coil Latent Cooling Rate",
6546 : Constant::Units::W,
6547 16 : thisDXCoil.LatCoolingEnergyRate,
6548 : OutputProcessor::TimeStepType::System,
6549 : OutputProcessor::StoreType::Average,
6550 16 : thisDXCoil.Name);
6551 32 : SetupOutputVariable(state,
6552 : "Cooling Coil Latent Cooling Energy",
6553 : Constant::Units::J,
6554 16 : thisDXCoil.LatCoolingEnergy,
6555 : OutputProcessor::TimeStepType::System,
6556 : OutputProcessor::StoreType::Sum,
6557 16 : thisDXCoil.Name);
6558 32 : SetupOutputVariable(state,
6559 : "Cooling Coil Runtime Fraction",
6560 : Constant::Units::None,
6561 16 : thisDXCoil.CoolingCoilRuntimeFraction,
6562 : OutputProcessor::TimeStepType::System,
6563 : OutputProcessor::StoreType::Average,
6564 16 : thisDXCoil.Name);
6565 : // Followings for VRF_FluidTCtrl Only
6566 32 : SetupOutputVariable(state,
6567 : "Cooling Coil VRF Evaporating Temperature",
6568 : Constant::Units::C,
6569 16 : thisDXCoil.EvaporatingTemp,
6570 : OutputProcessor::TimeStepType::System,
6571 : OutputProcessor::StoreType::Average,
6572 16 : thisDXCoil.Name);
6573 32 : SetupOutputVariable(state,
6574 : "Cooling Coil VRF Super Heating Degrees",
6575 : Constant::Units::C,
6576 16 : thisDXCoil.ActualSH,
6577 : OutputProcessor::TimeStepType::System,
6578 : OutputProcessor::StoreType::Average,
6579 16 : thisDXCoil.Name);
6580 :
6581 16 : 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 16 : else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
6604 : // Setup Report Variables for Heating Equipment:
6605 : // CurrentModuleObject='Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl
6606 32 : SetupOutputVariable(state,
6607 : "Heating Coil Heating Rate",
6608 : Constant::Units::W,
6609 16 : thisDXCoil.TotalHeatingEnergyRate,
6610 : OutputProcessor::TimeStepType::System,
6611 : OutputProcessor::StoreType::Average,
6612 16 : thisDXCoil.Name);
6613 32 : SetupOutputVariable(state,
6614 : "Heating Coil Heating Energy",
6615 : Constant::Units::J,
6616 16 : thisDXCoil.TotalHeatingEnergy,
6617 : OutputProcessor::TimeStepType::System,
6618 : OutputProcessor::StoreType::Sum,
6619 16 : thisDXCoil.Name,
6620 : Constant::eResource::EnergyTransfer,
6621 : OutputProcessor::Group::HVAC,
6622 : OutputProcessor::EndUseCat::HeatingCoils);
6623 32 : SetupOutputVariable(state,
6624 : "Heating Coil Runtime Fraction",
6625 : Constant::Units::None,
6626 16 : thisDXCoil.HeatingCoilRuntimeFraction,
6627 : OutputProcessor::TimeStepType::System,
6628 : OutputProcessor::StoreType::Average,
6629 16 : thisDXCoil.Name);
6630 : // Followings for VRF_FluidTCtrl Only
6631 32 : SetupOutputVariable(state,
6632 : "Heating Coil VRF Condensing Temperature",
6633 : Constant::Units::C,
6634 16 : thisDXCoil.CondensingTemp,
6635 : OutputProcessor::TimeStepType::System,
6636 : OutputProcessor::StoreType::Average,
6637 16 : thisDXCoil.Name);
6638 32 : SetupOutputVariable(state,
6639 : "Heating Coil VRF Subcooling Degrees",
6640 : Constant::Units::C,
6641 16 : thisDXCoil.ActualSC,
6642 : OutputProcessor::TimeStepType::System,
6643 : OutputProcessor::StoreType::Average,
6644 16 : thisDXCoil.Name);
6645 : }
6646 : }
6647 :
6648 251 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
6649 : // setup EMS sizing actuators for single speed DX
6650 187 : for (DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDoe2DXCoils; ++DXCoilNum) {
6651 :
6652 146 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
6653 :
6654 146 : SetupEMSActuator(state,
6655 : "Coil:Cooling:DX:SingleSpeed",
6656 : thisDXCoil.Name,
6657 : "Autosized Rated Air Flow Rate",
6658 : "[m3/s]",
6659 : thisDXCoil.RatedAirVolFlowRateEMSOverrideON(1),
6660 146 : thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(1));
6661 :
6662 146 : SetupEMSActuator(state,
6663 : "Coil:Cooling:DX:SingleSpeed",
6664 : thisDXCoil.Name,
6665 : "Autosized Rated Sensible Heat Ratio",
6666 : "[W/W]",
6667 : thisDXCoil.RatedSHREMSOverrideOn(1),
6668 146 : thisDXCoil.RatedSHREMSOverrideValue(1));
6669 :
6670 146 : SetupEMSActuator(state,
6671 : "Coil:Cooling:DX:SingleSpeed",
6672 : thisDXCoil.Name,
6673 : "Autosized Rated Total Cooling Capacity",
6674 : "[W]",
6675 : thisDXCoil.RatedTotCapEMSOverrideOn(1),
6676 146 : thisDXCoil.RatedTotCapEMSOverrideValue(1));
6677 : }
6678 : }
6679 251 : Alphas.deallocate();
6680 251 : cAlphaFields.deallocate();
6681 251 : cNumericFields.deallocate();
6682 251 : Numbers.deallocate();
6683 251 : lAlphaBlanks.deallocate();
6684 251 : lNumericBlanks.deallocate();
6685 :
6686 251 : Alphas2.deallocate();
6687 251 : cAlphaFields2.deallocate();
6688 251 : cNumericFields2.deallocate();
6689 251 : Numbers2.deallocate();
6690 251 : lAlphaBlanks2.deallocate();
6691 251 : lNumericBlanks2.deallocate();
6692 : bool anyEMSRan;
6693 251 : ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyEMSRan, ObjexxFCL::Optional_int_const());
6694 251 : }
6695 :
6696 63554260 : 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 63554260 : 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 63554260 : 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 63554260 : if (state.dataDXCoils->MyOneTimeFlag) {
6731 : // initialize the environment and sizing flags
6732 247 : state.dataDXCoils->MyEnvrnFlag.dimension(state.dataDXCoils->NumDXCoils, true);
6733 247 : state.dataDXCoils->MySizeFlag.dimension(state.dataDXCoils->NumDXCoils, true);
6734 247 : state.dataDXCoils->MyOneTimeFlag = false;
6735 : }
6736 :
6737 63554260 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
6738 :
6739 : // if "ISHundredPercentDOASDXCoil" =.TRUE., then set coil as 100% DOAS dx coil
6740 63554260 : state.dataHVACGlobal->DXCT = (thisDXCoil.ISHundredPercentDOASDXCoil) ? HVAC::DXCoilType::DOAS : HVAC::DXCoilType::Regular;
6741 :
6742 190235637 : if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
6743 64190622 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
6744 636362 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum)) {
6745 :
6746 16 : SizeDXCoil(state, DXCoilNum);
6747 :
6748 16 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(1) / thisDXCoil.RatedTotCap2;
6749 32 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
6750 16 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
6751 4 : ShowWarningError(state,
6752 4 : format("{} \"{}\": Rated air volume flow rate per watt of rated total water heating capacity is out of range",
6753 2 : thisDXCoil.DXCoilType,
6754 2 : thisDXCoil.Name));
6755 4 : ShowContinueError(state,
6756 4 : 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 2 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
6759 : RatedVolFlowPerRatedTotCap,
6760 2 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
6761 : }
6762 : HPInletAirHumRat =
6763 16 : PsyWFnTdbTwbPb(state, thisDXCoil.RatedInletDBTemp, thisDXCoil.RatedInletWBTemp, DataEnvironment::StdPressureSeaLevel, RoutineName);
6764 16 : state.dataHVACGlobal->HPWHInletDBTemp = thisDXCoil.RatedInletDBTemp;
6765 16 : state.dataHVACGlobal->HPWHInletWBTemp = thisDXCoil.RatedInletWBTemp;
6766 32 : thisDXCoil.RatedAirMassFlowRate(1) =
6767 16 : thisDXCoil.RatedAirVolFlowRate(1) *
6768 16 : 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 16 : CalcHPWHDXCoil(state, DXCoilNum, 1.0);
6773 16 : if (state.dataDXCoils->MySizeFlag(DXCoilNum)) {
6774 16 : SizeDXCoil(state, DXCoilNum);
6775 16 : state.dataDXCoils->MySizeFlag(DXCoilNum) = false;
6776 : }
6777 :
6778 16 : thisDXCoil.RatedCBF(1) = CalcCBF(state,
6779 16 : thisDXCoil.DXCoilType,
6780 16 : thisDXCoil.Name,
6781 : thisDXCoil.RatedInletDBTemp,
6782 : HPInletAirHumRat,
6783 16 : thisDXCoil.RatedTotCap(1),
6784 16 : thisDXCoil.RatedAirVolFlowRate(1),
6785 16 : thisDXCoil.RatedSHR(1),
6786 : true);
6787 16 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum) = false;
6788 : }
6789 :
6790 77267461 : if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) &&
6791 13713201 : state.dataDXCoils->MyEnvrnFlag(DXCoilNum)) {
6792 71 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
6793 10 : if (thisDXCoil.MSHPHeatRecActive) {
6794 0 : for (SpeedNum = 1; SpeedNum <= thisDXCoil.NumOfSpeeds; ++SpeedNum) {
6795 0 : 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 71 : 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 63554260 : if (thisDXCoil.FindCompanionUpStreamCoil) {
6810 3916290 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6811 3915398 : thisDXCoil.CompanionUpstreamDXCoil = GetHPCoolingCoilIndex(state, thisDXCoil.DXCoilType, thisDXCoil.Name, DXCoilNum);
6812 3915398 : if (thisDXCoil.CompanionUpstreamDXCoil > 0) {
6813 74 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).ReportCoolingCoilCrankcasePower = false;
6814 74 : thisDXCoil.FindCompanionUpStreamCoil = false;
6815 : // Copy condenser node number from DX cooling coil when used with a companion DX heating coil
6816 370 : for (Mode = 1; Mode <= MaxModes; ++Mode) {
6817 296 : thisDXCoil.CondenserInletNodeNum(Mode) =
6818 296 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CondenserInletNodeNum(Mode);
6819 : }
6820 : }
6821 : } else {
6822 892 : 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 63554260 : if (state.dataDXCoils->CrankcaseHeaterReportVarFlag) {
6828 7982 : 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 1236 : for (DXCoilNumTemp = 1; DXCoilNumTemp <= state.dataDXCoils->NumDXCoils; ++DXCoilNumTemp) {
6831 989 : if ((state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) ||
6832 1342 : (state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) ||
6833 353 : (state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling)) {
6834 685 : if (state.dataDXCoils->DXCoil(DXCoilNumTemp).ReportCoolingCoilCrankcasePower) {
6835 1222 : SetupOutputVariable(state,
6836 : "Cooling Coil Crankcase Heater Electricity Rate",
6837 : Constant::Units::W,
6838 611 : state.dataDXCoils->DXCoil(DXCoilNumTemp).CrankcaseHeaterPower,
6839 : OutputProcessor::TimeStepType::System,
6840 : OutputProcessor::StoreType::Average,
6841 611 : state.dataDXCoils->DXCoil(DXCoilNumTemp).Name);
6842 1222 : SetupOutputVariable(state,
6843 : "Cooling Coil Crankcase Heater Electricity Energy",
6844 : Constant::Units::J,
6845 611 : state.dataDXCoils->DXCoil(DXCoilNumTemp).CrankcaseHeaterConsumption,
6846 : OutputProcessor::TimeStepType::System,
6847 : OutputProcessor::StoreType::Sum,
6848 611 : state.dataDXCoils->DXCoil(DXCoilNumTemp).Name,
6849 : Constant::eResource::Electricity,
6850 : OutputProcessor::Group::HVAC,
6851 : OutputProcessor::EndUseCat::Cooling);
6852 611 : state.dataDXCoils->DXCoil(DXCoilNumTemp).ReportCoolingCoilCrankcasePower = false;
6853 : }
6854 : }
6855 : }
6856 247 : state.dataDXCoils->CrankcaseHeaterReportVarFlag = false;
6857 : } //(AirLoopInputsFilled)THEN
6858 : } //(CrankcaseHeaterReportVarFlag)THEN
6859 :
6860 63554260 : if (!state.dataGlobal->SysSizingCalc && state.dataDXCoils->MySizeFlag(DXCoilNum)) {
6861 : // for each coil, do the sizing once.
6862 973 : SizeDXCoil(state, DXCoilNum);
6863 973 : state.dataDXCoils->MySizeFlag(DXCoilNum) = false;
6864 :
6865 973 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
6866 281 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
6867 :
6868 754 : Mode = 1;
6869 : // Check for zero capacity or zero max flow rate
6870 754 : 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 754 : 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 754 : 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 754 : if (thisDXCoil.DXCoilType_Num !=
6884 : HVAC::CoilVRF_FluidTCtrl_Cooling) { // the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil
6885 738 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
6886 1476 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
6887 738 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
6888 0 : ShowWarningError(state,
6889 0 : format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range.",
6890 0 : thisDXCoil.DXCoilType,
6891 0 : thisDXCoil.Name));
6892 0 : ShowContinueError(state,
6893 0 : 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 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
6896 : RatedVolFlowPerRatedTotCap,
6897 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
6898 : }
6899 : }
6900 :
6901 1508 : thisDXCoil.RatedAirMassFlowRate(Mode) =
6902 754 : thisDXCoil.RatedAirVolFlowRate(Mode) *
6903 754 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
6904 : // get high speed rated coil bypass factor
6905 754 : thisDXCoil.RatedCBF(Mode) = CalcCBF(state,
6906 754 : thisDXCoil.DXCoilType,
6907 754 : thisDXCoil.Name,
6908 : RatedInletAirTemp,
6909 : RatedInletAirHumRat,
6910 754 : thisDXCoil.RatedTotCap(Mode),
6911 754 : thisDXCoil.RatedAirVolFlowRate(Mode),
6912 754 : thisDXCoil.RatedSHR(Mode));
6913 :
6914 : // call coil model with everything set at rating point
6915 754 : thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(Mode);
6916 754 : thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(Mode);
6917 754 : thisDXCoil.InletAirTemp = RatedInletAirTemp;
6918 : Real64 tempInletAirHumRat =
6919 754 : 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 754 : thisDXCoil.InletAirHumRat = tempInletAirHumRat;
6924 754 : thisDXCoil.InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTemp, tempInletAirHumRat);
6925 :
6926 : // store environment data fill back in after rating point calc is over
6927 754 : Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
6928 754 : Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
6929 754 : Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
6930 754 : Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
6931 754 : Real64 ratedOutdoorAirWetBulb = 23.9; // from I/O ref. more precise value?
6932 754 : state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTemp;
6933 754 : state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
6934 754 : state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
6935 1508 : state.dataEnvrn->OutHumRat =
6936 754 : Psychrometrics::PsyWFnTdbTwbPb(state, RatedOutdoorAirTemp, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
6937 754 : if (thisDXCoil.CondenserInletNodeNum(1) > 0) { // set condenser inlet node values
6938 168 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = RatedOutdoorAirTemp;
6939 168 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat = state.dataEnvrn->OutHumRat;
6940 168 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb = ratedOutdoorAirWetBulb;
6941 : }
6942 :
6943 : // calculate coil model at rating point
6944 754 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6945 625 : CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, _, 1.0);
6946 129 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
6947 67 : CalcMultiSpeedDXCoil(state, DXCoilNum, 1.0, 1.0);
6948 62 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
6949 46 : CalcVRFCoolingCoil(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, 1.0, _, _, _);
6950 16 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
6951 16 : CalcVRFCoolingCoil_FluidTCtrl(
6952 : state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, 1.0, _, _, Constant::MaxCap);
6953 : }
6954 :
6955 : // coil outlets
6956 754 : Real64 RatedOutletWetBulb(0.0);
6957 754 : RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
6958 : state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
6959 :
6960 754 : state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
6961 : state,
6962 754 : thisDXCoil.Name,
6963 754 : 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 754 : 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 754 : state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
6980 754 : state.dataEnvrn->OutHumRat = holdOutHumRat;
6981 754 : state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
6982 754 : state.dataEnvrn->OutBaroPress = holdOutBaroPress;
6983 : }
6984 :
6985 973 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
6986 29 : for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
6987 53 : for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
6988 35 : Mode = DehumidModeNum * 2 + CapacityStageNum;
6989 : // Check for zero capacity or zero max flow rate
6990 35 : 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 35 : 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 35 : 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 35 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
7005 70 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7006 35 : ((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 70 : thisDXCoil.RatedAirMassFlowRate(Mode) =
7021 35 : thisDXCoil.RatedAirVolFlowRate(Mode) *
7022 35 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
7023 : // get rated coil bypass factor
7024 35 : thisDXCoil.RatedCBF(Mode) = CalcCBF(state,
7025 35 : thisDXCoil.CoilPerformanceType(Mode),
7026 35 : thisDXCoil.CoilPerformanceName(Mode),
7027 : RatedInletAirTemp,
7028 : RatedInletAirHumRat,
7029 35 : thisDXCoil.RatedTotCap(Mode),
7030 35 : thisDXCoil.RatedAirVolFlowRate(Mode),
7031 35 : thisDXCoil.RatedSHR(Mode));
7032 : } // End capacity stages loop
7033 : } // End dehumidification modes loop
7034 : }
7035 :
7036 973 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating ||
7037 852 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7038 :
7039 137 : Mode = 1;
7040 137 : 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 137 : 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 137 : if (ErrorsFound) {
7049 0 : ShowFatalError(state, "Preceding condition causes termination.");
7050 : }
7051 137 : RatedHeatPumpIndoorAirTemp = 21.11; // 21.11C or 70F
7052 137 : RatedHeatPumpIndoorHumRat = 0.00881; // Humidity ratio corresponding to 70F dry bulb/60F wet bulb
7053 274 : thisDXCoil.RatedAirMassFlowRate(Mode) =
7054 137 : thisDXCoil.RatedAirVolFlowRate(Mode) *
7055 137 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedHeatPumpIndoorAirTemp, RatedHeatPumpIndoorHumRat, RoutineName);
7056 :
7057 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7058 137 : if (thisDXCoil.DXCoilType_Num !=
7059 : HVAC::CoilVRF_FluidTCtrl_Heating) { // the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil
7060 121 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
7061 242 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7062 121 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7063 0 : ShowWarningError(state,
7064 0 : format("Sizing: {} {}: Rated air volume flow rate per watt of rated total heating capacity is out of range.",
7065 0 : thisDXCoil.DXCoilType,
7066 0 : thisDXCoil.Name));
7067 0 : ShowContinueError(state,
7068 0 : 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 0 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7071 : RatedVolFlowPerRatedTotCap,
7072 0 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7073 : }
7074 : }
7075 :
7076 : // call coil model with everything set at rating point
7077 137 : thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(Mode);
7078 137 : thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(Mode);
7079 :
7080 137 : thisDXCoil.InletAirTemp = RatedInletAirTempHeat;
7081 137 : Real64 tempInletAirHumRat = Psychrometrics::PsyWFnTdbTwbPb(
7082 : state, RatedInletAirTempHeat, RatedInletWetBulbTempHeat, DataEnvironment::StdPressureSeaLevel, RoutineName);
7083 137 : thisDXCoil.InletAirHumRat = tempInletAirHumRat;
7084 137 : thisDXCoil.InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTempHeat, tempInletAirHumRat);
7085 :
7086 : // store environment data fill back in after rating point calc is over
7087 137 : Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
7088 137 : Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
7089 137 : Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
7090 137 : Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
7091 :
7092 137 : state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTempHeat;
7093 :
7094 137 : Real64 ratedOutdoorAirWetBulb = 6.11; // from I/O ref. more precise value?
7095 137 : state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
7096 137 : state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
7097 137 : state.dataEnvrn->OutHumRat = Psychrometrics::PsyWFnTdbTwbPb(
7098 : state, RatedOutdoorAirTempHeat, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
7099 :
7100 137 : if (thisDXCoil.CondenserInletNodeNum(1) > 0) { // set condenser inlet node values
7101 61 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = RatedOutdoorAirTempHeat;
7102 61 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat = state.dataEnvrn->OutHumRat;
7103 61 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb = ratedOutdoorAirWetBulb;
7104 : }
7105 :
7106 : // calculate coil model at rating point
7107 137 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
7108 75 : CalcDXHeatingCoil(state, DXCoilNum, 1.0, HVAC::FanOp::Cycling, 1.0);
7109 62 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
7110 46 : CalcDXHeatingCoil(state, DXCoilNum, 1.0, HVAC::FanOp::Cycling, _, _);
7111 16 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7112 16 : CalcVRFHeatingCoil_FluidTCtrl(state, HVAC::CompressorOp::On, DXCoilNum, 1.0, HVAC::FanOp::Cycling, _, _);
7113 : }
7114 : // coil outlets
7115 137 : Real64 RatedOutletWetBulb(0.0);
7116 137 : RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
7117 : state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
7118 :
7119 137 : state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
7120 : state,
7121 137 : thisDXCoil.Name,
7122 137 : 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 137 : 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 137 : state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
7139 137 : state.dataEnvrn->OutHumRat = holdOutHumRat;
7140 137 : state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
7141 137 : state.dataEnvrn->OutBaroPress = holdOutBaroPress;
7142 : }
7143 :
7144 973 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7145 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7146 67 : RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate2 / thisDXCoil.RatedTotCap2;
7147 134 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7148 67 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7149 10 : ShowWarningError(state,
7150 10 : 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 5 : thisDXCoil.Name));
7153 10 : ShowContinueError(state,
7154 10 : 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 5 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7157 : RatedVolFlowPerRatedTotCap,
7158 5 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7159 : }
7160 :
7161 67 : thisDXCoil.RatedAirMassFlowRate2 =
7162 134 : thisDXCoil.RatedAirVolFlowRate2 *
7163 67 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
7164 : // get low speed rated coil bypass factor
7165 134 : thisDXCoil.RatedCBF2 = CalcCBF(state,
7166 67 : thisDXCoil.DXCoilType,
7167 67 : 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 67 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air) {
7176 66 : CalcTwoSpeedDXCoilStandardRating(state, DXCoilNum);
7177 : }
7178 : }
7179 :
7180 : // Multispeed Cooling
7181 973 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7182 162 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
7183 : // Check for zero capacity or zero max flow rate
7184 113 : 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 113 : 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 113 : 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 113 : RatedVolFlowPerRatedTotCap = thisDXCoil.MSRatedAirVolFlowRate(Mode) / thisDXCoil.MSRatedTotCap(Mode);
7199 226 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7200 113 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7201 58 : ShowWarningError(
7202 : state,
7203 58 : format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range at speed {}",
7204 29 : thisDXCoil.DXCoilType,
7205 29 : thisDXCoil.Name,
7206 : Mode));
7207 58 : ShowContinueError(state,
7208 58 : 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 29 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7211 : RatedVolFlowPerRatedTotCap,
7212 29 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7213 : }
7214 226 : thisDXCoil.MSRatedAirMassFlowRate(Mode) =
7215 113 : thisDXCoil.MSRatedAirVolFlowRate(Mode) *
7216 113 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
7217 : // get high speed rated coil bypass factor
7218 113 : thisDXCoil.MSRatedCBF(Mode) = CalcCBF(state,
7219 113 : thisDXCoil.DXCoilType,
7220 113 : thisDXCoil.Name,
7221 : RatedInletAirTemp,
7222 : RatedInletAirHumRat,
7223 113 : thisDXCoil.MSRatedTotCap(Mode),
7224 113 : thisDXCoil.MSRatedAirVolFlowRate(Mode),
7225 113 : thisDXCoil.MSRatedSHR(Mode));
7226 : }
7227 : }
7228 :
7229 : // Multispeed Heating
7230 973 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7231 22 : RatedHeatPumpIndoorAirTemp = 21.11; // 21.11C or 70F
7232 22 : RatedHeatPumpIndoorHumRat = 0.00881; // Humidity ratio corresponding to 70F dry bulb/60F wet bulb
7233 92 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
7234 :
7235 140 : thisDXCoil.MSRatedAirMassFlowRate(Mode) =
7236 70 : thisDXCoil.MSRatedAirVolFlowRate(Mode) *
7237 70 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedHeatPumpIndoorAirTemp, RatedHeatPumpIndoorHumRat, RoutineName);
7238 : // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
7239 70 : RatedVolFlowPerRatedTotCap = thisDXCoil.MSRatedAirVolFlowRate(Mode) / thisDXCoil.MSRatedTotCap(Mode);
7240 140 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
7241 70 : ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
7242 12 : ShowWarningError(state,
7243 12 : 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 6 : thisDXCoil.Name,
7246 : Mode));
7247 12 : ShowContinueError(state,
7248 12 : 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 6 : HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
7251 : RatedVolFlowPerRatedTotCap,
7252 6 : HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
7253 : }
7254 : }
7255 : }
7256 :
7257 : // store fan info for coil
7258 973 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
7259 973 : state, thisDXCoil.Name, thisDXCoil.DXCoilType, thisDXCoil.SupplyFanName, thisDXCoil.supplyFanType, thisDXCoil.SupplyFanIndex);
7260 : }
7261 :
7262 63554260 : AirInletNode = thisDXCoil.AirInNode;
7263 :
7264 : // Each iteration, load the coil data structure with the inlet conditions
7265 :
7266 63554260 : thisDXCoil.InletAirMassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
7267 63554260 : thisDXCoil.InletAirMassFlowRateMax =
7268 63554260 : max(state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax, state.dataLoopNodes->Node(AirInletNode).MassFlowRate);
7269 63554260 : thisDXCoil.InletAirTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
7270 63554260 : thisDXCoil.InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
7271 63554260 : 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 63554260 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7276 12732986 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
7277 81924 : thisDXCoil.EvapInletWetBulb = PsyTwbFnTdbWPb(state,
7278 81924 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr).ZT,
7279 81924 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr).airHumRat,
7280 81924 : state.dataEnvrn->OutBaroPress,
7281 : RoutineName);
7282 : }
7283 : }
7284 :
7285 63554260 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
7286 636362 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
7287 636362 : 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 636362 : if (thisDXCoil.CondenserInletNodeNum(1) > 0) {
7294 636362 : if (state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press == 0.0) {
7295 0 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press = state.dataEnvrn->StdBaroPress;
7296 : }
7297 : }
7298 : }
7299 63554260 : thisDXCoil.BasinHeaterPower = 0.0;
7300 :
7301 63554260 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
7302 163849 : thisDXCoil.CompressorPartLoadRatio = 0.0;
7303 163849 : thisDXCoil.SecCoilSensibleHeatGainRate = 0.0;
7304 163849 : thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
7305 163849 : thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
7306 163849 : thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
7307 : }
7308 63554260 : }
7309 :
7310 1005 : 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 1005 : 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 1005 : std::string CompName; // component name
7363 1005 : std::string CompType; // component type
7364 1005 : std::string SizingString; // input field sizing description (e.g., Nominal Capacity)
7365 1005 : bool bPRINT = true; // TRUE if sizing is reported to output (eio)
7366 : Real64 TempSize; // autosized value of coil input field
7367 1005 : 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 1005 : if (state.dataSize->SysSizingRunDone || state.dataSize->ZoneSizingRunDone) {
7375 875 : HardSizeNoDesRun = false;
7376 : } else {
7377 130 : HardSizeNoDesRun = true;
7378 : }
7379 :
7380 1005 : if (state.dataSize->CurSysNum > 0) {
7381 625 : CheckThisAirSystemForSizing(state, state.dataSize->CurSysNum, SizingDesRunThisAirSys);
7382 : } else {
7383 380 : SizingDesRunThisAirSys = false;
7384 : }
7385 1005 : if (state.dataSize->CurZoneEqNum > 0) {
7386 356 : CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
7387 : } else {
7388 649 : SizingDesRunThisZone = false;
7389 : }
7390 :
7391 1005 : IsAutoSize = false;
7392 1005 : SizeSecDXCoil = false;
7393 1005 : MSRatedTotCapDesAtMaxSpeed = 0.0;
7394 1005 : DefrostCapacityDes = 0.0;
7395 1005 : DefrostCapacityUser = 0.0;
7396 1005 : MSRatedAirVolFlowRateDes = 0.0;
7397 1005 : MSRatedSHRDes = 0.0;
7398 1005 : MSEvapCondAirFlowDes = 0.0;
7399 1005 : MSEvapCondAirFlowUser = 0.0;
7400 1005 : MSEvapCondPumpElecNomPowerDes = 0.0;
7401 1005 : MSEvapCondPumpElecNomPowerUser = 0.0;
7402 1005 : SecCoilAirFlowDes = 0.0;
7403 1005 : SecCoilAirFlowUser = 0.0;
7404 :
7405 : // Sizer classes
7406 1005 : CoolingSHRSizer sizerCoolingSHR;
7407 1005 : bool ErrorsFound = false;
7408 :
7409 1005 : 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 2017 : for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
7415 2041 : for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
7416 1029 : Mode = DehumidModeNum * 2 + CapacityStageNum;
7417 1029 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
7418 1003 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
7419 32 : if (thisDXCoil.RatedAirVolFlowRate(1) == Constant::AutoCalculate) {
7420 : // report autocalculated sizing
7421 6 : PrintFlag = true;
7422 6 : CompName = thisDXCoil.Name;
7423 6 : CompType = thisDXCoil.DXCoilType;
7424 : // DXCoil( DXCoilNum ).RatedAirVolFlowRate( 1 ) = DXCoil( DXCoilNum ).RatedTotCap2 * 0.00005035
7425 6 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap2;
7426 6 : state.dataSize->DataFractionUsedForSizing = 0.00005035;
7427 6 : TempSize = AutoSize;
7428 6 : AutoCalculateSizer sizerHPRatedAirVolFlow;
7429 6 : std::string stringOverride = "Rated Evaporator Air Flow Rate [m3/s]";
7430 6 : if (state.dataGlobal->isEpJSON) {
7431 0 : stringOverride = "rated_evaporator_air_flow_rate [m3/s]";
7432 : }
7433 6 : sizerHPRatedAirVolFlow.overrideSizingString(stringOverride);
7434 6 : sizerHPRatedAirVolFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7435 6 : thisDXCoil.RatedAirVolFlowRate(1) = sizerHPRatedAirVolFlow.size(state, TempSize, ErrorsFound);
7436 6 : PrintFlag = false;
7437 6 : }
7438 :
7439 32 : if (thisDXCoil.RatedHPWHCondWaterFlow == Constant::AutoCalculate) {
7440 : // report autocalculated sizing
7441 6 : PrintFlag = true;
7442 6 : CompName = thisDXCoil.Name;
7443 6 : CompType = thisDXCoil.DXCoilType;
7444 : // DXCoil( DXCoilNum ).RatedAirVolFlowRate( 1 ) = DXCoil( DXCoilNum ).RatedTotCap2 * 0.00000004487
7445 6 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap2;
7446 6 : state.dataSize->DataFractionUsedForSizing = 0.00000004487;
7447 6 : TempSize = AutoSize;
7448 6 : AutoCalculateSizer sizerHPWHCondWaterFlow;
7449 6 : std::string stringOverride = "Rated Condenser Water Flow Rate [m3/s]";
7450 6 : if (state.dataGlobal->isEpJSON) {
7451 0 : stringOverride = "rated_condenser_water_flow_rate [m3/s]";
7452 : }
7453 6 : sizerHPWHCondWaterFlow.overrideSizingString(stringOverride);
7454 6 : sizerHPWHCondWaterFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7455 6 : thisDXCoil.RatedHPWHCondWaterFlow = sizerHPWHCondWaterFlow.size(state, TempSize, ErrorsFound);
7456 6 : PrintFlag = false;
7457 6 : }
7458 32 : } else {
7459 997 : PrintFlag = true;
7460 997 : FieldNum = 0;
7461 997 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7462 35 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7463 35 : FieldNum = 4;
7464 35 : state.dataSize->DataBypassFrac = thisDXCoil.BypassedFlowFrac(Mode);
7465 962 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
7466 75 : CompName = thisDXCoil.Name;
7467 75 : FieldNum = 3;
7468 : // doesn't look like this is needed for air flow sizing, only for heating capacity sizing
7469 150 : state.dataSize->DataCoolCoilCap =
7470 75 : state.dataSize->DXCoolCap; // pass global variable used only for heat pumps (i.e., DX cooling and heating coils)
7471 76 : if ((thisDXCoil.IsSecondaryDXCoilInZone) &&
7472 1 : (thisDXCoil.CondenserType(1) ==
7473 : DataHeatBalance::RefrigCondenserType::Air)) { // secondary DX coil in secondary zone is specified
7474 1 : SizeSecDXCoil = true;
7475 : }
7476 887 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
7477 46 : CompName = thisDXCoil.Name;
7478 46 : FieldNum = 2;
7479 841 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
7480 46 : CompName = thisDXCoil.Name;
7481 46 : FieldNum = 3;
7482 795 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7483 16 : CompName = thisDXCoil.Name;
7484 779 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7485 16 : CompName = thisDXCoil.Name;
7486 763 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7487 49 : thisDXCoil.RatedAirVolFlowRate(Mode) = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
7488 49 : CompName = thisDXCoil.Name;
7489 49 : PrintFlag = false;
7490 714 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7491 22 : thisDXCoil.RatedAirVolFlowRate(Mode) = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
7492 22 : CompName = thisDXCoil.Name;
7493 22 : PrintFlag = false;
7494 : } else {
7495 692 : CompName = thisDXCoil.Name;
7496 692 : FieldNum = 4;
7497 : }
7498 :
7499 997 : TempSize = thisDXCoil.RatedAirVolFlowRate(Mode);
7500 997 : if (FieldNum > 0) {
7501 894 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [m3/s]";
7502 : } else {
7503 103 : SizingString = "Rated Air Flow Rate [m3/s]";
7504 : }
7505 997 : CompType = thisDXCoil.DXCoilType;
7506 997 : state.dataSize->DataIsDXCoil = true;
7507 997 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
7508 997 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
7509 997 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating ||
7510 959 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
7511 159 : bool errorsFound = false;
7512 159 : HeatingAirFlowSizer sizingHeatingAirFlow;
7513 159 : sizingHeatingAirFlow.overrideSizingString(SizingString);
7514 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7515 159 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7516 159 : thisDXCoil.RatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
7517 159 : } else {
7518 838 : bool errorsFound = false;
7519 838 : CoolingAirFlowSizer sizingCoolingAirFlow;
7520 838 : sizingCoolingAirFlow.overrideSizingString(SizingString);
7521 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7522 838 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7523 838 : thisDXCoil.RatedAirVolFlowRate(Mode) = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7524 838 : }
7525 997 : state.dataSize->DataIsDXCoil = false;
7526 997 : state.dataSize->DataEMSOverrideON = false;
7527 997 : state.dataSize->DataEMSOverride = 0.0;
7528 997 : state.dataSize->DataBypassFrac = 0.0;
7529 : }
7530 :
7531 1029 : 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 1029 : PrintFlag = true;
7568 1029 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.CCapFTemp(Mode);
7569 1029 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7570 35 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7571 35 : FieldNum = 1;
7572 35 : TempSize = thisDXCoil.RatedTotCap(Mode);
7573 35 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7574 994 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating ||
7575 873 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7576 137 : CompName = thisDXCoil.Name;
7577 137 : FieldNum = 1;
7578 137 : TempSize = thisDXCoil.RatedTotCap(Mode);
7579 137 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7580 137 : state.dataSize->DataCoolCoilCap = state.dataSize->DXCoolCap;
7581 857 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
7582 831 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
7583 32 : CompName = thisDXCoil.Name;
7584 32 : FieldNum = 1;
7585 32 : TempSize = thisDXCoil.RatedTotCap(Mode);
7586 32 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7587 32 : PrintFlag = false;
7588 32 : state.dataLoopNodes->Node(thisDXCoil.WaterInNode).Temp =
7589 32 : thisDXCoil.RatedInletWaterTemp; // set the rated water inlet node for HPWHs for use in CalcHPWHDXCoil
7590 825 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7591 16 : CompName = thisDXCoil.Name;
7592 16 : FieldNum = 1;
7593 16 : TempSize = thisDXCoil.RatedTotCap(Mode);
7594 16 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7595 16 : if (state.dataSize->CurZoneEqNum > 0) {
7596 16 : CoilInTemp =
7597 16 : 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 16 : CalcVRFCoilCapModFac(state, 0, _, CompName, CoilInTemp, _, _, _, state.dataSize->DataTotCapCurveValue);
7608 809 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7609 49 : CompName = thisDXCoil.Name;
7610 49 : FieldNum = 7 + (thisDXCoil.NumOfSpeeds - 1) * 13;
7611 49 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(thisDXCoil.NumOfSpeeds);
7612 49 : TempSize = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
7613 49 : PrintFlag = false;
7614 49 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7615 760 : } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
7616 22 : CompName = thisDXCoil.Name;
7617 22 : FieldNum = 10 + (thisDXCoil.NumOfSpeeds - 1) * 6;
7618 22 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(thisDXCoil.NumOfSpeeds);
7619 22 : TempSize = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
7620 22 : PrintFlag = false;
7621 22 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7622 : } else {
7623 738 : CompName = thisDXCoil.Name;
7624 738 : FieldNum = 1;
7625 738 : TempSize = thisDXCoil.RatedTotCap(Mode);
7626 738 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
7627 : }
7628 1029 : CompType = thisDXCoil.DXCoilType;
7629 1029 : state.dataSize->DataIsDXCoil = true;
7630 1029 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
7631 1029 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
7632 1029 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical ||
7633 932 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
7634 159 : HeatingCapacitySizer sizerHeatingCapacity;
7635 159 : sizerHeatingCapacity.overrideSizingString(SizingString);
7636 159 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7637 159 : thisDXCoil.RatedTotCap(Mode) = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
7638 159 : } else {
7639 870 : CoolingCapacitySizer sizerCoolingCapacity;
7640 870 : sizerCoolingCapacity.overrideSizingString(SizingString);
7641 870 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7642 870 : thisDXCoil.RatedTotCap(Mode) = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
7643 870 : }
7644 1029 : state.dataSize->DataIsDXCoil = false;
7645 1029 : state.dataSize->DataFlowUsedForSizing = 0.0;
7646 1029 : state.dataSize->DataCoolCoilCap = 0.0;
7647 1029 : state.dataSize->DataTotCapCurveIndex = 0;
7648 1029 : state.dataSize->DataEMSOverrideON = false;
7649 1029 : state.dataSize->DataEMSOverride = 0.0;
7650 1029 : state.dataSize->DataConstantUsedForSizing = 0.0;
7651 1029 : state.dataSize->DataFractionUsedForSizing = 0.0;
7652 1029 : state.dataSize->DataTotCapCurveValue = 0.0;
7653 :
7654 : // Cooling coil capacity
7655 1029 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7656 337 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling ||
7657 256 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7658 789 : state.dataSize->DXCoolCap = thisDXCoil.RatedTotCap(Mode);
7659 : }
7660 :
7661 : // Sizing DX cooling coil SHR
7662 1029 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7663 337 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling ||
7664 256 : thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
7665 :
7666 789 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7667 35 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7668 : } else {
7669 754 : CompName = thisDXCoil.Name;
7670 : }
7671 789 : CompType = thisDXCoil.DXCoilType;
7672 789 : TempSize = thisDXCoil.RatedSHR(Mode);
7673 789 : state.dataSize->DataDXSpeedNum = Mode;
7674 789 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
7675 789 : state.dataSize->DataCapacityUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7676 789 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedSHREMSOverrideOn(Mode);
7677 789 : state.dataSize->DataEMSOverride = thisDXCoil.RatedSHREMSOverrideValue(Mode);
7678 789 : bool ErrorsFound = false;
7679 789 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7680 789 : thisDXCoil.RatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
7681 789 : state.dataSize->DataDXSpeedNum = 0;
7682 789 : state.dataSize->DataFlowUsedForSizing = 0.0;
7683 789 : state.dataSize->DataCapacityUsedForSizing = 0.0;
7684 789 : state.dataSize->DataEMSOverrideON = false;
7685 789 : state.dataSize->DataEMSOverride = 0.0;
7686 :
7687 : } // End of Rated SHR
7688 :
7689 : // Sizing evaporator condenser air flow
7690 1029 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondAirFlow(Mode) != 0.0 &&
7691 0 : (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7692 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
7693 :
7694 0 : AutoCalculateSizer sizerEvapCondAirFlow;
7695 0 : std::string stringOverride = "Evaporative Condenser Air Flow Rate [m3/s]";
7696 0 : if (state.dataGlobal->isEpJSON) {
7697 0 : stringOverride = "evaporative_condenser_air_flow_rate [m3/s]";
7698 : }
7699 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7700 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7701 : } else {
7702 0 : CompName = thisDXCoil.Name;
7703 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7704 0 : stringOverride = "High Speed Evaporative Condenser Air Flow Rate [m3/s]";
7705 0 : if (state.dataGlobal->isEpJSON) {
7706 0 : stringOverride = "high_speed_evaporative_condenser_air_flow_rate [m3/s]";
7707 : }
7708 : } else {
7709 0 : stringOverride = "Evaporative Condenser Air Flow Rate [m3/s]";
7710 0 : if (state.dataGlobal->isEpJSON) {
7711 0 : stringOverride = "evaporative_condenser_air_flow_rate [m3/s]";
7712 : }
7713 : }
7714 : }
7715 0 : CompType = thisDXCoil.DXCoilType;
7716 : // Auto-size condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
7717 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7718 0 : state.dataSize->DataFractionUsedForSizing = 0.000114;
7719 0 : TempSize = thisDXCoil.EvapCondAirFlow(Mode);
7720 0 : sizerEvapCondAirFlow.overrideSizingString(stringOverride);
7721 0 : sizerEvapCondAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7722 0 : thisDXCoil.EvapCondAirFlow(Mode) = sizerEvapCondAirFlow.size(state, TempSize, ErrorsFound);
7723 0 : }
7724 :
7725 1029 : if (SizeSecDXCoil) { // autosize secondary coil air flow rate for AirCooled condenser type
7726 1 : IsAutoSize = false;
7727 1 : if (thisDXCoil.SecCoilAirFlow == AutoSize) {
7728 1 : IsAutoSize = true;
7729 : }
7730 : // Autosize Primary Coil Air Flow * Secondary Coil Scaling Factor
7731 1 : SecCoilAirFlowDes = thisDXCoil.RatedAirVolFlowRate(1) * thisDXCoil.SecCoilAirFlowScalingFactor;
7732 1 : if (IsAutoSize) {
7733 1 : thisDXCoil.SecCoilAirFlow = SecCoilAirFlowDes;
7734 1 : 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 1029 : PrintFlag = true;
7764 1029 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondAirFlow2 != 0.0 &&
7765 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7766 0 : CompName = thisDXCoil.Name;
7767 0 : FieldNum = 15; // Low Speed Evaporative Condenser Air Flow Rate
7768 0 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [m3/s]";
7769 0 : CompType = thisDXCoil.DXCoilType;
7770 : // Autosize low speed condenser air flow to 1/3 Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
7771 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7772 0 : state.dataSize->DataFractionUsedForSizing = 0.000114 * 0.3333;
7773 0 : TempSize = thisDXCoil.EvapCondAirFlow2;
7774 0 : AutoCalculateSizer sizerEvapCondAirFlow2;
7775 0 : std::string stringOverride = "Low Speed Evaporative Condenser Air Flow Rate [m3/s]";
7776 0 : if (state.dataGlobal->isEpJSON) {
7777 0 : stringOverride = "low_speed_evaporative_condenser_air_flow_rate [m3/s]";
7778 : }
7779 0 : sizerEvapCondAirFlow2.overrideSizingString(stringOverride);
7780 0 : sizerEvapCondAirFlow2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7781 0 : thisDXCoil.EvapCondAirFlow2 = sizerEvapCondAirFlow2.size(state, TempSize, ErrorsFound);
7782 0 : }
7783 :
7784 : // Sizing evaporative condenser pump electric nominal power
7785 1029 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondPumpElecNomPower(Mode) != 0.0 &&
7786 0 : (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
7787 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
7788 :
7789 0 : AutoCalculateSizer sizerEvapCondPumpPower;
7790 0 : std::string stringOverride = "Evaporative Condenser Pump Rated Power Consumption [W]";
7791 0 : if (state.dataGlobal->isEpJSON) {
7792 0 : stringOverride = "evaporative_condenser_pump_rated_power_consumption [W]";
7793 : }
7794 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
7795 0 : CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
7796 : } else {
7797 0 : CompName = thisDXCoil.Name;
7798 0 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7799 0 : stringOverride = "High Speed Evaporative Condenser Pump Rated Power Consumption [W]";
7800 0 : if (state.dataGlobal->isEpJSON) {
7801 0 : stringOverride = "high_speed_evaporative_condenser_pump_rated_power_consumption [W]";
7802 : }
7803 : } else {
7804 0 : stringOverride = "Evaporative Condenser Pump Rated Power Consumption [W]";
7805 0 : if (state.dataGlobal->isEpJSON) {
7806 0 : stringOverride = "evaporative_condenser_pump_rated_power_consumption [W]";
7807 : }
7808 : }
7809 : }
7810 0 : CompType = thisDXCoil.DXCoilType;
7811 : // Autosize high speed evap condenser pump power to Total Capacity * 0.004266 w/w (15 w/ton)
7812 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7813 0 : state.dataSize->DataFractionUsedForSizing = 0.004266;
7814 0 : TempSize = thisDXCoil.EvapCondPumpElecNomPower(Mode);
7815 0 : sizerEvapCondPumpPower.overrideSizingString(stringOverride);
7816 0 : sizerEvapCondPumpPower.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7817 0 : thisDXCoil.EvapCondPumpElecNomPower(Mode) = sizerEvapCondPumpPower.size(state, TempSize, ErrorsFound);
7818 0 : }
7819 :
7820 : // Sizing low speed evaporative condenser pump electric nominal power
7821 1029 : if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondPumpElecNomPower2 != 0.0 &&
7822 0 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7823 0 : CompName = thisDXCoil.Name;
7824 0 : CompType = thisDXCoil.DXCoilType;
7825 : // Autosize low speed evap condenser pump power to 1/3 Total Capacity * 0.004266 w/w (15 w/ton)
7826 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7827 0 : state.dataSize->DataFractionUsedForSizing = 0.004266 * 0.3333;
7828 0 : TempSize = thisDXCoil.EvapCondPumpElecNomPower2;
7829 0 : AutoCalculateSizer sizerEvapCondPumpPower2;
7830 0 : std::string stringOverride = "Low Speed Evaporative Condenser Pump Rated Power Consumption [W]";
7831 0 : if (state.dataGlobal->isEpJSON) {
7832 0 : stringOverride = "low_speed_evaporative_condenser_pump_rated_power_consumption [W]";
7833 : }
7834 0 : sizerEvapCondPumpPower2.overrideSizingString(stringOverride);
7835 0 : sizerEvapCondPumpPower2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7836 0 : thisDXCoil.EvapCondPumpElecNomPower2 = sizerEvapCondPumpPower2.size(state, TempSize, ErrorsFound);
7837 0 : }
7838 :
7839 : // // Sizing rated low speed air flow rate
7840 1029 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7841 67 : CompName = thisDXCoil.Name;
7842 67 : CompType = thisDXCoil.DXCoilType;
7843 : // Autosize low speed air flow rate to 1/3 high speed air flow rate
7844 67 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
7845 67 : state.dataSize->DataFractionUsedForSizing = 0.3333;
7846 67 : TempSize = thisDXCoil.RatedAirVolFlowRate2;
7847 67 : AutoCalculateSizer sizerLowSpdAirFlow;
7848 67 : std::string stringOverride = "Low Speed Rated Air Flow Rate [m3/s]";
7849 67 : if (state.dataGlobal->isEpJSON) {
7850 3 : stringOverride = "low_speed_rated_air_flow_rate [m3/s]";
7851 : }
7852 67 : sizerLowSpdAirFlow.overrideSizingString(stringOverride);
7853 67 : sizerLowSpdAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7854 67 : thisDXCoil.RatedAirVolFlowRate2 = sizerLowSpdAirFlow.size(state, TempSize, ErrorsFound);
7855 67 : }
7856 :
7857 : // // Sizing rated low speed total cooling capacity
7858 1029 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7859 67 : CompName = thisDXCoil.Name;
7860 67 : CompType = thisDXCoil.DXCoilType;
7861 : // Autosize low speed capacity to 1/3 high speed capacity
7862 67 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
7863 67 : state.dataSize->DataFractionUsedForSizing = 0.3333;
7864 67 : TempSize = thisDXCoil.RatedTotCap2;
7865 67 : AutoCalculateSizer sizerLowSpdCap;
7866 67 : std::string stringOverride = "Low Speed Gross Rated Total Cooling Capacity [W]";
7867 67 : if (state.dataGlobal->isEpJSON) {
7868 3 : stringOverride = "low_speed_gross_rated_total_cooling_capacity [W]";
7869 : }
7870 67 : sizerLowSpdCap.overrideSizingString(stringOverride);
7871 67 : sizerLowSpdCap.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7872 67 : thisDXCoil.RatedTotCap2 = sizerLowSpdCap.size(state, TempSize, ErrorsFound);
7873 67 : }
7874 :
7875 1029 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7876 67 : 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 67 : 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 67 : 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 67 : 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 1029 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
7921 67 : CompName = thisDXCoil.Name;
7922 67 : FieldNum = 7;
7923 67 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum);
7924 67 : CompType = thisDXCoil.DXCoilType;
7925 : // Autosize low speed SHR to be the same as high speed SHR
7926 67 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedSHR(Mode);
7927 67 : state.dataSize->DataFractionUsedForSizing = 1.0;
7928 67 : state.dataSize->DataDXSpeedNum = 2; // refers to low speed in sizer
7929 67 : bool ErrorsFound = false;
7930 67 : TempSize = thisDXCoil.RatedSHR2;
7931 67 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7932 67 : thisDXCoil.RatedSHR2 = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
7933 67 : state.dataSize->DataConstantUsedForSizing = 0.0;
7934 67 : state.dataSize->DataFractionUsedForSizing = 0.0;
7935 67 : state.dataSize->DataDXSpeedNum = 0;
7936 : }
7937 :
7938 : // // Sizing resistive defrost heater capacity
7939 1029 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating &&
7940 967 : 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 945 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
7944 48 : CompName = thisDXCoil.Name;
7945 48 : CompType = thisDXCoil.DXCoilType;
7946 : // Autosize low speed capacity to 1/3 high speed capacity
7947 48 : state.dataSize->DataConstantUsedForSizing = state.dataSize->DXCoolCap;
7948 48 : state.dataSize->DataFractionUsedForSizing = 1.0;
7949 48 : TempSize = thisDXCoil.DefrostCapacity;
7950 48 : AutoCalculateSizer sizerResDefCap;
7951 48 : std::string stringOverride = "Resistive Defrost Heater Capacity [W]";
7952 48 : if (state.dataGlobal->isEpJSON) {
7953 0 : stringOverride = "resistive_defrost_heater_capacity [W]";
7954 : }
7955 48 : sizerResDefCap.overrideSizingString(stringOverride);
7956 48 : sizerResDefCap.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7957 48 : thisDXCoil.DefrostCapacity = sizerResDefCap.size(state, TempSize, ErrorsFound);
7958 48 : } else {
7959 897 : 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 1005 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
7968 : // flow rate autosize
7969 162 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
7970 : // Sizing multispeed air volume flow rate
7971 113 : IsAutoSize = false;
7972 113 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) == AutoSize) {
7973 7 : IsAutoSize = true;
7974 : }
7975 113 : state.dataSize->DataIsDXCoil = true;
7976 113 : CompName = thisDXCoil.Name;
7977 113 : CompType = thisDXCoil.DXCoilType;
7978 113 : if (Mode == thisDXCoil.NumOfSpeeds) {
7979 49 : FieldNum = 10 + (Mode - 1) * 14;
7980 49 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
7981 49 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
7982 49 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
7983 49 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
7984 49 : bool errorsFound = false;
7985 49 : CoolingAirFlowSizer sizingCoolingAirFlow;
7986 49 : sizingCoolingAirFlow.overrideSizingString(SizingString);
7987 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
7988 49 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
7989 49 : TempSize = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7990 49 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = TempSize;
7991 49 : state.dataSize->DataEMSOverrideON = false;
7992 49 : state.dataSize->DataEMSOverride = 0.0;
7993 49 : if (!IsAutoSize && !HardSizeNoDesRun) {
7994 36 : TempSize = AutoSize;
7995 36 : bPRINT = false;
7996 36 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
7997 36 : MSRatedAirVolFlowRateDes = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
7998 36 : bPRINT = true;
7999 : }
8000 49 : if (IsAutoSize) {
8001 2 : MSRatedAirVolFlowRateDes = TempSize;
8002 : }
8003 49 : } else {
8004 64 : FieldNum = 10 + (Mode - 1) * 14;
8005 64 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
8006 64 : if (IsAutoSize || !HardSizeNoDesRun) {
8007 : // Autosize low speed flow to fraction of the highest speed flow
8008 41 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
8009 41 : if (!IsAutoSize && !HardSizeNoDesRun) {
8010 36 : state.dataSize->DataConstantUsedForSizing = MSRatedAirVolFlowRateDes;
8011 : }
8012 41 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8013 : }
8014 64 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8015 64 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
8016 64 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
8017 64 : bool errorsFound = false;
8018 64 : CoolingAirFlowSizer sizingCoolingAirFlow;
8019 64 : sizingCoolingAirFlow.overrideSizingString(SizingString);
8020 64 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8021 64 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
8022 64 : }
8023 113 : state.dataSize->DataEMSOverride = 0.0;
8024 113 : state.dataSize->DataEMSOverrideON = false;
8025 113 : state.dataSize->DataIsDXCoil = false;
8026 113 : state.dataSize->DataTotCapCurveIndex = 0;
8027 113 : state.dataSize->DataConstantUsedForSizing = 0.0;
8028 113 : 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 113 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8033 64 : 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 162 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8048 113 : IsAutoSize = false;
8049 113 : if (thisDXCoil.MSRatedTotCap(Mode) == AutoSize) {
8050 7 : IsAutoSize = true;
8051 : }
8052 113 : CompName = thisDXCoil.Name;
8053 113 : CompType = thisDXCoil.DXCoilType;
8054 113 : state.dataSize->DataIsDXCoil = true;
8055 113 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(Mode);
8056 113 : if (Mode == thisDXCoil.NumOfSpeeds) {
8057 49 : PrintFlag = true;
8058 49 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8059 49 : FieldNum = 7 + (Mode - 1) * 14;
8060 49 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8061 49 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8062 49 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8063 49 : MSRatedTotCapDesAtMaxSpeed = thisDXCoil.MSRatedTotCap(Mode);
8064 49 : if (!HardSizeNoDesRun) {
8065 38 : PrintFlag = false;
8066 38 : TempSize = DataSizing::AutoSize;
8067 : // Auto-size capacity at the highest speed
8068 38 : CoolingCapacitySizer sizerCoolingCapacity;
8069 38 : sizerCoolingCapacity.overrideSizingString(SizingString);
8070 38 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8071 38 : TempSize = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
8072 38 : state.dataSize->DataConstantUsedForSizing = TempSize;
8073 38 : state.dataSize->DataFractionUsedForSizing = 1.0;
8074 38 : MSRatedTotCapDesAtMaxSpeed = TempSize;
8075 38 : thisDXCoil.MSRatedTotCapDes(Mode) = TempSize;
8076 38 : PrintFlag = true;
8077 38 : }
8078 49 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8079 49 : CoolingCapacitySizer sizerCoolingCapacity2;
8080 49 : sizerCoolingCapacity2.overrideSizingString(SizingString);
8081 49 : sizerCoolingCapacity2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8082 49 : TempSize = sizerCoolingCapacity2.size(state, TempSize, ErrorsFound);
8083 49 : thisDXCoil.MSRatedTotCap(Mode) = TempSize;
8084 49 : if (IsAutoSize) {
8085 2 : MSRatedTotCapDesAtMaxSpeed = TempSize;
8086 2 : thisDXCoil.MSRatedTotCapDes(Mode) = TempSize;
8087 : }
8088 49 : } else {
8089 : // cooling capacity at lower speeds
8090 64 : PrintFlag = true;
8091 64 : FieldNum = 7 + (Mode - 1) * 14;
8092 64 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8093 64 : if (IsAutoSize || !HardSizeNoDesRun) {
8094 : // autosize low speed capacity to fraction of the highest speed capacity
8095 41 : if (!HardSizeNoDesRun) {
8096 41 : state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8097 : } else {
8098 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
8099 : }
8100 41 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8101 41 : thisDXCoil.MSRatedTotCapDes(Mode) = state.dataSize->DataConstantUsedForSizing * state.dataSize->DataFractionUsedForSizing;
8102 : }
8103 64 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8104 64 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8105 64 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8106 64 : CoolingCapacitySizer sizerCoolingCapacity;
8107 64 : sizerCoolingCapacity.overrideSizingString(SizingString);
8108 64 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8109 64 : thisDXCoil.MSRatedTotCap(Mode) = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
8110 64 : }
8111 113 : state.dataSize->DataEMSOverride = 0.0;
8112 113 : state.dataSize->DataEMSOverrideON = false;
8113 113 : state.dataSize->DataIsDXCoil = false;
8114 113 : state.dataSize->DataCoolCoilCap = 0.0;
8115 113 : state.dataSize->DataTotCapCurveIndex = 0;
8116 113 : state.dataSize->DataConstantUsedForSizing = 0.0;
8117 113 : 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 113 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8122 64 : 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 162 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8137 113 : IsAutoSize = false;
8138 113 : if (thisDXCoil.MSRatedSHR(Mode) == AutoSize) {
8139 7 : IsAutoSize = true;
8140 : }
8141 113 : if (Mode == thisDXCoil.NumOfSpeeds) {
8142 49 : CompType = thisDXCoil.DXCoilType;
8143 49 : CompName = thisDXCoil.Name;
8144 49 : TempSize = thisDXCoil.MSRatedSHR(Mode);
8145 49 : state.dataSize->DataFlowUsedForSizing = MSRatedAirVolFlowRateDes;
8146 49 : state.dataSize->DataCapacityUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8147 49 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedSHREMSOverrideOn(Mode);
8148 49 : state.dataSize->DataEMSOverride = thisDXCoil.RatedSHREMSOverrideValue(Mode);
8149 49 : bool ErrorsFound = false;
8150 49 : state.dataSize->DataDXSpeedNum = Mode;
8151 49 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8152 49 : thisDXCoil.MSRatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
8153 : // added for rated sensible cooling capacity estimate for html reporting, issue #7381
8154 49 : 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 49 : MSRatedSHRDes = thisDXCoil.MSRatedSHR(Mode);
8159 : } else {
8160 64 : TempSize = thisDXCoil.MSRatedSHR(Mode);
8161 64 : bool ErrorsFound = false;
8162 64 : state.dataSize->DataDXSpeedNum = Mode;
8163 64 : state.dataSize->DataFractionUsedForSizing = MSRatedSHRDes;
8164 64 : state.dataSize->DataConstantUsedForSizing = 1.0;
8165 64 : sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8166 64 : thisDXCoil.MSRatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
8167 : }
8168 : }
8169 49 : state.dataSize->DataFlowUsedForSizing = 0.0;
8170 49 : state.dataSize->DataCapacityUsedForSizing = 0.0;
8171 49 : state.dataSize->DataEMSOverrideON = false;
8172 49 : state.dataSize->DataEMSOverride = 0.0;
8173 49 : state.dataSize->DataDXSpeedNum = 0;
8174 49 : state.dataSize->DataFractionUsedForSizing = 0.0;
8175 49 : state.dataSize->DataConstantUsedForSizing = 0.0;
8176 :
8177 : // Rated Evaporative condenser airflow rates
8178 162 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8179 113 : IsAutoSize = false;
8180 113 : if (thisDXCoil.MSEvapCondAirFlow(Mode) == AutoSize) {
8181 0 : IsAutoSize = true;
8182 : }
8183 113 : if (IsAutoSize || !HardSizeNoDesRun) {
8184 : // Autosize condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
8185 79 : MSEvapCondAirFlowDes = ((float)Mode / thisDXCoil.NumOfSpeeds) * MSRatedTotCapDesAtMaxSpeed * 0.000114;
8186 : } else {
8187 : // this is done to duplicate any existing calc method
8188 34 : MSEvapCondAirFlowDes = thisDXCoil.MSRatedTotCap(Mode) * 0.000114;
8189 : }
8190 113 : if (IsAutoSize) {
8191 0 : thisDXCoil.MSEvapCondAirFlow(Mode) = MSEvapCondAirFlowDes;
8192 0 : BaseSizer::reportSizerOutput(state,
8193 : thisDXCoil.DXCoilType,
8194 : thisDXCoil.Name,
8195 0 : format("Design Size Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
8196 : MSEvapCondAirFlowDes);
8197 : } else {
8198 113 : if (thisDXCoil.MSEvapCondAirFlow(Mode) > 0.0 && MSEvapCondAirFlowDes > 0.0 && !HardSizeNoDesRun) {
8199 8 : MSEvapCondAirFlowUser = thisDXCoil.MSEvapCondAirFlow(Mode);
8200 24 : BaseSizer::reportSizerOutput(state,
8201 : thisDXCoil.DXCoilType,
8202 : thisDXCoil.Name,
8203 16 : format("Design Size Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
8204 : MSEvapCondAirFlowDes,
8205 16 : format("User-Specified Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
8206 : MSEvapCondAirFlowUser);
8207 8 : 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 113 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8226 64 : 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 162 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8242 113 : IsAutoSize = false;
8243 113 : if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) == AutoSize) {
8244 0 : IsAutoSize = true;
8245 : }
8246 :
8247 113 : if (IsAutoSize || !HardSizeNoDesRun) {
8248 : // Autosize low speed evap condenser pump power to 1/3 Total Capacity * 0.004266 w/w (15 w/ton)
8249 79 : MSEvapCondPumpElecNomPowerDes = ((float)Mode / thisDXCoil.NumOfSpeeds) * MSRatedTotCapDesAtMaxSpeed * 0.004266;
8250 : } else {
8251 : // this is done to duplicate any existing calc method
8252 34 : MSEvapCondPumpElecNomPowerDes = thisDXCoil.MSRatedTotCap(Mode) * 0.004266;
8253 : }
8254 : // Design Size data is always available
8255 113 : if (IsAutoSize) {
8256 0 : thisDXCoil.MSEvapCondPumpElecNomPower(Mode) = MSEvapCondPumpElecNomPowerDes;
8257 0 : BaseSizer::reportSizerOutput(state,
8258 : thisDXCoil.DXCoilType,
8259 : thisDXCoil.Name,
8260 0 : format("Design Size Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
8261 : MSEvapCondPumpElecNomPowerDes);
8262 : } else {
8263 113 : if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) > 0.0 && MSEvapCondPumpElecNomPowerDes > 0.0 && !HardSizeNoDesRun) {
8264 8 : MSEvapCondPumpElecNomPowerUser = thisDXCoil.MSEvapCondPumpElecNomPower(Mode);
8265 24 : BaseSizer::reportSizerOutput(state,
8266 : thisDXCoil.DXCoilType,
8267 : thisDXCoil.Name,
8268 16 : format("Design Size Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
8269 : MSEvapCondPumpElecNomPowerDes,
8270 16 : format("User-Specified Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
8271 : MSEvapCondPumpElecNomPowerUser);
8272 8 : 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 113 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8293 64 : 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 1005 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
8311 : // flow rate autosize
8312 92 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8313 70 : IsAutoSize = false;
8314 70 : if (thisDXCoil.MSRatedAirVolFlowRate(Mode) == AutoSize) {
8315 32 : IsAutoSize = true;
8316 : }
8317 70 : state.dataSize->DataIsDXCoil = true;
8318 70 : CompName = thisDXCoil.Name;
8319 70 : CompType = thisDXCoil.DXCoilType;
8320 : // Sizing rated air flow rate
8321 70 : if (Mode == thisDXCoil.NumOfSpeeds) {
8322 22 : FieldNum = 12 + (Mode - 1) * 6;
8323 22 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
8324 22 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8325 22 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
8326 22 : state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
8327 22 : bool errorsFound = false;
8328 22 : HeatingAirFlowSizer sizingHeatingAirFlow;
8329 22 : sizingHeatingAirFlow.overrideSizingString(SizingString);
8330 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8331 22 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8332 22 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
8333 22 : if (!IsAutoSize && !HardSizeNoDesRun) {
8334 5 : TempSize = AutoSize;
8335 5 : bPRINT = false;
8336 5 : errorsFound = false;
8337 5 : HeatingAirFlowSizer sizingHeatingAirFlow2;
8338 5 : sizingHeatingAirFlow2.overrideSizingString(SizingString);
8339 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8340 5 : sizingHeatingAirFlow2.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8341 5 : MSRatedAirVolFlowRateDes = sizingHeatingAirFlow2.size(state, TempSize, errorsFound);
8342 5 : bPRINT = true;
8343 5 : }
8344 22 : } else {
8345 48 : FieldNum = 12 + (Mode - 1) * 6;
8346 48 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
8347 48 : if (IsAutoSize || !HardSizeNoDesRun) {
8348 : // Auto-size low speed flow to fraction of the highest speed capacity
8349 31 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
8350 31 : if (!IsAutoSize && !HardSizeNoDesRun) {
8351 7 : state.dataSize->DataConstantUsedForSizing = MSRatedAirVolFlowRateDes;
8352 : }
8353 31 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8354 : }
8355 48 : TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8356 48 : bool errorsFound = false;
8357 48 : HeatingAirFlowSizer sizingHeatingAirFlow;
8358 48 : sizingHeatingAirFlow.overrideSizingString(SizingString);
8359 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
8360 48 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
8361 48 : thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
8362 48 : }
8363 70 : state.dataSize->DataEMSOverride = 0.0;
8364 70 : state.dataSize->DataEMSOverrideON = false;
8365 70 : state.dataSize->DataIsDXCoil = false;
8366 70 : state.dataSize->DataTotCapCurveIndex = 0;
8367 70 : state.dataSize->DataConstantUsedForSizing = 0.0;
8368 70 : 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 70 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8373 48 : 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 22 : 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 92 : for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
8430 70 : IsAutoSize = false;
8431 70 : if (thisDXCoil.MSRatedTotCap(Mode) == AutoSize) {
8432 36 : IsAutoSize = true;
8433 : }
8434 70 : state.dataSize->DataIsDXCoil = true;
8435 70 : CompName = thisDXCoil.Name;
8436 70 : CompType = thisDXCoil.DXCoilType;
8437 70 : if (Mode == thisDXCoil.NumOfSpeeds) {
8438 22 : state.dataSize->DataFlowUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(Mode);
8439 22 : FieldNum = 10 + (Mode - 1) * 6;
8440 22 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8441 22 : state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(Mode);
8442 22 : if (IsAutoSize || !HardSizeNoDesRun) {
8443 : // Heating capacity is assumed to be equal to the cooling capacity
8444 13 : PrintFlag = false;
8445 13 : state.dataSize->DataFractionUsedForSizing = 1.0;
8446 13 : if (thisDXCoil.CompanionUpstreamDXCoil > 0) {
8447 5 : NumOfSpeedCompanion = state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).NumOfSpeeds;
8448 5 : state.dataSize->DataConstantUsedForSizing =
8449 5 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).MSRatedTotCapDes(NumOfSpeedCompanion);
8450 : } else {
8451 8 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(1); // sized above
8452 : }
8453 13 : TempSize = DataSizing::AutoSize;
8454 13 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8455 13 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8456 13 : HeatingCapacitySizer sizerHeatingCapacity;
8457 13 : sizerHeatingCapacity.overrideSizingString(SizingString);
8458 13 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8459 13 : MSRatedTotCapDesAtMaxSpeed = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
8460 13 : state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8461 13 : state.dataSize->DataFractionUsedForSizing = 1.0;
8462 13 : }
8463 22 : PrintFlag = true;
8464 22 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8465 22 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8466 22 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8467 22 : HeatingCapacitySizer sizerHeatingCapacity;
8468 22 : sizerHeatingCapacity.overrideSizingString(SizingString);
8469 22 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8470 22 : TempSize = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
8471 22 : thisDXCoil.MSRatedTotCap(Mode) = TempSize;
8472 22 : if (IsAutoSize) {
8473 10 : MSRatedTotCapDesAtMaxSpeed = TempSize;
8474 : }
8475 22 : } else {
8476 48 : PrintFlag = true;
8477 48 : FieldNum = 10 + (Mode - 1) * 6;
8478 48 : SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
8479 48 : if (IsAutoSize || !HardSizeNoDesRun) {
8480 : // autosize low speed capacity to fraction of the highest speed capacity
8481 31 : if (!HardSizeNoDesRun) {
8482 31 : state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
8483 : } else {
8484 0 : state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
8485 : }
8486 31 : state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
8487 : }
8488 48 : TempSize = thisDXCoil.MSRatedTotCap(Mode);
8489 48 : state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
8490 48 : state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
8491 48 : HeatingCapacitySizer sizerHeatingCapacity;
8492 48 : sizerHeatingCapacity.overrideSizingString(SizingString);
8493 48 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
8494 48 : TempSize = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
8495 48 : thisDXCoil.MSRatedTotCap(Mode) = TempSize;
8496 48 : }
8497 70 : PrintFlag = false;
8498 70 : state.dataSize->DataEMSOverrideON = false;
8499 70 : state.dataSize->DataEMSOverride = 0.0;
8500 70 : state.dataSize->DataIsDXCoil = false;
8501 70 : state.dataSize->DataFlowUsedForSizing = 0.0;
8502 70 : state.dataSize->DataCoolCoilCap = 0.0;
8503 70 : state.dataSize->DataTotCapCurveIndex = 0;
8504 70 : state.dataSize->DataConstantUsedForSizing = 0.0;
8505 70 : state.dataSize->DataFractionUsedForSizing = 0.0;
8506 : }
8507 : // Ensure capacity at lower speed must be lower or equal to the capacity at higher speed.
8508 70 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
8509 48 : 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 22 : IsAutoSize = false;
8525 22 : if (thisDXCoil.DefrostCapacity == AutoSize) {
8526 8 : IsAutoSize = true;
8527 : }
8528 22 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
8529 0 : DefrostCapacityDes = thisDXCoil.MSRatedTotCap(1);
8530 : } else {
8531 22 : DefrostCapacityDes = 0.0;
8532 : }
8533 22 : if (IsAutoSize) {
8534 8 : thisDXCoil.DefrostCapacity = DefrostCapacityDes;
8535 8 : BaseSizer::reportSizerOutput(
8536 : state, thisDXCoil.DXCoilType, thisDXCoil.Name, "Design Size Resistive Defrost Heater Capacity", DefrostCapacityDes);
8537 : } else {
8538 14 : 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 2635 : if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed &&
8564 625 : (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air ||
8565 2010 : thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap)) ||
8566 380 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
8567 1400 : CalcDXCoilStandardRating(state,
8568 700 : thisDXCoil.Name,
8569 700 : thisDXCoil.DXCoilType,
8570 : thisDXCoil.DXCoilType_Num,
8571 : 1,
8572 700 : thisDXCoil.RatedTotCap(1),
8573 700 : thisDXCoil.RatedCOP(1),
8574 700 : thisDXCoil.CCapFFlow(1),
8575 700 : thisDXCoil.CCapFTemp(1),
8576 700 : thisDXCoil.EIRFFlow(1),
8577 700 : thisDXCoil.EIRFTemp(1),
8578 700 : thisDXCoil.PLFFPLR(1),
8579 700 : thisDXCoil.RatedAirVolFlowRate(1),
8580 700 : thisDXCoil.FanPowerPerEvapAirFlowRate(1),
8581 700 : thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1),
8582 700 : thisDXCoil.CondenserType,
8583 700 : thisDXCoil.RegionNum,
8584 700 : thisDXCoil.MinOATCompressor,
8585 700 : thisDXCoil.OATempCompressorOn,
8586 700 : thisDXCoil.OATempCompressorOnOffBlank,
8587 700 : thisDXCoil.DefrostControl,
8588 700 : thisDXCoil.ASHRAE127StdRprt);
8589 : }
8590 : // Call routine that computes AHRI certified rating for multi-speed DX cooling Coils
8591 1005 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
8592 284 : CalcDXCoilStandardRating(state,
8593 71 : thisDXCoil.Name,
8594 71 : 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 71 : thisDXCoil.CondenserType,
8608 71 : thisDXCoil.RegionNum,
8609 71 : thisDXCoil.MinOATCompressor,
8610 71 : thisDXCoil.OATempCompressorOn,
8611 71 : thisDXCoil.OATempCompressorOnOffBlank,
8612 71 : thisDXCoil.DefrostControl,
8613 142 : ObjexxFCL::Optional_bool_const());
8614 : }
8615 :
8616 1006 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed && (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air ||
8617 1 : thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap)) {
8618 134 : StandardRatings::CalcTwoSpeedDXCoilRating(state,
8619 67 : thisDXCoil.Name,
8620 67 : 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 67 : thisDXCoil.CondenserType,
8637 67 : thisDXCoil.PLFFPLR(1));
8638 : }
8639 :
8640 : // create predefined report entries
8641 1005 : equipName = thisDXCoil.Name;
8642 : // put tables for cooling and heating separate
8643 1005 : switch (thisDXCoil.DXCoilType_Num) {
8644 752 : case HVAC::CoilDX_CoolingSingleSpeed:
8645 : case HVAC::CoilDX_CoolingTwoSpeed:
8646 : case HVAC::CoilDX_CoolingTwoStageWHumControl:
8647 : case HVAC::CoilDX_MultiSpeedCooling: {
8648 752 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilType, equipName, thisDXCoil.DXCoilType);
8649 752 : if (thisDXCoil.NumOfSpeeds == 0) {
8650 703 : if (thisDXCoil.NumCapacityStages == 1) {
8651 693 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.RatedTotCap(1));
8652 1386 : PreDefTableEntry(
8653 693 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1));
8654 1386 : PreDefTableEntry(state,
8655 693 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
8656 : equipName,
8657 693 : thisDXCoil.RatedTotCap(1) - thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1));
8658 693 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.RatedSHR(1));
8659 693 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.RatedCOP(1));
8660 : } else {
8661 10 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.RatedTotCap(2));
8662 20 : PreDefTableEntry(
8663 10 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.RatedTotCap(2) * thisDXCoil.RatedSHR(2));
8664 20 : PreDefTableEntry(state,
8665 10 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
8666 : equipName,
8667 10 : thisDXCoil.RatedTotCap(2) - thisDXCoil.RatedTotCap(2) * thisDXCoil.RatedSHR(2));
8668 10 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.RatedSHR(2));
8669 10 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.RatedCOP(2));
8670 : }
8671 : } else {
8672 162 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8673 113 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.MSRatedTotCap(Mode));
8674 226 : PreDefTableEntry(
8675 113 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.MSRatedTotCap(Mode) * thisDXCoil.MSRatedSHR(Mode));
8676 226 : PreDefTableEntry(state,
8677 113 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
8678 : equipName,
8679 113 : thisDXCoil.MSRatedTotCap(Mode) - thisDXCoil.MSRatedTotCap(Mode) * thisDXCoil.MSRatedSHR(Mode));
8680 113 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.MSRatedSHR(Mode));
8681 113 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.MSRatedCOP(Mode));
8682 : }
8683 : }
8684 1504 : addFootNoteSubTable(state,
8685 752 : 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 752 : } break;
8688 129 : case HVAC::CoilDX_HeatingEmpirical:
8689 : case HVAC::CoilDX_MultiSpeedHeating:
8690 : case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
8691 : case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
8692 129 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilType, equipName, thisDXCoil.DXCoilType);
8693 129 : if (thisDXCoil.NumOfSpeeds == 0) {
8694 107 : if (thisDXCoil.NumCapacityStages == 1) {
8695 107 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.RatedTotCap(1));
8696 107 : 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 92 : for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
8703 70 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.MSRatedTotCap(Mode));
8704 70 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.MSRatedCOP(Mode));
8705 : }
8706 : }
8707 258 : addFootNoteSubTable(state,
8708 129 : 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 258 : OutputReportPredefined::PreDefTableEntry(
8713 129 : state, state.dataOutRptPredefined->pdchDXHeatCoilMinOADBTforCompOp, equipName, thisDXCoil.MinOATCompressor);
8714 258 : OutputReportPredefined::PreDefTableEntry(state,
8715 129 : state.dataOutRptPredefined->pdchDXHeatCoilAirloopName,
8716 : equipName,
8717 387 : 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 258 : OutputReportPredefined::PreDefTableEntry(
8721 129 : state, state.dataOutRptPredefined->pdchDXHeatCoilMinOADBTforCompOp_2023, equipName, thisDXCoil.MinOATCompressor);
8722 258 : OutputReportPredefined::PreDefTableEntry(state,
8723 129 : state.dataOutRptPredefined->pdchDXHeatCoilAirloopName_2023,
8724 : equipName,
8725 387 : thisDXCoil.AirLoopNum > 0 ? state.dataAirSystemsData->PrimaryAirSystems(thisDXCoil.AirLoopNum).Name
8726 : : "N/A");
8727 129 : } break;
8728 124 : default:
8729 124 : break;
8730 : }
8731 1005 : }
8732 :
8733 1104418 : 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 1104418 : DXCoilData &Coil = state.dataDXCoils->DXCoil(DXCoilNum);
8790 1104418 : NodeData &AirInletNode = state.dataLoopNodes->Node(Coil.AirInNode);
8791 1104418 : NodeData &WaterInletNode = state.dataLoopNodes->Node(Coil.WaterInNode);
8792 1104418 : 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 1104418 : if (PartLoadRatio == 0.0) {
8797 362896 : WaterOutletNode = WaterInletNode;
8798 362896 : Coil.TotalHeatingEnergyRate = 0.0;
8799 362896 : return;
8800 : } else {
8801 741522 : RatedHeatingCapacity = Coil.RatedTotCap2;
8802 741522 : RatedHeatingCOP = Coil.RatedCOP(1);
8803 741522 : InletWaterTemp = WaterInletNode.Temp;
8804 741522 : CondInletMassFlowRate = WaterInletNode.MassFlowRate / PartLoadRatio;
8805 741522 : EvapInletMassFlowRate = AirInletNode.MassFlowRate / PartLoadRatio;
8806 741522 : CpWater = CPHW(InletWaterTemp);
8807 741522 : CompressorPower = 0.0;
8808 741522 : OperatingHeatingPower = 0.0;
8809 741522 : TankHeatingCOP = 0.0;
8810 : }
8811 :
8812 : // determine inlet air temperature type for curve objects
8813 741522 : if (Coil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
8814 741522 : 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 741522 : if (Coil.HCapFTemp > 0) {
8821 741522 : if (state.dataCurveManager->curves(Coil.HCapFTemp)->numDims == 1) {
8822 0 : HeatCapFTemp = CurveValue(state, Coil.HCapFTemp, InletAirTemp);
8823 : } else {
8824 741522 : HeatCapFTemp = CurveValue(state, Coil.HCapFTemp, InletAirTemp, InletWaterTemp);
8825 : }
8826 : // Warn user if curve output goes negative
8827 741522 : 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 741522 : if (Coil.HCOPFTemp > 0) {
8860 741522 : if (state.dataCurveManager->curves(Coil.HCOPFTemp)->numDims == 1) {
8861 0 : HeatCOPFTemp = CurveValue(state, Coil.HCOPFTemp, InletAirTemp);
8862 : } else {
8863 741522 : HeatCOPFTemp = CurveValue(state, Coil.HCOPFTemp, InletAirTemp, InletWaterTemp);
8864 : }
8865 : // Warn user if curve output goes negative
8866 741522 : 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 741522 : 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 741522 : HeatCapFAirFlow = 1.0;
8922 : }
8923 :
8924 741522 : 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 741522 : HeatCOPFAirFlow = 1.0;
8947 : }
8948 :
8949 741522 : 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 741522 : HeatCapFWaterFlow = 1.0;
8973 : }
8974 :
8975 741522 : 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 741522 : HeatCOPFWaterFlow = 1.0;
8999 : }
9000 :
9001 : // adjust Heating Capacity and COP for off-design conditions
9002 741522 : OperatingHeatingCapacity = RatedHeatingCapacity * HeatCapFTemp * HeatCapFAirFlow * HeatCapFWaterFlow;
9003 741522 : OperatingHeatingCOP = RatedHeatingCOP * HeatCOPFTemp * HeatCOPFAirFlow * HeatCOPFWaterFlow;
9004 :
9005 741522 : if (OperatingHeatingCOP > 0.0) {
9006 741522 : OperatingHeatingPower = OperatingHeatingCapacity / OperatingHeatingCOP;
9007 : }
9008 :
9009 741522 : PumpHeatToWater = Coil.HPWHCondPumpElecNomPower * Coil.HPWHCondPumpFracToWater;
9010 741522 : TankHeatingCOP = OperatingHeatingCOP;
9011 :
9012 : // account for pump heat if not included in total water heating capacity
9013 741522 : if (Coil.CondPumpHeatInCapacity) {
9014 0 : TotalTankHeatingCapacity = OperatingHeatingCapacity;
9015 : } else {
9016 741522 : TotalTankHeatingCapacity = OperatingHeatingCapacity + PumpHeatToWater;
9017 : }
9018 :
9019 : // find part load fraction to calculate RTF
9020 741522 : if (Coil.PLFFPLR(1) > 0) {
9021 741522 : PartLoadFraction = max(0.7, CurveValue(state, Coil.PLFFPLR(1), PartLoadRatio));
9022 : } else {
9023 0 : PartLoadFraction = 1.0;
9024 : }
9025 :
9026 741522 : HPRTF = min(1.0, (PartLoadRatio / PartLoadFraction));
9027 :
9028 741522 : Real64 locFanElecPower = state.dataFans->fans(Coil.SupplyFanIndex)->totalPower;
9029 :
9030 : // calculate evaporator total cooling capacity
9031 741522 : if (HPRTF > 0.0) {
9032 741522 : if (Coil.FanPowerIncludedInCOP) {
9033 421046 : 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 421046 : CompressorPower = OperatingHeatingPower - locFanElecPower / HPRTF;
9041 421046 : if ((OperatingHeatingPower + Coil.HPWHCondPumpElecNomPower) > 0.0) {
9042 421046 : TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + Coil.HPWHCondPumpElecNomPower);
9043 : }
9044 : }
9045 : } else {
9046 320476 : 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 320476 : CompressorPower = OperatingHeatingPower;
9054 320476 : if ((OperatingHeatingPower + locFanElecPower / HPRTF + Coil.HPWHCondPumpElecNomPower) > 0.0) {
9055 320476 : TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + locFanElecPower / HPRTF + Coil.HPWHCondPumpElecNomPower);
9056 : }
9057 : }
9058 : }
9059 : }
9060 :
9061 741522 : if (Coil.CondPumpHeatInCapacity) {
9062 0 : EvapCoolingCapacity = TotalTankHeatingCapacity - PumpHeatToWater - CompressorPower;
9063 : } else {
9064 741522 : EvapCoolingCapacity = TotalTankHeatingCapacity - CompressorPower;
9065 : }
9066 :
9067 : // set evaporator total cooling capacity prior to CalcDOE2DXCoil subroutine
9068 741522 : Coil.RatedTotCap(1) = EvapCoolingCapacity;
9069 :
9070 : // determine condenser water inlet/outlet condition at full capacity
9071 741522 : if (CondInletMassFlowRate == 0.0) {
9072 418529 : OutletWaterTemp = InletWaterTemp;
9073 : } else {
9074 322993 : OutletWaterTemp = InletWaterTemp + TotalTankHeatingCapacity / (CpWater * CondInletMassFlowRate);
9075 : }
9076 :
9077 741522 : WaterOutletNode.Temp = OutletWaterTemp;
9078 :
9079 741522 : 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 741522 : state.dataDXCoils->HPWHHeatingCapacity = TotalTankHeatingCapacity;
9084 : // total heating COP including compressor, fan, and condenser pump
9085 741522 : state.dataDXCoils->HPWHHeatingCOP = TankHeatingCOP;
9086 :
9087 : // send DX coil total cooling capacity to HPWH for reporting
9088 741522 : state.dataHVACGlobal->DXCoilTotalCapacity = EvapCoolingCapacity;
9089 :
9090 741522 : Coil.TotalHeatingEnergyRate = TotalTankHeatingCapacity * PartLoadRatio;
9091 :
9092 : // calculate total compressor plus condenser pump power, fan power reported in fan module
9093 741522 : Coil.ElecWaterHeatingPower = (CompressorPower + Coil.HPWHCondPumpElecNomPower) * HPRTF;
9094 : }
9095 :
9096 39937904 : 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 39937904 : Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
9153 39937904 : 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 39937904 : 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 39937904 : if (present(PerfMode)) {
9230 280657 : Mode = PerfMode;
9231 : } else {
9232 39657247 : 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 39937904 : if (present(OnOffAirFlowRatio)) {
9238 36506346 : AirFlowRatio = OnOffAirFlowRatio;
9239 : } else {
9240 3431558 : 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 39937904 : if (present(CoolingHeatingPLR)) {
9246 30498184 : DXcoolToHeatPLRRatio = CoolingHeatingPLR;
9247 : } else {
9248 9439720 : DXcoolToHeatPLRRatio = 1.0;
9249 : }
9250 :
9251 39937904 : MaxIter = 30;
9252 39937904 : RF = 0.4;
9253 39937904 : Counter = 0;
9254 39937904 : Tolerance = 0.01;
9255 39937904 : CondInletTemp = 0.0;
9256 39937904 : CondInletHumRat = 0.0;
9257 :
9258 39937904 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
9259 :
9260 39937904 : BypassFlowFraction = thisDXCoil.BypassedFlowFrac(Mode);
9261 39937904 : AirMassFlow = thisDXCoil.InletAirMassFlowRate * (1.0 - BypassFlowFraction);
9262 39937904 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
9263 39937904 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
9264 39937904 : 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 39937904 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
9268 39937904 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
9269 39937904 : thisDXCoil.PartLoadRatio = 0.0;
9270 39937904 : thisDXCoil.BasinHeaterPower = 0.0;
9271 :
9272 39937904 : if (thisDXCoil.CondenserType(Mode) != DataHeatBalance::RefrigCondenserType::WaterHeater) {
9273 39301542 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
9274 8760981 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
9275 : // If node is not connected to anything, pressure = default, use weather data
9276 8760981 : 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 8760981 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
9283 8760981 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
9284 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
9285 8760981 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
9286 : }
9287 : } else {
9288 30540561 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
9289 30540561 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
9290 30540561 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9291 30540561 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
9292 : }
9293 39301542 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
9294 81926 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
9295 81926 : OutdoorDryBulb = secZoneHB.ZT;
9296 81926 : OutdoorHumRat = secZoneHB.airHumRat;
9297 81926 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
9298 81926 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9299 : }
9300 : } else {
9301 636362 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
9302 636362 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
9303 : // If node is not connected to anything, pressure = default, use weather data
9304 636362 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
9305 390 : OutdoorPressure = state.dataEnvrn->OutBaroPress; // node not connected
9306 : }
9307 : } else {
9308 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9309 : }
9310 : }
9311 :
9312 39937904 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
9313 39189186 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
9314 39189186 : CompAmbTemp = OutdoorDryBulb;
9315 39189186 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
9316 81926 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
9317 81926 : CondInletTemp = secZoneHB.ZT;
9318 81926 : CompAmbTemp = CondInletTemp; // assumes compressor is in same location as secondary coil
9319 81926 : OutdoorDryBulb = CondInletTemp;
9320 81926 : OutdoorHumRat = secZoneHB.airHumRat;
9321 81926 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
9322 81926 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
9323 : }
9324 748718 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
9325 112356 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
9326 112356 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
9327 : // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
9328 112356 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
9329 112356 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
9330 112356 : CompAmbTemp = OutdoorDryBulb;
9331 636362 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::WaterHeater) {
9332 636362 : CompAmbTemp = state.dataHVACGlobal->HPWHCrankcaseDBTemp; // Temperature at HP water heater compressor
9333 636362 : 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 39937904 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
9339 15410110 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
9340 15410110 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
9341 56165 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
9342 : }
9343 : } else {
9344 24527794 : CrankcaseHeatingPower = 0.0;
9345 : }
9346 :
9347 : // calculate end time of current time step to determine if error messages should be printed
9348 39937904 : 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 39937904 : if (thisDXCoil.PrintLowAmbMessage) { // .AND. &
9356 5852 : if (state.dataDXCoils->CurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
9357 650 : if (thisDXCoil.LowAmbErrIndex == 0) {
9358 10 : ShowWarningMessage(state, format("{}{}", RoutineName, thisDXCoil.LowAmbBuffer1));
9359 10 : ShowContinueError(state, thisDXCoil.LowAmbBuffer2);
9360 30 : ShowContinueError(state, "... Operation at low ambient temperatures may require special performance curves.");
9361 : }
9362 650 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
9363 5200 : ShowRecurringWarningErrorAtEnd(state,
9364 1950 : std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
9365 : "\" - Low condenser dry-bulb temperature error continues...",
9366 650 : thisDXCoil.LowAmbErrIndex,
9367 650 : thisDXCoil.LowTempLast,
9368 650 : 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 39937904 : if (thisDXCoil.PrintLowOutTempMessage) {
9387 4417 : if (state.dataDXCoils->CurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
9388 728 : if (thisDXCoil.LowOutletTempIndex == 0) {
9389 11 : ShowWarningMessage(state, format("{}{}", RoutineName, thisDXCoil.LowOutTempBuffer1));
9390 11 : ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
9391 22 : ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
9392 22 : ShowContinueError(state,
9393 22 : format(" 1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
9394 11 : thisDXCoil.FullLoadInletAirTempLast));
9395 22 : ShowContinueError(state, " 2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
9396 33 : ShowContinueError(state,
9397 : " 3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
9398 : }
9399 5824 : ShowRecurringWarningErrorAtEnd(state,
9400 2184 : 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 728 : thisDXCoil.LowOutletTempIndex,
9404 728 : thisDXCoil.FullLoadOutAirTempLast,
9405 728 : 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 39937904 : thisDXCoil.TimeStepSysLast = TimeStepSys;
9411 39937904 : thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CurrentEndTime;
9412 39937904 : thisDXCoil.PrintLowAmbMessage = false;
9413 39937904 : thisDXCoil.PrintLowOutTempMessage = false;
9414 :
9415 31848519 : if ((AirMassFlow > 0.0) &&
9416 32280676 : (thisDXCoil.availSched->getCurrentVal() > 0.0 || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9417 309974 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
9418 86922646 : (PartLoadRatio > 0.0) && (compressorOp == HVAC::CompressorOp::On) &&
9419 15136223 : CompAmbTemp > thisDXCoil.MinOATCompressor) { // criteria for coil operation
9420 15136223 : if (fanOp == HVAC::FanOp::Cycling) {
9421 7526858 : AirMassFlow /= (PartLoadRatio / DXcoolToHeatPLRRatio);
9422 7609365 : } else if (fanOp == HVAC::FanOp::Continuous && thisDXCoil.DXCoilType_Num != HVAC::CoilDX_CoolingTwoSpeed) {
9423 7609365 : 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 15136223 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
9434 15136223 : 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 15136223 : 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 15136223 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9443 15014040 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9444 273482 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap2;
9445 : } else {
9446 14862741 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
9447 : }
9448 9851862 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag && thisDXCoil.DXCoilType_Num != HVAC::CoilDX_HeatPumpWaterHeaterPumped &&
9449 26349362 : thisDXCoil.DXCoilType_Num != HVAC::CoilDX_HeatPumpWaterHeaterWrapped &&
9450 1361277 : ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
9451 1358791 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
9452 2486 : if (thisDXCoil.ErrIndex1 == 0) {
9453 6 : ShowWarningMessage(
9454 : state,
9455 6 : format("{}{}=\"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at {:.3R} m3/s/W.",
9456 : RoutineName,
9457 3 : thisDXCoil.DXCoilType,
9458 3 : thisDXCoil.Name,
9459 : VolFlowperRatedTotCap));
9460 6 : ShowContinueErrorTimeStamp(state, "");
9461 6 : ShowContinueError(state,
9462 6 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
9463 3 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
9464 3 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
9465 6 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components,");
9466 9 : ShowContinueError(state, "or variable air volume [VAV] system using incorrect coil type.");
9467 : }
9468 19888 : ShowRecurringWarningErrorAtEnd(
9469 : state,
9470 7458 : 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 2486 : thisDXCoil.ErrIndex1,
9473 : VolFlowperRatedTotCap,
9474 : VolFlowperRatedTotCap);
9475 15133737 : } else if (!state.dataGlobal->WarmupFlag &&
9476 2194401 : (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9477 17368306 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
9478 58698 : ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
9479 58698 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
9480 29016 : if (thisDXCoil.ErrIndex1 == 0) {
9481 2 : ShowWarningMessage(
9482 : state,
9483 2 : 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 1 : thisDXCoil.DXCoilType,
9486 1 : thisDXCoil.Name,
9487 : VolFlowperRatedTotCap));
9488 2 : ShowContinueErrorTimeStamp(state, "");
9489 2 : ShowContinueError(state,
9490 2 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
9491 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
9492 1 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
9493 3 : 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 232128 : ShowRecurringWarningErrorAtEnd(
9498 : state,
9499 87048 : 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 29016 : 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 15136223 : RatedCBF = thisDXCoil.RatedCBF(Mode);
9509 15136223 : if (RatedCBF > 0.0) {
9510 15136223 : A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
9511 : } else {
9512 0 : A0 = 0.0;
9513 : }
9514 15136223 : ADiff = -A0 / AirMassFlow;
9515 15136223 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
9516 15113595 : CBF = std::exp(ADiff);
9517 : } else {
9518 22628 : 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 15136223 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
9523 14817755 : if (OutdoorDryBulb < 0.0 && !state.dataGlobal->WarmupFlag) { // Same threshold as for air-cooled electric chiller
9524 5852 : thisDXCoil.PrintLowAmbMessage = true;
9525 5852 : thisDXCoil.LowTempLast = OutdoorDryBulb;
9526 5852 : if (thisDXCoil.LowAmbErrIndex == 0) {
9527 : thisDXCoil.LowAmbBuffer1 =
9528 244 : format("{} \"{}\" - Air-cooled condenser inlet dry-bulb temperature below 0 C. Outdoor dry-bulb temperature = {:.2R}",
9529 122 : thisDXCoil.DXCoilType,
9530 122 : thisDXCoil.Name,
9531 122 : OutdoorDryBulb);
9532 244 : thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
9533 366 : CreateSysTimeIntervalString(state);
9534 : }
9535 : }
9536 318468 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
9537 44986 : if (OutdoorWetBulb < 10.0 && !state.dataGlobal->WarmupFlag) { // Same threshold as for evap-cooled electric chiller
9538 0 : thisDXCoil.PrintLowAmbMessage = true;
9539 0 : thisDXCoil.LowTempLast = OutdoorWetBulb;
9540 0 : if (thisDXCoil.LowAmbErrIndex == 0) {
9541 : thisDXCoil.LowAmbBuffer1 =
9542 0 : format("{} \"{}\" - Evap-cooled condenser inlet wet-bulb temperature below 10 C. Outdoor wet-bulb temperature = {:.2R}",
9543 0 : thisDXCoil.DXCoilType,
9544 0 : thisDXCoil.Name,
9545 0 : OutdoorWetBulb);
9546 0 : thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
9547 0 : 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 15136223 : InletAirHumRatTemp = InletAirHumRat;
9555 15136223 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
9556 : while (true) {
9557 24149498 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9558 24027315 : 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 547695 : TotCapTempModFac = 1.0;
9561 547695 : TotCapFlowModFac = 1.0;
9562 : } else {
9563 23601803 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
9564 23601803 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC, CondInletTemp);
9565 : } else {
9566 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), CondInletTemp);
9567 : }
9568 :
9569 : // Warn user if curve output goes negative
9570 23601803 : 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 23601803 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
9603 : // Warn user if curve output goes negative
9604 23601803 : 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 24149498 : TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
9627 : // if user specified SHR modifier curves are available calculate the SHR as follows:
9628 24149498 : 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 24149498 : hDelta = TotCap / AirMassFlow;
9641 24149498 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
9642 24149498 : 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 24149498 : wADP = PsyWFnTdbH(state, tADP, hADP, calcDoe2DXCoil);
9646 24149498 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
9647 24149498 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
9648 24149498 : 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 24149498 : if (wADP > InletAirHumRatTemp || (Counter >= 1 && Counter < MaxIter)) {
9654 11318708 : if (InletAirHumRatTemp == 0.0) {
9655 9 : InletAirHumRatTemp = 0.00001;
9656 : }
9657 11318708 : 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 11318708 : InletAirHumRatTemp = RF * wADP + (1.0 - RF) * InletAirHumRatTemp;
9662 11318708 : 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 11318708 : ++Counter;
9666 11318708 : if (std::abs(werror) > Tolerance) {
9667 9013275 : continue; // Recalculate with modified inlet conditions
9668 : }
9669 2305433 : break;
9670 : } else {
9671 : break;
9672 : }
9673 : }
9674 : } // end of DO iteration loop
9675 :
9676 15136223 : if (thisDXCoil.PLFFPLR(Mode) > 0) {
9677 15136223 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PartLoadRatio); // Calculate part-load factor
9678 : } else {
9679 0 : PLF = 1.0;
9680 : }
9681 :
9682 15136223 : 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 15136223 : thisDXCoil.PartLoadRatio = PartLoadRatio;
9709 15136223 : thisDXCoil.CoolingCoilRuntimeFraction = PartLoadRatio / PLF;
9710 15136223 : 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 15136223 : } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
9743 747051 : 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 15136223 : if (fanOp == HVAC::FanOp::Cycling) {
9748 7526858 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
9749 : }
9750 :
9751 : // Calculate full load output conditions
9752 15136223 : 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 15136223 : if (SHR > 1.0 || Counter > 0) {
9766 2305433 : SHR = 1.0;
9767 : }
9768 15136223 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
9769 15136223 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9770 15136223 : if (SHR < 1.0) {
9771 12830790 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9772 : } else {
9773 2305433 : FullLoadOutAirHumRat = InletAirHumRat;
9774 : }
9775 : }
9776 15136223 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
9777 :
9778 : // Check for saturation error and modify temperature at constant enthalpy
9779 15136223 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure)) {
9780 241665 : 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 241665 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
9785 : }
9786 :
9787 : // Store actual outlet conditions when DX coil is ON for use in heat recovery module
9788 15136223 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = FullLoadOutAirTemp;
9789 15136223 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = FullLoadOutAirHumRat;
9790 :
9791 : // Add warning message for cold cooling coil (FullLoadOutAirTemp < 2 C)
9792 15136223 : if (FullLoadOutAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
9793 4421 : thisDXCoil.PrintLowOutTempMessage = true;
9794 4421 : thisDXCoil.FullLoadOutAirTempLast = FullLoadOutAirTemp;
9795 4421 : if (thisDXCoil.LowOutletTempIndex == 0) {
9796 90 : thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
9797 180 : 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 90 : thisDXCoil.DXCoilType,
9800 90 : thisDXCoil.Name,
9801 90 : FullLoadOutAirTemp);
9802 180 : thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
9803 270 : 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 15136223 : if (fanOp == HVAC::FanOp::Continuous) {
9810 7609365 : QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode));
9811 7609365 : QLatActual = TotCap * (1.0 - SHR);
9812 7609365 : SHRUnadjusted = SHR;
9813 7609365 : 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 7609365 : if (Mode == 2 || Mode == 4) {
9819 98314 : SHR = SHRUnadjusted * (1.0 - thisDXCoil.BypassedFlowFrac(Mode - 1)) + SHR * thisDXCoil.BypassedFlowFrac(Mode - 1);
9820 : }
9821 :
9822 : // Calculate full load output conditions
9823 7609365 : 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 7609365 : if (SHR > 1.0 || Counter > 0) {
9837 592895 : SHR = 1.0;
9838 : }
9839 7609365 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
9840 7609365 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
9841 7609365 : if (SHR < 1.0) {
9842 6356414 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
9843 : } else {
9844 1252951 : FullLoadOutAirHumRat = InletAirHumRat;
9845 : }
9846 : }
9847 7609365 : 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 7526858 : } else if (fanOp == HVAC::FanOp::Cycling) {
9852 7526858 : 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 15136223 : if (((fanOp == HVAC::FanOp::Continuous) && (Mode == 1)) || (Mode == 3)) {
9907 : // Continuous fan, cycling compressor
9908 7511051 : OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
9909 7511051 : OutletAirHumRat = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirHumRat + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirHumRat);
9910 7511051 : 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 7625172 : OutletAirEnthalpy = FullLoadOutAirEnth * DXcoolToHeatPLRRatio + InletAirEnthalpy * (1.0 - DXcoolToHeatPLRRatio);
9917 7625172 : OutletAirHumRat = FullLoadOutAirHumRat * DXcoolToHeatPLRRatio + InletAirHumRat * (1.0 - DXcoolToHeatPLRRatio);
9918 7625172 : OutletAirTemp = FullLoadOutAirTemp * DXcoolToHeatPLRRatio + InletAirDryBulbTemp * (1.0 - DXcoolToHeatPLRRatio);
9919 : }
9920 :
9921 : // Check for saturation error and modify temperature at constant enthalpy
9922 15136223 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, calcDoe2DXCoil)) {
9923 168364 : 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 168364 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
9928 : }
9929 :
9930 : // Mix with air that was bypassed around coil, if any
9931 15136223 : if (BypassFlowFraction > 0.0) {
9932 103788 : OutletAirEnthalpy = (1.0 - BypassFlowFraction) * OutletAirEnthalpy + BypassFlowFraction * InletAirEnthalpy;
9933 103788 : OutletAirHumRat = (1.0 - BypassFlowFraction) * OutletAirHumRat + BypassFlowFraction * InletAirHumRat;
9934 103788 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
9935 : // Check for saturation error and modify temperature at constant enthalpy
9936 103788 : 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 15136223 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
9947 15014040 : thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
9948 : // Coil:DX:HeatPumpWaterHeater does not have EIR temp or flow curves
9949 273482 : EIRTempModFac = 1.0;
9950 273482 : EIRFlowModFac = 1.0;
9951 : } else {
9952 14862741 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirWetBulbC, CondInletTemp);
9953 :
9954 : // Warn user if curve output goes negative
9955 14862741 : 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 14862741 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
9985 :
9986 : // Warn user if curve output goes negative
9987 14862741 : 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 15136223 : 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 15136223 : if (Mode == 1 || Mode == 3) {
10013 15037909 : thisDXCoil.ElecCoolingPower = TotCap * EIR * thisDXCoil.CoolingCoilRuntimeFraction;
10014 : } else {
10015 98314 : 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 15136223 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10023 15136223 : CalcComponentSensibleLatentOutput(AirMassFlow,
10024 : InletAirDryBulbTemp,
10025 : InletAirHumRat,
10026 : OutletAirTemp,
10027 : OutletAirHumRat,
10028 15136223 : thisDXCoil.SensCoolingEnergyRate,
10029 15136223 : thisDXCoil.LatCoolingEnergyRate,
10030 15136223 : 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 15136223 : 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 15136223 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
10039 15136223 : 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 15136223 : 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 44986 : RhoWater = RhoH2O(OutdoorDryBulb);
10053 44986 : thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater * thisDXCoil.CoolingCoilRuntimeFraction;
10054 44986 : thisDXCoil.EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower(Mode) * thisDXCoil.CoolingCoilRuntimeFraction;
10055 : // Calculate basin heater power
10056 44986 : CalcBasinHeaterPower(state,
10057 : thisDXCoil.BasinHeaterPowerFTempDiff,
10058 : thisDXCoil.basinHeaterSched,
10059 : thisDXCoil.BasinHeaterSetPointTemp,
10060 44986 : thisDXCoil.BasinHeaterPower);
10061 44986 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
10062 44986 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
10063 : }
10064 : }
10065 :
10066 15136223 : thisDXCoil.OutletAirTemp = OutletAirTemp;
10067 15136223 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
10068 15136223 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
10069 :
10070 : } else {
10071 :
10072 : // DX coil is off; just pass through conditions
10073 24801681 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10074 24801681 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
10075 24801681 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
10076 :
10077 24801681 : thisDXCoil.ElecCoolingPower = 0.0;
10078 24801681 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
10079 24801681 : thisDXCoil.SensCoolingEnergyRate = 0.0;
10080 24801681 : thisDXCoil.LatCoolingEnergyRate = 0.0;
10081 24801681 : thisDXCoil.EvapCondPumpElecPower = 0.0;
10082 24801681 : thisDXCoil.EvapWaterConsumpRate = 0.0;
10083 :
10084 : // Reset globals when DX coil is OFF for use in heat recovery module
10085 24801681 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
10086 24801681 : 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 24801681 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
10091 24801681 : 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 24801681 : if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
10099 75255 : 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 24726426 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
10108 67370 : CalcBasinHeaterPower(state,
10109 : thisDXCoil.BasinHeaterPowerFTempDiff,
10110 : thisDXCoil.basinHeaterSched,
10111 : thisDXCoil.BasinHeaterSetPointTemp,
10112 67370 : thisDXCoil.BasinHeaterPower);
10113 : }
10114 : }
10115 :
10116 : } // end of on/off if - else
10117 :
10118 : // set water system demand request (if needed)
10119 39937904 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
10120 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
10121 0 : thisDXCoil.EvapWaterConsumpRate;
10122 : }
10123 :
10124 39937904 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
10125 39937904 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
10126 39937904 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
10127 39937904 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
10128 39937904 : thisDXCoil.CondInletTemp = CondInletTemp;
10129 :
10130 : // set outlet node conditions
10131 39937904 : int airOutletNode = thisDXCoil.AirOutNode;
10132 39937904 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
10133 39937904 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
10134 :
10135 : // calc secondary coil if specified
10136 39937904 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
10137 81926 : CalcSecondaryDXCoils(state, DXCoilNum);
10138 : }
10139 39937904 : }
10140 :
10141 1701164 : 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 1701164 : Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
10190 1701164 : 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 1701164 : 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 1701164 : if (present(PerfMode)) {
10261 0 : Mode = PerfMode;
10262 : } else {
10263 1701164 : 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 1701164 : if (present(OnOffAirFlowRatio)) {
10269 1701118 : AirFlowRatio = OnOffAirFlowRatio;
10270 : } else {
10271 46 : AirFlowRatio = 1.0;
10272 : }
10273 :
10274 1701164 : MaxIter = 30;
10275 1701164 : RF = 0.4;
10276 1701164 : Counter = 0;
10277 1701164 : Tolerance = 0.01;
10278 1701164 : CondInletTemp = 0.0;
10279 1701164 : CondInletHumRat = 0.0;
10280 :
10281 1701164 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
10282 :
10283 1701164 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10284 1701164 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
10285 1701164 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10286 1701164 : 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 1701164 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
10290 1701164 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
10291 1701164 : thisDXCoil.PartLoadRatio = 0.0;
10292 1701164 : thisDXCoil.BasinHeaterPower = 0.0;
10293 :
10294 1701164 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
10295 1701164 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
10296 1701164 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
10297 156109 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10298 156109 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10299 156109 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10300 : } else {
10301 1545055 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
10302 : // If node is not connected to anything, pressure = default, use weather data
10303 1545055 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
10304 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10305 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10306 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10307 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10308 : } else {
10309 1545055 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
10310 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
10311 1545055 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
10312 : }
10313 : }
10314 : } else {
10315 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10316 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10317 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10318 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10319 : }
10320 :
10321 1701164 : 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 1701164 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp or water inlet temp
10330 1701164 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
10331 156109 : CompAmbTemp = state.dataEnvrn->OutDryBulbTemp; // for crankcase heater use actual outdoor temp for water-cooled
10332 : } else {
10333 1545055 : 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 1701164 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
10340 90229 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
10341 90229 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
10342 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
10343 : }
10344 : } else {
10345 1610935 : CrankcaseHeatingPower = 0.0;
10346 : }
10347 :
10348 : // calculate end time of current time step to determine if error messages should be printed
10349 1701164 : 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 1701164 : 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 1701164 : if (thisDXCoil.PrintHighAmbMessage) { // .AND. &
10375 0 : 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 1701164 : 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 1701164 : thisDXCoil.TimeStepSysLast = TimeStepSys;
10418 1701164 : thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime;
10419 1701164 : thisDXCoil.PrintLowAmbMessage = false;
10420 1701164 : thisDXCoil.PrintLowOutTempMessage = false;
10421 :
10422 1701164 : 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 927411 : if (fanOp == HVAC::FanOp::Cycling) {
10425 252614 : AirMassFlow /= PartLoadRatio;
10426 674797 : } else if (fanOp == HVAC::FanOp::Continuous) {
10427 674797 : 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 927411 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
10438 927411 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
10439 927411 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
10440 :
10441 927411 : 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 993002 : if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag &&
10446 65591 : ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
10447 65263 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
10448 328 : if (thisDXCoil.ErrIndex1 == 0) {
10449 2 : ShowWarningMessage(
10450 : state,
10451 2 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at {:.3R} m3/s/W.",
10452 1 : thisDXCoil.DXCoilType,
10453 1 : thisDXCoil.Name,
10454 : VolFlowperRatedTotCap));
10455 2 : ShowContinueErrorTimeStamp(state, "");
10456 2 : ShowContinueError(state,
10457 2 : format("...Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
10458 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
10459 1 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
10460 2 : ShowContinueError(state, "...Possible causes include inconsistent air flow rates in system components,");
10461 2 : ShowContinueError(state, "...or mixing manual inputs with autosize inputs. Also check the following values and calculations.");
10462 2 : ShowContinueError(state, "...Volume Flow Rate per Rated Total Capacity = Volume Flow Rate / Rated Total Capacity");
10463 2 : ShowContinueError(state, "...Volume Flow Rate = Air Mass Flow Rate / Air Density");
10464 2 : ShowContinueError(state, "...Data used for calculations:");
10465 1 : ShowContinueError(state, format("...Rated Total Capacity = {:.2R} W.", thisDXCoil.RatedTotCap(Mode)));
10466 2 : ShowContinueError(state, "...Volume Flow Rate = Air Mass Flow Rate / Air Density");
10467 1 : ShowContinueError(state, format("...Volume Flow Rate = {:.8R} m3/s.", AirVolumeFlowRate));
10468 1 : ShowContinueError(state, format("...Air Mass Flow Rate = {:.8R} kg/s.", AirMassFlow));
10469 2 : ShowContinueError(
10470 : state,
10471 2 : format("...Air Density = {:.8R} kg/m3.", PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat)));
10472 2 : ShowContinueError(state, "...Data used for air density calculation:");
10473 1 : ShowContinueError(state, format("...Outdoor Air Pressure = {:.3R} Pa.", OutdoorPressure));
10474 1 : ShowContinueError(state, format("...Inlet Air Dry-Bulb Temp = {:.3R} C.", InletAirDryBulbTemp));
10475 1 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.8R} kgWater/kgDryAir.", InletAirHumRat));
10476 : }
10477 2624 : ShowRecurringWarningErrorAtEnd(
10478 : state,
10479 656 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
10480 : "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
10481 328 : 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 927411 : RatedCBF = thisDXCoil.RatedCBF(Mode);
10489 927411 : if (RatedCBF > 0.0) {
10490 927411 : A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
10491 : } else {
10492 0 : A0 = 0.0;
10493 : }
10494 927411 : ADiff = -A0 / AirMassFlow;
10495 927411 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
10496 927411 : 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 927411 : 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 927411 : if (OutdoorDryBulb > thisDXCoil.MaxOATCompressor && !state.dataGlobal->WarmupFlag) {
10518 0 : thisDXCoil.PrintHighAmbMessage = true;
10519 0 : thisDXCoil.HighTempLast = OutdoorDryBulb;
10520 0 : if (thisDXCoil.HighAmbErrIndex == 0) {
10521 0 : thisDXCoil.HighAmbBuffer1 = format("{} \"{}\" - Condenser inlet temperature above {:.2R} C. Condenser temperature = {:.2R}",
10522 0 : thisDXCoil.DXCoilType,
10523 0 : thisDXCoil.Name,
10524 0 : thisDXCoil.MaxOATCompressor,
10525 0 : OutdoorDryBulb);
10526 0 : thisDXCoil.HighAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
10527 0 : 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 927411 : InletAirHumRatTemp = InletAirHumRat;
10534 :
10535 927411 : Label50:;
10536 927411 : switch (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims) {
10537 687258 : case 1:
10538 687258 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC);
10539 687258 : break;
10540 240153 : case 2:
10541 : default: // this default allows the simulation to continue, but will issue a warning, should be removed eventually
10542 240153 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC, CondInletTemp);
10543 240153 : break;
10544 : }
10545 :
10546 : // Warn user if curve output goes negative
10547 927411 : 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 927411 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
10574 927411 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
10575 :
10576 : // Warn user if curve output goes negative
10577 927411 : 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 927411 : if (present(MaxCoolCap)) {
10600 927365 : TotCap = min(MaxCoolCap, thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac);
10601 : } else {
10602 46 : TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
10603 : }
10604 :
10605 927411 : TotCap *= PartLoadRatio;
10606 :
10607 : // Calculate apparatus dew point conditions using TotCap and CBF
10608 927411 : 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 927411 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
10612 927411 : 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 927411 : wADP = min(InletAirHumRat, PsyWFnTdbH(state, tADP, hADP, RoutineName));
10616 927411 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
10617 927411 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
10618 847660 : SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
10619 : } else {
10620 79751 : SHR = 1.0;
10621 : }
10622 : // Check for dry evaporator conditions (win < wadp)
10623 927411 : 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 927411 : if (thisDXCoil.PLFFPLR(Mode) > 0 && CompCycRatio < 1.0) {
10642 0 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CompCycRatio); // Calculate part-load factor
10643 : } else {
10644 927411 : PLF = 1.0;
10645 : }
10646 :
10647 927411 : 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 927411 : thisDXCoil.PartLoadRatio = PartLoadRatio;
10662 927411 : thisDXCoil.CoolingCoilRuntimeFraction = CompCycRatio / PLF;
10663 927411 : 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 927411 : } 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 927411 : if (fanOp == HVAC::FanOp::Cycling) {
10685 252614 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
10686 : }
10687 :
10688 : // Calculate full load output conditions
10689 : // if ( SHR > 1.0 || Counter > 0 ) SHR = 1.0;
10690 927411 : if (SHR > 1.0) {
10691 0 : SHR = 1.0;
10692 : }
10693 927411 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
10694 927411 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
10695 927411 : if (SHR < 1.0) {
10696 596744 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
10697 : } else {
10698 330667 : FullLoadOutAirHumRat = InletAirHumRat;
10699 : }
10700 927411 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
10701 :
10702 : // Check for saturation error and modify temperature at constant enthalpy
10703 927411 : if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure)) {
10704 765 : 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 765 : FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
10709 : }
10710 :
10711 : // Store actual outlet conditions when DX coil is ON for use in heat recovery module
10712 927411 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = FullLoadOutAirTemp;
10713 927411 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = FullLoadOutAirHumRat;
10714 :
10715 : // Add warning message for cold cooling coil (FullLoadOutAirTemp < 2 C)
10716 927411 : 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 927411 : if (fanOp == HVAC::FanOp::Continuous && CompCycRatio < 1.0) {
10734 284330 : QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode)); // always the same number
10735 284330 : QLatActual = TotCap * (1.0 - SHR);
10736 284330 : SHRUnadjusted = SHR;
10737 284330 : 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 284330 : if (SHR > 1.0) {
10743 0 : SHR = 1.0;
10744 : }
10745 284330 : FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
10746 284330 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
10747 284330 : if (SHR < 1.0) {
10748 183363 : FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
10749 : } else {
10750 100967 : FullLoadOutAirHumRat = InletAirHumRat;
10751 : }
10752 284330 : 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 927411 : 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 284330 : OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
10763 284330 : OutletAirHumRat = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirHumRat + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirHumRat);
10764 284330 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
10765 : } else {
10766 : // Default to cycling fan, cycling compressor
10767 643081 : OutletAirEnthalpy = FullLoadOutAirEnth;
10768 643081 : OutletAirHumRat = FullLoadOutAirHumRat;
10769 643081 : OutletAirTemp = FullLoadOutAirTemp;
10770 : }
10771 :
10772 : // Check for saturation error and modify temperature at constant enthalpy
10773 927411 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, RoutineName)) {
10774 3982 : 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 3982 : 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 927411 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10786 :
10787 : // Coil total/sensible/latent cooling rates
10788 927411 : CalcComponentSensibleLatentOutput(AirMassFlow,
10789 : InletAirDryBulbTemp,
10790 : InletAirHumRat,
10791 : OutletAirTemp,
10792 : OutletAirHumRat,
10793 927411 : thisDXCoil.SensCoolingEnergyRate,
10794 927411 : thisDXCoil.LatCoolingEnergyRate,
10795 927411 : thisDXCoil.TotalCoolingEnergyRate);
10796 :
10797 927411 : thisDXCoil.OutletAirTemp = OutletAirTemp;
10798 927411 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
10799 927411 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
10800 :
10801 : } else {
10802 :
10803 : // DX coil is off; just pass through conditions
10804 773753 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10805 773753 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
10806 773753 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
10807 :
10808 773753 : thisDXCoil.ElecCoolingPower = 0.0;
10809 773753 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
10810 773753 : thisDXCoil.SensCoolingEnergyRate = 0.0;
10811 773753 : thisDXCoil.LatCoolingEnergyRate = 0.0;
10812 773753 : thisDXCoil.EvapCondPumpElecPower = 0.0;
10813 773753 : thisDXCoil.EvapWaterConsumpRate = 0.0;
10814 :
10815 : // Reset globals when DX coil is OFF for use in heat recovery module
10816 773753 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
10817 773753 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
10818 :
10819 : } // end of on/off if - else
10820 :
10821 : // set water system demand request (if needed)
10822 1701164 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
10823 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
10824 0 : thisDXCoil.EvapWaterConsumpRate;
10825 : }
10826 :
10827 1701164 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
10828 1701164 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
10829 1701164 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
10830 1701164 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
10831 1701164 : thisDXCoil.CondInletTemp = CondInletTemp;
10832 1701164 : state.dataDXCoils->DXCoilTotalCooling(DXCoilNum) = thisDXCoil.TotalCoolingEnergyRate;
10833 1701164 : state.dataDXCoils->DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
10834 :
10835 : // set outlet node conditions
10836 1701164 : int airOutletNode = thisDXCoil.AirOutNode;
10837 1701164 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
10838 1701164 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
10839 1701164 : }
10840 :
10841 7586296 : 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 7586296 : 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 7586296 : 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 7586296 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
10938 :
10939 7586296 : if (present(OnOffAirFlowRatio)) {
10940 7586250 : AirFlowRatio = OnOffAirFlowRatio;
10941 : } else {
10942 46 : AirFlowRatio = 1.0;
10943 : }
10944 :
10945 7586296 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
10946 : // Get condenser outdoor node info from DX Heating Coil
10947 7586296 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
10948 2426429 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp;
10949 2426429 : CompAmbTemp = OutdoorDryBulb;
10950 2426429 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
10951 156109 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10952 156109 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10953 156109 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10954 156109 : CompAmbTemp = state.dataEnvrn->OutDryBulbTemp;
10955 : } else {
10956 2270320 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press;
10957 : // If node is not connected to anything, pressure = default, use weather data
10958 2270320 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
10959 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10960 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10961 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10962 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10963 : } else {
10964 2270320 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat;
10965 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
10966 2270320 : OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb;
10967 : }
10968 2270320 : 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 5159867 : } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
10978 81925 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
10979 81925 : OutdoorDryBulb = secZoneHB.ZT;
10980 81925 : OutdoorHumRat = secZoneHB.airHumRat;
10981 81925 : OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
10982 81925 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10983 81925 : CompAmbTemp = OutdoorDryBulb;
10984 : } else {
10985 5077942 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
10986 5077942 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
10987 5077942 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
10988 5077942 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
10989 5077942 : CompAmbTemp = OutdoorDryBulb;
10990 : }
10991 :
10992 7586296 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
10993 7586296 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
10994 7586296 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
10995 7586296 : 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 7586296 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
11000 7586296 : PLRHeating = 0.0;
11001 7586296 : thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
11002 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
11003 7586296 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
11004 1959749 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
11005 1959749 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
11006 56165 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
11007 : }
11008 : } else {
11009 5626547 : CrankcaseHeatingPower = 0.0;
11010 : }
11011 :
11012 8824410 : if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
11013 1238114 : OutdoorDryBulb > thisDXCoil.MinOATCompressor) {
11014 : // for cycling fan, reset mass flow to full on rate
11015 608583 : if (fanOp == HVAC::FanOp::Cycling) {
11016 252610 : AirMassFlow /= PartLoadRatio;
11017 : }
11018 608583 : if (fanOp == HVAC::FanOp::Continuous) {
11019 355973 : AirMassFlow *= AirFlowRatio;
11020 : }
11021 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton)
11022 608583 : 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 608583 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
11026 :
11027 1214086 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
11028 605503 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
11029 3080 : 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 24640 : ShowRecurringWarningErrorAtEnd(
11045 : state,
11046 6160 : thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
11047 : "\" - Air volume flow rate per watt of rated total heating capacity is out of range error continues...",
11048 3080 : 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 608583 : if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
11058 56682 : switch (thisDXCoil.HeatingPerformanceOATType) {
11059 1 : case HVAC::OATType::DryBulb: {
11060 1 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
11061 1 : } break;
11062 56681 : case HVAC::OATType::WetBulb: {
11063 56681 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp, OutdoorWetBulb);
11064 56681 : } break;
11065 0 : default: {
11066 0 : TotCapTempModFac = 1.0;
11067 0 : } break;
11068 : }
11069 : } else {
11070 551901 : switch (thisDXCoil.HeatingPerformanceOATType) {
11071 312950 : case HVAC::OATType::DryBulb: {
11072 312950 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
11073 289170 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), OutdoorDryBulb);
11074 : } else {
11075 23780 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp);
11076 : }
11077 312950 : } break;
11078 238951 : case HVAC::OATType::WetBulb: {
11079 238951 : 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 238951 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp);
11083 : }
11084 238951 : } break;
11085 0 : default: {
11086 0 : TotCapTempModFac = 1.0;
11087 0 : } break;
11088 : }
11089 : }
11090 :
11091 608583 : 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 608583 : AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
11111 608583 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
11112 :
11113 : // Calculate total heating capacity for off-rated conditions
11114 608583 : 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 608583 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
11119 608583 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
11120 :
11121 : // Initializing defrost adjustment factors
11122 608583 : LoadDueToDefrost = 0.0;
11123 608583 : HeatingCapacityMultiplier = 1.0;
11124 608583 : FractionalDefrostTime = 0.0;
11125 608583 : InputPowerMultiplier = 1.0;
11126 :
11127 : // Check outdoor temperature to determine of defrost is active
11128 608583 : if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost && thisDXCoil.CondenserType(Mode) != DataHeatBalance::RefrigCondenserType::Water) {
11129 : // Calculate defrost adjustment factors depending on defrost control type
11130 88366 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
11131 87823 : FractionalDefrostTime = thisDXCoil.DefrostTime;
11132 87823 : if (FractionalDefrostTime > 0.0) {
11133 87823 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
11134 0 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
11135 0 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
11136 : } else {
11137 87823 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
11138 87823 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
11139 87823 : 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 543 : FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
11150 543 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
11151 0 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
11152 0 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
11153 : } else {
11154 543 : HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
11155 543 : InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
11156 543 : 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 88366 : if (FractionalDefrostTime > 0.0) {
11167 : // Calculate defrost adjustment factors depending on defrost control strategy
11168 88366 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
11169 543 : LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.RatedTotCap(Mode) / 1.01667);
11170 543 : DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
11171 543 : thisDXCoil.DefrostPower = DefrostEIRTempModFac * (thisDXCoil.RatedTotCap(Mode) / 1.01667) * FractionalDefrostTime;
11172 : } else { // Defrost strategy is resistive
11173 87823 : 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 608583 : if (present(MaxHeatCap)) {
11183 319366 : TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
11184 319366 : TotCap = min(MaxHeatCap, TotCap);
11185 : } else {
11186 289217 : TotCapAdj = TotCap * HeatingCapacityMultiplier;
11187 : }
11188 :
11189 : // Calculate full load outlet conditions
11190 608583 : FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
11191 608583 : FullLoadOutAirHumRat = InletAirHumRat;
11192 608583 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
11193 608583 : 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 608583 : 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 608583 : if (fanOp == HVAC::FanOp::Continuous) {
11206 : // continuous fan, cycling compressor
11207 355973 : OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
11208 355973 : OutletAirHumRat = (PartLoadRatio * FullLoadOutAirHumRat + (1.0 - PartLoadRatio) * InletAirHumRat);
11209 355973 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11210 : } else {
11211 : // default to cycling fan, cycling compressor
11212 252610 : OutletAirEnthalpy = FullLoadOutAirEnth;
11213 252610 : OutletAirHumRat = FullLoadOutAirHumRat;
11214 252610 : 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 608583 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
11221 289171 : if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 1) {
11222 289170 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), OutdoorDryBulb);
11223 : } else {
11224 1 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
11225 : }
11226 289171 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
11227 : } else {
11228 319412 : EIRTempModFac = 1.0;
11229 319412 : EIRFlowModFac = 1.0;
11230 : }
11231 :
11232 608583 : 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 608583 : EIR = thisDXCoil.RatedEIR(Mode) * EIRTempModFac * EIRFlowModFac;
11249 : // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
11250 608583 : if (TotCapAdj > 0.0) {
11251 608526 : PLRHeating = min(1.0, (PartLoadRatio + (LoadDueToDefrost * PartLoadRatio) / TotCapAdj));
11252 : } else {
11253 57 : PLRHeating = 0.0;
11254 : }
11255 608583 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating) {
11256 289171 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PLRHeating); // Calculate part-load factor
11257 : } else {
11258 319412 : PLF = 1.0;
11259 : }
11260 :
11261 608583 : if (PLF < 0.7) {
11262 0 : if (thisDXCoil.PLRErrIndex == 0) {
11263 0 : ShowWarningMessage(
11264 : state,
11265 0 : format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
11266 0 : ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
11267 0 : ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
11268 0 : ShowContinueErrorTimeStamp(state, "");
11269 : }
11270 0 : ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
11271 0 : PLF = 0.7;
11272 : }
11273 :
11274 608583 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
11275 608583 : 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 608583 : } 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 608583 : if (fanOp == HVAC::FanOp::Cycling) {
11296 252610 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
11297 : }
11298 608583 : 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 608583 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
11304 319435 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
11305 : } else {
11306 289148 : thisDXCoil.CrankcaseHeaterPower =
11307 289148 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
11308 289148 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
11309 : }
11310 :
11311 608583 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
11312 608583 : 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 608583 : thisDXCoil.DefrostPower *= thisDXCoil.HeatingCoilRuntimeFraction;
11316 :
11317 608583 : thisDXCoil.OutletAirTemp = OutletAirTemp;
11318 608583 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
11319 608583 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
11320 608583 : thisDXCoil.CompressorPartLoadRatio = PartLoadRatio;
11321 :
11322 : } else {
11323 :
11324 : // DX coil is off; just pass through conditions
11325 6977713 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
11326 6977713 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
11327 6977713 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
11328 :
11329 6977713 : thisDXCoil.ElecHeatingPower = 0.0;
11330 6977713 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
11331 6977713 : 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 6977713 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
11336 2512644 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
11337 : } else {
11338 4465069 : thisDXCoil.CrankcaseHeaterPower =
11339 4465069 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
11340 : }
11341 6977713 : thisDXCoil.CompressorPartLoadRatio = 0.0;
11342 :
11343 : } // end of on/off if - else
11344 :
11345 7586296 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
11346 7586296 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
11347 7586296 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
11348 7586296 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
11349 7586296 : state.dataDXCoils->DXCoilTotalHeating(DXCoilNum) = thisDXCoil.TotalHeatingEnergyRate;
11350 7586296 : state.dataDXCoils->DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
11351 7586296 : state.dataDXCoils->DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;
11352 :
11353 : // set outlet node conditions
11354 7586296 : int airOutletNode = thisDXCoil.AirOutNode;
11355 7586296 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
11356 7586296 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
11357 :
11358 : // calc secondary coil if specified
11359 7586296 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
11360 81925 : CalcSecondaryDXCoils(state, DXCoilNum);
11361 : }
11362 7586296 : }
11363 :
11364 4183337 : 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 4183337 : 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 4183337 : Real64 CompAmbTemp(0.0); // Ambient temperature at compressor
11457 :
11458 4183337 : if (present(ForceOn)) {
11459 55368 : LocalForceOn = true;
11460 : } else {
11461 4127969 : LocalForceOn = false;
11462 : }
11463 :
11464 4183337 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
11465 :
11466 4183337 : if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
11467 334720 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
11468 : // If node is not connected to anything, pressure = default, use weather data
11469 334720 : 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 334720 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
11476 334720 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
11477 334720 : OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure);
11478 : }
11479 334720 : CompAmbTemp = OutdoorDryBulb;
11480 334720 : 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 3848617 : } 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 3848617 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
11497 3848617 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
11498 3848617 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
11499 3848617 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
11500 3848617 : CompAmbTemp = OutdoorDryBulb;
11501 : }
11502 :
11503 4183337 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
11504 4183337 : AirMassFlowRatio = thisDXCoil.InletAirMassFlowRateMax / thisDXCoil.RatedAirMassFlowRate(Mode);
11505 4183337 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
11506 4183337 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
11507 4183337 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
11508 4183337 : InletAirHumRat = thisDXCoil.InletAirHumRat;
11509 4183337 : 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 4183337 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
11514 4183337 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
11515 4159844 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
11516 23493 : } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11517 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
11518 23493 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
11519 23493 : CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
11520 : }
11521 :
11522 5973608 : if ((AirMassFlow > 0.0 && CompAmbTemp >= thisDXCoil.MinOATCompressor) && ((thisDXCoil.availSched->getCurrentVal() > 0.0) || (LocalForceOn)) &&
11523 1790271 : (SpeedRatio > 0.0 || CycRatio > 0.0)) {
11524 :
11525 3061187 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
11526 3061187 : if (SpeedRatio > 0.0) {
11527 : // Adjust high speed coil bypass factor for actual maximum air flow rate.
11528 2201124 : RatedCBFHS = thisDXCoil.RatedCBF(Mode);
11529 2201124 : CBFHS = AdjustCBF(RatedCBFHS, thisDXCoil.RatedAirMassFlowRate(Mode), thisDXCoil.InletAirMassFlowRateMax);
11530 : // get high speed total capacity and SHR at current conditions
11531 6603372 : CalcTotCapSHR(state,
11532 : InletAirDryBulbTemp,
11533 : InletAirHumRat,
11534 : InletAirEnthalpy,
11535 : InletAirWetBulbC,
11536 : AirMassFlowRatio,
11537 : thisDXCoil.InletAirMassFlowRateMax,
11538 2201124 : thisDXCoil.RatedTotCap(Mode),
11539 : CBFHS,
11540 2201124 : thisDXCoil.CCapFTemp(Mode),
11541 2201124 : thisDXCoil.CCapFFlow(Mode),
11542 : TotCapHS,
11543 : SHRHS,
11544 : CondInletTemp,
11545 : OutdoorPressure,
11546 2201124 : 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 2201124 : if (thisDXCoil.UserSHRCurveExists) {
11551 3662 : SHRHS = CalcSHRUserDefinedCurves(state,
11552 : InletAirDryBulbTemp,
11553 : InletAirWetBulbC,
11554 : AirMassFlowRatio,
11555 3662 : thisDXCoil.SHRFTemp(Mode),
11556 3662 : thisDXCoil.SHRFFlow(Mode),
11557 3662 : thisDXCoil.RatedSHR(Mode));
11558 : }
11559 : // get low speed total capacity and SHR at current conditions
11560 2201124 : 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 2201124 : thisDXCoil.CCapFFlow(Mode),
11571 : TotCapLS,
11572 : SHRLS,
11573 : CondInletTemp,
11574 : OutdoorPressure,
11575 2201124 : 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 2201124 : if (thisDXCoil.UserSHRCurveExists) {
11580 3662 : 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 2201124 : EIRTempModFacHS = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirWetBulbC, CondInletTemp);
11590 2201124 : EIRFlowModFacHS = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
11591 2201124 : 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 2201124 : EIRTempModFacLS = CurveValue(state, thisDXCoil.EIRFTemp2, InletAirWetBulbC, CondInletTemp);
11596 2201124 : EIRLS = thisDXCoil.RatedEIR2 * EIRTempModFacLS;
11597 :
11598 : // get current total capacity, SHR, EIR
11599 2201124 : if (SpeedRatio >= 1.0) {
11600 703254 : TotCap = TotCapHS;
11601 703254 : SHR = SHRHS;
11602 703254 : EIR = EIRHS;
11603 703254 : CBFNom = CBFHS;
11604 703254 : AirMassFlowNom = thisDXCoil.InletAirMassFlowRateMax;
11605 703254 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
11606 703254 : EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower(Mode);
11607 : } else {
11608 1497870 : TotCap = SpeedRatio * TotCapHS + (1.0 - SpeedRatio) * TotCapLS;
11609 1497870 : EIR = SpeedRatio * EIRHS + (1.0 - SpeedRatio) * EIRLS;
11610 1497870 : CBFNom = SpeedRatio * CBFHS + (1.0 - SpeedRatio) * thisDXCoil.RatedCBF2;
11611 1497870 : AirMassFlowNom = SpeedRatio * thisDXCoil.InletAirMassFlowRateMax + (1.0 - SpeedRatio) * thisDXCoil.RatedAirMassFlowRate2;
11612 1497870 : CondAirMassFlow = RhoAir * (SpeedRatio * thisDXCoil.EvapCondAirFlow(Mode) + (1.0 - SpeedRatio) * thisDXCoil.EvapCondAirFlow2);
11613 1497870 : EvapCondPumpElecPower =
11614 1497870 : SpeedRatio * thisDXCoil.EvapCondPumpElecNomPower(Mode) + (1.0 - SpeedRatio) * thisDXCoil.EvapCondPumpElecNomPower2;
11615 : }
11616 2201124 : hDelta = TotCap / AirMassFlow;
11617 2201124 : if (thisDXCoil.UserSHRCurveExists) {
11618 3662 : if (SpeedRatio >= 1.0) {
11619 2939 : SHR = SHRHS;
11620 : } else {
11621 723 : SHR = min(SpeedRatio * SHRHS + (1.0 - SpeedRatio) * SHRLS, 1.0);
11622 : }
11623 3662 : OutletAirEnthalpy = InletAirEnthalpy - hDelta;
11624 3662 : if (SHR < 1.0) {
11625 3662 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11626 3662 : OutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11627 3662 : if (OutletAirHumRat <= 0.0) {
11628 0 : OutletAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
11629 : }
11630 : } else {
11631 0 : SHR = 1.0;
11632 0 : OutletAirHumRat = InletAirHumRat;
11633 : }
11634 3662 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11635 3662 : OutletAirDryBulbTempSat = PsyTdpFnWPb(state, OutletAirHumRat, OutdoorPressure, RoutineNameHighSpeedOutlet);
11636 3662 : if (OutletAirDryBulbTempSat > OutletAirDryBulbTemp) {
11637 3635 : OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11638 3635 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy, RoutineNameHighSpeedOutlet);
11639 : }
11640 :
11641 : } else {
11642 : // Adjust CBF for off-nominal flow
11643 2197462 : CBF = AdjustCBF(CBFNom, AirMassFlowNom, AirMassFlow);
11644 : // Calculate new apparatus dew point conditions
11645 2197462 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
11646 2197462 : 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 2197462 : wADP = PsyWFnTdbH(state, tADP, hADP);
11650 2197462 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
11651 : // get corresponding SHR
11652 2197462 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
11653 2197462 : 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 2197462 : OutletAirEnthalpy = InletAirEnthalpy - hDelta;
11660 : // get outlet conditions
11661 2197462 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11662 2197462 : OutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11663 :
11664 2197462 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
11665 2197462 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
11666 2197462 : if (OutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
11667 383753 : OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11668 383753 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy);
11669 : }
11670 : }
11671 : // Coil total/sensible/latent cooling rates and electrical power
11672 2201124 : CalcComponentSensibleLatentOutput(AirMassFlow,
11673 : InletAirDryBulbTemp,
11674 : InletAirHumRat,
11675 : OutletAirDryBulbTemp,
11676 : OutletAirHumRat,
11677 2201124 : thisDXCoil.SensCoolingEnergyRate,
11678 2201124 : thisDXCoil.LatCoolingEnergyRate,
11679 2201124 : thisDXCoil.TotalCoolingEnergyRate);
11680 2201124 : thisDXCoil.ElecCoolingPower = TotCap * EIR;
11681 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
11682 2201124 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
11683 2201124 : thisDXCoil.PartLoadRatio = 1.0;
11684 2201124 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0;
11685 :
11686 2201124 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
11687 2201124 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
11688 2201124 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
11689 :
11690 860063 : } else if (CycRatio > 0.0) {
11691 :
11692 860063 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11693 : // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
11694 6143 : CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect2);
11695 6143 : 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 860063 : 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 860063 : thisDXCoil.CCapFFlow(Mode),
11712 : TotCapLS,
11713 : SHRLS,
11714 : CondInletTemp,
11715 : OutdoorPressure,
11716 860063 : thisDXCoil.capModFacTotal);
11717 : // get the low speed SHR from user specified SHR modifier curves
11718 860063 : if (thisDXCoil.UserSHRCurveExists) {
11719 1886 : 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 860063 : hDelta = TotCapLS / AirMassFlow;
11725 860063 : if (thisDXCoil.UserSHRCurveExists) {
11726 1886 : SHR = SHRLS;
11727 1886 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
11728 1886 : if (SHR < 1.0) {
11729 1886 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11730 1886 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11731 1886 : if (LSOutletAirHumRat <= 0.0) {
11732 0 : LSOutletAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
11733 : }
11734 : } else {
11735 0 : SHR = 1.0;
11736 0 : LSOutletAirHumRat = InletAirHumRat;
11737 : }
11738 1886 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
11739 1886 : OutletAirDryBulbTempSat = PsyTdpFnWPb(state, LSOutletAirHumRat, OutdoorPressure, RoutineNameLowSpeedOutlet);
11740 1886 : if (OutletAirDryBulbTempSat > LSOutletAirDryBulbTemp) {
11741 1 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11742 1 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineNameLowSpeedOutlet);
11743 : }
11744 :
11745 : } else {
11746 : // Adjust CBF for off-nominal flow
11747 858177 : CBF = AdjustCBF(thisDXCoil.RatedCBF2, thisDXCoil.RatedAirMassFlowRate2, AirMassFlow);
11748 : // Calculate new apparatus dew point conditions
11749 858177 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
11750 858177 : 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 858177 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineNameNewDewPointConditions);
11754 858177 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
11755 : // get corresponding SHR
11756 858177 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
11757 858177 : 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 858177 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
11764 858177 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
11765 858177 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
11766 858177 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
11767 858177 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineNameLowSpeedOutlet);
11768 858177 : if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
11769 84351 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
11770 84351 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineNameLowSpeedOutlet);
11771 : }
11772 : }
11773 : // outlet conditions are average of inlet and low speed weighted by CycRatio
11774 860063 : OutletAirEnthalpy = CycRatio * LSOutletAirEnthalpy + (1.0 - CycRatio) * InletAirEnthalpy;
11775 860063 : OutletAirHumRat = CycRatio * LSOutletAirHumRat + (1.0 - CycRatio) * InletAirHumRat;
11776 860063 : 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 860063 : EIRTempModFacLS = CurveValue(state, thisDXCoil.EIRFTemp2, InletAirWetBulbC, CondInletTemp);
11781 860063 : EIRLS = thisDXCoil.RatedEIR2 * EIRTempModFacLS;
11782 : // get the part load factor that will account for cycling losses
11783 860063 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CycRatio);
11784 860063 : if (PLF < 0.7) {
11785 0 : PLF = 0.7;
11786 : }
11787 : // calculate the run time fraction
11788 860063 : thisDXCoil.CoolingCoilRuntimeFraction = CycRatio / PLF;
11789 860063 : thisDXCoil.PartLoadRatio = CycRatio;
11790 860063 : 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 860063 : thisDXCoil.ElecCoolingPower = TotCapLS * EIRLS * thisDXCoil.CoolingCoilRuntimeFraction;
11795 :
11796 : // Coil total/sensible/latent cooling rates and electrical power
11797 860063 : CalcComponentSensibleLatentOutput(AirMassFlow,
11798 : InletAirDryBulbTemp,
11799 : InletAirHumRat,
11800 : OutletAirDryBulbTemp,
11801 : OutletAirHumRat,
11802 860063 : thisDXCoil.SensCoolingEnergyRate,
11803 860063 : thisDXCoil.LatCoolingEnergyRate,
11804 860063 : thisDXCoil.TotalCoolingEnergyRate);
11805 860063 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
11806 860063 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
11807 860063 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
11808 860063 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
11809 860063 : CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow2 * thisDXCoil.CoolingCoilRuntimeFraction;
11810 860063 : EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower2 * thisDXCoil.CoolingCoilRuntimeFraction;
11811 : }
11812 :
11813 3061187 : 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 19013 : RhoWater = RhoH2O(OutdoorDryBulb);
11820 19013 : thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater;
11821 19013 : thisDXCoil.EvapCondPumpElecPower = EvapCondPumpElecPower;
11822 : // set water system demand request (if needed)
11823 19013 : 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 19013 : CalcBasinHeaterPower(state,
11831 : thisDXCoil.BasinHeaterPowerFTempDiff,
11832 : thisDXCoil.basinHeaterSched,
11833 : thisDXCoil.BasinHeaterSetPointTemp,
11834 19013 : thisDXCoil.BasinHeaterPower);
11835 19013 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
11836 : }
11837 :
11838 : } else {
11839 :
11840 : // DX coil is off; just pass through conditions
11841 1122150 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
11842 1122150 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
11843 1122150 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
11844 :
11845 1122150 : thisDXCoil.ElecCoolingPower = 0.0;
11846 1122150 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
11847 1122150 : thisDXCoil.SensCoolingEnergyRate = 0.0;
11848 1122150 : thisDXCoil.LatCoolingEnergyRate = 0.0;
11849 1122150 : thisDXCoil.EvapCondPumpElecPower = 0.0;
11850 1122150 : thisDXCoil.EvapWaterConsumpRate = 0.0;
11851 :
11852 : // Calculate basin heater power
11853 1122150 : if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
11854 4480 : CalcBasinHeaterPower(state,
11855 : thisDXCoil.BasinHeaterPowerFTempDiff,
11856 : thisDXCoil.basinHeaterSched,
11857 : thisDXCoil.BasinHeaterSetPointTemp,
11858 4480 : thisDXCoil.BasinHeaterPower);
11859 : }
11860 : }
11861 :
11862 4183337 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
11863 4183337 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
11864 4183337 : thisDXCoil.CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure
11865 :
11866 : // set outlet node conditions
11867 4183337 : int airOutletNode = thisDXCoil.AirOutNode;
11868 4183337 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
11869 4183337 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
11870 :
11871 : // calc secondary coil if specified
11872 4183337 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
11873 0 : CalcSecondaryDXCoils(state, DXCoilNum);
11874 : }
11875 4183337 : }
11876 :
11877 130449 : 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 130449 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
11906 :
11907 130449 : if (thisDXCoil.NumCapacityStages == 1) {
11908 11265 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
11909 : } else {
11910 119184 : PerfMode = (int)DehumidMode * 2 + 1;
11911 119184 : if (thisDXCoil.CondenserType(PerfMode) == DataHeatBalance::RefrigCondenserType::Evap) {
11912 0 : thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
11913 119184 : } 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 130449 : }
11923 :
11924 53207081 : 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 53207081 : if (CBFNom > 0.0) {
11949 53207081 : A0 = -std::log(CBFNom) * AirMassFlowRateNom;
11950 : } else {
11951 0 : A0 = 0.0;
11952 : }
11953 53207081 : ADiff = -A0 / AirMassFlowRate;
11954 53207081 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
11955 53180282 : CBFAdj = std::exp(ADiff);
11956 : } else {
11957 26799 : CBFAdj = 1.0e-6;
11958 : }
11959 :
11960 53207081 : return CBFAdj;
11961 : }
11962 :
11963 26701 : 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 26701 : Real64 CBF(0.0); // the result - the coil bypass factor
11995 :
11996 : // FUNCTION PARAMETER DEFINITIONS:
11997 : static constexpr std::string_view RoutineName("CalcCBF");
11998 26701 : 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 26701 : Real64 DeltaH(0.0); // Enthalpy drop across evaporator at given conditions [J/kg]
12003 26701 : Real64 DeltaT(0.0); // Temperature drop across evaporator at given conditions [C]
12004 26701 : Real64 DeltaHumRat(0.0); // Humidity ratio drop across evaporator at given conditions [kg/kg]
12005 26701 : Real64 OutletAirTemp(InletAirTemp); // Outlet dry-bulb temperature from evaporator at given conditions [C]
12006 26701 : 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 26701 : 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 26701 : 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 26701 : Real64 SlopeAtConds(0.0); // Slope (DeltaHumRat/DeltaT) at given conditions
12019 26701 : 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 26701 : bool CBFErrors(false); // Set to true if errors in CBF calculation, fatal at end of routine
12025 :
12026 26701 : if (AirVolFlowRate <= 0.0 || TotCap <= 0.0) { // Coil not running or has no capacity, don't calculate CBF
12027 0 : return CBF;
12028 : }
12029 :
12030 26701 : AirMassFlowRate = AirVolFlowRate * PsyRhoAirFnPbTdbW(state, DataEnvironment::StdPressureSeaLevel, InletAirTemp, InletAirHumRat, RoutineName);
12031 26701 : DeltaH = TotCap / AirMassFlowRate;
12032 26701 : InletAirEnthalpy = PsyHFnTdbW(InletAirTemp, InletAirHumRat);
12033 26701 : HTinHumRatOut = InletAirEnthalpy - (1.0 - SHR) * DeltaH;
12034 26701 : OutletAirHumRat = PsyWFnTdbH(state, InletAirTemp, HTinHumRatOut);
12035 26701 : DeltaHumRat = InletAirHumRat - OutletAirHumRat;
12036 26701 : OutletAirEnthalpy = InletAirEnthalpy - DeltaH;
12037 26701 : 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 26701 : OutletAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
12041 26701 : if (OutletAirRH >= 1.0 && PrintFlag) {
12042 10 : ShowWarningError(state, format("For object = {}, name = \"{}\"", UnitType, UnitName));
12043 20 : ShowContinueError(state, "Calculated outlet air relative humidity greater than 1. The combination of");
12044 20 : ShowContinueError(state, "rated air volume flow rate, total cooling capacity and sensible heat ratio yields coil exiting");
12045 20 : ShowContinueError(state, "air conditions above the saturation curve. Possible fixes are to reduce the rated total cooling");
12046 20 : ShowContinueError(state, "capacity, increase the rated air volume flow rate, or reduce the rated sensible heat ratio for this coil.");
12047 20 : ShowContinueError(state, "If autosizing, it is recommended that all three of these values be autosized.");
12048 20 : ShowContinueError(state, "...Inputs used for calculating cooling coil bypass factor.");
12049 10 : ShowContinueError(state, format("...Inlet Air Temperature = {:.2R} C", InletAirTemp));
12050 10 : ShowContinueError(state, format("...Outlet Air Temperature = {:.2R} C", OutletAirTemp));
12051 10 : ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", InletAirHumRat));
12052 10 : ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
12053 10 : ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
12054 10 : ShowContinueError(state, format("...Air Mass Flow Rate used in calculation = {:.6R} kg/s", AirMassFlowRate));
12055 10 : ShowContinueError(state, format("...Air Volume Flow Rate used in calculation = {:.6R} m3/s", AirVolFlowRate));
12056 10 : if (TotCap > 0.0) {
12057 20 : if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
12058 10 : ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
12059 0 : ShowContinueError(state,
12060 0 : format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
12061 0 : AirVolFlowRate / TotCap));
12062 : }
12063 : }
12064 20 : ShowContinueErrorTimeStamp(state, "");
12065 10 : OutletAirTempSat = PsyTsatFnHPb(state, OutletAirEnthalpy, DataEnvironment::StdPressureSeaLevel, RoutineName);
12066 10 : if (OutletAirTemp < OutletAirTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
12067 10 : OutletAirTemp = OutletAirTempSat + 0.005;
12068 10 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy, RoutineName);
12069 10 : DeltaHumRat = InletAirHumRat - OutletAirHumRat;
12070 10 : HTinHumRatOut = PsyHFnTdbW(InletAirTemp, OutletAirHumRat);
12071 10 : adjustedSHR = (HTinHumRatOut - OutletAirEnthalpy) / DeltaH;
12072 20 : ShowContinueError(state, "CalcCBF: SHR adjusted to achieve valid outlet air properties and the simulation continues.");
12073 10 : ShowContinueError(state, format("CalcCBF: initial SHR = {:.5R}", SHR));
12074 10 : ShowContinueError(state, format("CalcCBF: adjusted SHR = {:.5R}", adjustedSHR));
12075 : }
12076 : }
12077 26701 : DeltaT = InletAirTemp - OutletAirTemp;
12078 26701 : 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 26701 : if (DeltaT > 0.0) {
12106 26701 : SlopeAtConds = DeltaHumRat / DeltaT;
12107 : }
12108 :
12109 : // IF (SlopeAtConds .le. .0000001d0 .or. OutletAirHumRat .le. 0.0d0) THEN
12110 26701 : 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 26701 : ADPTemp = PsyTdpFnWPb(state, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel);
12140 :
12141 26701 : Tolerance = 1.0; // initial conditions for iteration
12142 26701 : ErrorLast = 100.0;
12143 26701 : Iter = 0;
12144 26701 : DeltaADPTemp = 5.0;
12145 361471 : while ((Iter <= IterMax) && (Tolerance > 0.001)) {
12146 : // Do for IterMax iterations or until the error gets below .1%
12147 334770 : if (Iter > 0) {
12148 308069 : ADPTemp += DeltaADPTemp;
12149 : }
12150 334770 : ++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 334770 : ADPHumRat = min(OutletAirHumRat, PsyWFnTdpPb(state, ADPTemp, DataEnvironment::StdPressureSeaLevel));
12157 334770 : Slope = (InletAirHumRat - ADPHumRat) / max(0.001, (InletAirTemp - ADPTemp));
12158 :
12159 : // check for convergence (slopes are equal to within error tolerance)
12160 :
12161 334770 : Error = (Slope - SlopeAtConds) / SlopeAtConds;
12162 334770 : if ((Error > 0.0) && (ErrorLast < 0.0)) {
12163 108013 : DeltaADPTemp = -DeltaADPTemp / 2.0;
12164 226757 : } else if ((Error < 0.0) && (ErrorLast > 0.0)) {
12165 122375 : DeltaADPTemp = -DeltaADPTemp / 2.0;
12166 104382 : } else if (std::abs(Error) > std::abs(ErrorLast)) {
12167 543 : DeltaADPTemp = -DeltaADPTemp / 2.0;
12168 : }
12169 334770 : ErrorLast = Error;
12170 :
12171 334770 : Tolerance = std::abs(Error);
12172 : }
12173 :
12174 : // Calculate Bypass Factor from Enthalpies
12175 :
12176 26701 : InletAirEnthalpy = PsyHFnTdbW(InletAirTemp, InletAirHumRat);
12177 26701 : OutletAirEnthalpy = PsyHFnTdbW(OutletAirTemp, OutletAirHumRat);
12178 26701 : ADPEnthalpy = PsyHFnTdbW(ADPTemp, ADPHumRat);
12179 26701 : CBF = min(1.0, (OutletAirEnthalpy - ADPEnthalpy) / (InletAirEnthalpy - ADPEnthalpy));
12180 26701 : 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 26701 : 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 26701 : if (CBFErrors) {
12203 0 : ShowFatalError(state, format("{} \"{}\" Errors found in calculating coil bypass factors", UnitType, UnitName));
12204 : }
12205 :
12206 26701 : return CBF;
12207 : }
12208 :
12209 860 : 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 860 : Real64 SHR(0.0); // the result - the adjusted design SHR
12240 :
12241 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
12242 860 : Real64 CBF_calculated(0.0); // coil bypass factor based on TotCap, AirFlow, SHR, and BaroPress
12243 860 : Real64 InletAirEnthalpy(0.0); // Enthalpy of inlet air to evaporator at given conditions [J/kg]
12244 860 : Real64 DeltaH(0.0); // Enthalpy drop across evaporator at given conditions [J/kg]
12245 860 : Real64 HTinHumRatOut(0.0); // Air enthalpy at inlet air temp and outlet air humidity ratio [J/kg]
12246 860 : Real64 DeltaHumRat(0.0); // Humidity ratio drop across evaporator at given conditions [kg/kg]
12247 860 : Real64 OutletAirTemp(0.0); // Outlet dry-bulb temperature from evaporator at given conditions [C]
12248 860 : Real64 OutletAirEnthalpy(0.0); // Enthalpy of outlet air at given conditions [J/kg]
12249 860 : Real64 OutletAirHumRat(0.0); // Outlet humidity ratio from evaporator at given conditions [kg/kg]
12250 860 : Real64 OutletAirRH(0.0); // relative humidity of the outlet air
12251 860 : Real64 CalcADPTemp(0.0); // actual ADP temperature based on bypass factor [C]
12252 860 : Real64 CalcADPHumRat(0.0); // actual ADP humidity ratio based on bypass factor [kg/kg]
12253 860 : Real64 CalcADPTempFnHR(0.0); // actual ADP temperature as a function of humidity ratio based on bypass factor [C]
12254 860 : Real64 ADPerror(0.0); // difference between ADP function of temperature and humidity ratio [deltaC]
12255 860 : Real64 AirMassFlow(0.0); // air mass flow rate based on standard barometric pressure [kg/s]
12256 860 : bool bStillValidating(true); // while loop flag
12257 860 : bool bNoReporting(false); // don't report specific warnings in calcCBF while iterating on result
12258 860 : bool bReversePerturb(false); // identifies when SHR is being lowered based on outlet air RH
12259 :
12260 860 : SHR = InitialSHR;
12261 860 : AirMassFlow =
12262 860 : AirVolFlowRate * PsyRhoAirFnPbTdbW(state, DataEnvironment::StdPressureSeaLevel, RatedInletAirTemp, RatedInletAirHumRat, CallingRoutine);
12263 26076 : while (bStillValidating) {
12264 25216 : CBF_calculated = max(0.0, CalcCBF(state, UnitType, UnitName, RatedInletAirTemp, RatedInletAirHumRat, TotCap, AirMassFlow, SHR, bNoReporting));
12265 25216 : DeltaH = TotCap / AirMassFlow;
12266 25216 : InletAirEnthalpy = PsyHFnTdbW(RatedInletAirTemp, RatedInletAirHumRat);
12267 25216 : HTinHumRatOut = InletAirEnthalpy - (1.0 - SHR) * DeltaH;
12268 25216 : OutletAirHumRat = PsyWFnTdbH(state, RatedInletAirTemp, HTinHumRatOut, CallingRoutine);
12269 25216 : DeltaHumRat = RatedInletAirHumRat - OutletAirHumRat;
12270 25216 : OutletAirEnthalpy = InletAirEnthalpy - DeltaH;
12271 25216 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
12272 25216 : OutletAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, CallingRoutine);
12273 25216 : if (CBF_calculated < 1) {
12274 25216 : CalcADPTemp = RatedInletAirTemp - ((RatedInletAirTemp - OutletAirTemp) / (1 - CBF_calculated));
12275 25216 : CalcADPHumRat = RatedInletAirHumRat - ((DeltaHumRat) / (1 - CBF_calculated));
12276 25216 : CalcADPTempFnHR = PsyTdpFnWPb(state, CalcADPHumRat, DataEnvironment::StdPressureSeaLevel, CallingRoutine);
12277 25216 : 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 25216 : if (std::abs(ADPerror) > 0.012) {
12283 25216 : if (OutletAirRH >= 1.0) { // if RH > 1, reduce SHR until it crosses the saturation curve
12284 612 : SHR -= 0.001;
12285 612 : bReversePerturb = true;
12286 612 : 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 24604 : if (bReversePerturb) {
12292 608 : bStillValidating = false; // stop iterating once SHR causes ADP to cross back under saturation curve, take what you get
12293 : } else {
12294 23996 : SHR += 0.001; // increase SHR slowly until ADP temps are resolved
12295 : }
12296 : }
12297 25216 : if (SHR > 0.8) {
12298 252 : 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 860 : return SHR;
12306 : }
12307 :
12308 8242573 : 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 8242573 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
12372 :
12373 8242573 : if (thisDXCoil.DXCoilType_Num != HVAC::CoilDX_MultiSpeedCooling) {
12374 7893695 : Twet_Rated = thisDXCoil.Twet_Rated(Mode);
12375 7893695 : Gamma_Rated = thisDXCoil.Gamma_Rated(Mode);
12376 7893695 : Nmax = thisDXCoil.MaxONOFFCyclesperHour(Mode);
12377 7893695 : Tcl = thisDXCoil.LatentCapacityTimeConstant(Mode);
12378 : } else {
12379 348878 : Twet_Rated = thisDXCoil.MSTwet_Rated(Mode);
12380 348878 : Gamma_Rated = thisDXCoil.MSGamma_Rated(Mode);
12381 348878 : Nmax = thisDXCoil.MSMaxONOFFCyclesperHour(Mode);
12382 348878 : 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 8242573 : if (RTF >= 1.0 || Twet_Rated <= 0.0 || Gamma_Rated <= 0.0 || Nmax <= 0.0 || Tcl <= 0.0) {
12389 7325187 : SHReff = SHRss;
12390 7325187 : return SHReff;
12391 : }
12392 :
12393 917386 : Twet_max = 9999.0; // high limit for Twet
12394 :
12395 : // Calculate the model parameters at the actual operating conditions
12396 917386 : Twet = min(Twet_Rated * QLatRated / (QLatActual + 1.e-10), Twet_max);
12397 917386 : 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 917386 : Ton = 3600.0 / (4.0 * Nmax * (1.0 - RTF)); // duration of cooling coil on-cycle (sec)
12401 917386 : Toff = 3600.0 / (4.0 * Nmax * RTF); // duration of cooling coil off-cycle (sec)
12402 :
12403 : // Cap Toff to meet the equation restriction
12404 917386 : if (Gamma > 0.0) {
12405 917386 : 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 917386 : 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 917386 : aa = (Gamma * Toffa) - (0.25 / Twet) * pow_2(Gamma) * pow_2(Toffa);
12430 917386 : To1 = aa + Tcl;
12431 917386 : Error = 1.0;
12432 1903934 : while (Error > 0.001) {
12433 986548 : To2 = aa - Tcl * (std::exp(-To1 / Tcl) - 1.0);
12434 986548 : Error = std::abs((To2 - To1) / To1);
12435 986548 : 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 917386 : aa = std::exp(max(-700.0, -Ton / Tcl));
12442 : // Calculate latent heat ratio multiplier
12443 917386 : LHRmult = max(((Ton - To2) / (Ton + Tcl * (aa - 1.0))), 0.0);
12444 :
12445 : // Calculate part-load or "effective" sensible heat ratio
12446 917386 : SHReff = 1.0 - (1.0 - SHRss) * LHRmult;
12447 :
12448 917386 : if (SHReff < SHRss) {
12449 775 : SHReff = SHRss; // Effective SHR can be less than the steady-state SHR
12450 : }
12451 917386 : if (SHReff > 1.0) {
12452 0 : SHReff = 1.0; // Effective sensible heat ratio can't be greater than 1.0
12453 : }
12454 :
12455 917386 : return SHReff;
12456 : }
12457 :
12458 8636826 : 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 8636826 : constexpr int MaxIter(30); // Maximum number of iterations for dry evaporator calculations
12512 8636826 : constexpr Real64 RF(0.4); // Relaxation factor for dry evaporator iterations
12513 8636826 : constexpr Real64 Tolerance(0.01); // Error tolerance for dry evaporator iterations
12514 8636826 : 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 8636826 : Counter = 0;
12534 : // Tolerance = 0.01d0
12535 8636826 : werror = 0.0;
12536 :
12537 8636826 : InletWetBulbCalc = InletWetBulb;
12538 8636826 : InletHumRatCalc = InletHumRat;
12539 :
12540 8636826 : if (AirMassFlow <= 0.00001) {
12541 61 : TotCap = 0.0;
12542 61 : SHR = 0.0;
12543 61 : 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 13246796 : TotCapTempModFac = CurveValue(state, CCapFTemp, InletWetBulbCalc, CondInletTemp);
12550 : // Get capacity modifying factor (function of mass flow) for off-rated conditions
12551 13246796 : TotCapFlowModFac = CurveValue(state, CCapFFlow, AirMassFlowRatio);
12552 : // Get total capacity
12553 13246796 : TotCapCalc = TotCapNom * TotCapFlowModFac * TotCapTempModFac;
12554 :
12555 : // Calculate apparatus dew point conditions using TotCap and CBF
12556 13246796 : hDelta = TotCapCalc / AirMassFlow;
12557 13246796 : hADP = InletEnthalpy - hDelta / (1.0 - CBF);
12558 13246796 : tADP = PsyTsatFnHPb(state, hADP, Pressure);
12559 13246796 : wADP = PsyWFnTdbH(state, tADP, hADP);
12560 13246796 : hTinwADP = PsyHFnTdbW(InletDryBulb, wADP);
12561 13246796 : if ((InletEnthalpy - hADP) > 1.e-10) {
12562 13246796 : 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 13246796 : if (wADP > InletHumRatCalc || (Counter >= 1 && Counter < MaxIter)) {
12568 5806735 : if (InletHumRatCalc == 0.0) {
12569 0 : InletHumRatCalc = MinHumRatCalc;
12570 : }
12571 : // InletHumRatCalc=MAX(InletHumRatCalc,MinHumRatCalc) ! proposed.
12572 :
12573 5806735 : 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 5806735 : InletHumRatCalc = RF * wADP + (1.0 - RF) * InletHumRatCalc;
12578 5806735 : InletWetBulbCalc = PsyTwbFnTdbWPb(state, InletDryBulb, InletHumRatCalc, Pressure);
12579 5806735 : ++Counter;
12580 5806735 : if (std::abs(werror) > Tolerance) {
12581 4610031 : continue; // Recalculate with modified inlet conditions
12582 : }
12583 1196704 : 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 8636765 : if (SHRCalc > 1.0 || Counter > 0) {
12593 1196704 : SHRCalc = 1.0;
12594 : }
12595 :
12596 8636765 : SHR = SHRCalc;
12597 8636765 : TotCap = TotCapCalc;
12598 8636765 : TotCapModFac = TotCapTempModFac * TotCapFlowModFac;
12599 : }
12600 :
12601 6865501 : 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 6865501 : Real64 MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
12631 6865501 : Real64 MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
12632 6865501 : 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 6865501 : 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 6865501 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
12714 :
12715 6865501 : if (thisDXCoil.CondenserInletNodeNum(DXMode) != 0) {
12716 3430422 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).Press;
12717 : // If node is not connected to anything, pressure = default, use weather data
12718 3430422 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
12719 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12720 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
12721 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12722 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
12723 : } else {
12724 3430422 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).Temp;
12725 3430422 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).HumRat;
12726 3430422 : OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, RoutineName);
12727 : }
12728 3430422 : 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 3435079 : } 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 3435079 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12743 3435079 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
12744 3435079 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
12745 3435079 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
12746 : }
12747 :
12748 6865501 : if (SpeedNum > 1) {
12749 1809612 : SpeedNumLS = SpeedNum - 1;
12750 1809612 : SpeedNumHS = SpeedNum;
12751 1809612 : if (SpeedNum > thisDXCoil.NumOfSpeeds) {
12752 0 : SpeedNumLS = thisDXCoil.NumOfSpeeds - 1;
12753 0 : SpeedNumHS = thisDXCoil.NumOfSpeeds;
12754 : }
12755 : } else {
12756 5055889 : SpeedNumLS = 1;
12757 5055889 : SpeedNumHS = 1;
12758 : }
12759 :
12760 6865501 : MSHPWasteHeat = 0.0;
12761 6865501 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
12762 6865501 : AirMassFlowRatioLS = MSHPMassFlowRateLow / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS);
12763 6865501 : AirMassFlowRatioHS = MSHPMassFlowRateHigh / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS);
12764 6865501 : 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 6865501 : } 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 6865501 : thisDXCoil.PartLoadRatio = 0.0;
12799 6865501 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
12800 6865501 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
12801 6865501 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
12802 6865501 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
12803 6865501 : 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 6865501 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure, RoutineName);
12808 6865501 : if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Air) {
12809 6865501 : 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 6865501 : if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
12816 3426752 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
12817 3426752 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
12818 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
12819 : }
12820 : } else {
12821 3438749 : CrankcaseHeatingPower = 0.0;
12822 : }
12823 :
12824 5793706 : if ((AirMassFlow > 0.0 && CondInletTemp >= thisDXCoil.MinOATCompressor) && (thisDXCoil.availSched->getCurrentVal() > 0.0) &&
12825 12659207 : ((SpeedRatio > 0.0 && SingleMode == 0) || CycRatio > 0.0) && (compressorOp == HVAC::CompressorOp::On)) {
12826 :
12827 2105288 : RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat, RoutineName);
12828 2105288 : 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 1269227 : 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 1269227 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumLS);
12835 1269227 : if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
12836 1759155 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
12837 489928 : state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
12838 489928 : if (thisDXCoil.MSErrIndex(SpeedNumLS) == 0) {
12839 64 : ShowWarningMessage(
12840 : state,
12841 64 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
12842 32 : thisDXCoil.DXCoilType,
12843 32 : thisDXCoil.Name,
12844 : SpeedNumLS));
12845 64 : ShowContinueErrorTimeStamp(state, "");
12846 64 : ShowContinueError(state,
12847 64 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
12848 32 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12849 32 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12850 : VolFlowperRatedTotCap));
12851 64 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
12852 96 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
12853 : }
12854 3919424 : ShowRecurringWarningErrorAtEnd(state,
12855 979856 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
12856 : "at speed {} error continues...",
12857 489928 : thisDXCoil.DXCoilType,
12858 489928 : 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 1269227 : 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 1269227 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumHS);
12870 1269227 : if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
12871 1390528 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
12872 121301 : state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
12873 121301 : if (thisDXCoil.MSErrIndex(SpeedNumHS) == 0) {
12874 32 : ShowWarningMessage(
12875 : state,
12876 32 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
12877 16 : thisDXCoil.DXCoilType,
12878 16 : thisDXCoil.Name,
12879 : SpeedNumHS));
12880 32 : ShowContinueErrorTimeStamp(state, "");
12881 32 : ShowContinueError(state,
12882 32 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
12883 16 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12884 16 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
12885 : VolFlowperRatedTotCap));
12886 32 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
12887 48 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
12888 : }
12889 970408 : ShowRecurringWarningErrorAtEnd(state,
12890 242602 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
12891 : "at speed {} error continues...",
12892 121301 : thisDXCoil.DXCoilType,
12893 121301 : 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 1269227 : RatedCBFHS = thisDXCoil.MSRatedCBF(SpeedNumHS);
12902 1269227 : CBFHS = AdjustCBF(RatedCBFHS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS), MSHPMassFlowRateHigh);
12903 1269227 : RatedCBFLS = thisDXCoil.MSRatedCBF(SpeedNumLS);
12904 1269227 : CBFLS = AdjustCBF(RatedCBFLS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS), MSHPMassFlowRateLow);
12905 : // get low speed total capacity and SHR at current conditions
12906 3807681 : CalcTotCapSHR(state,
12907 : InletAirDryBulbTemp,
12908 : InletAirHumRat,
12909 : InletAirEnthalpy,
12910 : InletAirWetBulbC,
12911 : AirMassFlowRatioLS,
12912 : MSHPMassFlowRateLow,
12913 1269227 : thisDXCoil.MSRatedTotCap(SpeedNumLS),
12914 : CBFLS,
12915 1269227 : thisDXCoil.MSCCapFTemp(SpeedNumLS),
12916 1269227 : thisDXCoil.MSCCapFFlow(SpeedNumLS),
12917 : TotCapLS,
12918 : SHRLS,
12919 : CondInletTemp,
12920 : OutdoorPressure,
12921 1269227 : thisDXCoil.capModFacTotal);
12922 : // get low speed outlet conditions
12923 1269227 : hDelta = TotCapLS / MSHPMassFlowRateLow;
12924 : // Calculate new apparatus dew point conditions
12925 1269227 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBFLS);
12926 1269227 : 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 1269227 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
12930 1269227 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
12931 : // get corresponding SHR
12932 1269227 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
12933 1269227 : 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 1269227 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
12940 1269227 : hTinwout = InletAirEnthalpy - (1.0 - SHRLS) * hDelta;
12941 1269227 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
12942 1269227 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
12943 1269227 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineName);
12944 1269227 : if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
12945 630 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
12946 630 : LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineName);
12947 : }
12948 :
12949 : // get high speed total capacity and SHR at current conditions
12950 :
12951 3807681 : CalcTotCapSHR(state,
12952 : InletAirDryBulbTemp,
12953 : InletAirHumRat,
12954 : InletAirEnthalpy,
12955 : InletAirWetBulbC,
12956 : AirMassFlowRatioHS,
12957 : MSHPMassFlowRateHigh,
12958 1269227 : thisDXCoil.MSRatedTotCap(SpeedNumHS),
12959 : CBFHS,
12960 1269227 : thisDXCoil.MSCCapFTemp(SpeedNumHS),
12961 1269227 : thisDXCoil.MSCCapFFlow(SpeedNumHS),
12962 : TotCapHS,
12963 : SHRHS,
12964 : CondInletTemp,
12965 : OutdoorPressure,
12966 1269227 : thisDXCoil.capModFacTotal);
12967 1269227 : hDelta = TotCapHS / MSHPMassFlowRateHigh;
12968 : // Calculate new apparatus dew point conditions
12969 1269227 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBFHS);
12970 1269227 : 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 1269227 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
12974 1269227 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
12975 : // get corresponding SHR
12976 1269227 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
12977 1269227 : 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 1269227 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNumHS), SpeedRatio);
12984 1269227 : if (PLF < 0.7) {
12985 0 : PLF = 0.7;
12986 : }
12987 : // calculate the run time fraction
12988 1269227 : thisDXCoil.CoolingCoilRuntimeFraction = SpeedRatio / PLF;
12989 1269227 : thisDXCoil.PartLoadRatio = SpeedRatio;
12990 :
12991 1269227 : 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 1269227 : HSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
12997 1269227 : hTinwout = InletAirEnthalpy - (1.0 - SHRHS) * hDelta;
12998 1269227 : HSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
12999 1269227 : HSOutletAirDryBulbTemp = PsyTdbFnHW(HSOutletAirEnthalpy, HSOutletAirHumRat);
13000 1269227 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, HSOutletAirEnthalpy, OutdoorPressure, RoutineName);
13001 1269227 : if (HSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
13002 634 : HSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
13003 634 : 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 1269227 : 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 1269227 : EIRTempModFacHS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), InletAirWetBulbC, CondInletTemp);
13036 1269227 : EIRFlowModFacHS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumHS), AirMassFlowRatioHS);
13037 1269227 : EIRHS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumHS) * EIRFlowModFacHS * EIRTempModFacHS;
13038 : // get low speed EIR at current conditions
13039 1269227 : EIRTempModFacLS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), InletAirWetBulbC, CondInletTemp);
13040 1269227 : EIRFlowModFacLS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumLS), AirMassFlowRatioLS);
13041 1269227 : EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumLS) * EIRTempModFacLS * EIRFlowModFacLS;
13042 :
13043 : // get current total capacity, SHR, EIR
13044 1269227 : if (SpeedRatio >= 1.0) {
13045 702035 : SHR = SHRHS;
13046 702035 : EIR = EIRHS;
13047 702035 : CondAirMassFlow = RhoAir * thisDXCoil.MSEvapCondAirFlow(SpeedNumHS);
13048 702035 : EvapCondPumpElecPower = thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumHS);
13049 : } else {
13050 567192 : EIR = SpeedRatio * EIRHS + (1.0 - SpeedRatio) * EIRLS;
13051 567192 : SHR = SpeedRatio * SHRHS + (1.0 - SpeedRatio) * SHRLS;
13052 567192 : CondAirMassFlow =
13053 567192 : RhoAir * (SpeedRatio * thisDXCoil.MSEvapCondAirFlow(SpeedNumHS) + (1.0 - SpeedRatio) * thisDXCoil.MSEvapCondAirFlow(SpeedNumLS));
13054 567192 : EvapCondPumpElecPower = SpeedRatio * thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumHS) +
13055 567192 : (1.0 - SpeedRatio) * thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumLS);
13056 : }
13057 :
13058 : // Outlet calculation
13059 1269227 : Real64 SensibleOutputLS(0.0); // low speed sensible output rate
13060 1269227 : Real64 LatentOutputLS(0.0); // low speed latent output rate
13061 1269227 : Real64 TotalOutputLS(0.0); // low speed total output rate
13062 1269227 : Real64 SensibleOutputHS(0.0); // high speed sensible output rate
13063 1269227 : Real64 LatentOutputHS(0.0); // high speed latent output rate
13064 1269227 : Real64 TotalOutputHS(0.0); // high speed total output rate
13065 1269227 : CalcComponentSensibleLatentOutput(MSHPMassFlowRateLow,
13066 : InletAirDryBulbTemp,
13067 : InletAirHumRat,
13068 : LSOutletAirDryBulbTemp,
13069 : LSOutletAirHumRat,
13070 : SensibleOutputLS,
13071 : LatentOutputLS,
13072 : TotalOutputLS);
13073 1269227 : CalcComponentSensibleLatentOutput(MSHPMassFlowRateHigh,
13074 : InletAirDryBulbTemp,
13075 : InletAirHumRat,
13076 : HSOutletAirDryBulbTemp,
13077 : HSOutletAirHumRat,
13078 : SensibleOutputHS,
13079 : LatentOutputHS,
13080 : TotalOutputHS);
13081 1269227 : thisDXCoil.TotalCoolingEnergyRate = TotalOutputHS * SpeedRatio + TotalOutputLS * (1.0 - SpeedRatio);
13082 1269227 : thisDXCoil.SensCoolingEnergyRate = SensibleOutputHS * SpeedRatio + SensibleOutputLS * (1.0 - SpeedRatio);
13083 1269227 : thisDXCoil.LatCoolingEnergyRate = LatentOutputHS * SpeedRatio + LatentOutputLS * (1.0 - SpeedRatio);
13084 : // Average outlet enthalpy
13085 1269227 : OutletAirEnthalpy = InletAirEnthalpy - thisDXCoil.TotalCoolingEnergyRate / thisDXCoil.InletAirMassFlowRate;
13086 :
13087 1269227 : if (fanOp == HVAC::FanOp::Cycling) {
13088 207793 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
13089 : }
13090 : // Update outlet conditions
13091 1269227 : if (SpeedRatio == 0.0 && fanOp == HVAC::FanOp::Cycling) {
13092 6743 : OutletAirEnthalpy = LSOutletAirEnthalpy;
13093 6743 : OutletAirHumRat = LSOutletAirHumRat;
13094 6743 : OutletAirDryBulbTemp = LSOutletAirDryBulbTemp;
13095 1262484 : } else if (SpeedRatio >= 1.0 && fanOp == HVAC::FanOp::Cycling) {
13096 152096 : OutletAirEnthalpy = HSOutletAirEnthalpy;
13097 152096 : OutletAirHumRat = HSOutletAirHumRat;
13098 152096 : OutletAirDryBulbTemp = HSOutletAirDryBulbTemp;
13099 : } else {
13100 1110388 : OutletAirHumRat =
13101 1110388 : ((HSOutletAirHumRat * SpeedRatio * MSHPMassFlowRateHigh) + (LSOutletAirHumRat * (1.0 - SpeedRatio) * MSHPMassFlowRateLow)) /
13102 1110388 : thisDXCoil.InletAirMassFlowRate;
13103 1110388 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
13104 1110388 : if (OutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
13105 8946 : OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
13106 8946 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy, RoutineName);
13107 8946 : CalcComponentSensibleLatentOutput(AirMassFlow,
13108 : InletAirDryBulbTemp,
13109 : InletAirHumRat,
13110 : OutletAirDryBulbTemp,
13111 : OutletAirHumRat,
13112 8946 : thisDXCoil.SensCoolingEnergyRate,
13113 8946 : thisDXCoil.LatCoolingEnergyRate,
13114 8946 : thisDXCoil.TotalCoolingEnergyRate);
13115 : }
13116 : }
13117 :
13118 1269227 : LSElecCoolingPower = TotCapLS * EIRLS;
13119 1269227 : HSElecCoolingPower = TotCapHS * EIRHS;
13120 :
13121 : // Power calculation
13122 1269227 : if (!thisDXCoil.PLRImpact) {
13123 1269227 : 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 1269227 : thisDXCoil.CoolingCoilRuntimeFraction = 1.0;
13130 :
13131 : // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
13132 1269227 : 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 1269227 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13138 317468 : if (thisDXCoil.MSWasteHeat(SpeedNumLS) == 0) {
13139 0 : WasteHeatLS = thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13140 : } else {
13141 317468 : WasteHeatLS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumLS), OutdoorDryBulb, InletAirDryBulbTemp) *
13142 317468 : thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13143 : }
13144 317468 : if (thisDXCoil.MSWasteHeat(SpeedNumHS) == 0) {
13145 0 : WasteHeatHS = thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13146 : } else {
13147 317468 : WasteHeatHS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumHS), OutdoorDryBulb, InletAirDryBulbTemp) *
13148 317468 : thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13149 : }
13150 317468 : thisDXCoil.MSFuelWasteHeat = (SpeedRatio * WasteHeatHS + (1.0 - SpeedRatio) * WasteHeatLS) * thisDXCoil.ElecCoolingPower;
13151 317468 : if (thisDXCoil.MSHPHeatRecActive) {
13152 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
13153 : }
13154 : }
13155 :
13156 : // Energy use for other fuel types
13157 1269227 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13158 317468 : thisDXCoil.FuelUsed = thisDXCoil.ElecCoolingPower;
13159 317468 : thisDXCoil.ElecCoolingPower = 0.0;
13160 : }
13161 :
13162 1269227 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
13163 1269227 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
13164 1269227 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
13165 1269227 : thisDXCoil.CrankcaseHeaterPower = 0.0;
13166 :
13167 2105288 : } else if (CycRatio > 0.0) {
13168 :
13169 836061 : if (fanOp == HVAC::FanOp::Cycling) {
13170 487183 : AirMassFlow /= CycRatio;
13171 : }
13172 836061 : if (fanOp == HVAC::FanOp::Continuous) {
13173 348878 : AirMassFlow = MSHPMassFlowRateHigh;
13174 : }
13175 :
13176 : // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at low speed
13177 836061 : 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 836061 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNum);
13181 836061 : if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13182 1158870 : (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
13183 322809 : state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
13184 310229 : if (thisDXCoil.MSErrIndex(SpeedNum) == 0) {
13185 2 : ShowWarningMessage(
13186 : state,
13187 2 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
13188 1 : thisDXCoil.DXCoilType,
13189 1 : thisDXCoil.Name,
13190 : SpeedNum));
13191 2 : ShowContinueErrorTimeStamp(state, "");
13192 2 : ShowContinueError(state,
13193 2 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13194 1 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13195 1 : HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13196 : VolFlowperRatedTotCap));
13197 2 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13198 3 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13199 : }
13200 2481832 : ShowRecurringWarningErrorAtEnd(state,
13201 620458 : format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
13202 : "at speed {} error continues...",
13203 310229 : thisDXCoil.DXCoilType,
13204 310229 : thisDXCoil.Name,
13205 : SpeedNumHS),
13206 : thisDXCoil.MSErrIndex(SpeedNumHS),
13207 : VolFlowperRatedTotCap,
13208 : VolFlowperRatedTotCap);
13209 : }
13210 :
13211 836061 : 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 836061 : RatedCBFLS = thisDXCoil.MSRatedCBF(SpeedNum);
13218 836061 : 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 2508183 : CalcTotCapSHR(state,
13224 : InletAirDryBulbTemp,
13225 : InletAirHumRat,
13226 : InletAirEnthalpy,
13227 : InletAirWetBulbC,
13228 : AirMassFlowRatioLS,
13229 : MSHPMassFlowRateHigh,
13230 836061 : thisDXCoil.MSRatedTotCap(SpeedNum),
13231 : CBFLS,
13232 836061 : thisDXCoil.MSCCapFTemp(SpeedNum),
13233 836061 : thisDXCoil.MSCCapFFlow(SpeedNum),
13234 : TotCapLS,
13235 : SHRLS,
13236 : CondInletTemp,
13237 : OutdoorPressure,
13238 836061 : 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 836061 : hDelta = TotCapLS / AirMassFlow;
13242 : // Adjust CBF for off-nominal flow
13243 836061 : CBF = AdjustCBF(thisDXCoil.MSRatedCBF(SpeedNum), thisDXCoil.MSRatedAirMassFlowRate(SpeedNum), AirMassFlow);
13244 : // Calculate new apparatus dew point conditions
13245 836061 : hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
13246 836061 : 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 836061 : wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
13250 836061 : hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
13251 : // get corresponding SHR
13252 836061 : if ((InletAirEnthalpy - hADP) > 1.e-10) {
13253 836061 : 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 836061 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNum), CycRatio);
13261 836061 : 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 836061 : if (PLF < 0.7) {
13274 0 : PLF = 0.7;
13275 : }
13276 : // calculate the run time fraction
13277 836061 : thisDXCoil.CoolingCoilRuntimeFraction = CycRatio / PLF;
13278 836061 : thisDXCoil.PartLoadRatio = CycRatio;
13279 :
13280 836061 : 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 836061 : LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
13286 836061 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
13287 836061 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
13288 836061 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
13289 836061 : OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineName);
13290 836061 : if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
13291 321 : LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
13292 321 : 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 836061 : if (fanOp == HVAC::FanOp::Continuous) {
13298 348878 : QLatRated = thisDXCoil.MSRatedTotCap(SpeedNum) * (1.0 - thisDXCoil.MSRatedSHR(SpeedNum));
13299 348878 : QLatActual = TotCapLS * (1.0 - SHR);
13300 348878 : SHRUnadjusted = SHR;
13301 348878 : 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 348878 : if (SHR > 1.0) {
13312 0 : SHR = 1.0;
13313 : }
13314 348878 : hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
13315 348878 : if (SHR < 1.0) {
13316 244591 : LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
13317 : } else {
13318 104287 : LSOutletAirHumRat = InletAirHumRat;
13319 : }
13320 348878 : LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
13321 : }
13322 :
13323 836061 : if (fanOp == HVAC::FanOp::Cycling) {
13324 487183 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
13325 : }
13326 836061 : if (fanOp == HVAC::FanOp::Continuous) {
13327 : // outlet conditions are average of inlet and low speed weighted by CycRatio
13328 : // Continuous fan, cycling compressor
13329 348878 : Real64 CycAirFlowRatio =
13330 348878 : CycRatio * AirMassFlow / thisDXCoil.InletAirMassFlowRate; // ratio of compressor on airflow to average timestep airflow
13331 348878 : OutletAirEnthalpy = CycAirFlowRatio * LSOutletAirEnthalpy + (1.0 - CycAirFlowRatio) * InletAirEnthalpy;
13332 348878 : OutletAirHumRat = CycAirFlowRatio * LSOutletAirHumRat + (1.0 - CycAirFlowRatio) * InletAirHumRat;
13333 348878 : OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
13334 : } else {
13335 487183 : OutletAirHumRat = LSOutletAirHumRat;
13336 487183 : OutletAirDryBulbTemp = LSOutletAirDryBulbTemp;
13337 487183 : OutletAirEnthalpy = LSOutletAirEnthalpy;
13338 : }
13339 :
13340 : // get low speed EIR at current conditions
13341 836061 : EIRTempModFacLS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNum), InletAirWetBulbC, CondInletTemp);
13342 836061 : EIRFlowModFacLS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNum), AirMassFlowRatioLS);
13343 836061 : EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNum) * EIRTempModFacLS * EIRFlowModFacLS;
13344 :
13345 : // get the electrical power consumption
13346 836061 : thisDXCoil.ElecCoolingPower = TotCapLS * EIRLS * thisDXCoil.CoolingCoilRuntimeFraction;
13347 : // calculate cooling output power
13348 : // AirMassFlow = DXCoil(DXCoilNum)%InletAirMassFlowRate
13349 836061 : CalcComponentSensibleLatentOutput(AirMassFlow,
13350 : InletAirDryBulbTemp,
13351 : InletAirHumRat,
13352 : LSOutletAirDryBulbTemp,
13353 : LSOutletAirHumRat,
13354 836061 : thisDXCoil.SensCoolingEnergyRate,
13355 836061 : thisDXCoil.LatCoolingEnergyRate,
13356 836061 : thisDXCoil.TotalCoolingEnergyRate);
13357 836061 : thisDXCoil.TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate * CycRatio;
13358 836061 : thisDXCoil.SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate * CycRatio;
13359 836061 : 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 836061 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
13363 836061 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
13364 836061 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
13365 836061 : thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
13366 836061 : CondAirMassFlow = RhoAir * thisDXCoil.MSEvapCondAirFlow(SpeedNum) * thisDXCoil.CoolingCoilRuntimeFraction;
13367 836061 : EvapCondPumpElecPower = thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNum) * thisDXCoil.CoolingCoilRuntimeFraction;
13368 :
13369 : // Waste heat
13370 836061 : 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 836061 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13383 98244 : thisDXCoil.FuelUsed = thisDXCoil.ElecCoolingPower;
13384 98244 : thisDXCoil.ElecCoolingPower = 0.0;
13385 : }
13386 :
13387 836061 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
13388 836061 : 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 2105288 : 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 4760213 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
13424 4760213 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
13425 4760213 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
13426 :
13427 4760213 : thisDXCoil.FuelUsed = 0.0;
13428 4760213 : thisDXCoil.ElecCoolingPower = 0.0;
13429 4760213 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
13430 4760213 : thisDXCoil.SensCoolingEnergyRate = 0.0;
13431 4760213 : thisDXCoil.LatCoolingEnergyRate = 0.0;
13432 4760213 : thisDXCoil.EvapCondPumpElecPower = 0.0;
13433 4760213 : thisDXCoil.EvapWaterConsumpRate = 0.0;
13434 :
13435 4760213 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
13436 4760213 : 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 4760213 : 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 6865501 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
13453 6865501 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
13454 6865501 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
13455 6865501 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
13456 6865501 : thisDXCoil.CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure
13457 :
13458 : // set outlet node conditions
13459 6865501 : int airOutletNode = thisDXCoil.AirOutNode;
13460 6865501 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
13461 6865501 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
13462 :
13463 : // calc secondary coil if specified
13464 6865501 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
13465 0 : CalcSecondaryDXCoils(state, DXCoilNum);
13466 : }
13467 6865501 : }
13468 :
13469 6847941 : 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 6847941 : Real64 MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
13497 6847941 : Real64 MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
13498 6847941 : 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 6847941 : 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 6847941 : 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 6847941 : FullLoadOutAirEnth = 0.0; // Autodesk:Uninit Force default initialization
13568 :
13569 6847941 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
13570 :
13571 6847941 : if (SpeedNum > 1) {
13572 1207252 : SpeedNumLS = SpeedNum - 1;
13573 1207252 : SpeedNumHS = SpeedNum;
13574 1207252 : if (SpeedNum > thisDXCoil.NumOfSpeeds) {
13575 0 : SpeedNumLS = thisDXCoil.NumOfSpeeds - 1;
13576 0 : SpeedNumHS = thisDXCoil.NumOfSpeeds;
13577 : }
13578 : } else {
13579 5640689 : SpeedNumLS = 1;
13580 5640689 : SpeedNumHS = 1;
13581 : }
13582 :
13583 6847941 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
13584 6847941 : AirMassFlowRatioLS = MSHPMassFlowRateLow / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS);
13585 6847941 : AirMassFlowRatioHS = MSHPMassFlowRateHigh / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS);
13586 6847941 : 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 6847941 : } 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 6847941 : AirFlowRatio = 1.0;
13621 6847941 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
13622 2803453 : MSHPWasteHeat = 0.0;
13623 : }
13624 :
13625 : // Get condenser outdoor node info from DX Heating Coil
13626 6847941 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
13627 2703794 : OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press;
13628 : // If node is not connected to anything, pressure = default, use weather data
13629 2703794 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
13630 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13631 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13632 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13633 : } else {
13634 2703794 : OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp;
13635 2703794 : OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat;
13636 : }
13637 2703794 : 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 4144147 : } 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 4144147 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13652 4144147 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13653 4144147 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13654 : }
13655 :
13656 6847941 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
13657 6847941 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
13658 6847941 : 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 6847941 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure, RoutineName);
13663 6847941 : PLRHeating = 0.0;
13664 6847941 : thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
13665 : // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
13666 6847941 : if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
13667 2856635 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
13668 2856635 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
13669 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
13670 : }
13671 : } else {
13672 3991306 : CrankcaseHeatingPower = 0.0;
13673 : }
13674 6847941 : thisDXCoil.PartLoadRatio = 0.0;
13675 6847941 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
13676 :
13677 7857774 : if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && ((CycRatio > 0.0) || (SpeedRatio > 0.0 && SingleMode == 0)) &&
13678 1009833 : OutdoorDryBulb > thisDXCoil.MinOATCompressor) {
13679 :
13680 1009833 : 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 305149 : 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 305149 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumLS);
13687 610298 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13688 305149 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
13689 283862 : if (thisDXCoil.MSErrIndex(SpeedNumLS) == 0) {
13690 8 : ShowWarningMessage(
13691 : state,
13692 8 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed {}.",
13693 4 : thisDXCoil.DXCoilType,
13694 4 : thisDXCoil.Name,
13695 : SpeedNumLS));
13696 8 : ShowContinueErrorTimeStamp(state, "");
13697 8 : ShowContinueError(state,
13698 8 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13699 4 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13700 4 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13701 : VolFlowperRatedTotCap));
13702 8 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13703 12 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13704 : }
13705 2270896 : ShowRecurringWarningErrorAtEnd(state,
13706 567724 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range "
13707 : "at speed {} error continues...",
13708 283862 : thisDXCoil.DXCoilType,
13709 283862 : 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 305149 : 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 305149 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumHS);
13721 610298 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
13722 305149 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
13723 283646 : if (thisDXCoil.MSErrIndex(SpeedNumHS) == 0) {
13724 4 : ShowWarningMessage(
13725 : state,
13726 4 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed {}.",
13727 2 : thisDXCoil.DXCoilType,
13728 2 : thisDXCoil.Name,
13729 : SpeedNumHS));
13730 4 : ShowContinueErrorTimeStamp(state, "");
13731 4 : ShowContinueError(state,
13732 4 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
13733 2 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13734 2 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
13735 : VolFlowperRatedTotCap));
13736 4 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
13737 6 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
13738 : }
13739 2269168 : ShowRecurringWarningErrorAtEnd(state,
13740 567292 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range "
13741 : "at speed {} error continues...",
13742 283646 : thisDXCoil.DXCoilType,
13743 283646 : 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 305149 : if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNumLS))->numDims == 1) {
13756 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumLS), OutdoorDryBulb);
13757 : } else {
13758 305149 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumLS), InletAirDryBulbTemp, OutdoorDryBulb);
13759 : }
13760 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
13761 305149 : TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNumLS), AirMassFlowRatioLS);
13762 : // Calculate total heating capacity for off-rated conditions
13763 305149 : TotCapLS = thisDXCoil.MSRatedTotCap(SpeedNumLS) * TotCapFlowModFac * TotCapTempModFac;
13764 : // High speed
13765 305149 : if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNumHS))->numDims == 1) {
13766 0 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumHS), OutdoorDryBulb);
13767 : } else {
13768 305149 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumHS), InletAirDryBulbTemp, OutdoorDryBulb);
13769 : }
13770 : // Get total capacity modifying factor (function of mass flow) for off-rated conditions
13771 305149 : TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNumHS), AirMassFlowRatioHS);
13772 : // Calculate total heating capacity for off-rated conditions
13773 305149 : 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 305149 : if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(SpeedNumLS))->numDims == 1) {
13780 0 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), OutdoorDryBulb);
13781 : } else {
13782 305149 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), InletAirDryBulbTemp, OutdoorDryBulb);
13783 : }
13784 305149 : EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumLS), AirMassFlowRatioLS);
13785 305149 : EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumLS) * EIRTempModFac * EIRFlowModFac;
13786 : // High Speed
13787 305149 : if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(SpeedNumHS))->numDims == 1) {
13788 0 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), OutdoorDryBulb);
13789 : } else {
13790 305149 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), InletAirDryBulbTemp, OutdoorDryBulb);
13791 : }
13792 305149 : EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumHS), AirMassFlowRatioHS);
13793 305149 : 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 305149 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
13798 305149 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure, RoutineName)));
13799 :
13800 : // Initializing defrost adjustment factors
13801 305149 : LoadDueToDefrostLS = 0.0;
13802 305149 : LoadDueToDefrostHS = 0.0;
13803 305149 : HeatingCapacityMultiplier = 1.0;
13804 305149 : FractionalDefrostTime = 0.0;
13805 305149 : InputPowerMultiplier = 1.0;
13806 305149 : DefrostPowerLS = 0.0;
13807 305149 : DefrostPowerHS = 0.0;
13808 :
13809 : // Check outdoor temperature to determine if defrost is active
13810 305149 : if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost) {
13811 : // Calculate defrost adjustment factors depending on defrost control type
13812 303898 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
13813 303898 : FractionalDefrostTime = thisDXCoil.DefrostTime;
13814 303898 : if (FractionalDefrostTime > 0.0) {
13815 303898 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13816 0 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
13817 0 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
13818 : } else {
13819 303898 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
13820 303898 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
13821 303898 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
13822 0 : ShowWarningMessage(
13823 : state,
13824 0 : 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 0 : thisDXCoil.Name));
13827 0 : 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 303898 : if (FractionalDefrostTime > 0.0) {
13850 : // Calculate defrost adjustment factors depending on defrost control strategy
13851 303898 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
13852 303898 : DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
13853 303898 : LoadDueToDefrostLS =
13854 303898 : (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(SpeedNumLS) / 1.01667);
13855 303898 : DefrostPowerLS = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(SpeedNumLS) / 1.01667) * FractionalDefrostTime;
13856 303898 : LoadDueToDefrostHS =
13857 303898 : (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(SpeedNumHS) / 1.01667);
13858 303898 : DefrostPowerHS = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(SpeedNumHS) / 1.01667) * FractionalDefrostTime;
13859 : } else { // Defrost strategy is resistive
13860 0 : thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
13861 : }
13862 : } else { // Defrost is not active because (OutDryBulbTemp .GT. DXCoil(DXCoilNum)%MaxOATDefrost)
13863 0 : thisDXCoil.DefrostPower = 0.0;
13864 : }
13865 : }
13866 :
13867 305149 : TotCapLSAdj = TotCapLS * HeatingCapacityMultiplier;
13868 305149 : TotCapHSAdj = TotCapHS * HeatingCapacityMultiplier;
13869 :
13870 : // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
13871 305149 : PLRHeating = min(1.0, (SpeedRatio + LoadDueToDefrostHS / TotCapHSAdj));
13872 305149 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNumHS), PLRHeating); // Calculate part-load factor
13873 :
13874 305149 : 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 305149 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
13891 305149 : 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 305149 : } 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 305149 : LSFullLoadOutAirEnth = InletAirEnthalpy + TotCapLSAdj / MSHPMassFlowRateLow;
13913 305149 : HSFullLoadOutAirEnth = InletAirEnthalpy + TotCapHSAdj / MSHPMassFlowRateHigh;
13914 305149 : LSElecHeatingPower = TotCapLS * EIRLS * InputPowerMultiplier;
13915 305149 : HSElecHeatingPower = TotCapHS * EIRHS * InputPowerMultiplier;
13916 305149 : OutletAirHumRat = InletAirHumRat;
13917 :
13918 : // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
13919 305149 : if (fanOp == HVAC::FanOp::Cycling) {
13920 300659 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
13921 : }
13922 :
13923 : // Power calculation
13924 305149 : if (!thisDXCoil.PLRImpact) {
13925 305149 : 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 305149 : thisDXCoil.TotalHeatingEnergyRate = MSHPMassFlowRateHigh * (HSFullLoadOutAirEnth - InletAirEnthalpy) * SpeedRatio +
13932 305149 : MSHPMassFlowRateLow * (LSFullLoadOutAirEnth - InletAirEnthalpy) * (1.0 - SpeedRatio);
13933 305149 : OutletAirEnthalpy = InletAirEnthalpy + thisDXCoil.TotalHeatingEnergyRate / thisDXCoil.InletAirMassFlowRate;
13934 305149 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
13935 305149 : FullLoadOutAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, OutdoorPressure, RoutineNameAverageLoad);
13936 305149 : 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 305149 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13947 0 : if (thisDXCoil.MSWasteHeat(SpeedNumLS) == 0) {
13948 0 : WasteHeatLS = thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13949 : } else {
13950 0 : WasteHeatLS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumLS), OutdoorDryBulb, InletAirDryBulbTemp) *
13951 0 : thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
13952 : }
13953 0 : if (thisDXCoil.MSWasteHeat(SpeedNumHS) == 0) {
13954 0 : WasteHeatHS = thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13955 : } else {
13956 0 : WasteHeatHS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumHS), OutdoorDryBulb, InletAirDryBulbTemp) *
13957 0 : thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
13958 : }
13959 0 : thisDXCoil.MSFuelWasteHeat = (SpeedRatio * WasteHeatHS + (1.0 - SpeedRatio) * WasteHeatLS) * thisDXCoil.ElecCoolingPower;
13960 0 : if (thisDXCoil.MSHPHeatRecActive) {
13961 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
13962 : }
13963 : }
13964 305149 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
13965 :
13966 0 : thisDXCoil.FuelUsed = thisDXCoil.ElecHeatingPower;
13967 0 : 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 305149 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
13973 305149 : if (!thisDXCoil.PLRImpact) {
13974 305149 : 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 305149 : thisDXCoil.OutletAirTemp = OutletAirTemp;
13981 305149 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
13982 305149 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
13983 305149 : thisDXCoil.CrankcaseHeaterPower = 0.0;
13984 :
13985 : // Stage 1
13986 704684 : } else if (CycRatio > 0.0 || (CycRatio > 0.0 && SingleMode == 1)) {
13987 :
13988 : // for cycling fan, reset mass flow to full on rate
13989 704684 : if (fanOp == HVAC::FanOp::Cycling) {
13990 118669 : AirMassFlow /= CycRatio;
13991 : }
13992 704684 : if (fanOp == HVAC::FanOp::Continuous) {
13993 586015 : AirMassFlow = MSHPMassFlowRateHigh;
13994 : }
13995 : // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton)
13996 704684 : 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 704684 : VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNum);
14000 :
14001 1409368 : if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
14002 704684 : (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
14003 693793 : if (thisDXCoil.ErrIndex1 == 0) {
14004 12 : ShowWarningMessage(state,
14005 12 : format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed 1.",
14006 6 : thisDXCoil.DXCoilType,
14007 6 : thisDXCoil.Name));
14008 12 : ShowContinueErrorTimeStamp(state, "");
14009 12 : ShowContinueError(state,
14010 12 : format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
14011 6 : HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
14012 6 : HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
14013 : VolFlowperRatedTotCap));
14014 12 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
14015 18 : ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
14016 : }
14017 5550344 : ShowRecurringWarningErrorAtEnd(
14018 : state,
14019 1387586 : 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 693793 : 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 704684 : if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNum))->numDims == 1) {
14031 633808 : TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNum), OutdoorDryBulb);
14032 : } else {
14033 70876 : 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 704684 : TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNum), AirMassFlowRatioLS);
14040 : // Calculate total heating capacity for off-rated conditions
14041 704684 : 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 704684 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
14046 704684 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure, RoutineName)));
14047 :
14048 : // Initializing defrost adjustment factors
14049 704684 : LoadDueToDefrost = 0.0;
14050 704684 : HeatingCapacityMultiplier = 1.0;
14051 704684 : FractionalDefrostTime = 0.0;
14052 704684 : InputPowerMultiplier = 1.0;
14053 :
14054 : // Check outdoor temperature to determine of defrost is active
14055 704684 : if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost) {
14056 : // Calculate defrost adjustment factors depending on defrost control type
14057 445264 : if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
14058 445264 : FractionalDefrostTime = thisDXCoil.DefrostTime;
14059 445264 : if (FractionalDefrostTime > 0.0) {
14060 445264 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
14061 0 : HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
14062 0 : InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
14063 : } else {
14064 445264 : HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
14065 445264 : InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
14066 445264 : if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
14067 0 : ShowWarningMessage(
14068 : state,
14069 0 : 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 0 : thisDXCoil.Name));
14072 0 : 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 445264 : if (FractionalDefrostTime > 0.0) {
14095 : // Calculate defrost adjustment factors depending on defrost control strategy
14096 445264 : if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
14097 445264 : LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(1) / 1.01667);
14098 445264 : DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
14099 445264 : thisDXCoil.DefrostPower = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(1) / 1.01667) * FractionalDefrostTime;
14100 : } else { // Defrost strategy is resistive
14101 0 : 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 704684 : TotCapAdj = TotCap * HeatingCapacityMultiplier;
14110 :
14111 : // Calculate full load outlet conditions
14112 704684 : FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
14113 704684 : FullLoadOutAirHumRat = InletAirHumRat;
14114 704684 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
14115 704684 : 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 704684 : 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 704684 : OutletAirEnthalpy = FullLoadOutAirEnth;
14127 704684 : OutletAirHumRat = FullLoadOutAirHumRat;
14128 704684 : 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 704684 : if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(1))->numDims == 1) {
14134 633808 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(1), OutdoorDryBulb);
14135 : } else {
14136 70876 : EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(1), InletAirDryBulbTemp, OutdoorDryBulb);
14137 : }
14138 704684 : EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(1), AirMassFlowRatioLS);
14139 704684 : EIR = 1.0 / thisDXCoil.MSRatedCOP(1) * EIRTempModFac * EIRFlowModFac;
14140 : // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
14141 704684 : PLRHeating = min(1.0, (CycRatio + LoadDueToDefrost / TotCapAdj));
14142 704684 : PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(1), PLRHeating); // Calculate part-load factor
14143 704684 : 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 704684 : 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 704684 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
14169 704684 : 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 704684 : } 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 704684 : if (fanOp == HVAC::FanOp::Cycling) {
14190 118669 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
14191 : }
14192 704684 : 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 704684 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
14198 350487 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
14199 : } else {
14200 354197 : thisDXCoil.CrankcaseHeaterPower =
14201 354197 : CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
14202 354197 : state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
14203 : }
14204 :
14205 704684 : thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (FullLoadOutAirEnth - InletAirEnthalpy) * CycRatio;
14206 704684 : if (fanOp == HVAC::FanOp::Continuous) {
14207 586015 : OutletAirEnthalpy = InletAirEnthalpy + thisDXCoil.TotalHeatingEnergyRate / thisDXCoil.InletAirMassFlowRate;
14208 586015 : OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
14209 : }
14210 704684 : if (thisDXCoil.MSHPHeatRecActive || thisDXCoil.FuelType != Constant::eFuel::Electricity) {
14211 0 : if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
14212 0 : thisDXCoil.MSFuelWasteHeat = thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecHeatingPower;
14213 : } else {
14214 0 : thisDXCoil.MSFuelWasteHeat = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNum), OutdoorDryBulb, InletAirDryBulbTemp) *
14215 0 : thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecHeatingPower;
14216 : }
14217 0 : if (thisDXCoil.MSHPHeatRecActive) {
14218 0 : MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
14219 : }
14220 : }
14221 704684 : if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
14222 :
14223 0 : thisDXCoil.FuelUsed = thisDXCoil.ElecHeatingPower;
14224 0 : 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 704684 : thisDXCoil.DefrostPower *= thisDXCoil.HeatingCoilRuntimeFraction;
14229 :
14230 704684 : thisDXCoil.OutletAirTemp = OutletAirTemp;
14231 704684 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
14232 704684 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
14233 : }
14234 :
14235 : } else {
14236 :
14237 : // DX coil is off; just pass through conditions
14238 5838108 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
14239 5838108 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
14240 5838108 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
14241 :
14242 5838108 : thisDXCoil.ElecHeatingPower = 0.0;
14243 5838108 : thisDXCoil.FuelUsed = 0.0;
14244 5838108 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
14245 5838108 : 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 5838108 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
14250 2452966 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
14251 : } else {
14252 3385142 : thisDXCoil.CrankcaseHeaterPower =
14253 3385142 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
14254 : }
14255 :
14256 : } // end of on/off if - else
14257 :
14258 6847941 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
14259 6847941 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
14260 6847941 : thisDXCoil.PartLoadRatio = PLRHeating;
14261 6847941 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
14262 6847941 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
14263 6847941 : thisDXCoil.MSSpeedNumLS = SpeedNumLS;
14264 6847941 : thisDXCoil.MSSpeedNumHS = SpeedNumHS;
14265 6847941 : thisDXCoil.MSSpeedRatio = SpeedRatio;
14266 6847941 : thisDXCoil.MSCycRatio = CycRatio;
14267 :
14268 : // set outlet node conditions
14269 6847941 : int airOutletNode = thisDXCoil.AirOutNode;
14270 6847941 : state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
14271 6847941 : state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
14272 :
14273 : // calc secondary coil if specified
14274 6847941 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
14275 0 : CalcSecondaryDXCoils(state, DXCoilNum);
14276 : }
14277 6847941 : }
14278 :
14279 63554260 : 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 63554260 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
14294 :
14295 63554260 : AirOutletNode = thisDXCoil.AirOutNode;
14296 63554260 : AirInletNode = thisDXCoil.AirInNode;
14297 : // changed outputs
14298 63554260 : state.dataLoopNodes->Node(AirOutletNode).Enthalpy = thisDXCoil.OutletAirEnthalpy;
14299 63554260 : state.dataLoopNodes->Node(AirOutletNode).Temp = thisDXCoil.OutletAirTemp;
14300 63554260 : state.dataLoopNodes->Node(AirOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
14301 63554260 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRate = thisDXCoil.InletAirMassFlowRate;
14302 : // pass through outputs
14303 63554260 : state.dataLoopNodes->Node(AirOutletNode).Quality = state.dataLoopNodes->Node(AirInletNode).Quality;
14304 63554260 : state.dataLoopNodes->Node(AirOutletNode).Press = state.dataLoopNodes->Node(AirInletNode).Press;
14305 63554260 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMin = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMin;
14306 63554260 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMax = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax;
14307 63554260 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMinAvail;
14308 63554260 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMaxAvail;
14309 :
14310 63554260 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
14311 1314605 : state.dataLoopNodes->Node(AirOutletNode).CO2 = state.dataLoopNodes->Node(AirInletNode).CO2;
14312 : }
14313 63554260 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
14314 173539 : state.dataLoopNodes->Node(AirOutletNode).GenContam = state.dataLoopNodes->Node(AirInletNode).GenContam;
14315 : }
14316 63554260 : }
14317 :
14318 63554260 : 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 63554260 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
14335 :
14336 63554260 : if (thisDXCoil.reportCoilFinalSizes) {
14337 16882556 : if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->DoingSizing) {
14338 984 : Real64 ratedSensCap(0.0);
14339 984 : ratedSensCap = thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1);
14340 984 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
14341 984 : state, thisDXCoil.Name, thisDXCoil.DXCoilType, thisDXCoil.RatedTotCap(1), ratedSensCap, thisDXCoil.RatedAirVolFlowRate(1), -999.0);
14342 984 : thisDXCoil.reportCoilFinalSizes = false;
14343 : }
14344 : }
14345 :
14346 63554260 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
14347 :
14348 63554260 : switch (thisDXCoil.DXCoilType_Num) {
14349 8113636 : case HVAC::CoilDX_HeatingEmpirical:
14350 : case HVAC::CoilVRF_Heating:
14351 : case HVAC::CoilVRF_FluidTCtrl_Heating: {
14352 8113636 : thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
14353 8113636 : thisDXCoil.ElecHeatingConsumption = thisDXCoil.ElecHeatingPower * ReportingConstant;
14354 8113636 : thisDXCoil.DefrostConsumption = thisDXCoil.DefrostPower * ReportingConstant;
14355 8113636 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14356 8113636 : state.dataHVACGlobal->DXElecHeatingPower = thisDXCoil.ElecHeatingPower + thisDXCoil.CrankcaseHeaterPower;
14357 8113636 : state.dataHVACGlobal->DefrostElecPower = thisDXCoil.DefrostPower;
14358 8113636 : } break;
14359 6847935 : case HVAC::CoilDX_MultiSpeedHeating: {
14360 6847935 : thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
14361 6847935 : if (thisDXCoil.FuelType == Constant::eFuel::Electricity) {
14362 6208683 : thisDXCoil.ElecHeatingConsumption = thisDXCoil.ElecHeatingPower * ReportingConstant;
14363 : } else {
14364 639252 : thisDXCoil.FuelConsumed = thisDXCoil.FuelUsed * ReportingConstant;
14365 : }
14366 6847935 : thisDXCoil.DefrostConsumption = thisDXCoil.DefrostPower * ReportingConstant;
14367 6847935 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14368 6847935 : state.dataHVACGlobal->DXElecHeatingPower = thisDXCoil.ElecHeatingPower + thisDXCoil.CrankcaseHeaterPower;
14369 6847935 : state.dataHVACGlobal->DefrostElecPower = thisDXCoil.DefrostPower;
14370 6847935 : } break;
14371 6865266 : case HVAC::CoilDX_MultiSpeedCooling: {
14372 6865266 : thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
14373 6865266 : thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
14374 6865266 : thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
14375 6865266 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14376 6865266 : state.dataHVACGlobal->DXElecCoolingPower = thisDXCoil.ElecCoolingPower;
14377 6865266 : thisDXCoil.EvapCondPumpElecConsumption = thisDXCoil.EvapCondPumpElecPower * ReportingConstant;
14378 6865266 : thisDXCoil.EvapWaterConsump = thisDXCoil.EvapWaterConsumpRate * ReportingConstant;
14379 6865266 : if (thisDXCoil.FuelType == Constant::eFuel::Electricity) {
14380 5608644 : thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
14381 : } else {
14382 1256622 : thisDXCoil.FuelConsumed = thisDXCoil.FuelUsed * ReportingConstant;
14383 : }
14384 6865266 : if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
14385 0 : thisDXCoil.BasinHeaterConsumption = thisDXCoil.BasinHeaterPower * ReportingConstant;
14386 : }
14387 6865266 : } break;
14388 636362 : case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
14389 : case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
14390 : // water heating energy for HP water heater DX Coil condenser
14391 636362 : thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
14392 : // water heating power for HP water heater
14393 636362 : thisDXCoil.ElecWaterHeatingConsumption = thisDXCoil.ElecWaterHeatingPower * ReportingConstant;
14394 : // other usual DX cooling coil outputs
14395 636362 : thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
14396 636362 : thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
14397 636362 : thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
14398 636362 : thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
14399 636362 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14400 : // DXElecCoolingPower global is only used for air-to-air cooling and heating coils
14401 636362 : state.dataHVACGlobal->DXElecCoolingPower = 0.0;
14402 636362 : } break;
14403 41091061 : default: {
14404 41091061 : thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
14405 41091061 : thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
14406 41091061 : thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
14407 41091061 : thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
14408 41091061 : thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
14409 41091061 : state.dataHVACGlobal->DXElecCoolingPower = thisDXCoil.ElecCoolingPower;
14410 41091061 : thisDXCoil.EvapCondPumpElecConsumption = thisDXCoil.EvapCondPumpElecPower * ReportingConstant;
14411 41091061 : thisDXCoil.EvapWaterConsump = thisDXCoil.EvapWaterConsumpRate * ReportingConstant;
14412 41091061 : if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
14413 122565 : thisDXCoil.BasinHeaterConsumption = thisDXCoil.BasinHeaterPower * ReportingConstant;
14414 : }
14415 41091061 : } break;
14416 : }
14417 :
14418 63554260 : 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 0 : Real64 Tavg = (thisDXCoil.InletAirTemp + thisDXCoil.OutletAirTemp) / 2.0;
14423 : // CR9155 Remove specific humidity calculations
14424 : // mdot * del HumRat / rho water
14425 0 : thisDXCoil.CondensateVdot =
14426 0 : max(0.0, (thisDXCoil.InletAirMassFlowRate * (thisDXCoil.InletAirHumRat - thisDXCoil.OutletAirHumRat) / Psychrometrics::RhoH2O(Tavg)));
14427 0 : thisDXCoil.CondensateVol = thisDXCoil.CondensateVdot * ReportingConstant;
14428 :
14429 0 : state.dataWaterData->WaterStorage(thisDXCoil.CondensateTankID).VdotAvailSupply(thisDXCoil.CondensateTankSupplyARRID) =
14430 0 : thisDXCoil.CondensateVdot;
14431 0 : state.dataWaterData->WaterStorage(thisDXCoil.CondensateTankID).TwaterSupply(thisDXCoil.CondensateTankSupplyARRID) = thisDXCoil.OutletAirTemp;
14432 : }
14433 :
14434 63554260 : state.dataAirLoop->LoopDXCoilRTF = max(thisDXCoil.CoolingCoilRuntimeFraction, thisDXCoil.HeatingCoilRuntimeFraction);
14435 63554260 : if (thisDXCoil.AirLoopNum > 0) {
14436 4712292 : state.dataAirLoop->AirLoopAFNInfo(thisDXCoil.AirLoopNum).AFNLoopDXCoilRTF =
14437 4712292 : max(thisDXCoil.CoolingCoilRuntimeFraction, thisDXCoil.HeatingCoilRuntimeFraction);
14438 : }
14439 63554260 : }
14440 :
14441 66 : 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 66 : Real64 constexpr CoolingCoilInletAirWetBulbTempRated(19.4); // 19.44C (67F)
14464 66 : Real64 constexpr CoolingCoilInletAirDryBulbTempRated(26.7);
14465 66 : Real64 constexpr OutdoorUnitInletAirDryBulbTempRated(35.0); // 35.00C (95F)
14466 66 : static Array1D<Real64> const OutdoorUnitInletAirDryBulbTempPLTestPoint(3, {27.5, 20.0, 18.3});
14467 66 : static Array1D<Real64> const NetCapacityFactorPLTestPoint(3, {0.75, 0.50, 0.25});
14468 66 : Real64 constexpr ConvFromSIToIP(3.412141633); // Conversion from SI to IP [3.412 Btu/hr-W]
14469 :
14470 66 : Real64 constexpr AirMassFlowRatioRated(1.0); // AHRI test is at the design flow rate
14471 : // and hence AirMassFlowRatio is 1.0
14472 :
14473 66 : Real64 constexpr DefaultFanPowerPerEvapAirFlowRate(773.3); // 365 W/1000 scfm or 773.3 W/(m3/s). The AHRI standard
14474 66 : 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 66 : auto &NetCoolingCapRated = state.dataDXCoils->NetCoolingCapRated;
14484 66 : auto &EER = state.dataDXCoils->EER;
14485 66 : auto &IEER = state.dataDXCoils->IEER;
14486 66 : auto &TotCapTempModFac = state.dataDXCoils->TotCapTempModFac;
14487 66 : auto &TotCapFlowModFac = state.dataDXCoils->TotCapFlowModFac;
14488 66 : auto &EIRTempModFac = state.dataDXCoils->EIRTempModFac;
14489 66 : auto &EIRFlowModFac = state.dataDXCoils->EIRFlowModFac;
14490 66 : auto &TempDryBulb_Leaving_Apoint = state.dataDXCoils->TempDryBulb_Leaving_Apoint;
14491 :
14492 66 : constexpr Real64 AccuracyTolerance(0.2); // tolerance in AHRI 340/360 Table 6 note 1
14493 66 : constexpr int MaximumIterations(1000);
14494 : Real64 EIR;
14495 : Real64 TotalElecPowerRated;
14496 66 : Array1D<Real64> EER_TestPoint_SI(4); // 1 = A, 2 = B, 3= C, 4= D
14497 66 : Array1D<Real64> EER_TestPoint_IP(4); // 1 = A, 2 = B, 3= C, 4= D
14498 66 : Array1D<Real64> NetCapacity_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
14499 66 : Array1D<Real64> NetPower_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
14500 66 : 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 66 : 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 66 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
14549 :
14550 : // Get fan index and name if not already available
14551 66 : if (thisDXCoil.SupplyFanIndex == 0) {
14552 66 : GetFanIndexForTwoSpeedCoil(state, DXCoilNum, thisDXCoil.SupplyFanIndex, thisDXCoil.SupplyFanName, thisDXCoil.supplyFanType);
14553 : }
14554 66 : if (thisDXCoil.SupplyFanIndex == 0) { // didn't find VAV fan, do not rate this coil
14555 14 : thisDXCoil.RateWithInternalStaticAndFanObject = false;
14556 28 : ShowWarningError(state,
14557 28 : format("CalcTwoSpeedDXCoilStandardRating: Did not find an appropriate fan associated with DX coil named = \"{}\". Standard "
14558 : "Ratings will not be calculated.",
14559 14 : thisDXCoil.Name));
14560 14 : return;
14561 : }
14562 52 : bool saveTurnFansOn = state.dataHVACGlobal->TurnFansOn;
14563 52 : bool saveTurnFansOff = state.dataHVACGlobal->TurnFansOff;
14564 52 : state.dataHVACGlobal->TurnFansOn = true; // enable fans, will override fan availability schedule if needed
14565 52 : 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 52 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14570 :
14571 29 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatioRated);
14572 29 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
14573 145 : 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 116 : if (NetCoolingCapRated <= 21000.0) {
14576 14 : ExternalStatic = 50.0;
14577 102 : } else if (21000.0 < NetCoolingCapRated && NetCoolingCapRated <= 30800.0) {
14578 0 : ExternalStatic = 60.0;
14579 102 : } else if (30800.0 < NetCoolingCapRated && NetCoolingCapRated <= 39300.0) {
14580 0 : ExternalStatic = 70.0;
14581 102 : } else if (39300.0 < NetCoolingCapRated && NetCoolingCapRated <= 61500.0) {
14582 11 : ExternalStatic = 90.0;
14583 91 : } else if (61500.0 < NetCoolingCapRated && NetCoolingCapRated <= 82100.0) {
14584 3 : ExternalStatic = 100.0;
14585 88 : } else if (82100.0 < NetCoolingCapRated && NetCoolingCapRated <= 103000.0) {
14586 0 : ExternalStatic = 110.0;
14587 88 : } else if (103000.0 < NetCoolingCapRated && NetCoolingCapRated <= 117000.0) {
14588 0 : ExternalStatic = 140.0;
14589 88 : } else if (117000.0 < NetCoolingCapRated && NetCoolingCapRated <= 147000.0) {
14590 16 : ExternalStatic = 160.0;
14591 72 : } else if (147000.0 < NetCoolingCapRated) {
14592 72 : ExternalStatic = 190.0;
14593 : }
14594 116 : FanStaticPressureRise = ExternalStatic + thisDXCoil.InternalStaticPressureDrop;
14595 116 : FanInletNode = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->inletNodeNum;
14596 116 : FanOutletNode = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->outletNodeNum;
14597 :
14598 : // set node state variables in preparation for fan model.
14599 116 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
14600 116 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
14601 116 : state.dataLoopNodes->Node(FanInletNode).Temp = CoolingCoilInletAirDryBulbTempRated;
14602 116 : state.dataLoopNodes->Node(FanInletNode).HumRat = PsyWFnTdbTwbPb(
14603 116 : state, CoolingCoilInletAirDryBulbTempRated, CoolingCoilInletAirWetBulbTempRated, state.dataEnvrn->OutBaroPress, RoutineName);
14604 116 : state.dataLoopNodes->Node(FanInletNode).Enthalpy =
14605 116 : PsyHFnTdbW(CoolingCoilInletAirDryBulbTempRated, state.dataLoopNodes->Node(FanInletNode).HumRat);
14606 116 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
14607 116 : FanPowerCorrection = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->totalPower;
14608 :
14609 116 : FanHeatCorrection = state.dataLoopNodes->Node(FanInletNode).MassFlowRate *
14610 116 : (state.dataLoopNodes->Node(FanOutletNode).Enthalpy - state.dataLoopNodes->Node(FanInletNode).Enthalpy);
14611 :
14612 116 : NetCoolingCapRated = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14613 : }
14614 :
14615 : } else {
14616 23 : FanPowerPerEvapAirFlowRate = DefaultFanPowerPerEvapAirFlowRate;
14617 23 : FanPowerPerEvapAirFlowRateSEER2 = DefaultFanPowerPerEvapAirFlowRateSEER2;
14618 23 : FanPowerCorrection = DefaultFanPowerPerEvapAirFlowRate * thisDXCoil.RatedAirVolFlowRate(1);
14619 23 : FanHeatCorrection = DefaultFanPowerPerEvapAirFlowRate * thisDXCoil.RatedAirVolFlowRate(1);
14620 23 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatioRated);
14621 23 : TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
14622 23 : NetCoolingCapRated = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14623 : }
14624 :
14625 52 : 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 52 : EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
14629 52 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatioRated);
14630 52 : if (thisDXCoil.RatedCOP(1) > 0.0) {
14631 : // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
14632 52 : EIR = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP(1);
14633 : } else {
14634 0 : EIR = 0.0;
14635 : }
14636 52 : TotalElecPowerRated = EIR * (thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac) + FanPowerCorrection;
14637 :
14638 52 : if (TotalElecPowerRated > 0.0) {
14639 52 : EER = NetCoolingCapRated / TotalElecPowerRated;
14640 : } else {
14641 0 : EER = 0.0;
14642 : }
14643 :
14644 : // IEER - A point 100 % net capacity
14645 52 : EER_TestPoint_SI(1) = EER;
14646 52 : 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 52 : thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
14651 52 : thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(1);
14652 52 : thisDXCoil.InletAirTemp = 26.7;
14653 52 : thisDXCoil.InletAirHumRat = PsyWFnTdbTwbPb(state, 26.7, 19.4, state.dataEnvrn->OutBaroPress, RoutineName);
14654 52 : thisDXCoil.InletAirEnthalpy = PsyHFnTdbW(26.7, thisDXCoil.InletAirHumRat);
14655 :
14656 52 : Real64 const heldOutDryBulb = state.dataEnvrn->OutDryBulbTemp;
14657 52 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
14658 8 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = OutdoorUnitInletAirDryBulbTempRated;
14659 : } else {
14660 44 : state.dataEnvrn->OutDryBulbTemp = OutdoorUnitInletAirDryBulbTempRated;
14661 : }
14662 52 : SpeedRatio = 1.0;
14663 52 : CycRatio = 1.0;
14664 52 : CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio, true);
14665 52 : TempDryBulb_Leaving_Apoint = state.dataDXCoils->DXCoilOutletTemp(DXCoilNum); // store result
14666 :
14667 : // IEER - part load test points ***************************************************
14668 208 : for (PartLoadTestPoint = 1; PartLoadTestPoint <= 3; ++PartLoadTestPoint) {
14669 : // determine minimum unloading capacity fraction at point B conditions.
14670 156 : if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
14671 24 : state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
14672 : } else {
14673 132 : state.dataEnvrn->OutDryBulbTemp = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
14674 : }
14675 :
14676 156 : TargetNetCapacity = NetCapacityFactorPLTestPoint(PartLoadTestPoint) * NetCoolingCapRated;
14677 :
14678 : // set up parameters for the solver here
14679 156 : Real64 const par3 = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
14680 156 : Real64 par7 = FanPowerPerEvapAirFlowRate;
14681 156 : int fanInNode = 0;
14682 156 : int fanOutNode = 0;
14683 156 : Real64 externalStatic = 0.0;
14684 156 : int fanIndex = 0;
14685 156 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14686 87 : par7 = 0.0;
14687 87 : fanInNode = FanInletNode;
14688 87 : fanOutNode = FanOutletNode;
14689 87 : externalStatic = ExternalStatic;
14690 87 : fanIndex = thisDXCoil.SupplyFanIndex;
14691 : }
14692 :
14693 156 : 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 156 : Real64 dbRated = CoolingCoilInletAirDryBulbTempRated;
14704 156 : Real64 wbRated = CoolingCoilInletAirWetBulbTempRated;
14705 : auto f = // (AUTO_OK_LAMBDA)
14706 55472 : [&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 55316 : auto &coil = state.dataDXCoils->DXCoil(DXCoilNum);
14710 55316 : Real64 AirMassFlowRatio = 0.0;
14711 55316 : if (coil.RatedAirMassFlowRate(1) > 0.0) {
14712 55316 : AirMassFlowRatio = SupplyAirMassFlowRate / coil.RatedAirMassFlowRate(1);
14713 : }
14714 55316 : Real64 SupplyAirHumRat = PsyWFnTdbTwbPb(state, dbRated, wbRated, state.dataEnvrn->OutBaroPress, RoutineName);
14715 55316 : Real64 SupplyAirRho = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, dbRated, SupplyAirHumRat, RoutineName);
14716 55316 : Real64 SupplyAirVolFlowRate = SupplyAirMassFlowRate / SupplyAirRho;
14717 :
14718 : Real64 FanHeatCorrection;
14719 55316 : if (coil.RateWithInternalStaticAndFanObject) {
14720 : // modify external static per AHRI 340/360, Table 6, note 1.
14721 33034 : Real64 FanStaticPressureRise = coil.InternalStaticPressureDrop + (externalStatic * pow_2(AirMassFlowRatio));
14722 33034 : auto &inletNode = state.dataLoopNodes->Node(fanInNode);
14723 33034 : auto &outletNode = state.dataLoopNodes->Node(fanOutNode);
14724 33034 : inletNode.MassFlowRate = SupplyAirMassFlowRate;
14725 33034 : outletNode.MassFlowRate = SupplyAirMassFlowRate;
14726 33034 : inletNode.Temp = dbRated;
14727 33034 : inletNode.HumRat = PsyWFnTdbTwbPb(state, dbRated, wbRated, state.dataEnvrn->OutBaroPress, RoutineName);
14728 33034 : inletNode.Enthalpy = PsyHFnTdbW(dbRated, inletNode.HumRat);
14729 33034 : state.dataFans->fans(coil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
14730 33034 : FanHeatCorrection = SupplyAirMassFlowRate * (outletNode.Enthalpy - inletNode.Enthalpy);
14731 : } else {
14732 22282 : FanHeatCorrection = par7 * SupplyAirVolFlowRate;
14733 : }
14734 :
14735 55316 : Real64 TotCapFlowModFac = Curve::CurveValue(state, coil.CCapFFlow(1), AirMassFlowRatio);
14736 55316 : Real64 TotCapTempModFac = Curve::CurveValue(state, coil.CCapFTemp(1), wbRated, par3);
14737 55316 : Real64 HighSpeedNetCoolingCap = coil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14738 :
14739 : // TotCapFlowModFac = CurveManager::CurveValue(state, coil.CCapFFlow(1), AirMassFlowRatio);
14740 55316 : TotCapTempModFac = Curve::CurveValue(state, coil.CCapFTemp2, wbRated, par3);
14741 55316 : Real64 LowSpeedNetCoolingCap = coil.RatedTotCap2 * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
14742 :
14743 : Real64 SpeedRatio;
14744 : Real64 CycRatio;
14745 55316 : if (LowSpeedNetCoolingCap <= TargetNetCapacity) {
14746 42199 : CycRatio = 1.0;
14747 42199 : SpeedRatio = (TargetNetCapacity - LowSpeedNetCoolingCap) / (HighSpeedNetCoolingCap - LowSpeedNetCoolingCap);
14748 : } else { // minimum unloading limit exceeded for no cycling
14749 13117 : SpeedRatio = 0.0;
14750 13117 : CycRatio = TargetNetCapacity / LowSpeedNetCoolingCap;
14751 : }
14752 :
14753 55316 : coil.InletAirMassFlowRate = SupplyAirMassFlowRate;
14754 55316 : CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio, true);
14755 55316 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(DXCoilNum);
14756 55316 : return TempDryBulb_Leaving_Apoint - OutletAirTemp;
14757 156 : };
14758 156 : General::SolveRoot(state,
14759 : AccuracyTolerance,
14760 : MaximumIterations,
14761 : SolverFlag,
14762 : PartLoadAirMassFlowRate,
14763 : f,
14764 : LowerBoundMassFlowRate,
14765 156 : thisDXCoil.RatedAirMassFlowRate(1));
14766 :
14767 156 : 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 156 : } 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 156 : SupAirMdot_TestPoint(1 + PartLoadTestPoint) = PartLoadAirMassFlowRate;
14788 156 : AirMassFlowRatio = PartLoadAirMassFlowRate / thisDXCoil.RatedAirMassFlowRate(1);
14789 156 : SupplyAirHumRat = PsyWFnTdbTwbPb(
14790 156 : state, CoolingCoilInletAirDryBulbTempRated, CoolingCoilInletAirWetBulbTempRated, state.dataEnvrn->OutBaroPress, RoutineName);
14791 156 : SupplyAirRho = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, CoolingCoilInletAirDryBulbTempRated, SupplyAirHumRat, RoutineName);
14792 156 : SupplyAirVolFlowRate = PartLoadAirMassFlowRate / SupplyAirRho;
14793 :
14794 156 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
14795 87 : FanStaticPressureRise = thisDXCoil.InternalStaticPressureDrop + (ExternalStatic * pow_2(AirMassFlowRatio));
14796 87 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = PartLoadAirMassFlowRate;
14797 87 : state.dataLoopNodes->Node(FanInletNode).Temp = CoolingCoilInletAirDryBulbTempRated;
14798 87 : state.dataLoopNodes->Node(FanInletNode).HumRat = SupplyAirHumRat;
14799 87 : state.dataLoopNodes->Node(FanInletNode).Enthalpy = PsyHFnTdbW(CoolingCoilInletAirDryBulbTempRated, SupplyAirHumRat);
14800 :
14801 87 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
14802 87 : FanPowerCorrection = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->totalPower;
14803 :
14804 87 : FanHeatCorrection =
14805 87 : PartLoadAirMassFlowRate * (state.dataLoopNodes->Node(FanOutletNode).Enthalpy - state.dataLoopNodes->Node(FanInletNode).Enthalpy);
14806 :
14807 : } else {
14808 69 : FanPowerCorrection = FanPowerPerEvapAirFlowRate * PartLoadAirMassFlowRate;
14809 69 : FanHeatCorrection = FanPowerPerEvapAirFlowRate * PartLoadAirMassFlowRate;
14810 : }
14811 :
14812 156 : TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatio);
14813 : // Warn user if curve output goes negative
14814 156 : 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 468 : TotCapTempModFac = CurveValue(
14836 156 : state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14837 : // Warn user if curve output goes negative
14838 156 : 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 156 : HighSpeedTotCoolingCap = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac;
14864 156 : HighSpeedNetCoolingCap = HighSpeedTotCoolingCap - FanHeatCorrection;
14865 :
14866 468 : EIRTempModFac = CurveValue(
14867 156 : state, thisDXCoil.EIRFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14868 156 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatio);
14869 156 : if (thisDXCoil.RatedCOP(1) > 0.0) {
14870 : // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
14871 156 : 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 312 : TotCapTempModFac = CurveValue(
14878 156 : state, thisDXCoil.CCapFTemp2, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14879 : // Warn user if curve output goes negative
14880 156 : 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 156 : LowSpeedTotCoolingCap = thisDXCoil.RatedTotCap2 * TotCapTempModFac * TotCapFlowModFac;
14906 156 : LowSpeedNetCoolingCap = LowSpeedTotCoolingCap - FanHeatCorrection;
14907 :
14908 312 : EIRTempModFac = CurveValue(
14909 156 : state, thisDXCoil.EIRFTemp2, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
14910 156 : EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatio);
14911 156 : if (thisDXCoil.RatedCOP2 > 0.0) {
14912 : // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
14913 156 : EIR_LowSpeed = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP2;
14914 : } else {
14915 0 : EIR_LowSpeed = 0.0;
14916 : }
14917 :
14918 156 : if (LowSpeedNetCoolingCap <= TargetNetCapacity) {
14919 104 : CycRatio = 1.0;
14920 104 : SpeedRatio = (TargetNetCapacity - LowSpeedNetCoolingCap) / (HighSpeedNetCoolingCap - LowSpeedNetCoolingCap);
14921 104 : TotCoolingCap = HighSpeedTotCoolingCap * SpeedRatio + LowSpeedTotCoolingCap * (1.0 - SpeedRatio);
14922 104 : NetCoolingCap = TotCoolingCap - FanHeatCorrection;
14923 104 : EIR = EIR_HighSpeed * SpeedRatio + EIR_LowSpeed * (1.0 - SpeedRatio);
14924 104 : TotalElecPowerRated = TotCoolingCap * EIR + FanPowerCorrection;
14925 104 : EER_TestPoint_SI(1 + PartLoadTestPoint) = NetCoolingCap / TotalElecPowerRated;
14926 104 : EER_TestPoint_IP(1 + PartLoadTestPoint) = EER_TestPoint_SI(1 + PartLoadTestPoint) * ConvFromSIToIP;
14927 104 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = NetCoolingCap;
14928 104 : NetPower_TestPoint(1 + PartLoadTestPoint) = TotalElecPowerRated;
14929 : } else { // minimum unloading limit exceeded without cycling, so cycle
14930 52 : SpeedRatio = 0.0;
14931 52 : CycRatio = TargetNetCapacity / LowSpeedNetCoolingCap;
14932 52 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(1), CycRatio);
14933 52 : if (PLF < 0.7) {
14934 0 : PLF = 0.7;
14935 : }
14936 52 : RunTimeFraction = CycRatio / PLF;
14937 52 : RunTimeFraction = min(RunTimeFraction, 1.0);
14938 52 : TotCoolingCap = LowSpeedTotCoolingCap * RunTimeFraction;
14939 52 : NetCoolingCap = TotCoolingCap - FanHeatCorrection;
14940 52 : TotalElecPowerRated = LowSpeedTotCoolingCap * EIR_LowSpeed * RunTimeFraction + FanPowerCorrection;
14941 52 : EER_TestPoint_SI(1 + PartLoadTestPoint) = NetCoolingCap / TotalElecPowerRated;
14942 52 : EER_TestPoint_IP(1 + PartLoadTestPoint) = EER_TestPoint_SI(1 + PartLoadTestPoint) * ConvFromSIToIP;
14943 52 : NetCapacity_TestPoint(1 + PartLoadTestPoint) = NetCoolingCap;
14944 52 : NetPower_TestPoint(1 + PartLoadTestPoint) = TotalElecPowerRated;
14945 : }
14946 : }
14947 : } // loop over 3 part load test points
14948 52 : state.dataHVACGlobal->TurnFansOn = saveTurnFansOn;
14949 52 : state.dataHVACGlobal->TurnFansOff = saveTurnFansOff;
14950 :
14951 52 : IEER = (0.02 * EER_TestPoint_IP(1)) + (0.617 * EER_TestPoint_IP(2)) + (0.238 * EER_TestPoint_IP(3)) + (0.125 * EER_TestPoint_IP(4));
14952 : // CalcMultiSpeedDXCoilCooling() //??
14953 : // begin output
14954 52 : if (state.dataDXCoils->CalcTwoSpeedDXCoilStandardRatingOneTimeEIOHeaderWrite) {
14955 23 : print(state.files.eio, Header);
14956 23 : state.dataDXCoils->CalcTwoSpeedDXCoilStandardRatingOneTimeEIOHeaderWrite = false;
14957 46 : state.dataOutRptPredefined->pdstVAVDXCoolCoil =
14958 23 : newPreDefSubTable(state, state.dataOutRptPredefined->pdrEquip, "VAV DX Cooling Standard Rating Details");
14959 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilType =
14960 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "DX Cooling Coil Type");
14961 23 : state.dataOutRptPredefined->pdchVAVDXFanName = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Associated Fan");
14962 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilNetCapSI =
14963 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Net Cooling Capacity [W]");
14964 23 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP [W/W]");
14965 23 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEERIP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER [Btu/W-h]");
14966 23 : state.dataOutRptPredefined->pdchVAVDXCoolCoilIEERIP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "IEER [Btu/W-h]");
14967 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotA =
14968 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 100% [kg/s]");
14969 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_B =
14970 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 75% Capacity [W/W]");
14971 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_B_IP =
14972 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 75% Capacity [Btu/W-h]");
14973 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotB =
14974 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 75% [kg/s]");
14975 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_C =
14976 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 50% Capacity [W/W]");
14977 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_C_IP =
14978 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 50% Capacity [Btu/W-h]");
14979 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotC =
14980 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 50% [kg/s]");
14981 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_D =
14982 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 25% Capacity [W/W]");
14983 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_D_IP =
14984 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 25% Capacity [Btu/W-h]");
14985 46 : state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotD =
14986 23 : newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 25% [kg/s]");
14987 :
14988 : // determine footnote content
14989 23 : countStaticInputs = 0;
14990 92 : for (index = 1; index <= state.dataDXCoils->NumDXCoils; ++index) {
14991 :
14992 98 : if (state.dataDXCoils->DXCoil(index).RateWithInternalStaticAndFanObject &&
14993 29 : state.dataDXCoils->DXCoil(index).DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
14994 29 : ++countStaticInputs;
14995 : }
14996 : }
14997 :
14998 23 : if (countStaticInputs == state.dataDXCoils->NumDXMulSpeedCoils) {
14999 22 : addFootNoteSubTable(state,
15000 11 : state.dataOutRptPredefined->pdstVAVDXCoolCoil,
15001 : "Packaged VAV unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2");
15002 12 : } else if (countStaticInputs == 0) {
15003 24 : addFootNoteSubTable(state,
15004 12 : 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 52 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
15017 29 : return {"Fan:VariableVolume", thisDXCoil.SupplyFanName};
15018 : } else {
15019 23 : return {"N/A", "N/A"};
15020 : }
15021 52 : }();
15022 :
15023 52 : print(state.files.eio,
15024 : Format_891,
15025 : "Coil:Cooling:DX:TwoSpeed",
15026 52 : thisDXCoil.Name,
15027 52 : fan_type_name.first,
15028 52 : fan_type_name.second,
15029 : NetCoolingCapRated,
15030 52 : (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 52 : 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 22 : print(state.files.eio, "{}\n", Format_994);
15052 22 : state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag = false;
15053 : }
15054 : static constexpr std::string_view Format_995(" DX Cooling Coil Standard Rating Information, {}, {}, {:.1R}, {}, {}, {}, {}, {}\n");
15055 52 : print(state.files.eio,
15056 : Format_995,
15057 : "Coil:Cooling:DX:TwoSpeed",
15058 52 : thisDXCoil.Name,
15059 : NetCoolingCapRated,
15060 : EER_TestPoint_SI(1),
15061 : EER_TestPoint_IP(1),
15062 : "N/A",
15063 : "N/A",
15064 : IEER);
15065 :
15066 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilType, thisDXCoil.Name, "Coil:Cooling:DX:TwoSpeed");
15067 : // W to tons
15068 52 : 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 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilCOP, thisDXCoil.Name, EER_TestPoint_SI(1), 2);
15076 52 : 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 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilIEERIP, thisDXCoil.Name, IEER, 1);
15080 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERUserIP, thisDXCoil.Name, "N/A");
15081 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERStandardIP, thisDXCoil.Name, "N/A");
15082 :
15083 52 : addFootNoteSubTable(state, state.dataOutRptPredefined->pdstDXCoolCoil, StandardRatings::AHRI2017FOOTNOTE);
15084 :
15085 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilType, thisDXCoil.Name, "Coil:Cooling:DX:TwoSpeed");
15086 52 : if (thisDXCoil.RateWithInternalStaticAndFanObject) {
15087 29 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXFanName, thisDXCoil.Name, thisDXCoil.SupplyFanName);
15088 : } else {
15089 23 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXFanName, thisDXCoil.Name, "None");
15090 : }
15091 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilNetCapSI, thisDXCoil.Name, NetCoolingCapRated, 2);
15092 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP, thisDXCoil.Name, EER_TestPoint_SI(1), 2);
15093 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilIEERIP, thisDXCoil.Name, IEER, 2);
15094 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEERIP, thisDXCoil.Name, EER_TestPoint_IP(1), 2);
15095 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotA, thisDXCoil.Name, SupAirMdot_TestPoint(1), 4);
15096 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_B, thisDXCoil.Name, EER_TestPoint_SI(2), 2);
15097 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_B_IP, thisDXCoil.Name, EER_TestPoint_IP(2), 2);
15098 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotB, thisDXCoil.Name, SupAirMdot_TestPoint(2), 4);
15099 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_C, thisDXCoil.Name, EER_TestPoint_SI(3), 2);
15100 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_C_IP, thisDXCoil.Name, EER_TestPoint_IP(3), 2);
15101 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotC, thisDXCoil.Name, SupAirMdot_TestPoint(3), 4);
15102 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_D, thisDXCoil.Name, EER_TestPoint_SI(4), 2);
15103 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_D_IP, thisDXCoil.Name, EER_TestPoint_IP(4), 2);
15104 52 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotD, thisDXCoil.Name, SupAirMdot_TestPoint(4), 4);
15105 :
15106 52 : state.dataEnvrn->OutDryBulbTemp = heldOutDryBulb; // reset the outdoor dry bulb when done with it
15107 122 : }
15108 :
15109 66 : 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 66 : 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 66 : FoundBranch = 0;
15131 66 : FoundAirSysNum = 0;
15132 66 : SupplyFanIndex = 0;
15133 66 : SupplyFanName = "n/a";
15134 322 : for (AirSysNum = 1; AirSysNum <= NumPrimaryAirSys; ++AirSysNum) {
15135 :
15136 512 : for (BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).NumBranches; ++BranchNum) {
15137 :
15138 1066 : for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).TotalComponents; ++CompNum) {
15139 :
15140 876 : if (state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num ==
15141 : SimAirServingZones::CompType::DXSystem) {
15142 :
15143 224 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name,
15144 224 : state.dataDXCoils->DXCoil(CoolingCoilIndex).CoilSystemName)) {
15145 66 : FoundBranch = BranchNum;
15146 66 : FoundAirSysNum = AirSysNum;
15147 66 : break;
15148 : }
15149 : // these are specified in SimAirServingZones and need to be moved to a Data* file. UnitarySystem=19
15150 652 : } else if (state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num ==
15151 : SimAirServingZones::CompType::UnitarySystemModel) {
15152 :
15153 12 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name,
15154 12 : state.dataDXCoils->DXCoil(CoolingCoilIndex).CoilSystemName)) {
15155 0 : FoundBranch = BranchNum;
15156 0 : FoundAirSysNum = AirSysNum;
15157 0 : break;
15158 : }
15159 : }
15160 : }
15161 :
15162 256 : if (FoundBranch > 0 && FoundAirSysNum > 0) {
15163 657 : for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).TotalComponents;
15164 : ++CompNum) {
15165 604 : if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
15166 : SimAirServingZones::CompType::Fan_Simple_VAV) {
15167 99 : SupplyFanName = state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).Name;
15168 99 : SupplyFanIndex = Fans::GetFanIndex(state, SupplyFanName);
15169 99 : supplyFanType = HVAC::FanType::VAV;
15170 99 : break;
15171 : // these are specified in SimAirServingZones and need to be moved to a Data* file. UnitarySystem=19
15172 505 : } else if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
15173 : SimAirServingZones::CompType::Fan_System_Object) {
15174 12 : SupplyFanName = state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).Name;
15175 12 : SupplyFanIndex = Fans::GetFanIndex(state, SupplyFanName);
15176 12 : supplyFanType = HVAC::FanType::SystemModel;
15177 :
15178 493 : } 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 66 : }
15191 :
15192 994 : 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 994 : if (state.dataDXCoils->GetCoilsInputFlag) {
15209 143 : GetDXCoils(state);
15210 143 : state.dataDXCoils->GetCoilsInputFlag = false;
15211 : }
15212 :
15213 994 : DXCoilIndex = Util::FindItemInList(DXCoilName, state.dataDXCoils->DXCoil);
15214 994 : if (DXCoilIndex == 0) {
15215 7 : 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 7 : ErrorsFound = true;
15224 : }
15225 994 : }
15226 :
15227 : std::string
15228 15 : 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 15 : if (state.dataDXCoils->GetCoilsInputFlag) {
15240 0 : GetDXCoils(state);
15241 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15242 : }
15243 :
15244 15 : 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 15 : return state.dataDXCoils->DXCoil(DXCoilIndex).Name;
15258 : }
15259 : }
15260 :
15261 243 : 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 243 : if (state.dataDXCoils->GetCoilsInputFlag) {
15285 0 : GetDXCoils(state);
15286 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15287 : }
15288 :
15289 243 : if (Util::SameString(CoilType, "Coil:Heating:DX:SingleSpeed") || Util::SameString(CoilType, "Coil:Cooling:DX:SingleSpeed")) {
15290 243 : WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
15291 243 : if (WhichCoil != 0) {
15292 243 : 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 243 : 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 243 : return CoilCapacity;
15321 : }
15322 :
15323 432 : 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 432 : if (state.dataDXCoils->GetCoilsInputFlag) {
15344 0 : GetDXCoils(state);
15345 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15346 : }
15347 :
15348 432 : 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 432 : 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 432 : switch (state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
15363 33 : case HVAC::CoilDX_MultiSpeedCooling:
15364 : case HVAC::CoilDX_MultiSpeedHeating: {
15365 33 : CoilCapacity = state.dataDXCoils->DXCoil(CoilIndex).MSRatedTotCap(state.dataDXCoils->DXCoil(CoilIndex).NumOfSpeeds);
15366 33 : } break;
15367 399 : default: {
15368 399 : CoilCapacity = state.dataDXCoils->DXCoil(CoilIndex).RatedTotCap(state.dataDXCoils->DXCoil(CoilIndex).NumCapacityStages);
15369 399 : } break;
15370 : }
15371 : }
15372 :
15373 432 : return CoilCapacity;
15374 : }
15375 :
15376 406 : 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 406 : if (state.dataDXCoils->GetCoilsInputFlag) {
15402 101 : GetDXCoils(state);
15403 101 : state.dataDXCoils->GetCoilsInputFlag = false;
15404 : }
15405 :
15406 406 : if (present(PrintWarning)) {
15407 374 : PrintMessage = PrintWarning;
15408 : } else {
15409 32 : PrintMessage = true;
15410 : }
15411 :
15412 406 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15413 406 : if (WhichCoil != 0) {
15414 403 : TypeNum = state.dataDXCoils->DXCoil(WhichCoil).DXCoilType_Num;
15415 : } else {
15416 3 : if (PrintMessage) {
15417 0 : ShowSevereError(state, format("GetCoilTypeNum: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
15418 : }
15419 3 : ErrorsFound = true;
15420 3 : TypeNum = 0;
15421 : }
15422 :
15423 406 : return TypeNum;
15424 : }
15425 :
15426 823 : 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 823 : if (state.dataDXCoils->GetCoilsInputFlag) {
15434 0 : GetDXCoils(state);
15435 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15436 : }
15437 :
15438 823 : 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 823 : return state.dataDXCoils->DXCoil(CoilIndex).MinOATCompressor;
15445 : }
15446 : }
15447 :
15448 388 : 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 388 : if (state.dataDXCoils->GetCoilsInputFlag) {
15472 1 : GetDXCoils(state);
15473 1 : state.dataDXCoils->GetCoilsInputFlag = false;
15474 : }
15475 :
15476 388 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15477 388 : if (WhichCoil != 0) {
15478 388 : 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 388 : 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 409 : 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 409 : if (state.dataDXCoils->GetCoilsInputFlag) {
15537 6 : GetDXCoils(state);
15538 6 : state.dataDXCoils->GetCoilsInputFlag = false;
15539 : }
15540 :
15541 409 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15542 409 : if (WhichCoil != 0) {
15543 409 : 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 409 : 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 606 : 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 606 : if (state.dataDXCoils->GetCoilsInputFlag) {
15603 0 : GetDXCoils(state);
15604 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15605 : }
15606 :
15607 606 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15608 606 : if (WhichCoil != 0) {
15609 606 : 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 606 : return CondNode;
15617 : }
15618 :
15619 1 : 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 1 : if (state.dataDXCoils->GetCoilsInputFlag) {
15643 0 : GetDXCoils(state);
15644 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15645 : }
15646 :
15647 1 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15648 1 : if (WhichCoil != 0) {
15649 1 : 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 1 : return BypassFraction;
15657 : }
15658 :
15659 3915398 : 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 3915398 : DXCoolingCoilIndex = 0;
15682 :
15683 : DataLoopNode::ConnectionObjectType HeatingCoilTypeNum = static_cast<DataLoopNode::ConnectionObjectType>(
15684 3915398 : getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC, Util::makeUPPER(HeatingCoilType)));
15685 :
15686 : DataLoopNode::ConnectionObjectType CompSetsParentType; // Parent object type which uses DX heating coil pass into this function
15687 3915398 : std::string CompSetsParentName;
15688 132996963 : for (WhichComp = 1; WhichComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichComp) {
15689 :
15690 139405925 : if (HeatingCoilTypeNum != state.dataBranchNodeConnections->CompSets(WhichComp).ComponentObjectType ||
15691 6408962 : !Util::SameString(HeatingCoilName, state.dataBranchNodeConnections->CompSets(WhichComp).CName)) {
15692 129081565 : continue;
15693 : }
15694 3915398 : CompSetsParentType = state.dataBranchNodeConnections->CompSets(WhichComp).ParentObjectType;
15695 3915398 : CompSetsParentName = state.dataBranchNodeConnections->CompSets(WhichComp).ParentCName;
15696 3915398 : if ((CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAir) ||
15697 3915341 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::ZoneHVACPackagedTerminalHeatPump) ||
15698 3915332 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed) ||
15699 3915332 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass) ||
15700 : (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitarySystem)) {
15701 : // Search for DX cooling coils
15702 144980528 : for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
15703 156714383 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, CompSetsParentName) ||
15704 15649193 : (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
15705 : DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed)) {
15706 141065130 : continue;
15707 : }
15708 : DXCoolingCoilIndex =
15709 60 : Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
15710 60 : break;
15711 : }
15712 144981157 : for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
15713 156715106 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, CompSetsParentName) ||
15714 15649333 : (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
15715 : DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed)) {
15716 141065759 : continue;
15717 : }
15718 : DXCoolingCoilIndex =
15719 14 : Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
15720 14 : break;
15721 : }
15722 : // Search for Heat Exchanger Assisted DX cooling coils
15723 3915398 : if (DXCoolingCoilIndex == 0) {
15724 144979720 : for (WhichHXAssistedComp = 1; WhichHXAssistedComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichHXAssistedComp) {
15725 156713440 : if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ParentCName, CompSetsParentName) ||
15726 15649044 : (state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ComponentObjectType !=
15727 : DataLoopNode::ConnectionObjectType::CoilSystemCoolingDXHeatExchangerAssisted)) {
15728 141064396 : 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 3915398 : } 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 3915398 : 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 3915398 : if (DXCoolingCoilIndex > 0) {
15760 74 : if (state.dataDXCoils->DXCoil(DXCoolingCoilIndex).CrankcaseHeaterCapacity != 0.0) {
15761 14 : if (state.dataDXCoils->DXCoil(DXCoolingCoilIndex).CrankcaseHeaterCapacity !=
15762 28 : state.dataDXCoils->DXCoil(HeatingCoilIndex).CrankcaseHeaterCapacity ||
15763 14 : state.dataDXCoils->DXCoil(DXCoolingCoilIndex).MaxOATCrankcaseHeater !=
15764 14 : 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 3915398 : return DXCoolingCoilIndex;
15778 3915398 : }
15779 :
15780 20 : 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 20 : if (state.dataDXCoils->GetCoilsInputFlag) {
15803 0 : GetDXCoils(state);
15804 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15805 : }
15806 :
15807 20 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15808 20 : if (WhichCoil != 0) {
15809 20 : 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 20 : return NumberOfSpeeds;
15817 : }
15818 :
15819 148006 : 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 148006 : if (state.dataDXCoils->GetCoilsInputFlag) {
15841 0 : GetDXCoils(state);
15842 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15843 : }
15844 :
15845 148006 : if (present(CoilIndex)) {
15846 147880 : 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 147880 : WhichCoil = CoilIndex;
15853 : }
15854 : } else {
15855 126 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15856 : }
15857 148006 : if (WhichCoil != 0) {
15858 148006 : 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 2 : 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 2 : if (state.dataDXCoils->GetCoilsInputFlag) {
15895 0 : GetDXCoils(state);
15896 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15897 : }
15898 :
15899 2 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
15900 2 : if (WhichCoil != 0) {
15901 2 : switch (state.dataDXCoils->DXCoil(WhichCoil).DXCoilType_Num) {
15902 2 : case HVAC::CoilDX_CoolingSingleSpeed:
15903 : case HVAC::CoilDX_CoolingTwoSpeed:
15904 : case HVAC::CoilDX_HeatingEmpirical:
15905 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
15906 2 : AirFlow = state.dataDXCoils->DXCoil(WhichCoil).RatedAirVolFlowRate(1);
15907 2 : } 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 2 : return AirFlow;
15928 : }
15929 :
15930 586 : 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 586 : if (state.dataDXCoils->GetCoilsInputFlag) {
15950 0 : GetDXCoils(state);
15951 0 : state.dataDXCoils->GetCoilsInputFlag = false;
15952 : }
15953 :
15954 586 : if (CoilIndex != 0) {
15955 586 : switch (state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
15956 459 : case HVAC::CoilDX_CoolingSingleSpeed:
15957 : case HVAC::CoilDX_CoolingTwoSpeed:
15958 : case HVAC::CoilDX_HeatingEmpirical:
15959 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
15960 459 : CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).CCapFTemp(1);
15961 459 : } break;
15962 51 : case HVAC::CoilDX_MultiSpeedCooling:
15963 : case HVAC::CoilDX_MultiSpeedHeating: {
15964 51 : CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).MSCCapFTemp(state.dataDXCoils->DXCoil(CoilIndex).NumOfSpeeds);
15965 51 : } break;
15966 76 : case HVAC::CoilVRF_Heating: {
15967 76 : CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).CCapFTemp(1);
15968 76 : } 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 586 : return CapFTCurveIndex;
15985 : }
15986 :
15987 1228 : 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 1228 : if (state.dataDXCoils->GetCoilsInputFlag) {
16028 0 : GetDXCoils(state);
16029 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16030 : }
16031 :
16032 1228 : if (DXCoilNum <= 0 || DXCoilNum > state.dataDXCoils->NumDXCoils) {
16033 0 : ShowSevereError(state,
16034 0 : format("SetDXCoolingCoilData: called with DX Cooling Coil Number out of range={} should be >0 and <{}",
16035 : DXCoilNum,
16036 0 : state.dataDXCoils->NumDXCoils));
16037 0 : ErrorsFound = true;
16038 0 : return;
16039 : }
16040 :
16041 1228 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
16042 1228 : if (present(HeatingCoilPLFCurvePTR)) {
16043 48 : thisDXCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurvePTR;
16044 : }
16045 :
16046 1228 : if (present(CondenserType)) {
16047 124 : thisDXCoil.CondenserType = CondenserType;
16048 : }
16049 :
16050 1228 : if (present(CondenserInletNodeNum)) {
16051 124 : thisDXCoil.CondenserInletNodeNum(1) = CondenserInletNodeNum;
16052 : }
16053 :
16054 1228 : if (present(MaxOATCrankcaseHeater)) {
16055 124 : thisDXCoil.MaxOATCrankcaseHeater = MaxOATCrankcaseHeater;
16056 : }
16057 :
16058 1228 : if (present(MaxOATCooling)) {
16059 62 : thisDXCoil.MaxOATCompressor = MaxOATCooling;
16060 : }
16061 :
16062 1228 : if (present(MaxOATHeating)) {
16063 16 : thisDXCoil.MaxOATCompressor = MaxOATHeating;
16064 : }
16065 :
16066 1228 : if (present(MinOATCooling)) {
16067 62 : thisDXCoil.MinOATCompressor = MinOATCooling;
16068 : }
16069 :
16070 1228 : if (present(MinOATHeating)) {
16071 62 : thisDXCoil.MinOATCompressor = MinOATHeating;
16072 : }
16073 :
16074 1228 : if (present(HeatingPerformanceOATType)) {
16075 62 : thisDXCoil.HeatingPerformanceOATType = HeatingPerformanceOATType;
16076 : }
16077 :
16078 1228 : if (present(DefrostStrategy)) {
16079 62 : thisDXCoil.DefrostStrategy = DefrostStrategy;
16080 : }
16081 :
16082 1228 : if (present(DefrostControl)) {
16083 62 : thisDXCoil.DefrostControl = DefrostControl;
16084 : }
16085 :
16086 1228 : if (present(DefrostEIRPtr)) {
16087 62 : thisDXCoil.DefrostEIRFT = DefrostEIRPtr;
16088 : }
16089 :
16090 1228 : if (present(DefrostFraction)) {
16091 62 : thisDXCoil.DefrostTime = DefrostFraction;
16092 : }
16093 :
16094 1228 : if (present(DefrostCapacity)) {
16095 62 : thisDXCoil.DefrostCapacity = DefrostCapacity;
16096 : }
16097 :
16098 1228 : if (present(MaxOATDefrost)) {
16099 62 : thisDXCoil.MaxOATDefrost = MaxOATDefrost;
16100 : }
16101 :
16102 1228 : if (present(CoolingCoilPresent)) {
16103 62 : thisDXCoil.CoolingCoilPresent = CoolingCoilPresent;
16104 : }
16105 :
16106 1228 : if (present(HeatingCoilPresent)) {
16107 62 : thisDXCoil.HeatingCoilPresent = HeatingCoilPresent;
16108 : }
16109 :
16110 1228 : if (present(HeatSizeRatio)) {
16111 0 : thisDXCoil.HeatSizeRatio = HeatSizeRatio;
16112 : }
16113 :
16114 1228 : if (present(TotCap)) {
16115 0 : thisDXCoil.RatedTotCap(1) = TotCap;
16116 : }
16117 :
16118 1228 : if (present(SupplyFanIndex)) {
16119 16 : thisDXCoil.SupplyFanIndex = SupplyFanIndex;
16120 : }
16121 :
16122 1228 : if (present(SupplyFanName)) {
16123 16 : thisDXCoil.SupplyFanName = SupplyFanName;
16124 : }
16125 :
16126 1228 : if (present(supplyFanType)) {
16127 16 : thisDXCoil.supplyFanType = supplyFanType;
16128 16 : if (thisDXCoil.SupplyFanIndex > 0) {
16129 16 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
16130 16 : thisDXCoil.Name,
16131 16 : thisDXCoil.DXCoilType,
16132 16 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->Name,
16133 16 : state.dataFans->fans(thisDXCoil.SupplyFanIndex)->type,
16134 : thisDXCoil.SupplyFanIndex);
16135 : }
16136 : }
16137 : }
16138 :
16139 2 : 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 2 : if (state.dataDXCoils->GetCoilsInputFlag) {
16161 0 : GetDXCoils(state);
16162 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16163 : }
16164 :
16165 2 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
16166 2 : if (WhichCoil != 0) {
16167 2 : state.dataDXCoils->DXCoil(WhichCoil).FindCompanionUpStreamCoil = false;
16168 : } else {
16169 0 : ShowSevereError(state, format("SetCoilSystemHeatingDXFlag: Could not find Coil, Type=\"{}\"Name=\"{}\"", CoilType, CoilName));
16170 : }
16171 2 : }
16172 :
16173 67 : 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 67 : if (state.dataDXCoils->GetCoilsInputFlag) {
16189 0 : GetDXCoils(state);
16190 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16191 : }
16192 :
16193 67 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
16194 67 : if (WhichCoil != 0) {
16195 67 : state.dataDXCoils->DXCoil(WhichCoil).CoilSystemName = CoilSystemName;
16196 : } else {
16197 0 : ShowSevereError(state, format("SetCoilSystemCoolingData: Could not find Coil \"Name=\"{}\"", CoilName));
16198 : }
16199 67 : }
16200 :
16201 39471 : 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 39471 : if (SHRFTempCurveIndex == 0) {
16238 0 : SHRTempModFac = 1.0;
16239 : } else {
16240 39471 : SHRTempModFac = CurveValue(state, SHRFTempCurveIndex, InletWetBulb, InletDryBulb);
16241 39471 : 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 39471 : if (SHRFFlowCurveIndex == 0) {
16247 0 : SHRFlowModFac = 1.0;
16248 : } else {
16249 39471 : SHRFlowModFac = CurveValue(state, SHRFFlowCurveIndex, AirMassFlowRatio);
16250 39471 : if (SHRFlowModFac < 0.0) {
16251 0 : SHRFlowModFac = 0.0;
16252 : }
16253 : }
16254 : // Calculate "operating" sensible heat ratio
16255 39471 : SHRopr = SHRRated * SHRTempModFac * SHRFlowModFac;
16256 :
16257 39471 : if (SHRopr < 0.0) {
16258 0 : SHRopr = 0.0; // SHR cannot be less than zero
16259 : }
16260 39471 : if (SHRopr > 1.0) {
16261 30261 : SHRopr = 1.0; // SHR cannot be greater than 1.0
16262 : }
16263 :
16264 39471 : return SHRopr;
16265 : }
16266 :
16267 6 : 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 6 : if (state.dataDXCoils->GetCoilsInputFlag) {
16281 0 : GetDXCoils(state);
16282 0 : state.dataDXCoils->GetCoilsInputFlag = false;
16283 : }
16284 :
16285 6 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
16286 6 : if (WhichCoil != 0) {
16287 5 : 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 1 : ShowSevereError(state, format("SetDXCoilTypeData: Could not find Coil \"Name=\"{}\"", CoilName));
16292 : }
16293 6 : }
16294 :
16295 163851 : 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 163851 : Real64 SHR(0); // sensible heat ratio
16332 : Real64 RhoAir; // secondary coil entering air density [kg/m3]
16333 163851 : 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 163851 : EvapAirMassFlow = 0.0;
16348 :
16349 163851 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
16350 :
16351 163851 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
16352 163851 : auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
16353 : // Select the correct unit type
16354 163851 : switch (thisDXCoil.DXCoilType_Num) {
16355 81926 : 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 81926 : if (thisDXCoil.ElecCoolingPower > 0.0) {
16360 18553 : TotalHeatRejectionRate = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
16361 : } else {
16362 63373 : TotalHeatRejectionRate = 0.0;
16363 63373 : return;
16364 : }
16365 18553 : thisDXCoil.SecCoilSensibleHeatGainRate = TotalHeatRejectionRate;
16366 18553 : } break;
16367 81925 : case HVAC::CoilDX_HeatingEmpirical: {
16368 : // evaporator coil in the secondary zone
16369 81925 : if (thisDXCoil.ElecHeatingPower > 0.0) {
16370 30261 : TotalHeatRemovalRate = max(0.0, thisDXCoil.TotalHeatingEnergyRate - thisDXCoil.ElecHeatingPower);
16371 : } else {
16372 51664 : TotalHeatRemovalRate = 0.0;
16373 51664 : thisDXCoil.SecCoilSHR = 0.0;
16374 51664 : return;
16375 : }
16376 30261 : thisDXCoil.SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower;
16377 30261 : EvapInletDryBulb = secZoneHB.ZT;
16378 30261 : EvapInletHumRat = secZoneHB.airHumRat;
16379 30261 : RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat);
16380 30261 : EvapAirMassFlow = RhoAir * thisDXCoil.SecCoilAirFlow;
16381 : ;
16382 30261 : PartLoadRatio = thisDXCoil.CompressorPartLoadRatio;
16383 30261 : SecCoilRatedSHR = thisDXCoil.SecCoilRatedSHR;
16384 30261 : if ((EvapAirMassFlow > HVAC::SmallMassFlow) && (PartLoadRatio > 0.0) &&
16385 30261 : (EvapInletDryBulb > thisDXCoil.MinOATCompressor)) { // coil is running
16386 30261 : SecCoilFlowFraction = 1.0; // for single speed DX coil the secondary coil (condenser) flow fraction is 1.0
16387 30261 : CondInletDryBulb = state.dataLoopNodes->Node(thisDXCoil.AirInNode).Temp;
16388 30261 : EvapInletWetBulb = PsyTwbFnTdbWPb(state, EvapInletDryBulb, EvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
16389 30261 : EvapInletEnthalpy = PsyHFnTdbW(EvapInletDryBulb, EvapInletHumRat);
16390 30261 : SecCoilSHRFT = thisDXCoil.SecCoilSHRFT;
16391 30261 : SecCoilSHRFF = thisDXCoil.SecCoilSHRFF;
16392 : // determine the current SHR
16393 30261 : 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 30261 : FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16409 30261 : hTinwout = EvapInletEnthalpy - (1.0 - SHR) * ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
16410 30261 : FullLoadOutAirHumRat = PsyWFnTdbH(state, EvapInletDryBulb, hTinwout, RoutineName, true);
16411 30261 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
16412 : // when the air outlet temperature falls below the saturation temperature, it is reset to saturation temperature
16413 30261 : 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 30261 : thisDXCoil.SecCoilSensibleHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate * SHR;
16423 30261 : 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 30261 : thisDXCoil.SecCoilSHR = SHR;
16432 30261 : } break;
16433 0 : case HVAC::CoilDX_MultiSpeedHeating: {
16434 0 : EvapInletDryBulb = secZoneHB.ZT;
16435 0 : EvapInletHumRat = secZoneHB.airHumRat;
16436 0 : RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat);
16437 0 : MSSpeedRatio = thisDXCoil.MSSpeedRatio;
16438 0 : MSCycRatio = thisDXCoil.MSCycRatio;
16439 0 : MSSpeedNumHS = thisDXCoil.MSSpeedNumHS;
16440 0 : MSSpeedNumLS = thisDXCoil.MSSpeedNumLS;
16441 0 : if (MSSpeedRatio > 0.0) {
16442 0 : EvapAirMassFlow = RhoAir * (thisDXCoil.MSSecCoilAirFlow(MSSpeedNumHS) * MSSpeedRatio +
16443 0 : thisDXCoil.MSSecCoilAirFlow(MSSpeedNumLS) * (1.0 - MSSpeedRatio));
16444 0 : } else if (MSCycRatio > 0.0) {
16445 0 : EvapAirMassFlow = RhoAir * thisDXCoil.MSSecCoilAirFlow(MSSpeedNumLS);
16446 : }
16447 0 : if (thisDXCoil.ElecHeatingPower > 0.0) {
16448 0 : TotalHeatRemovalRate = max(0.0, thisDXCoil.TotalHeatingEnergyRate - thisDXCoil.ElecHeatingPower);
16449 : } else {
16450 0 : TotalHeatRemovalRate = 0.0;
16451 0 : return;
16452 : }
16453 0 : thisDXCoil.SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower;
16454 0 : if ((EvapAirMassFlow > HVAC::SmallMassFlow) && (MSSpeedRatio > 0.0 || MSCycRatio > 0.0) &&
16455 0 : (EvapInletDryBulb > thisDXCoil.MinOATCompressor)) { // coil is running
16456 0 : SecCoilFlowFraction = 1.0; // for single speed DX coil the secondary coil (condenser) flow fraction is 1.0
16457 0 : CondInletDryBulb = state.dataLoopNodes->Node(thisDXCoil.AirInNode).Temp;
16458 0 : EvapInletWetBulb = PsyTwbFnTdbWPb(state, EvapInletDryBulb, EvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
16459 0 : EvapInletEnthalpy = PsyHFnTdbW(EvapInletDryBulb, EvapInletHumRat);
16460 : // determine the current SHR
16461 0 : 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 0 : } else if (MSCycRatio > 0.0) {
16503 : // calculate SHR for the lower speed
16504 0 : PartLoadRatio = MSCycRatio;
16505 0 : SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumLS);
16506 0 : SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumLS);
16507 0 : SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumLS);
16508 0 : SecCoilFlowFraction = 1.0;
16509 0 : 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 0 : SHR = SHRLowSpeed;
16524 : }
16525 : // Calculate full load output conditions
16526 0 : FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16527 0 : hTinwout = EvapInletEnthalpy - (1.0 - SHR) * ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
16528 0 : FullLoadOutAirHumRat = PsyWFnTdbH(state, EvapInletDryBulb, hTinwout, RoutineName, true);
16529 0 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
16530 : // when the air outlet temperature falls below the saturation temperature, it is reset to saturation temperature
16531 0 : 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 0 : thisDXCoil.SecCoilSensibleHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate * SHR;
16541 0 : 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 0 : thisDXCoil.SecCoilSHR = SHR;
16550 0 : } 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 30261 : 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 30261 : int constexpr MaxIter(30);
16599 30261 : Real64 constexpr RelaxationFactor(0.4);
16600 30261 : Real64 constexpr Tolerance(0.1);
16601 30261 : 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 30261 : CoilMightBeDry = false;
16621 30261 : FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16622 30261 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, EvapInletHumRat);
16623 30261 : if (FullLoadOutAirTemp > PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
16624 30261 : CoilMightBeDry = true;
16625 : // find wADP, humidity ratio at apparatus dewpoint and inlet hum rat that would have dry coil
16626 30261 : DryCoilTestEvapInletHumRat = EvapInletHumRat;
16627 30261 : DryCoilTestEvapInletWetBulb = EvapInletWetBulb;
16628 30261 : Counter = 0;
16629 30261 : Converged = false;
16630 60522 : while (!Converged) {
16631 : // assumes coil bypass factor (CBF) = 0.0
16632 30261 : hADP = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
16633 30261 : tADP = PsyTsatFnHPb(state, hADP, state.dataEnvrn->OutBaroPress, RoutineName);
16634 30261 : wADP = min(EvapInletHumRat, PsyWFnTdbH(state, tADP, hADP, RoutineName));
16635 30261 : hTinwADP = PsyHFnTdbW(EvapInletDryBulb, wADP);
16636 30261 : if ((EvapInletEnthalpy - hADP) > 1.e-10) {
16637 30261 : SHRadp = min((hTinwADP - hADP) / (EvapInletEnthalpy - hADP), 1.0);
16638 : } else {
16639 0 : SHRadp = 1.0;
16640 : }
16641 30261 : 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 30261 : Converged = true;
16657 : }
16658 : }
16659 : }
16660 : // determine SHR from user specified nominal value and SHR modifier curves
16661 30261 : SHR = CalcSHRUserDefinedCurves(state, CondInletDryBulb, EvapInletWetBulb, SecCoilFlowFraction, SecCoilSHRFT, SecCoilSHRFF, SecCoilRatedSHR);
16662 30261 : if (CoilMightBeDry) {
16663 30261 : if ((EvapInletHumRat < DryCoilTestEvapInletHumRat) && (SHRadp > SHR)) { // coil is dry for sure
16664 0 : SHR = 1.0;
16665 30261 : } else if (SHRadp > SHR) {
16666 0 : SHR = SHRadp;
16667 : }
16668 : }
16669 30261 : return SHR;
16670 : }
16671 :
16672 527483 : 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 527483 : Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
16699 527483 : 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 527483 : 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 527483 : if (present(PerfMode)) {
16750 0 : Mode = PerfMode;
16751 : } else {
16752 527483 : 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 527483 : if (present(OnOffAirFlowRatio)) {
16758 0 : AirFlowRatio = OnOffAirFlowRatio;
16759 : } else {
16760 527483 : AirFlowRatio = 1.0;
16761 : }
16762 :
16763 527483 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
16764 :
16765 : // Initialize coil air side parameters
16766 527483 : CondInletTemp = 0.0;
16767 527483 : CondInletHumRat = 0.0;
16768 527483 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
16769 527483 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
16770 527483 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
16771 527483 : InletAirHumRat = thisDXCoil.InletAirHumRat;
16772 527483 : state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
16773 527483 : thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
16774 527483 : thisDXCoil.PartLoadRatio = 0.0;
16775 527483 : thisDXCoil.BasinHeaterPower = 0.0;
16776 527483 : thisDXCoil.EvaporatingTemp = state.dataHVACVarRefFlow->VRF(thisDXCoil.VRFOUPtr).IUEvaporatingTemp;
16777 :
16778 527483 : 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 527483 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
16799 527483 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
16800 527483 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
16801 527483 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
16802 : }
16803 :
16804 527483 : 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 527483 : CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp or water inlet temp
16813 527483 : 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 527483 : 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 527483 : if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
16823 75937 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
16824 75937 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
16825 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
16826 : }
16827 : } else {
16828 451546 : CrankcaseHeatingPower = 0.0;
16829 : }
16830 :
16831 : // calculate end time of current time step to determine if error messages should be printed
16832 527483 : 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 527483 : 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 527483 : thisDXCoil.TimeStepSysLast = TimeStepSys;
16895 527483 : thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime;
16896 527483 : thisDXCoil.PrintLowAmbMessage = false;
16897 527483 : thisDXCoil.PrintLowOutTempMessage = false;
16898 :
16899 527483 : 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 186623 : 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 186623 : TotCap = min(MaxCoolCap, thisDXCoil.RatedTotCap(Mode));
16907 :
16908 186623 : QCoilReq = -PartLoadRatio * TotCap;
16909 186623 : if (PartLoadRatio == 0.0) {
16910 0 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
16911 : } else {
16912 186623 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
16913 : }
16914 :
16915 : // Call ControlVRFIUCoil to calculate: (1) FanSpdRatio, (2) coil inlet/outlet conditions, and (3) SH/SC
16916 186623 : 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 186623 : AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
16930 :
16931 186623 : AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
16932 186623 : 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 186623 : RatedCBF = thisDXCoil.RatedCBF(Mode);
16938 186623 : if (RatedCBF > 0.0) {
16939 186623 : A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
16940 : } else {
16941 0 : A0 = 0.0;
16942 : }
16943 186623 : ADiff = -A0 / AirMassFlow;
16944 186623 : if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
16945 132670 : CBF = std::exp(ADiff);
16946 : } else {
16947 53953 : 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 186623 : if (thisDXCoil.PLFFPLR(Mode) > 0 && CompCycRatio < 1.0) {
17003 0 : PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CompCycRatio); // Calculate part-load factor
17004 : } else {
17005 186623 : PLF = 1.0;
17006 : }
17007 :
17008 186623 : 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 186623 : thisDXCoil.PartLoadRatio = PartLoadRatio;
17023 186623 : thisDXCoil.CoolingCoilRuntimeFraction = CompCycRatio / PLF;
17024 186623 : 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 186623 : } 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 186623 : if (fanOp == HVAC::FanOp::Cycling) {
17046 16953 : state.dataHVACGlobal->OnOffFanPartLoadFraction = thisDXCoil.CoolingCoilRuntimeFraction;
17047 : }
17048 :
17049 : // Check for saturation error and modify temperature at constant enthalpy
17050 186623 : if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) {
17051 2006 : 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 2006 : OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
17056 : }
17057 :
17058 : // Store actual outlet conditions when DX coil is ON for use in heat recovery module
17059 186623 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = OutletAirTemp;
17060 186623 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = OutletAirHumRat;
17061 :
17062 : // Add warning message for cold cooling coil (OutletAirTemp < 2 C)
17063 186623 : 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 186623 : CalcComponentSensibleLatentOutput(AirMassFlow * PartLoadRatio,
17080 : InletAirDryBulbTemp,
17081 : InletAirHumRat,
17082 : OutletAirTemp,
17083 : OutletAirHumRat,
17084 186623 : thisDXCoil.SensCoolingEnergyRate,
17085 186623 : thisDXCoil.LatCoolingEnergyRate,
17086 186623 : thisDXCoil.TotalCoolingEnergyRate);
17087 :
17088 : // Coil outlet conditions
17089 186623 : thisDXCoil.OutletAirTemp = OutletAirTemp;
17090 186623 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
17091 186623 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
17092 :
17093 : // Coil SH/SC
17094 186623 : thisDXCoil.ActualSH = ActualSH;
17095 186623 : thisDXCoil.ActualSC = ActualSC;
17096 :
17097 : } else {
17098 : // DX coil is off; just pass through conditions
17099 :
17100 340860 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
17101 340860 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
17102 340860 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
17103 :
17104 340860 : thisDXCoil.ElecCoolingPower = 0.0;
17105 340860 : thisDXCoil.TotalCoolingEnergyRate = 0.0;
17106 340860 : thisDXCoil.SensCoolingEnergyRate = 0.0;
17107 340860 : thisDXCoil.LatCoolingEnergyRate = 0.0;
17108 340860 : thisDXCoil.EvapCondPumpElecPower = 0.0;
17109 340860 : thisDXCoil.EvapWaterConsumpRate = 0.0;
17110 :
17111 340860 : thisDXCoil.ActualSH = 999.0;
17112 340860 : thisDXCoil.ActualSC = 999.0;
17113 :
17114 : // Reset globals when DX coil is OFF for use in heat recovery module
17115 340860 : state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
17116 340860 : state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
17117 :
17118 : } // end of on/off
17119 :
17120 : // set water system demand request (if needed)
17121 527483 : if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
17122 0 : state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
17123 0 : thisDXCoil.EvapWaterConsumpRate;
17124 : }
17125 :
17126 527483 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
17127 527483 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
17128 527483 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
17129 527483 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
17130 527483 : thisDXCoil.CondInletTemp = CondInletTemp;
17131 527483 : state.dataDXCoils->DXCoilTotalCooling(DXCoilNum) = thisDXCoil.TotalCoolingEnergyRate;
17132 527483 : state.dataDXCoils->DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
17133 527483 : }
17134 :
17135 527483 : 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 527483 : 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 527483 : 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 527483 : if (present(OnOffAirFlowRatio)) {
17213 0 : AirFlowRatio = OnOffAirFlowRatio;
17214 : } else {
17215 527483 : AirFlowRatio = 1.0;
17216 : }
17217 :
17218 : // Air cooled condenser
17219 527483 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
17220 527483 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
17221 527483 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
17222 527483 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
17223 :
17224 527483 : auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
17225 :
17226 527483 : AirMassFlow = thisDXCoil.InletAirMassFlowRate;
17227 527483 : InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
17228 527483 : InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
17229 527483 : InletAirHumRat = thisDXCoil.InletAirHumRat;
17230 527483 : InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
17231 527483 : PLRHeating = 0.0;
17232 527483 : thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
17233 527483 : 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 527483 : if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
17237 75937 : CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
17238 75937 : if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
17239 0 : CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
17240 : }
17241 : } else {
17242 451546 : CrankcaseHeatingPower = 0.0;
17243 : }
17244 :
17245 653078 : if ((AirMassFlow > 0.0) && (compressorOp == HVAC::CompressorOp::On) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
17246 125595 : (OutdoorDryBulb > thisDXCoil.MinOATCompressor)) {
17247 :
17248 125595 : TotCap = thisDXCoil.RatedTotCap(Mode);
17249 125595 : 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 125595 : if (present(MaxHeatCap)) {
17253 125579 : TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
17254 125579 : TotCap = min(MaxHeatCap, TotCap);
17255 : } else {
17256 16 : TotCapAdj = TotCap * HeatingCapacityMultiplier;
17257 : }
17258 :
17259 125595 : QCoilReq = PartLoadRatio * TotCap;
17260 125595 : if (PartLoadRatio == 0.0) {
17261 0 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
17262 : } else {
17263 125595 : AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
17264 : }
17265 :
17266 : // Call ControlVRFIUCoil to calculate: (1) FanSpdRatio, (2) coil inlet/outlet conditions, and (3) SH/SC
17267 125595 : 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 125595 : AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
17281 :
17282 125595 : 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 125595 : 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 125595 : 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 125595 : OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
17294 125595 : OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
17295 :
17296 : // Initializing defrost adjustment factors
17297 125595 : LoadDueToDefrost = 0.0;
17298 125595 : FractionalDefrostTime = 0.0;
17299 125595 : InputPowerMultiplier = 1.0;
17300 :
17301 : // Calculate full load outlet conditions
17302 125595 : FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
17303 125595 : FullLoadOutAirHumRat = InletAirHumRat;
17304 125595 : FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
17305 125595 : 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 125595 : 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 125595 : 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 125595 : EIRTempModFac = 1.0;
17328 125595 : EIRFlowModFac = 1.0;
17329 : }
17330 125595 : EIR = thisDXCoil.RatedEIR(Mode) * EIRTempModFac * EIRFlowModFac;
17331 :
17332 : // Calculate PLRHeating: modified PartLoadRatio due to defrost ( reverse-cycle defrost only )
17333 125595 : if (TotCap > 0.0) {
17334 125595 : PLRHeating = min(1.0, (PartLoadRatio + LoadDueToDefrost / TotCap));
17335 : } else {
17336 0 : PLRHeating = min(1.0, PartLoadRatio);
17337 : }
17338 :
17339 125595 : 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 125595 : PLF = 1.0;
17343 : }
17344 :
17345 125595 : 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 125595 : thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
17359 125595 : 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 125595 : } 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 125595 : if (fanOp == HVAC::FanOp::Cycling) {
17381 4355 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
17382 : }
17383 125595 : 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 125595 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
17388 125595 : 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 125595 : thisDXCoil.OutletAirTemp = OutletAirTemp;
17396 125595 : thisDXCoil.OutletAirHumRat = OutletAirHumRat;
17397 125595 : thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
17398 125595 : thisDXCoil.CompressorPartLoadRatio = PartLoadRatio;
17399 125595 : thisDXCoil.ActualSH = ActualSH;
17400 125595 : thisDXCoil.ActualSC = ActualSC;
17401 125595 : thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy) * PartLoadRatio;
17402 125595 : thisDXCoil.DefrostPower = thisDXCoil.DefrostPower * thisDXCoil.HeatingCoilRuntimeFraction;
17403 :
17404 : } else {
17405 : // DX coil is off; just pass through conditions
17406 :
17407 401888 : thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
17408 401888 : thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
17409 401888 : thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
17410 :
17411 401888 : thisDXCoil.ElecHeatingPower = 0.0;
17412 401888 : thisDXCoil.TotalHeatingEnergyRate = 0.0;
17413 401888 : 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 401888 : if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
17418 401888 : thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
17419 : } else {
17420 0 : thisDXCoil.CrankcaseHeaterPower =
17421 0 : CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
17422 : }
17423 401888 : thisDXCoil.CompressorPartLoadRatio = 0.0;
17424 :
17425 401888 : thisDXCoil.ActualSH = 999.0;
17426 401888 : thisDXCoil.ActualSC = 999.0;
17427 : } // end of on/off if - else
17428 :
17429 527483 : state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
17430 527483 : state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
17431 527483 : state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
17432 527483 : state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
17433 527483 : state.dataDXCoils->DXCoilTotalHeating(DXCoilNum) = thisDXCoil.TotalHeatingEnergyRate;
17434 527483 : state.dataDXCoils->DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
17435 527483 : state.dataDXCoils->DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;
17436 :
17437 : // calc secondary coil if specified
17438 527483 : if (thisDXCoil.IsSecondaryDXCoilInZone) {
17439 0 : CalcSecondaryDXCoils(state, DXCoilNum);
17440 : }
17441 527483 : }
17442 :
17443 1397219 : 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 1397219 : int MaxIter(500); // Max iteration numbers (-)
17475 : int SolFla; // Solving flag for SolveRoot (-)
17476 1397219 : int constexpr FlagCoolMode(0); // Flag for cooling mode
17477 1397219 : 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 1397219 : RHsat = 0.98; // Saturated RH
17509 1397219 : MaxSH = 15;
17510 1397219 : MaxSC = 20;
17511 1397219 : Garate = state.dataDXCoils->DXCoil(CoilIndex).RatedAirMassFlowRate(1);
17512 1397219 : FanSpdRatioMin = min(OAMassFlow / Garate, 1.0); // ensure that coil flow rate is higher than OA flow rate
17513 :
17514 1397219 : 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 1397219 : } else if (QCoil < 0) {
17526 : // Cooling Mode
17527 :
17528 : // Obtain coil cooling loads
17529 810327 : QCoilSenCoolingLoad = -QCoil;
17530 :
17531 : // Coefficients describing coil performance
17532 810327 : SH = state.dataDXCoils->DXCoil(CoilIndex).SH;
17533 810327 : C1Tevap = state.dataDXCoils->DXCoil(CoilIndex).C1Te;
17534 810327 : C2Tevap = state.dataDXCoils->DXCoil(CoilIndex).C2Te;
17535 810327 : C3Tevap = state.dataDXCoils->DXCoil(CoilIndex).C3Te;
17536 810327 : BF = state.dataDXCoils->DXCoil(CoilIndex).RateBFVRFIUEvap;
17537 :
17538 : // Coil sensible heat transfer_minimum value
17539 810327 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilIndex, Tin, TeTc, SH, BF, QinSenPerFlowRate, Ts_1);
17540 810327 : To_1 = Tin - QinSenPerFlowRate / 1005;
17541 810327 : QinSenMin1 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds real SH
17542 :
17543 810327 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilIndex, Tin, TeTc, MaxSH, BF, QinSenPerFlowRate, Ts_2);
17544 810327 : To_2 = Tin - QinSenPerFlowRate / 1005;
17545 810327 : QinSenMin2 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds maximum SH
17546 :
17547 810327 : if (QCoilSenCoolingLoad > QinSenMin1) {
17548 : // Increase fan speed to meet room sensible load; SH is not updated
17549 658480 : FanSpdRatioMax = 1.0;
17550 1737014 : auto f = [QCoilSenCoolingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
17551 1737014 : return FanSpdResidualCool(FanSpdRto, QCoilSenCoolingLoad, Ts_1, Tin, Garate, BF);
17552 658480 : };
17553 658480 : General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, Ratio1, f, FanSpdRatioMin, FanSpdRatioMax);
17554 658480 : if (SolFla < 0) {
17555 238426 : Ratio1 = FanSpdRatioMax; // over capacity
17556 : }
17557 658480 : FanSpdRatio = Ratio1;
17558 658480 : CoilOnOffRatio = 1.0;
17559 :
17560 658480 : Tout = To_1; // Since SH is not updated
17561 658480 : Ws = PsyWFnTdbRhPb(state, Ts_1, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
17562 658480 : if (Ws < Win) {
17563 652284 : Wout = Win - (Win - Ws) * (1 - BF);
17564 : } else {
17565 6196 : Wout = Win;
17566 : }
17567 658480 : Hout = PsyHFnTdbW(Tout, Wout);
17568 658480 : SCact = 999.0;
17569 658480 : 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 151847 : FanSpdRatio = FanSpdRatioMin;
17577 :
17578 151847 : CoilOnOffRatio = 1.0;
17579 :
17580 151847 : Tout = Tin - QCoilSenCoolingLoad / 1005.0 / FanSpdRatioMin / Garate;
17581 151847 : Ts = Tin - (Tin - Tout) / (1 - BF);
17582 151847 : deltaT = Ts - TeTc;
17583 :
17584 : // Update SH
17585 151847 : if (C3Tevap <= 0.0) {
17586 151843 : if (C2Tevap > 0.0) {
17587 151843 : SHact = (deltaT - C1Tevap) / C2Tevap;
17588 : } else {
17589 0 : SHact = 998.0;
17590 : }
17591 : } else {
17592 4 : SHact = (-C2Tevap + sqrt(pow_2(C2Tevap) - 4 * C3Tevap * (C1Tevap - deltaT))) / 2 / C3Tevap;
17593 : }
17594 :
17595 151847 : Ws = PsyWFnTdbRhPb(state, Ts, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
17596 151847 : if (Ws < Win) {
17597 113781 : Wout = Win - (Win - Ws) * (1 - BF);
17598 : } else {
17599 38066 : Wout = Win;
17600 : }
17601 :
17602 151847 : if (SHact > MaxSH) {
17603 : // Further implement On/Off Control
17604 67093 : SHact = MaxSH;
17605 67093 : CoilOnOffRatio = QCoilSenCoolingLoad / QinSenMin2;
17606 :
17607 67093 : Ts = Ts_2;
17608 67093 : Ws = PsyWFnTdbRhPb(state, Ts, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
17609 67093 : if (Ws < Win) {
17610 66191 : Wout = Win - (Win - Ws) * (1 - BF);
17611 : } else {
17612 902 : Wout = Win;
17613 : }
17614 :
17615 : // outlet air temperature and humidity ratio is time-weighted
17616 67093 : Tout = CoilOnOffRatio * To_2 + (1 - CoilOnOffRatio) * Tin;
17617 67093 : Wout = CoilOnOffRatio * Wout + (1 - CoilOnOffRatio) * Win;
17618 : }
17619 :
17620 151847 : Hout = PsyHFnTdbW(Tout, Wout);
17621 151847 : SCact = 999.0;
17622 : }
17623 :
17624 586892 : } else if (QCoil > 0) {
17625 : // Heating Mode
17626 :
17627 : // Obtain zonal heating loads
17628 586892 : QCoilSenHeatingLoad = QCoil;
17629 :
17630 : // Coefficients describing coil performance
17631 586892 : SC = state.dataDXCoils->DXCoil(CoilIndex).SC;
17632 586892 : C1Tcond = state.dataDXCoils->DXCoil(CoilIndex).C1Tc;
17633 586892 : C2Tcond = state.dataDXCoils->DXCoil(CoilIndex).C2Tc;
17634 586892 : C3Tcond = state.dataDXCoils->DXCoil(CoilIndex).C3Tc;
17635 586892 : BF = state.dataDXCoils->DXCoil(CoilIndex).RateBFVRFIUCond;
17636 :
17637 : // Coil sensible heat transfer_minimum value
17638 586892 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilIndex, Tin, TeTc, SC, BF, QinSenPerFlowRate, Ts_1);
17639 586892 : To_1 = QinSenPerFlowRate / 1005 + Tin;
17640 586892 : QinSenMin1 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds real SH
17641 :
17642 586892 : CalcVRFCoilSenCap(state, FlagHeatMode, CoilIndex, Tin, TeTc, MaxSC, BF, QinSenPerFlowRate, Ts_2);
17643 586892 : To_2 = QinSenPerFlowRate / 1005 + Tin;
17644 586892 : QinSenMin2 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds maximum SH
17645 :
17646 586892 : if (QCoilSenHeatingLoad > QinSenMin1) {
17647 : // Modulate fan speed to meet room sensible load; SC is not updated
17648 408152 : FanSpdRatioMax = 1.0;
17649 1183755 : auto f = [QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
17650 1183755 : return FanSpdResidualHeat(FanSpdRto, QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF);
17651 408152 : };
17652 408152 : 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 408152 : if (SolFla < 0) {
17655 40701 : Ratio1 = FanSpdRatioMax; // over capacity
17656 : }
17657 408152 : FanSpdRatio = Ratio1;
17658 408152 : CoilOnOffRatio = 1.0;
17659 :
17660 408152 : Tout = Tin + (Ts_1 - Tin) * (1 - BF);
17661 408152 : Wout = Win;
17662 408152 : Hout = PsyHFnTdbW(Tout, Wout);
17663 408152 : SHact = 999.0;
17664 408152 : 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 178740 : FanSpdRatio = FanSpdRatioMin;
17672 178740 : CoilOnOffRatio = 1.0;
17673 :
17674 178740 : Tout = Tin + QCoilSenHeatingLoad / 1005.0 / FanSpdRatio / Garate;
17675 178740 : Ts = Tin + (Tout - Tin) / (1 - BF);
17676 178740 : deltaT = TeTc - Ts;
17677 :
17678 : // Update SC
17679 178740 : 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 178740 : SCact = (-C2Tcond + sqrt(pow_2(C2Tcond) - 4 * C3Tcond * (C1Tcond - deltaT))) / 2 / C3Tcond;
17687 : }
17688 :
17689 178740 : if (SCact > MaxSC) {
17690 : // Implement On/Off Control
17691 39130 : SCact = MaxSC;
17692 39130 : CoilOnOffRatio = QCoilSenHeatingLoad / QinSenMin2;
17693 : // outlet air temperature is time-weighted
17694 39130 : Tout = CoilOnOffRatio * To_2 + (1 - CoilOnOffRatio) * Tin;
17695 : }
17696 178740 : Wout = Win;
17697 178740 : Hout = PsyHFnTdbW(Tout, Wout);
17698 178740 : SHact = 999.0;
17699 : }
17700 : }
17701 1397219 : }
17702 :
17703 2794470 : 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 2794470 : int constexpr FlagCoolMode(0); // Flag for cooling mode
17727 2794470 : 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 2794470 : if (OperationMode == FlagCoolMode) {
17741 : // Cooling: OperationMode 0
17742 :
17743 1620686 : C1Tevap = state.dataDXCoils->DXCoil(CoilNum).C1Te;
17744 1620686 : C2Tevap = state.dataDXCoils->DXCoil(CoilNum).C2Te;
17745 1620686 : C3Tevap = state.dataDXCoils->DXCoil(CoilNum).C3Te;
17746 1620686 : SH = SHSC;
17747 1620686 : T_coil_in = Tinlet;
17748 :
17749 : // Coil surface temperature
17750 1620686 : deltaT = C3Tevap * SH * SH + C2Tevap * SH + C1Tevap;
17751 1620686 : T_coil_surf = TeTc + deltaT;
17752 :
17753 : // Outlet air temperature
17754 1620686 : 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 1620686 : Q_sen = max(1005 * (T_coil_in - T_coil_out), 0.0);
17758 :
17759 1173784 : } else if (OperationMode == FlagHeatMode) {
17760 : // Heating: OperationMode 1
17761 :
17762 1173784 : C1Tcond = state.dataDXCoils->DXCoil(CoilNum).C1Tc;
17763 1173784 : C2Tcond = state.dataDXCoils->DXCoil(CoilNum).C2Tc;
17764 1173784 : C3Tcond = state.dataDXCoils->DXCoil(CoilNum).C3Tc;
17765 1173784 : SC = SHSC;
17766 1173784 : T_coil_in = Tinlet;
17767 :
17768 : // Coil surface temperature
17769 1173784 : deltaT = C3Tcond * SC * SC + C2Tcond * SC + C1Tcond;
17770 1173784 : T_coil_surf = TeTc - deltaT;
17771 :
17772 : // Coil outlet air temperature
17773 1173784 : T_coil_out = T_coil_in + (T_coil_surf - T_coil_in) * (1 - BF);
17774 :
17775 : // Coil sensilbe heat transfer_minimum value
17776 1173784 : Q_sen = max(1005 * (T_coil_out - T_coil_in), 0.0);
17777 : }
17778 2794470 : }
17779 :
17780 16 : 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 16 : bool ErrorsFound(false); // Flag for errors
17805 16 : int constexpr FlagCoolMode(0); // Flag for cooling mode
17806 16 : int constexpr FlagHeatMode(1); // Flag for heating mode
17807 16 : Real64 constexpr SH_rate(3); // Super heating at cooling mode, default 3(C)
17808 16 : Real64 constexpr SC_rate(5); // Subcooling at heating mode, default 5 (C)
17809 16 : Real64 constexpr Te_rate(6); // Evaporating temperature at cooling mode, default 6 (C)
17810 16 : 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 16 : if (present(CoilIndex)) {
17822 0 : CoilNum = CoilIndex;
17823 : } else {
17824 16 : GetDXCoilIndex(state, CoilName, CoilNum, ErrorsFound, "", true);
17825 : }
17826 :
17827 16 : BFC_rate = state.dataDXCoils->DXCoil(CoilNum).RateBFVRFIUEvap;
17828 16 : BFH_rate = state.dataDXCoils->DXCoil(CoilNum).RateBFVRFIUCond;
17829 :
17830 16 : if (OperationMode == FlagCoolMode) {
17831 : // Cooling: OperationMode 0
17832 :
17833 16 : if (present(BF)) {
17834 0 : BF_real = BF;
17835 : } else {
17836 16 : BF_real = BFC_rate;
17837 : }
17838 16 : if (present(TeTc)) {
17839 0 : TeTc_real = TeTc;
17840 : } else {
17841 16 : TeTc_real = Te_rate;
17842 : }
17843 16 : if (present(SHSC)) {
17844 0 : SHSC_real = SHSC;
17845 : } else {
17846 16 : SHSC_real = SH_rate;
17847 : }
17848 :
17849 : // Coil capacity at rated conditions
17850 16 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilNum, 26, Te_rate, SH_rate, BFC_rate, Q_rate, Ts);
17851 :
17852 : // Coil capacity at given conditions
17853 16 : CalcVRFCoilSenCap(state, FlagCoolMode, CoilNum, Tinlet, TeTc_real, SHSC_real, BF_real, Q_real, Ts);
17854 :
17855 16 : if (Q_rate > 0) {
17856 16 : 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 16 : }
17893 :
17894 1737014 : 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 1737014 : Real64 ZnSenLoad = QCoilSenCoolingLoad;
17908 : // +-100 W minimum zone load?
17909 1737014 : if (std::abs(ZnSenLoad) < 100.0) {
17910 0 : ZnSenLoad = sign(100.0, ZnSenLoad);
17911 : }
17912 1737014 : Real64 Tout = Tin - (Tin - Ts_1) * (1 - BF);
17913 1737014 : Real64 TotCap = FanSpdRto * Garate * 1005.0 * (Tin - Tout);
17914 1737014 : return (TotCap - ZnSenLoad) / ZnSenLoad;
17915 : }
17916 :
17917 1183755 : 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 1183755 : Real64 ZnSenLoad = QCoilSenHeatingLoad;
17932 : // +-100 W minimum zone load?
17933 1183755 : if (std::abs(ZnSenLoad) < 100.0) {
17934 0 : ZnSenLoad = sign(100.0, ZnSenLoad);
17935 : }
17936 1183755 : Real64 Tout = Tin + (Ts_1 - Tin) * (1 - BF);
17937 1183755 : Real64 TotCap = FanSpdRto * Garate * 1005.0 * (Tout - Tin);
17938 1183755 : return (TotCap - ZnSenLoad) / ZnSenLoad;
17939 : }
17940 :
17941 0 : 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 0 : if (state.dataDXCoils->DXCoil(DXCoilNum).FuelType != Constant::eFuel::Electricity) {
17952 0 : state.dataDXCoils->DXCoil(DXCoilNum).MSHPHeatRecActive = true;
17953 : }
17954 0 : }
17955 :
17956 32 : 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 32 : if (state.dataDXCoils->GetCoilsInputFlag) {
17969 0 : GetDXCoils(state);
17970 0 : state.dataDXCoils->GetCoilsInputFlag = false;
17971 : }
17972 :
17973 32 : WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
17974 32 : if (WhichCoil != 0) {
17975 32 : state.dataDXCoils->DXCoil(WhichCoil).AirLoopNum = AirLoopNum;
17976 : } else {
17977 0 : ShowSevereError(state, format("SetDXCoilAirLoopNumber: Could not find Coil \"Name=\"{}\"", CoilName));
17978 : }
17979 32 : } // 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
|